# articles

feed_id: urn:md5:4f56575f42207bed61294840682bab71
title: Python: multiprocessing vs threading
uri: Python-multiprocessing-vs-threading
url: http://www.fevrierdorian.com/blog/post/2012/04/04/Python-multiprocessing-vs-threading
content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_04_04_threadingVSmultiprocess/threadingVSmultiprocess_tn.png" alt="threadingVSmultiprocess_tn.png" style="float:left; margin: 0 1em 1em 0;" title="threadingVSmultiprocess_tn.png, avr. 2012"  height="150" width="150" />Ce billet va tenter de montrer, principalement par l'exemple les différences entre le module <em>threading</em> et le module... <em>multiprocessing</em>! Je vous propose donc deux petits codes pour démarrer rapidement.</p>


<p>La plupart des TD Maya on déjà entendu parler du threading. Non pas pour savoir a quoi ça servait exactement mais parce que Maya a toujours eu du mal avec ce machin la. <img src="/blog/themes/blueSilenceCustom/smilies/gne.gif" alt=":gne:" class="smiley" /></p>


<p>Cela dit, ce billet est très général et n'aborde pas les problèmes de threading dans Maya. <img src="/blog/themes/blueSilenceCustom/smilies/cayMal.gif" alt=":cayMal:" class="smiley" /> Juste les différences entre le module <em>threading</em> et <em>multiprocessing</em>.</p>    <h3>Le module threading</h3>


<p>Pour faire simple, avec ce module vous "fabriquez" des objets de type Thread, chacun ayant une tache a accomplir. Vous lancez ces objets dans la nature et vous attendez qu'ils reviennent...</p>


<p>Comment ça se passe dans la pratique? <img src="/blog/themes/blueSilenceCustom/smilies/reflechi.gif" alt=":reflechi:" class="smiley" /></p>


<p>Déjà, il vous faut une fonction suffisamment lourde pour mettre à genoux votre machine:</p>

<pre class="python python">K = <span style="color: #ff4500;">50</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> CostlyFunction<span style="color: black;">&#40;</span>z<span style="color: black;">&#41;</span>:
	result = <span style="color: #ff4500;">0</span>
	<span style="color: #ff7700;font-weight:bold;">for</span> k <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, K+<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>:
		result += z <span style="color: #66cc66;">**</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span> / k<span style="color: #66cc66;">**</span><span style="color: #ff4500;">1.5</span><span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">return</span> result</pre>


<p>Honteusement pompée du fil Stack Overflow: <a href="http://stackoverflow.com/a/4415314" hreflang="en">multiprocess or threading in python?</a>.</p>


<p>Comme je vous disais, il vous faut un objet de type Thread:</p>

<pre class="python python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">threading</span>
&nbsp;
K = <span style="color: #ff4500;">50</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">class</span> CostlyThread<span style="color: black;">&#40;</span><span style="color: #dc143c;">threading</span>.<span style="color: black;">Thread</span><span style="color: black;">&#41;</span>:
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, value<span style="color: black;">&#41;</span>:
&nbsp;
		<span style="color: #dc143c;">threading</span>.<span style="color: black;">Thread</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">value</span> = value
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">def</span> run<span style="color: black;">&#40;</span><span style="color: #008000;">self</span><span style="color: black;">&#41;</span>:
		<span style="color: #808080; font-style: italic;"># notre fonction</span>
		result = <span style="color: #ff4500;">0</span>
		z = <span style="color: #008000;">self</span>.<span style="color: black;">value</span>
		<span style="color: #ff7700;font-weight:bold;">for</span> k <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span>, K+<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>:
			result += z <span style="color: #66cc66;">**</span> <span style="color: black;">&#40;</span><span style="color: #ff4500;">1</span> / k<span style="color: #66cc66;">**</span><span style="color: #ff4500;">1.5</span><span style="color: black;">&#41;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">value</span> = result</pre>


<p>Et on balance tout!</p>

<pre class="python python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">time</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># timer</span>
startTime = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># va stocker les threads qu'on va lancer.</span>
threadList = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">100000</span><span style="color: black;">&#41;</span> :	<span style="color: #808080; font-style: italic;"># on lance cent milles threads</span>
&nbsp;
	curThread = CostlyThread<span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>
	curThread.<span style="color: black;">start</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># on lance le thread</span>
	threadList.<span style="color: black;">append</span><span style="color: black;">&#40;</span>curThread<span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># on ajoute le thread a la list</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># maintenant qu'on a tout lance, on récupère tout!</span>
resultList = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">for</span> curThread <span style="color: #ff7700;font-weight:bold;">in</span> threadList :
&nbsp;
	curThread.<span style="color: black;">join</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># on attend que le thread ait fini</span>
	result = curThread.<span style="color: black;">value</span>	<span style="color: #808080; font-style: italic;"># on récupère sa valeur</span>
	resultList.<span style="color: black;">append</span><span style="color: black;">&#40;</span>result<span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - startTime</pre>


<p>Sauvez tout ça dans un fichier python puis lancez un moniteur système et regardez bien ce que Python va faire...</p>


<p>21.4 secondes plus tard... <img src="/blog/themes/blueSilenceCustom/smilies/siffle.gif" alt=":siffle:" class="smiley" /></p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_04_04_threadingVSmultiprocess/threadingVSmultiprocess_002.png" alt="threadingVSmultiprocess_002.png" style="display:block; margin:0 auto;" title="threadingVSmultiprocess_002.png, avr. 2012"  height="131" width="239" /></p>


<p>Vous remarquerez que Python n'a pas tous les processeurs à fond. <img src="/blog/themes/blueSilenceCustom/smilies/redface.gif" alt=":redface:" class="smiley" /></p>


<p>En fait, le threading n'a pas pour vocation de faire "beaucoup de petits calculs". Il n'est pas efficace pour ce genre de chose (je ne rentre pas dans les détails, c'est très bien expliqué dans le fil Stack Overflow: <a href="http://stackoverflow.com/questions/34020/are-python-threads-buggy" hreflang="en">Are Python threads buggy?</a>).</p>


<p>Un des principal intérêt du threading c'est sa mise en place. Il est très simple à utiliser. On va principalement s'en servir pour faire des opérations nécessitant de la "latence".</p>


<p>Je pense qu'on doit pouvoir aller plus loin mais personnellement, je l'utilise souvent quand je dois faire plusieurs appels réseaux dans une boucle (récupérer la date de modification d'une liste de fichiers) c'est beaucoup plus efficace que d'attendre a chaque fois que le réseau nous donne la main pour redemander une informations similaire juste après.</p>


<p>Pas convaincu?</p>


<blockquote><p>25709 existences de fichier vérifiées en 38.35 secondes <img src="/blog/themes/blueSilenceCustom/smilies/IFuckTheWorld.gif" alt=":IFuckTheWorld:" class="smiley" /></p></blockquote>


<p>J'ose même pas imaginer le temps que ça aurait pris si j'avais fait la même chose en récursif...</p>


<p>Après, le réseau en question était solide (c'est pas du routeur de promotion Carrefour! <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /> ).

Cela dit, suivant l’opération faite par le thread vous pouvez plomber le réseau (ce sera toujours moins pire que Nuke et After Effect en rendu cela dit <img src="/blog/themes/blueSilenceCustom/smilies/trollface_smiley.png" alt=":trollface:" class="smiley" /> )... Donc faite attention.</p>


<p>Viens maintenant le problème de "calcul brut". Si le threading ne permet pas d'utiliser l’intégralité de son processeur, comment puis-je faire des calculs très lourds?</p>


<p>C'est la seconde partie de ce billet! <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></p>


<h3>Le module multiprocessing</h3>


<p>Ce module est un petit peu plus subtil à utiliser et il y a plusieurs façons de faire.</p>


<p>La méthode que nous allons voir est l'une des (la?) plus efficace:</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">import</span> multiprocessing <span style="color: #ff7700;font-weight:bold;">as</span> mp
&nbsp;
<span style="color: #808080; font-style: italic;"># timer</span>
startTime = <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
pool = mp.<span style="color: black;">Pool</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
asyncResult = pool.<span style="color: black;">map_async</span><span style="color: black;">&#40;</span>CostlyFunction, <span style="color: #008000;">xrange</span><span style="color: black;">&#40;</span><span style="color: #ff4500;">100000</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># on lance aussi cent milles operations</span>
resultList = asyncResult.<span style="color: black;">get</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># asyncResult.get() is a list of values</span>
<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #dc143c;">time</span>.<span style="color: #dc143c;">time</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> - startTime</pre>

<p>0.9 secondes plus tard (Et ouai, faut suivre...)</p>


<p>Vous n'avez peut être rien vu mais si vous avez toujours votre moniteur système d'ouvert avec un graph de charge processeur, vous verrez que pendant ce court laps de temps, tous les processeurs étaient en pleine activité...</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_04_04_threadingVSmultiprocess/threadingVSmultiprocess_001.png" alt="threadingVSmultiprocess_001.png" style="display:block; margin:0 auto;" title="threadingVSmultiprocess_001.png, avr. 2012"  height="135" width="223" /></p>


<p>Ajoutez un zéro et regardez comment votre processeur il pleure sa maman (on gaspille aussi plein d’énergie hein! <img src="/blog/themes/blueSilenceCustom/smilies/seSentCon.gif" alt=":seSentCon:" class="smiley" /> ).</p>


<p>Je m’arrête la. Le module multiprocessing offre beaucoup plus de possibilités (gestion d'une <em>queue</em>). Mais pour l'instant, je n'ai jamais eu a l'utiliser. <img src="/blog/themes/blueSilenceCustom/smilies/riva.gif" alt=":pasClasse:" class="smiley" /></p>


<h3>Conclusion</h3>


<p>J’espère que ce petit billet vous aura donné des bouts de code suffisant pour débuter. Personnellement, j’apprécie beaucoup la simplicité du module <em>threading</em> qu'on peut sortir dans pas mal de situations des lors qu'on touche au fichiers.</p>


<p>A bientôt!</p>


<p>Dorian</p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></center>


feed_id: urn:md5:5b23c6224f24f84afb5897f290a32de1
title: Du métal plus métalique?
uri: Du-métal-plus-métalique
url: http://www.fevrierdorian.com/blog/post/2012/03/18/Du-metal-plus-metalique
content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/metal_plus_metalique_tn.png" alt="metal_plus_metalique_tn.png" style="float:left; margin: 0 1em 1em 0;" title="metal_plus_metalique_tn.png, mar. 2012"  height="150" width="150" />Hello tous!</p>


<p>Comme j'en bouffe tous les jours en ce moment j'ai décidé vous faire partager le très intéressant billet de Master Zap: <a href="http://mentalraytips.blogspot.fr/2007/10/making-better-metal-with-miamaterial.html" hreflang="en">Making Better Metal with mia_material</a>.</p>


<p>Ceux qui l'ont déjà lu en long en large, passez votre chemin, je ne fait que répéter les dires du maitre.</p>


<p>Les autres, avec un peu de chance, vous allez apprendre quelque chose aujourd'hui. <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></p>    <h3>Un bon metal, c'est d'abord une bonne map HDR</h3>


<p>Avant de commencer, aller récupérer une des magnifiques image HDR de <a href="http://www.hdrlabs.com/sibl/archive.html" hreflang="en">sIBL Archive</a>.</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/sibl_archive_icon_light.png" alt="sibl_archive_icon_light.png" style="display:block; margin:0 auto;" title="sibl_archive_icon_light.png, mar. 2012"  height="120" width="140" /></p>


<p>Elles sont toutes sous licence <a href="https://creativecommons.org/licenses/by-nc-sa/3.0/fr/" hreflang="fr">Creative Commons Attribution-Noncommercial-Share Alike 3.0</a>, ce qui veut dire que vous ne pouvez pas gagner d'argent avec et que si vous les utilisez (comme ça va être le cas ici) il faut citer l'auteur et partager votre travail à l'identique.</p>


<p>Pour le choix de l'image. J'ai toujours eu une préférence pour Factory Catwalk:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/Factory_Catwalk.png" alt="Factory_Catwalk.png" style="display:block; margin:0 auto;" title="Factory_Catwalk.png, mar. 2012"  height="256" width="512" /></p>


<h3>Et go Maya!</h3>

<p>Comme d'hab', ouvrez Maya, mental ray, preset <em>Production</em>:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/maya_preset_production.png" alt="maya_preset_production.png" style="display:block; margin:0 auto;" title="maya_preset_production.png, mar. 2012"  height="238" width="237" /></p>


<p><em>Filter</em> en <em>Triangle</em>:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/maya_filter_triangle.png" alt="maya_filter_triangle.png" style="display:block; margin:0 auto;" title="maya_filter_triangle.png, mar. 2012"  height="145" width="196" /></p>


<p>Puis on créé une IBL:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/maya_create_ibl.png" alt="maya_create_ibl.png" style="display:block; margin:0 auto;" title="maya_create_ibl.png, mar. 2012"  height="126" width="395" /></p>


<p>Et on y met notre hdr:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/maya_ibl_hdr.png" alt="maya_ibl_hdr.png" style="display:block; margin:0 auto;" title="maya_ibl_hdr.png, mar. 2012"  height="151" width="418" /></p>


<p>Créez une sphère et appliquez lui un <em>mia_material_x</em>:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/metal_plus_metalique_001.png" alt="metal_plus_metalique_001.png" style="display:block; margin:0 auto;" title="metal_plus_metalique_001.png, mar. 2012"  height="480" width="640" /></p>


<p>Virez le <em>highlight</em> (je le fait car je ne peux <del>pas</del> plus le supporter personnellement):</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/metal_plus_metalique_002.png" alt="metal_plus_metalique_002.png" style="display:block; margin:0 auto;" title="metal_plus_metalique_002.png, mar. 2012"  height="214" width="452" /></p>
<center><i>Mettez la Specular Balance a 0.0</i></center>



<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/metal_plus_metalique_003.png" alt="metal_plus_metalique_003.png" style="display:block; margin:0 auto;" title="metal_plus_metalique_003.png, mar. 2012"  height="480" width="640" /></p>


<p>Pour avoir une colorimétrie correct, on applique une correction gamma:</p>

<pre class="mel mel">createNode mip_gamma_gain<span style="color: #339933;">;</span>
setAttr <span style="color: #ff0000;">&quot;mip_gamma_gain1.gamma&quot;</span> <span style="color:#800080;">2.2</span><span style="color: #339933;">;</span>
connectAttr <span style="color: #339933;">-</span>f mip_gamma_gain1.<span style="color: #202020;">message</span> perspShape.<span style="color: #202020;">miLensShader</span><span style="color: #339933;">;</span></pre>


<p>Et voila:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/metal_plus_metalique_004.png" alt="metal_plus_metalique_004.png" style="display:block; margin:0 auto;" title="metal_plus_metalique_004.png, mar. 2012"  height="480" width="640" /></p>


<p>Bon, pour faire du métal, a priori, on met la <em>color</em> en blanc et le <em>weight</em> a zéro, la <em>reflectivity</em> a 1.0 et on coche la case <em>Metal Material</em>:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/metal_plus_metalique_005.png" alt="metal_plus_metalique_005.png" style="display:block; margin:0 auto;" title="metal_plus_metalique_005.png, mar. 2012"  height="480" width="640" /></p>


<p>Comme on est des graphistes <img src="/blog/themes/blueSilenceCustom/smilies/nexath.gif" alt=":smileFou:" class="smiley" /> on met aussi de la couleur:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/metal_plus_metalique_006.png" alt="metal_plus_metalique_006.png" style="display:block; margin:0 auto;" title="metal_plus_metalique_006.png, mar. 2012"  height="480" width="640" /></p>


<p>Le centre de la sphère semble sombre ça ne ressemble pas vraiment à du métal. <img src="/blog/themes/blueSilenceCustom/smilies/reflechi.gif" alt=":reflechi:" class="smiley" /></p>


<p>Si vous connaissez un peu le mia_material, vous savez qu'il existe un paramètre dans l'onglet <a href="http://docs.autodesk.com/MENTALRAY/2012/ENU/mental%20ray%203.9%20Help/files/shaders/architectural/arch_mtl.html#BRDF" hreflang="en">BRDF</a> pour donner les deux valeurs extrêmes de reflection quand la surface est face à la camera et quand celle ci est complètement perpendiculaire (<em>0/90 Degree Reflection</em>). Avec un autre paramètre qui définit la courbe pour passer d'une valeur à l'autre.</p>


<p>Pour faire du metal à priori, il suffit de monter la première valeur (<em>0 Degree Reflection</em>) à une valeur proche de 1.0:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/metal_plus_metalique_007.png" alt="metal_plus_metalique_007.png" style="display:block; margin:0 auto;" title="metal_plus_metalique_007.png, mar. 2012"  height="141" width="439" /></p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/metal_plus_metalique_008.png" alt="metal_plus_metalique_008.png" style="display:block; margin:0 auto;" title="metal_plus_metalique_008.png, mar. 2012"  height="480" width="640" /></p>
<center><i>Oaaah De l'or qui briiiiille! <img src="/blog/themes/blueSilenceCustom/smilies/bete.gif" alt=":bete:" class="smiley" /> </i></center>



<p>Bon, et bien en fait, vous n'y êtes pas complètement. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>Là vous avez fait un bête miroir jaune... Dans le fond c'est assez proche du résultat final. Mais un des grand challenge du "Physical Based" c'est bien que ce n'est plus simplement une question d'oeil. <img src="/blog/themes/blueSilenceCustom/smilies/redface.gif" alt=":redface:" class="smiley" /></p>


<p>Et pour avoir un comportement de métal plus réaliste, il va falloir regarder du coté de Fresnel (si si).</p>


<p>Donc vous cochez la case:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/metal_plus_metalique_009.png" alt="metal_plus_metalique_009.png" style="display:block; margin:0 auto;" title="metal_plus_metalique_009.png, mar. 2012"  height="133" width="438" /></p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/metal_plus_metalique_010.png" alt="metal_plus_metalique_010.png" style="display:block; margin:0 auto;" title="metal_plus_metalique_010.png, mar. 2012"  height="480" width="640" /></p>
<center><i>Ne vous inquiétez pas, ce n'est pas le résultat final! <img src="/blog/themes/blueSilenceCustom/smilies/seSentCon.gif" alt=":seSentCon:" class="smiley" /> </i></center>



<p>Maintenant, ce que vous allez faire, c'est mettre l'index de refraction (oui oui, reFRACtion) a 25:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/metal_plus_metalique_011.png" alt="metal_plus_metalique_011.png" style="display:block; margin:0 auto;" title="metal_plus_metalique_011.png, mar. 2012"  height="480" width="640" /></p>


<p>La différence est assez subtile (comparez avec le <em>Keep image</em> de Maya) mais le second se rapprochera beaucoup plus d'un métal physiquement correct, notamment sur les bords.</p>


<p>En fait, pour le métal, la courbe qui définit la valeur de reflection en fonction de l'angle de la surface par rapport à la camera est très particulière (voir sur le billet de Zap). Quand elle se rapproche de 90 dégrées, elle descend pour remonter en flèche.</p>


<p>Quand à la théorie. Je doit avouez ne pas maitriser la chose (Master Zap non plus d’ailleurs):</p>


<blockquote><p>Metals are indeed not refractive, and are indeed not dielectrics (meaning, electrical insulators). They are Conductors, and for some baroque reason these are also considered to have an "Index of Refraction".</p></blockquote>


<p>Comme je suis du genre curieux, j'ai fait un peu de recherche (d'un niveau bien trop élevé pour moi) et j'en ai conclu que (Attention, grand moment de mathématique a trois francs six sous <img src="/blog/themes/blueSilenceCustom/smilies/yeoh.gif" alt=":dentcasse:" class="smiley" /> ):</p>
<ul>
<li>L'index de réfraction est le "ralentissement" de la lumière quand il entre dans un "milieu" (un material).</li>
<li>Cet index dépend de plusieurs paramètres dont la perméabilité diélectrique (material conducteur, ou pas). En effet, la lumière est une onde électromagnétique (Maxwell is watching you) donc (et c'est ça qui est fou!) la conduction d'un material joue un rôle dans la "déformation" de la lumière qui le traverse.</li>
<li>Les coefficients de Fresnel intervenant à l'intersection de deux milieux ayant des indices de réfraction différent (toi tu rentre déformé comme ci, toi tu rebondie déformé comme ça) explique la relation qu'il y a entre l'index de réfraction et la reflection d'un material. En gros, lors d'une "transition" entre deux milieux ayant des index de réfraction différent, il y a une reflection qui se forme.</li>
</ul>
<p>Perso, ça donne envie d’être physicien. J'imagine la révolution que ça a dut être dans la physique optique ça. D’ailleurs, si un physicien passe dans le coin et que je me suis complètement planté, qu'il se fasse un plaisir de m'insulter violemment dans les commentaires, je suis tout ouïe à une explication clair du phénomène. <img src="/blog/themes/blueSilenceCustom/smilies/seSentCon.gif" alt=":seSentCon:" class="smiley" /></p>


<p>Bref:</p>


<blockquote><p>Fresnel + index de refraction sur un material 100% opaque = variation de la reflection.</p></blockquote>


<h3>Liens</h3>

<p>Parce que je serai ravis de savoir si vous avez mieux compris que moi. <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /></p>

<ul>
<li><a href="https://fr.wikipedia.org/wiki/%C3%89quations_de_Maxwell" hreflang="fr">Équations de Maxwell</a></li>
<li><a href="https://fr.wikipedia.org/wiki/Indice_de_r%C3%A9fraction" hreflang="fr">Indice de réfraction</a></li>
<li><a href="https://fr.wikipedia.org/wiki/Permittivit%C3%A9_di%C3%A9lectrique" hreflang="fr">Permittivité diélectrique</a></li>
<li><a href="https://fr.wikipedia.org/wiki/Perm%C3%A9abilit%C3%A9_magn%C3%A9tique" hreflang="fr">Perméabilité magnétique</a></li>
<li><a href="https://fr.wikipedia.org/wiki/Coefficients_de_Fresnel" hreflang="fr">Coefficients de Fresnel</a></li>
</ul>

<p>Je vous invite aussi a regarder <a href="http://www.fevrierdorian.com/blog/public/billets/2012_03_18_metal_plus_metalique/palette_coating.pdf" hreflang="fr">ce PDF</a> pour Maxwell Render (<a href="http://forum.maxwellrender.fr/viewtopic.php?f=20&amp;t=2025" hreflang="fr">auteur: Roch</a>).</p>


<p>Sur ce pdf, on voit que la reflection varie en fonction d'un curieux paramètre nomme <em>Nd</em> (Quand il passe a 10, on voit très clairement une reflection). Et <a href="https://en.wikipedia.org/wiki/ND#Science_and_medicine" hreflang="en">d’après Wikipedia</a>, <em>Nd</em> correspond a l'index de réfraction d'un medium dont la longueur d'onde est de 589.592 nanomètre (<a href="https://fr.wikipedia.org/wiki/Raies_de_Fraunhofer" hreflang="fr">La raie de Fraunhofer</a> <em>D</em> du spectre solaire. <a href="https://en.wikipedia.org/wiki/Sodium" hreflang="en">Le sodium</a>... Et oui, ça renvoi loin et je vois pas pourquoi cette valeur la en particulier...).</p>


<p>En espérant vous avoir apporté quelque chose...</p>


<p>A bientôt!</p>

<center><i><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></i></center>



<h3>MAJ 20 Mars 2012</h3>

<p>Suite au <a href="http://www.fevrierdorian.com/blog/post/2012/03/18/Du-metal-plus-metalique#c4412" hreflang="en">commentaire</a> de Tristan, <a href="http://forum.mentalimages.com/showthread.php?9274-What-represent-25-50-IOR-values-for-mia_materials..." hreflang="fr">j'ai demandé</a> sur le forum de mental image d’où sortait ces index de refraction bizarre (25, 40, 50 etc...). <em>rlevenne</em> <a href="http://forum.mentalimages.com/showthread.php?9274-What-represent-25-50-IOR-values-for-mia_materials...#post37779" hreflang="en">explique clairement</a> qu'il s'agit d'un hack pour imiter la courbe de reflection du métal mais que les valeurs ne représentait rien mathématiquement parlant. Apparemment, le mia_material utilise <a href="https://en.wikipedia.org/wiki/Schlick%27s_approximation" hreflang="en">l'approximation de Schlick</a> pour calculer la BRDF. Cette approximation est rapide mais ne gère pas les index de réfraction complexes. Pour faire un métal physiquement correct, il faut une autre information: L’Extinction (la valeur <em>k</em> sur <a href="http://refractiveindex.info/?group=METALS&amp;material=Gold" hreflang="en">cette page</a>). C'est un paramètre que Maxwell expose. Bref, si vous êtes intéressé, lisez le post. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


feed_id: urn:md5:ccb9bda689de59470b9d41b2f1939f38
title: Noël de Geek: Levitron et OpenGL Superbible
uri: Noël-de-Geek-Levitron-et-OpenGL-Superbible
url: http://www.fevrierdorian.com/blog/post/2011/12/31/Noel-de-Geek-Levitron-et-OpenGL-Superbible
content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_12_29_Noel_De_Geek/Levitron_Omega_Noel_tn.png" alt="Levitron_Omega_Noel_tn.png" style="float:left; margin: 0 1em 1em 0;" title="Levitron_Omega_Noel_tn.png, déc. 2011"  height="150" width="150" />Hello tous!</p>


<p>J’espère que vous avez passé de bonnes fêtes! Bonne année à tous! (Oui, je sais, ce n'est pas encore passé mais il est 2h du matin et on est le 31 donc vu qu'a priori aujourd'hui tout le monde va préparer sa soirée, personne ne verra ce billet avant 2012... A part, peut être, les GoogleBots... <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /> )</p>


<p>Avant de continuer, je vous prévient de suite, c'est un billet complètement osef. <img src="/blog/themes/blueSilenceCustom/smilies/seSentCon.gif" alt=":seSentCon:" class="smiley" /></p>


<p>J'avais juste envie de vous faire partager ce que j'ai reçu pour Noël! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>    <h3>Levitron Omega, c'est plus fort que toi!</h3>


<p>Ça, c'est ma môman qui me l'a offert! C'est un peu le cadeau de geek par excellence (elle connait son fiston ma môman). <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_12_29_Noel_De_Geek/Levitron_Omega_Noel_001.jpg" title="Levitron_Omega_Noel_001.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_12_29_Noel_De_Geek/.Levitron_Omega_Noel_001_m.jpg" alt="Levitron_Omega_Noel_001.jpg" style="display:block; margin:0 auto;" title="Levitron_Omega_Noel_001.jpg, déc. 2011"  height="560" width="373" /></a></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_12_29_Noel_De_Geek/Levitron_Omega_Noel_002.jpg" title="Levitron_Omega_Noel_002.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_12_29_Noel_De_Geek/.Levitron_Omega_Noel_002_m.jpg" alt="Levitron_Omega_Noel_002.jpg" style="display:block; margin:0 auto;" title="Levitron_Omega_Noel_002.jpg, déc. 2011"  height="560" width="373" /></a></p>


<p>C'est une toupie qui flotte sur un aimant en anneau. Il faut quelques minutes pour équilibrer le socle (tout doit être parfaitement plat sinon la toupie "glisse") et lester la toupie (sinon elle est trop légère et pas assez stable).</p>


<p>Pour voir le truc en <em>live</em>:</p>

<center><iframe width="580" height="423" src="http://www.youtube.com/embed/W6cFsS8-mqI" allowfullscreen></iframe></center>



<p>Et si vous <del>êtes pauvre</del> ne voulez pas dépenser d'argent la dedans, vous pouvez toujours vous <a href="http://heligone.free.fr/levitron/" hreflang="en">la fabriquer vous même</a>. <img src="/blog/themes/blueSilenceCustom/smilies/trollface_smiley.png" alt=":trollface:" class="smiley" /></p>


<h3>OpenGL Superbible, la <em>Bible-tout-court</em> peut aller se rhabiller...</h3>


<p>Sur les conseils de mon ancien collègue <a href="http://www.linkedin.com/in/adrienherubel" hreflang="fr">Adrien Herubel</a>, j'ai profité de l'occasion pour demander la <a href="http://www.amazon.com/OpenGL-SuperBible-Comprehensive-Tutorial-Reference/dp/0321712617/" hreflang="en">OpenGL SuperBible: Comprehensive Tutorial and Reference (5th Edition)</a> (avouez que le nom en jette! <img src="/blog/themes/blueSilenceCustom/smilies/laClasse.gif" alt=":laClasse:" class="smiley" /> ).</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_12_29_Noel_De_Geek/OpenGL_Superbible5_001.jpg" title="Wright_MECH_5E.qxd"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_12_29_Noel_De_Geek/.OpenGL_Superbible5_001_m.jpg" alt="Wright_MECH_5E.qxd" style="display:block; margin:0 auto;" title="Wright_MECH_5E.qxd, déc. 2011"  height="560" width="450" /></a></p>


<p>Ça fait longtemps que je tâte OpenGL sans jamais vraiment entrer dedans...</p>


<p>Il faut dire que j'ai commencé à une période "difficile" dans l'histoire de l'API car OpenGL 3 (la "nouvelle" version de l'API donc) a rendu complètement obsolète l'ancienne façon de faire (soit 90% des ressources disponibles sur le net...). Les spécifications d'OpenGL ont évoluées très lentement en quasiment dix ans. Donc forcément, l'arrivé de cette version 3 qui remet beaucoup (tout?) en cause fout un bon gros coup de vieux <a href="http://nehe.gamedev.net/tutorial/lessons_01__05/22004/" hreflang="en">aux tutoriaux</a> considérés comme les meilleurs du web...</p>


<p>Et je vous assure qu'il y a encore un an, quasiment tout ce que je trouvais sur OpenGL sur le net avait un arrière goût de poisson pourri (<a href="http://www.lemonde.fr/technologies/article/2010/11/02/la-memoire-de-geocities-compilee-en-un-fichier_1434450_651865.html" hreflang="fr">RIP</a> <a href="http://thepiratebay.org/torrent/5923737/Geocities_-_The_Torrent" hreflang="en">GeoCities</a> <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /> #geek). les choses changent... Rapidement même... <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>En effet, c'est assez déprimant d'apprendre (difficilement) des choses dont on ne sait même pas si elles seront encore utilisées d'ici quelques années. Et pire, dont la philosophie n'a même plus de sens... <img src="/blog/themes/blueSilenceCustom/smilies/riva.gif" alt=":pasClasse:" class="smiley" /></p>


<p>Ce livre a l'avantage (et c'est aussi pour ça que je l'ai acheté) de faire complètement abstraction de "comment que c'est qu'on faisait avant" et de se focaliser sur une approche moderne.</p>


<p>Et pour tout vous dire, au bout de quelques semaines:</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_12_29_Noel_De_Geek/level-up.jpg" title="level-up.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_12_29_Noel_De_Geek/.level-up_m.jpg" alt="level-up.jpg" style="display:block; margin:0 auto;" title="level-up.jpg, déc. 2011"  height="400" width="560" /></a></p>
<center><i>Image honteusement pompé sur le net sans l'accord de <a href=http://www.psyetgeek.com/level-up-les-niveaux-de-mecanisme-de-defense-dans-le-jeu-video>son propriétaire</a>... Merci a lui en tout cas! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></i></center>



<p>Bref, ça roxx du poney et c'est super intéressant! <img src="/blog/themes/blueSilenceCustom/smilies/banane-jaune.gif" alt=":banaeyouhou:" class="smiley" /></p>


<p>Voili voulou!</p>


<p>A bientôt et bonne année!</p>


<p>Dorian</p>

<center><i><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></i></center>


feed_id: urn:md5:baef6decdb4bd78bf47bb82e743f0b33
title: Quoi de neuf? Wiki, TD Nuke, etc...
uri: Quoi-de-neuf-Wiki-TD-Nuke-etc
url: http://www.fevrierdorian.com/blog/post/2011/12/10/Quoi-de-neuf-Wiki-TD-Nuke-etc
content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_12_10_quoi_de_neuf/coral_tn.png" alt="coral_tn.png" style="float:left; margin: 0 1em 1em 0;" title="coral_tn.png, déc. 2011"  height="150" width="150" />Je sais que mon blog parait un peu à l'abandon... C'est pas faux! <img src="/blog/themes/blueSilenceCustom/smilies/siffle.gif" alt=":siffle:" class="smiley" /></p>


<p>Il y a eu pas mal de changements de mon coté. Le premier c'est que je suis maintenant TD Nuke à <em>Illumination Mac Guff</em> (Compo sur <a href="http://movies.yahoo.com/feature/lorax.html" hreflang="en">The Lorax</a>).</p>


<p>Forcement, Nuke j'y avais peu touché et c’était l'occasion de voir si la partie script de soft était aussi nul qu'on le disait. <img src="/blog/themes/blueSilenceCustom/smilies/as253.gif" alt=":enerve:" class="smiley" /></p>


<p>De plus, j'ai pas mal bossé sur <a href="http://fevrierdorian.com/wiki/index.php?title=Accueil" hreflang="fr">mon wiki</a> (je sais, il y a quasiment personne qui sait que j'ai un wiki...). Dans ce billet je vous propose un résumé des choses que j'ai faites qui peuvent vous intéresser. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>    <h3>Traduction articles VRay</h3>


<p>J'ai traduit deux articles très intéressants sur VRay. Il est à noté que les méthodes expliquées ici sont applicables à la plupart des moteurs de rendu raytrace. Vous ne perdrez donc pas votre temps en lisant ça. <img src="/blog/themes/blueSilenceCustom/smilies/redface.gif" alt=":redface:" class="smiley" /></p>

<ul>
<li><a href="http://fevrierdorian.com/wiki/index.php?title=Les_param%C3%A8tres_de_V-Ray_-_Le_Raycasting_%28Traduction%29" hreflang="fr">Les paramètres de V-Ray - Le Raycasting</a>. Traduit depuis: <a href="http://renderstuff.com/best-vray-settings-raycasting-cg-tutorial/" hreflang="en">Best V-Ray Settings – Raycasting</a> de <a href="http://renderstuff.com/" hreflang="en">RenderStuff</a>. C'est un article expliquant comment VRay (et les raytracers en général) utilisent la mémoire.</li>
<li><a href="http://fevrierdorian.com/wiki/index.php?title=V-Ray_-_Le_DMC_Sampler_d%C3%A9mystifi%C3%A9_%28Traduction%29" hreflang="fr">V-Ray - Le DMC Sampler démystifié</a>. Traduit depuis: <a href="http://interstation3d.com/tutorials/vray_dmc_sampler/demistyfing_dmc.html" hreflang="en">Demystifying V-Ray DMC Sampler</a> de <a href="http://interstation3d.com/about.html" hreflang="en">Toni Bratincevic</a>. Un article de référence expliquant les subtilités du DMC sampler de VRay par un gars de chez <a href="http://www.blur.com/" hreflang="en">Blur</a>.</li>
</ul>

<h3>Mental ray</h3>


<p>Toujours dans le rendu, j'ai traduit <a href="http://fevrierdorian.com/wiki/index.php?title=Nodes_builtin_bsdf_%28mentalray%29" hreflang="fr">quelques posts de Bitter sur le BSDF dans mental ray</a>. Je ne connaissais pas bien, c’était très intéressant et je pense que ça va devenir la norme d'ici quelques temps.</p>


<h3>Nuke</h3>


<p><img src="http://www.fevrierdorian.com/blog/public/logos/Logo_NUKE.gif" alt="Logo_NUKE.gif" style="display:block; margin:0 auto;" title="Logo_NUKE.gif, déc. 2011"  height="185" width="165" /></p>


<p>J'ai commencé une page sur <a href="http://fevrierdorian.com/wiki/index.php?title=Commandes_de_base_%28Nuke%29" hreflang="fr">les commandes de base Nuke</a>. Ça me sert de pense bête. Je vous la donne... Si ça peut vous aider... <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>Et aussi une petite page sur comment <a href="http://fevrierdorian.com/wiki/index.php?title=Cr%C3%A9er_un_gizmo_%28Nuke%29" hreflang="fr">créer un gizmo avec des attributs</a>. C'est très basique hein... <img src="/blog/themes/blueSilenceCustom/smilies/seSentCon.gif" alt=":seSentCon:" class="smiley" /></p>


<p>Je commence à me sentir à l'aise avec le compo et je pense poster quelques billets.</p>


<p>Un qui me tient à cœur c'est concernant la profondeur de champs via Z-Depth. J'ai entendu tellement de bêtises la dessus que je pense qu'un petit tour des méthodes peut être intéressant.</p>


<p>Je parlerai peut être aussi, dans un billet express, des différences fondamentales dans la façon de scripter dans Nuke et dans Maya. L'approche n'est pas tout à fait la même.</p>


<p>Bref, faut que je me libère du temps pour tout ça. :)</p>


<h3>Et surtout: coral!</h3>


<p><img src="http://www.fevrierdorian.com/blog/public/logos/coralAppIcon.png" alt="coralAppIcon.png" style="display:block; margin:0 auto;" title="coralAppIcon.png, déc. 2011"  height="168" width="256" /></p>


<p>De même, je code dans le projet <a href="http://coral-app.com/" hreflang="en">coral</a> (repo <a href="http://code.google.com/p/coral-repo/" hreflang="en">ici</a>). C'est une sorte de "mini-houdini" pour faire toute sortes de choses procédurales. L’intérêt est de pouvoir le connecter à Maya:</p>

<div class="external-media" style="margin: 1em auto; text-align: center;">
<iframe src="http://player.vimeo.com/video/29664872?title=0&amp;byline=0&amp;portrait=0" width="601" height="338" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>
</div>

<center><i>Et encore, dans cette vidéo on est loin de voir toute les possibilités du soft...</i></center>



<p>Il a été code par <a href="http://www.linkedin.com/pub/andrea-interguglielmi/4/b38/b97" hreflang="fr">Andrea Interguglielmi</a> (Un ancien de chez MPC et Animal Logic... On a vu pire comme CV... <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /> ).</p>


<p>Personnellement je code dans la partie OpenGL que je remet un peu d'aplomb pour pouvoir faire des choses plus évolués. Les choses avances tranquillement. La correction de bug étant la priorité (le but étant de pouvoir utiliser coral en prod). Andrea a une idée assez claire de ce qu'il souhaite intégrer (deformer, contrôle de foule, etc...).</p>


<p>Je pense que coral a aussi un énorme potentiel en VFX pur (modification de géométries, effets procéduraux, etc...). C'est peut être une voie que je vais privilégier car travailler sur un vrai système de <em>shading network</em> (un point qui semble intéresser Andrea) ne me semble pas une priorité. Il faut que j'en discute avec lui pour savoir ce qu'il a derrière la tête <img src="/blog/themes/blueSilenceCustom/smilies/hihi.gif" alt=":hihi:" class="smiley" /> .</p>


<p>Voila voila! Comme vous voyez, je suis pas mal booké! <img src="/blog/themes/blueSilenceCustom/smilies/yeoh.gif" alt=":dentcasse:" class="smiley" /></p>


<p>A bientôt!</p>


<p>Dorian</p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></center>


feed_id: urn:md5:c43dcbaffbe1818d51f6146fa136cff0
title: Faire un rendu en wireframe dans Maya
uri: Faire-un-rendu-en-wireframe-dans-Maya
url: http://www.fevrierdorian.com/blog/post/2011/11/03/Faire-un-rendu-en-wireframe-dans-Maya
content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_11_03_Wireframe/Wireframe_tn.png" alt="Wireframe_tn.png" style="float:left; margin: 0 1em 1em 0;" title="Wireframe_tn.png, nov. 2011"  height="150" width="150" />Je sais pas pour vous, j'ai toujours galéré pour faire un rendu correct en wireframe.</p>


<p>Oui, vous vous dite que tout le monde s'en fout des wireframes, c'est juste pour faire une zolie demoreel de modeleur. <img src="/blog/themes/blueSilenceCustom/smilies/yeoh.gif" alt=":dentcasse:" class="smiley" /></p>


<p>C'est pas faux! Mais n’empêche que j'ai toujours galéré.</p>


<p>La technique que je vous présente dans ce billet express n'est pas la meilleur mais je viens de la découvrir et elle est tellement simple/efficace que je voulais vous en faire part! <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></p>    <h3>Il était une fois...</h3>

<p>Tout commence donc par <a href="http://forum.mentalimages.com/showthread.php?8596-Interesting-article-i-found&amp;p=35074#post35074" hreflang="en">une réponse de bart</a> sur le forum de mental image suite à <a href="http://www.fevrierdorian.com/blog/post/2011/07/17/Mes-impression-sur-mental-ray-et-son-futur">mon article</a> sur l'avenir de mental ray.</p>


<p>Il me propose de lister les trucs que je pense intéressants pour les prods.</p>


<p>Je commence donc une petite liste chez moi qui commençait à être bien fournies et que je m'apprêtais a poster sur le forum.</p>


<p>Mais bien entendu, avant de passer pour le dernier des nigots, je vérifie une bonne fois pour toutes que ce que je demande n'est pas déjà faisable. (Histoire de pas perdre trop de crédibilité après les avoir un peu lynché dans <a href="http://www.fevrierdorian.com/blog/post/2011/07/17/Mes-impression-sur-mental-ray-et-son-futur">mon billet</a>...).</p>


<p>Le premier point que je cherche est: Un vrai shader pour faire du wireframe, avec moult options et tout, sans passer par les contours.</p>


<blockquote><p>Notez que ce n'est pas le premier point de la liste sinon je suis vraiment a coté de la plaque. C'était aussi pour comprendre comment un raytracer, aux vues de son fonctionnement, était capable de sortir les edges d'un mesh (c'est le nerd qui parle là...).</p></blockquote>


<p>Et je tombe sur ça:</p>


<blockquote><p>Assign Surface shader to the mesh, feed it with a ramp (type: box), go to UVs:Unitize.</p></blockquote>


<p><a href="http://forums.cgsociety.org/showpost.php?p=4019596&amp;postcount=15" hreflang="en">Source</a></p>


<p>C'est quoi son affaire là? <img src="/blog/themes/blueSilenceCustom/smilies/confused0028.gif" alt=":gne2:" class="smiley" /></p>


<p>Unitize, c'est quoi ce truc?</p>


<p>Et bien figurez vous que <strong>Edit Uvs/Unitize</strong> permet tout simplement de mettre les uvs par face! C'est ça le secret!</p>


<h3>Démonstration!</h3>


<p>Prenez n'importe quel objet géométrique:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_11_03_Wireframe/Wireframe001.png" alt="Wireframe001.png" style="display:block; margin:0 auto;" title="Wireframe001.png, nov. 2011"  height="424" width="419" /></p>
<center><i>Notez l'originalité <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /></i></center>



<p>Voici les UVs par défaut:
<img src="http://www.fevrierdorian.com/blog/public/billets/2011_11_03_Wireframe/Wireframe001b.png" alt="Wireframe001b.png" style="display:block; margin:0 auto;" title="Wireframe001b.png, nov. 2011"  height="384" width="510" /></p>


<p>Et bien faites<strong>Edit Uvs/Unitize</strong>:
<img src="http://www.fevrierdorian.com/blog/public/billets/2011_11_03_Wireframe/Wireframe002.png" alt="Wireframe002.png" style="display:block; margin:0 auto;" title="Wireframe002.png, nov. 2011"  height="109" width="212" /></p>


<p>Et...
<img src="http://www.fevrierdorian.com/blog/public/billets/2011_11_03_Wireframe/Wireframe003.png" alt="Wireframe003.png" style="display:block; margin:0 auto;" title="Wireframe003.png, nov. 2011"  height="335" width="328" /></p>
<center><i>Tadaaaa!!!</i></center>



<p>Le shading graph est aussi simple que ça:
<img src="http://www.fevrierdorian.com/blog/public/billets/2011_11_03_Wireframe/Wireframe004.png" alt="Wireframe004.png" style="display:block; margin:0 auto;" title="Wireframe004.png, nov. 2011"  height="224" width="540" /></p>


<p>Avec un surface shader:
<img src="http://www.fevrierdorian.com/blog/public/billets/2011_11_03_Wireframe/Wireframe005.png" alt="Wireframe005.png" style="display:block; margin:0 auto;" title="Wireframe005.png, nov. 2011"  height="421" width="478" /></p>


<p>Avec la ramp en Box:
<img src="http://www.fevrierdorian.com/blog/public/billets/2011_11_03_Wireframe/Wireframe006.png" alt="Wireframe006.png" style="display:block; margin:0 auto;" title="Wireframe006.png, nov. 2011"  height="577" width="461" /></p>


<p>Et voilà!
<a href="http://www.fevrierdorian.com/blog/public/billets/2011_11_03_Wireframe/Wireframe007.png" title="Wireframe007.png"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_11_03_Wireframe/.Wireframe007_m.jpg" alt="Wireframe007.png" style="display:block; margin:0 auto;" title="Wireframe007.png, nov. 2011"  height="512" width="560" /></a></p>


<p>Donc vous voyez, c'est loin d’être un truc de prod (c'est franchement limité), mais vu le nombre de cliques nécessaires pour obtenir le truc, je ne pouvais pas ne pas vous en parler. <img src="/blog/themes/blueSilenceCustom/smilies/banane-jaune.gif" alt=":banaeyouhou:" class="smiley" /></p>


<p>Si vous avez d'autres techniques de la mort n'hésitez pas! <img src="/blog/themes/blueSilenceCustom/smilies/sauteJoie.gif" alt=":sauteJoie:" class="smiley" /></p>


<p>A bientôt!</p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></center>



<p>PS: Oui je sais, pas mal de moteurs proposent des shaders tout prêts (<a href="http://www.spot3d.com/vray/help/maya/150R1/vrayedgestex_params.htm" hreflang="en">VRay</a>, <a href="http://www.cebas.com/index.php?pid=product&amp;prd_id=140&amp;feature=1178" hreflang="en">Final Render</a>, et sûrement d'autres).</p>


feed_id: urn:md5:5d032309b99261355833f3413e46f843
title: Quickly retrieve vertex positions of a Maya mesh (English Translation)
uri: Quickly-retrieve-vertex-positions-of-a-Maya-mesh-(English-Translation)
url:
http://www.fevrierdorian.com/blog/post/2011/09/27/Quickly-retrieve-vertex-positions-of-a-Maya-mesh-%28English-Translation%29

content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_03_30_Recuperer_Position_Vertex_Rapidement/recuperer_Position_Vertex_Rapidement_tn.png" alt="recuperer_Position_Vertex_Rapidement_tn.png" style="float:left; margin: 0 1em 1em 0;" title="recuperer_Position_Vertex_Rapidement_tn.png, mar. 2011"  height="150" width="150" />If you ever had to recover vertex positions of a mesh object, you probably crash yourself against the <em>xform</em> command and his legendary slowness. <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /></p>


<p>In this post, I purpose a piece of Python script using the Python Maya API that allows you to faster recover the list of all vertex positions of an object.</p>


<p>Primarily didactic, these codes may interest peoples who want to look a little more deeply how to use the API while having a concrete application. <img src="/blog/themes/blueSilenceCustom/smilies/laClasse.gif" alt=":laClasse:" class="smiley" /></p>    <h3>Using xform</h3>


<p>Here is the <a href="http://download.autodesk.com/us/maya/2011help/Commands/xform.html">xform</a> version of the script:</p>

<pre class="python python"><span style="color: #ff7700;font-weight:bold;">def</span> getVtxPos<span style="color: black;">&#40;</span> shapeNode <span style="color: black;">&#41;</span> :
&nbsp;
	vtxWorldPosition = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>    <span style="color: #808080; font-style: italic;"># will contain positions un space of all object vertex</span>
&nbsp;
	vtxIndexList = <span style="color: #dc143c;">cmds</span>.<span style="color: black;">getAttr</span><span style="color: black;">&#40;</span> shapeNode+<span style="color: #483d8b;">&quot;.vrts&quot;</span>, multiIndices=<span style="color: #008000;">True</span> <span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> vtxIndexList :
		curPointPosition = <span style="color: #dc143c;">cmds</span>.<span style="color: black;">xform</span><span style="color: black;">&#40;</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>shapeNode<span style="color: black;">&#41;</span>+<span style="color: #483d8b;">&quot;.pnts[&quot;</span>+<span style="color: #008000;">str</span><span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>+<span style="color: #483d8b;">&quot;]&quot;</span>, query=<span style="color: #008000;">True</span>, translation=<span style="color: #008000;">True</span>, worldSpace=<span style="color: #008000;">True</span> <span style="color: black;">&#41;</span>    <span style="color: #808080; font-style: italic;"># [1.1269192869360154, 4.5408735275268555, 1.3387055339628269]</span>
		vtxWorldPosition.<span style="color: black;">append</span><span style="color: black;">&#40;</span> curPointPosition <span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">return</span> vtxWorldPosition</pre>


<h3>With Maya API</h3>


<p>Alternative to xform.</p>

<pre class="python python"><span style="color: #ff7700;font-weight:bold;">import</span> maya.<span style="color: #dc143c;">OpenMaya</span> <span style="color: #ff7700;font-weight:bold;">as</span> <span style="color: #dc143c;">OpenMaya</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> particleFillSelection<span style="color: black;">&#40;</span>  <span style="color: black;">&#41;</span>:
&nbsp;
	<span style="color: #808080; font-style: italic;"># get the active selection</span>
	selection = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MSelectionList</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	<span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MGlobal</span>.<span style="color: black;">getActiveSelectionList</span><span style="color: black;">&#40;</span> selection <span style="color: black;">&#41;</span>
	iterSel = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MItSelectionList</span><span style="color: black;">&#40;</span>selection, <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFn</span>.<span style="color: black;">kMesh</span><span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #808080; font-style: italic;"># go througt selection</span>
	<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff7700;font-weight:bold;">not</span> iterSel.<span style="color: black;">isDone</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
&nbsp;
		<span style="color: #808080; font-style: italic;"># get dagPath</span>
		dagPath = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MDagPath</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
		iterSel.<span style="color: black;">getDagPath</span><span style="color: black;">&#40;</span> dagPath <span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #808080; font-style: italic;"># create empty point array</span>
		inMeshMPointArray = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MPointArray</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #808080; font-style: italic;"># create function set and get points in world space</span>
		currentInMeshMFnMesh = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnMesh</span><span style="color: black;">&#40;</span>dagPath<span style="color: black;">&#41;</span>
		currentInMeshMFnMesh.<span style="color: black;">getPoints</span><span style="color: black;">&#40;</span>inMeshMPointArray, <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MSpace</span>.<span style="color: black;">kWorld</span><span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #808080; font-style: italic;"># put each point to a list</span>
		pointList = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
&nbsp;
		<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span> inMeshMPointArray.<span style="color: black;">length</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span> :
&nbsp;
			pointList.<span style="color: black;">append</span><span style="color: black;">&#40;</span> <span style="color: black;">&#91;</span>inMeshMPointArray<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, inMeshMPointArray<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, inMeshMPointArray<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span> <span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #ff7700;font-weight:bold;">return</span> pointList</pre>


<blockquote><p>Notice: I thought that specifying the size of the list from the start would gain time but it changes nothing. It seems that <a href="http://stackoverflow.com/questions/311775/python-create-a-list-with-initial-capacity">Python handles it well</a>. So, I learned a new saying: <em>Premature optimization is the root of all evil</em>. <img src="/blog/themes/blueSilenceCustom/smilies/evilgrin0002.gif" alt=":gniarkgniark:" class="smiley" /></p></blockquote>


<h3>Benchmarks</h3>

<p>Well, it's fine to say it's faster. But how much? <img src="/blog/themes/blueSilenceCustom/smilies/reflexionIntense.gif" alt=":reflexionIntense:" class="smiley" /></p>


<p>Here are times I have with a 50x50 pSphere smoothed 4 (633602 vertices):</p>
<ul>
<li>With xform: 39 sec</li>
<li>With Python Maya API: 4 sec</li>
</ul>

<p>10x faster! This would give me almost want to code in C++, just to see results (which is suppose to be 10x faster than Python!)!!! <img src="/blog/themes/blueSilenceCustom/smilies/1420.gif" alt=":grenadelauncher:" class="smiley" /></p>


<h3>Conclusion</h3>


<p>Well now it's up to you to know when use it.</p>


<p>You can try to optimize <a href="http://www.fevrierdorian.com/blog/post/2011/03/14/Remplir-un-mesh-de-spheres-dans-Maya-La-methode-d-un-senior">Djelloul's algorythm</a> and let me know your results! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>Now, I couldn't do without the API if I have to retrieve vertex positions of a mesh. It's much faster. Even if it's a little more complicate, I admit, but when you have this code, you keep it and use it at the right time! <img src="/blog/themes/blueSilenceCustom/smilies/aupoil.gif" alt=":aupoil:" class="smiley" /></p>


<p>Hope you like this trick!</p>


<p>See you soon!</p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></center>


feed_id: urn:md5:0a8e2a12a431cfe2fc41231bce05af08
title: Project a mesh to another with Maya API (English Translation)
uri: Project-a-mesh-to-another-with-Maya-API-(English-Translation)
url:
http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29

content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_tn.png" alt="projection_mesh_api_tn.png" style="float:left; margin: 0 1em 1em 0;" title="projection_mesh_api_tn.png, fév. 2011"  height="150" width="150" />This is the english translation of <a href="http://www.fevrierdorian.com/blog/post/2011/02/20/Projeter-un-mesh-sur-un-autre-avec-l-API-Python-de-Maya">a tutorial</a> I've done that will allow you to project a mesh to another.</p>


<p>This is something that can be useful but most is pretty "fun" to do (some would say everything is relative <img src="/blog/themes/blueSilenceCustom/smilies/seSentCon.gif" alt=":seSentCon:" class="smiley" /> ) and it's a good way to learn fundamentals of matrice operations having a both simple and concrete example.</p>


<p>Amateur of the API, this tutorial is for you!</p>    <center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>


<blockquote><p>In advance, sorry for english. <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /></p></blockquote>


<p>Here is what we want to achieve:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_015.png" alt="projection_mesh_api_015.png" style="display:block; margin:0 auto;" title="projection_mesh_api_015.png, fév. 2011"  height="378" width="511" /></p>


<p>A mesh projected on another.</p>


<p>And the scene from which we start:</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_001.png" title="projection_mesh_api_001.png"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/.projection_mesh_api_001_m.jpg" alt="projection_mesh_api_001.png" style="display:block; margin:0 auto;" title="projection_mesh_api_001.png, fév. 2011"  height="376" width="560" /></a></p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h5>Sommaire</h5>
<ul>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#theory">Theory</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#startCode">Start code</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#attributesPreparation">Attributes preparation</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#prepareTheScene">Prepare the scene</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#theComputeMethod">The compute method</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#matricesExplainedToCGArtists">Matrices explained to CG artists</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#backToTheCode">Back to the code!</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#goThroughEachVertexAndModifyIt">Go through each vertex and modify it</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#buildAMesh">Build a mesh</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#sourceCodeAndConclusion">Source code and conclusion</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#doThisWithoutPython">Update: Do this without Python</a></li>
</ul>
<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h5>Theory <a name="theory"></a></h5>


<p>Once again, we begin with theory.</p>


<p>In facts, you'll see it's pretty simple because the harder part (the intersection) will be handle through <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_mesh.html#bbb75ee7d06620f430a660ad0017f909">an API call</a>:</p>

<pre class="python python"><span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnMesh</span>.<span style="color: black;">closestIntersection</span><span style="color: black;">&#40;</span> ... <span style="color: black;">&#41;</span></pre>

<p>This <a href="https://secure.wikimedia.org/wikipedia/en/wiki/Method(computer_programming)">method</a> handle intersection of a ray (point+direction) on a mesh and return some infos (the most important: The position of the projected point).</p>


<p>Basically, we need three things:</p>
<ul>
<li>A point of origin (the one we want to project)</li>
<li>A direction (a vector)</li>
<li>A destination mesh</li>
</ul>

<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_002.png" title="projection_mesh_api_002.png"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/.projection_mesh_api_002_m.jpg" alt="projection_mesh_api_002.png" style="display:block; margin:0 auto;" title="projection_mesh_api_002.png, fév. 2011"  height="410" width="560" /></a></p>


<p>The point of origin will be, of course, each vertex of the mesh to project (here, vertex numbers's are in yellow).</p>


<p>Direction will be the normal of the vertex to project (in green on the image. Okay, we do not see too much but put it a little good will damn! <img src="/blog/themes/blueSilenceCustom/smilies/cayMal.gif" alt=":cayMal:" class="smiley" /> ).</p>


<p>And the destination mesh will obviously be the mesh that will receive the plan (in our case, a sphere).</p>


<p>So we recover, each time, a point and a normal (yellow crosses).</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_003.png" title="projection_mesh_api_003.png"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/.projection_mesh_api_003_m.jpg" alt="projection_mesh_api_003.png" style="display:block; margin:0 auto;" title="projection_mesh_api_003.png, fév. 2011"  height="423" width="560" /></a></p>
<center><i>Forgive my "half-of-a-jpeg-dollar-moldy" diagram <img src="/blog/themes/blueSilenceCustom/smilies/riva.gif" alt=":pasClasse:" class="smiley" /></i></center>


<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h5>Start code <a name="startCode"></a></h5>


<p>Here is the the base code:</p>

<pre class="python python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> maya.<span style="color: #dc143c;">OpenMaya</span> <span style="color: #ff7700;font-weight:bold;">as</span> <span style="color: #dc143c;">OpenMaya</span>
<span style="color: #ff7700;font-weight:bold;">import</span> maya.<span style="color: #dc143c;">OpenMayaMPx</span> <span style="color: #ff7700;font-weight:bold;">as</span> <span style="color: #dc143c;">OpenMayaMPx</span>
&nbsp;
kPluginNodeTypeName = <span style="color: #483d8b;">&quot;projectMesh&quot;</span>
&nbsp;
kPluginNodeId = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MTypeId</span><span style="color: black;">&#40;</span> 0x80000 <span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Node definition</span>
<span style="color: #ff7700;font-weight:bold;">class</span> projectMeshNode<span style="color: black;">&#40;</span> <span style="color: #dc143c;">OpenMayaMPx</span>.<span style="color: black;">MPxNode</span> <span style="color: black;">&#41;</span> :
&nbsp;
	<span style="color: #808080; font-style: italic;"># constructor</span>
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span> <span style="color: #008000;">self</span> <span style="color: black;">&#41;</span> :
&nbsp;
		<span style="color: #dc143c;">OpenMayaMPx</span>.<span style="color: black;">MPxNode</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span> <span style="color: #008000;">self</span> <span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">def</span> compute<span style="color: black;">&#40;</span> <span style="color: #008000;">self</span>, plug, data <span style="color: black;">&#41;</span> :
&nbsp;
		<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;compute&quot;</span>
		<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MStatus</span>.<span style="color: black;">kSuccess</span>
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;"># creator</span>
<span style="color: #ff7700;font-weight:bold;">def</span> nodeCreator<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">OpenMayaMPx</span>.<span style="color: black;">asMPxPtr</span><span style="color: black;">&#40;</span> projectMeshNode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># initializer</span>
<span style="color: #ff7700;font-weight:bold;">def</span> nodeInitializer<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> :
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">return</span>
&nbsp;
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;"># initialize the script plug-in</span>
<span style="color: #ff7700;font-weight:bold;">def</span> initializePlugin<span style="color: black;">&#40;</span> mobject <span style="color: black;">&#41;</span> :
	mplugin = <span style="color: #dc143c;">OpenMayaMPx</span>.<span style="color: black;">MFnPlugin</span><span style="color: black;">&#40;</span> mobject <span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">try</span>:
		mplugin.<span style="color: black;">registerNode</span><span style="color: black;">&#40;</span> kPluginNodeTypeName, kPluginNodeId, nodeCreator, nodeInitializer <span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">except</span>:
		<span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;Failed to register node: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> kPluginNodeTypeName <span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">raise</span>
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;"># uninitialize the script plug-in</span>
<span style="color: #ff7700;font-weight:bold;">def</span> uninitializePlugin<span style="color: black;">&#40;</span> mobject <span style="color: black;">&#41;</span>:
	mplugin = <span style="color: #dc143c;">OpenMayaMPx</span>.<span style="color: black;">MFnPlugin</span><span style="color: black;">&#40;</span> mobject <span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">try</span>:
		mplugin.<span style="color: black;">deregisterNode</span><span style="color: black;">&#40;</span> kPluginNodeId <span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">except</span>:
		<span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;Failed to unregister node: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> kPluginNodeTypeName <span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">raise</span></pre>


<p>If you already had wrote a Maya node in Python, this code shouldn't make you too afraid.</p>


<p>Quick to explain for others <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /> .</p>

<pre class="python python"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">sys</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">import</span> maya.<span style="color: #dc143c;">OpenMaya</span> <span style="color: #ff7700;font-weight:bold;">as</span> <span style="color: #dc143c;">OpenMaya</span>
<span style="color: #ff7700;font-weight:bold;">import</span> maya.<span style="color: #dc143c;">OpenMayaMPx</span> <span style="color: #ff7700;font-weight:bold;">as</span> <span style="color: #dc143c;">OpenMayaMPx</span></pre>

<p>Import the main modules.</p>
<ul>
<li>The <em>sys</em> module is used to create error message when Maya load/unload the plugin (see below).</li>
<li>The other two are used to call Maya API methods.</li>
</ul>
<p>Nothing complicated.</p>

<pre class="python python">kPluginNodeTypeName = <span style="color: #483d8b;">&quot;projectMesh&quot;</span>
&nbsp;
kPluginNodeId = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MTypeId</span><span style="color: black;">&#40;</span> 0x80000 <span style="color: black;">&#41;</span></pre>
<ul>
<li><em>kPluginNodeTypeName</em> is a simple variable called below to give a name to you node type.</li>
<li><em>kPluginNodeId</em> is a value serving as an id for the node when it is written in binary files (mb). 0x80000 to 0xfffff are used by Maya samples. See (documentation|http://download.autodesk.com/us/maya/2011help/API/class_m_type_id.html] for more informations.</li>
</ul>
<pre class="python python"><span style="color: #808080; font-style: italic;"># Node definition</span>
<span style="color: #ff7700;font-weight:bold;">class</span> projectMeshNode<span style="color: black;">&#40;</span> <span style="color: #dc143c;">OpenMayaMPx</span>.<span style="color: black;">MPxNode</span> <span style="color: black;">&#41;</span> :
&nbsp;
	<span style="color: #808080; font-style: italic;"># constructor</span>
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span> <span style="color: #008000;">self</span> <span style="color: black;">&#41;</span> :
&nbsp;
		<span style="color: #dc143c;">OpenMayaMPx</span>.<span style="color: black;">MPxNode</span>.<span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span> <span style="color: #008000;">self</span> <span style="color: black;">&#41;</span>
&nbsp;
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">def</span> compute<span style="color: black;">&#40;</span> <span style="color: #008000;">self</span>, plug, data <span style="color: black;">&#41;</span> :
&nbsp;
		<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;compute&quot;</span>
		<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MStatus</span>.<span style="color: black;">kSuccess</span></pre>

<p>Here, the class is an instance of the <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_px_node.html">MPxNode</a> object which is himself a class done to create custom nodes (it's a fairly complex part I will not go througth in this tutorial as it deserves a full post <img src="/blog/themes/blueSilenceCustom/smilies/whistle2.gif" alt=":jdicajdirien:" class="smiley" /> ).</p>


<p>The <em>__init__</em> method is the first executed when the class is created. It simply initialise the <em>MPxNode</em> class.</p>


<p>The <em>compute</em> method is the one we will work the most. It's a herited methode from <em>MPxNode</em>. The part of the code "which do something". <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>If you're not familiar with classes and Python, this part of the code may seem complex, but don't worry, the only important part is the <em>compute</em> method.</p>

<pre class="python python"><span style="color: #808080; font-style: italic;"># creator</span>
<span style="color: #ff7700;font-weight:bold;">def</span> nodeCreator<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">OpenMayaMPx</span>.<span style="color: black;">asMPxPtr</span><span style="color: black;">&#40;</span> projectMeshNode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span></pre>

<p>A function, executed when initializing the plugin, which returns a pointer to the created class (and therefore, the node).</p>


<p>Python having no notion of pointer and Maya having need, in particular, to initialize the plugins, Autodesk has developed the OpenMayaMPx.asMPxPtr method (more informations <a href="http://autodesk.com/us/maya/2011help/files/Maya_Python_API_Using_the_Maya_Python_API.htm" hreflang="en">here</a>).</p>


<p>Once again, it's something basic, you put it, you do not think <img src="/blog/themes/blueSilenceCustom/smilies/bete.gif" alt=":bete:" class="smiley" /> .</p>

<pre class="python python"><span style="color: #808080; font-style: italic;"># initializer</span>
<span style="color: #ff7700;font-weight:bold;">def</span> nodeInitializer<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> :
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">return</span></pre>

<p>This method is also called during the node creation and allows (among others) to initialize the node attributes. This will be the first one that we will fulfill. For now, it make nothing at all.</p>

<pre class="python python"><span style="color: #808080; font-style: italic;"># initialize the script plug-in</span>
<span style="color: #ff7700;font-weight:bold;">def</span> initializePlugin<span style="color: black;">&#40;</span> mobject <span style="color: black;">&#41;</span> :
	mplugin = <span style="color: #dc143c;">OpenMayaMPx</span>.<span style="color: black;">MFnPlugin</span><span style="color: black;">&#40;</span> mobject <span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">try</span>:
		mplugin.<span style="color: black;">registerNode</span><span style="color: black;">&#40;</span> kPluginNodeTypeName, kPluginNodeId, nodeCreator, nodeInitializer <span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">except</span>:
		<span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;Failed to register node: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> kPluginNodeTypeName <span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">raise</span>
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;"># uninitialize the script plug-in</span>
<span style="color: #ff7700;font-weight:bold;">def</span> uninitializePlugin<span style="color: black;">&#40;</span> mobject <span style="color: black;">&#41;</span>:
	mplugin = <span style="color: #dc143c;">OpenMayaMPx</span>.<span style="color: black;">MFnPlugin</span><span style="color: black;">&#40;</span> mobject <span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">try</span>:
		mplugin.<span style="color: black;">deregisterNode</span><span style="color: black;">&#40;</span> kPluginNodeId <span style="color: black;">&#41;</span>
	<span style="color: #ff7700;font-weight:bold;">except</span>:
		<span style="color: #dc143c;">sys</span>.<span style="color: black;">stderr</span>.<span style="color: black;">write</span><span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;Failed to unregister node: %s<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> kPluginNodeTypeName <span style="color: black;">&#41;</span>
		<span style="color: #ff7700;font-weight:bold;">raise</span></pre>

<p>Let me tell you, this is really a "copy-paste" I've done from examples. Basically, these functions are called when loading/unloading plugins. They are used to register/unregister the plugins from Maya sessions.</p>


<p>Their behavior is simple, I invite you to review this code snippet for yourself (it doesn't harm! <img src="/blog/themes/blueSilenceCustom/smilies/evilgrin0002.gif" alt=":gniarkgniark:" class="smiley" /> ).</p>


<p>At this point you should be able to create your python node and load it in Maya</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_004.png" alt="projection_mesh_api_004.png" style="display:block; margin:0 auto;" title="projection_mesh_api_004.png, fév. 2011"  height="324" width="387" /></p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_005.png" alt="projection_mesh_api_005.png" style="display:block; margin:0 auto;" title="projection_mesh_api_005.png, fév. 2011"  height="465" width="476" /></p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_006.png" alt="projection_mesh_api_006.png" style="display:block; margin:0 auto;" title="projection_mesh_api_006.png, fév. 2011"  height="84" width="195" /></p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_007.png" alt="projection_mesh_api_007.png" style="display:block; margin:0 auto;" title="projection_mesh_api_007.png, fév. 2011"  height="75" width="433" /></p>


<p>And by creating it as follow:</p>

<pre class="mel mel">createNode projectMesh<span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// Result: projectMesh1 //</span></pre>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_008.png" alt="projection_mesh_api_008.png" style="display:block; margin:0 auto;" title="projection_mesh_api_008.png, fév. 2011"  height="171" width="474" /></p>


<p>To the extent that there is no attribute, this node does absolutely nothing! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h5>Attributes preparation <a name="attributesPreparation"></a></h5>


<p>As promised, we will start by the <em>nodeInitializer()</em> method which initialize the node attributes.</p>


<p>We will need three attributes:</p>
<ul>
<li>Two inputs: The mesh projecting his vertex and the mesh which recieve them.</li>
<li>An output: The output, projected mesh.</li>
</ul>

<p>Here we go! <img src="/blog/themes/blueSilenceCustom/smilies/1420.gif" alt=":grenadelauncher:" class="smiley" /></p>

<pre class="python python"><span style="color: #808080; font-style: italic;"># initializer</span>
<span style="color: #ff7700;font-weight:bold;">def</span> nodeInitializer<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> :
	typedAttr = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnTypedAttribute</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #808080; font-style: italic;"># Setup the input attributes</span>
	projectMeshNode.<span style="color: black;">inputMeshSrc</span> = typedAttr.<span style="color: black;">create</span><span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;inputMeshSrc&quot;</span>, <span style="color: #483d8b;">&quot;inMeshSrc&quot;</span>, <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnData</span>.<span style="color: black;">kMesh</span> <span style="color: black;">&#41;</span>
	typedAttr.<span style="color: black;">setReadable</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
&nbsp;
	projectMeshNode.<span style="color: black;">inputMeshTarget</span> = typedAttr.<span style="color: black;">create</span><span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;inputMeshTarget&quot;</span>, <span style="color: #483d8b;">&quot;inMeshTrg&quot;</span>, <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnData</span>.<span style="color: black;">kMesh</span> <span style="color: black;">&#41;</span>
	typedAttr.<span style="color: black;">setReadable</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #808080; font-style: italic;"># Setup the output attributes</span>
	projectMeshNode.<span style="color: black;">outputMesh</span> = typedAttr.<span style="color: black;">create</span><span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;outputMesh&quot;</span>, <span style="color: #483d8b;">&quot;outMesh&quot;</span>, <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnData</span>.<span style="color: black;">kMesh</span> <span style="color: black;">&#41;</span>
	typedAttr.<span style="color: black;">setWritable</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
	typedAttr.<span style="color: black;">setStorable</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #808080; font-style: italic;"># Add the attributes to the node</span>
	projectMeshNode.<span style="color: black;">addAttribute</span><span style="color: black;">&#40;</span> projectMeshNode.<span style="color: black;">inputMeshSrc</span> <span style="color: black;">&#41;</span>
	projectMeshNode.<span style="color: black;">addAttribute</span><span style="color: black;">&#40;</span> projectMeshNode.<span style="color: black;">inputMeshTarget</span> <span style="color: black;">&#41;</span>
	projectMeshNode.<span style="color: black;">addAttribute</span><span style="color: black;">&#40;</span> projectMeshNode.<span style="color: black;">outputMesh</span> <span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #808080; font-style: italic;"># Set the attribute dependencies</span>
	projectMeshNode.<span style="color: black;">attributeAffects</span><span style="color: black;">&#40;</span> projectMeshNode.<span style="color: black;">inputMeshSrc</span>, projectMeshNode.<span style="color: black;">outputMesh</span> <span style="color: black;">&#41;</span>
	projectMeshNode.<span style="color: black;">attributeAffects</span><span style="color: black;">&#40;</span> projectMeshNode.<span style="color: black;">inputMeshTarget</span>, projectMeshNode.<span style="color: black;">outputMesh</span> <span style="color: black;">&#41;</span></pre>


<p>The first line:</p>
<pre class="python python">typedAttr = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnTypedAttribute</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>

<p>Creates an "object" (known in the Maya API as "<a href="http://download.autodesk.com/us/maya/2009help/API/group___m_fn.html">Function Set</a>") that will help us to manipulate the attributes (especially build them):</p>
<pre class="python python"><span style="color: #808080; font-style: italic;"># Setup the input attributes</span>
projectMeshNode.<span style="color: black;">inputMeshSrc</span> = typedAttr.<span style="color: black;">create</span><span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;inputMeshSrc&quot;</span>, <span style="color: #483d8b;">&quot;inMeshSrc&quot;</span>, <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnData</span>.<span style="color: black;">kMesh</span> <span style="color: black;">&#41;</span>
typedAttr.<span style="color: black;">setReadable</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
&nbsp;
projectMeshNode.<span style="color: black;">inputMeshTarget</span> = typedAttr.<span style="color: black;">create</span><span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;inputMeshTarget&quot;</span>, <span style="color: #483d8b;">&quot;inMeshTrg&quot;</span>, <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnData</span>.<span style="color: black;">kMesh</span> <span style="color: black;">&#41;</span>
typedAttr.<span style="color: black;">setReadable</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># Setup the output attributes</span>
projectMeshNode.<span style="color: black;">outputMesh</span> = typedAttr.<span style="color: black;">create</span><span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;outputMesh&quot;</span>, <span style="color: #483d8b;">&quot;outMesh&quot;</span>, <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnData</span>.<span style="color: black;">kMesh</span> <span style="color: black;">&#41;</span>
typedAttr.<span style="color: black;">setWritable</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span>
typedAttr.<span style="color: black;">setStorable</span><span style="color: black;">&#40;</span><span style="color: #008000;">False</span><span style="color: black;">&#41;</span></pre>

<p>We create attributes. Nothing complicated (<a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_typed_attribute.html#fc105a88372e84910bc56c74c973bc26">see documentation</a>).</p>


<p>Some details on used arguments:</p>
<ul>
<li>The full attribute name (long name).</li>
<li>The short attribute name (short name).</li>
<li>The attribute "type" (as <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_type_id.html">API type</a>).</li>
</ul>
<p>The following methods each attribute declaration (<a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_attribute.html#ced78c59e2a6b0395810705bb2896bfb">setReadable</a>, <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_attribute.html#5b89d32b1d6beebfa7b21a58d1d8d6f2">setWritable</a>, <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_attribute.html#b0fe1b4159b4f4bcefd7c0cef9a7b389">setStorable</a>) add special things to the latest created attribute (<a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_attribute.html">see documentation</a> for more precisions).</p>

<pre class="python python"><span style="color: #808080; font-style: italic;"># Add the attributes to the node</span>
projectMeshNode.<span style="color: black;">addAttribute</span><span style="color: black;">&#40;</span> projectMeshNode.<span style="color: black;">inputMeshSrc</span> <span style="color: black;">&#41;</span>
projectMeshNode.<span style="color: black;">addAttribute</span><span style="color: black;">&#40;</span> projectMeshNode.<span style="color: black;">inputMeshTarget</span> <span style="color: black;">&#41;</span>
projectMeshNode.<span style="color: black;">addAttribute</span><span style="color: black;">&#40;</span> projectMeshNode.<span style="color: black;">outputMesh</span> <span style="color: black;">&#41;</span></pre>

<p>As the comment said, this part add/connect attributes created above to the node.</p>

<pre class="python python"><span style="color: #808080; font-style: italic;"># Set the attribute dependencies</span>
projectMeshNode.<span style="color: black;">attributeAffects</span><span style="color: black;">&#40;</span> projectMeshNode.<span style="color: black;">inputMeshSrc</span>, projectMeshNode.<span style="color: black;">outputMesh</span> <span style="color: black;">&#41;</span>
projectMeshNode.<span style="color: black;">attributeAffects</span><span style="color: black;">&#40;</span> projectMeshNode.<span style="color: black;">inputMeshTarget</span>, projectMeshNode.<span style="color: black;">outputMesh</span> <span style="color: black;">&#41;</span></pre>

<p>This part is very important! <img src="/blog/themes/blueSilenceCustom/smilies/adodonicoco.gif" alt=":papi:" class="smiley" /></p>


<p>It allows you to define "dependencies" between attributes.</p>


<p>In our case:</p>
<ul>
<li>If the <em>inputMeshSrc</em> attribute change, <em>outputMesh</em> attribute also change.</li>
<li>If the <em>inputMeshTarget</em> attribute change, <em>outputMesh</em> attribute also change.</li>
</ul>
<p>If these lines are not set, the <em>compute</em> method of the node we are creating will never be launched. The node will never be updated.</p>


<p>You can download the python node in the current state here:</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projectMesh001.7z">&gt;&gt; projectMesh001.7z &lt;&lt;</a></p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h5>Prepare the scene <a name="prepareTheScene"></a></h5>


<p>Before we actually code the behavior of the node, we need to connect some geometry to our future node.</p>


<p>Create a scene that looks like this:</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_001.png" title="projection_mesh_api_001.png"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/.projection_mesh_api_001_m.jpg" alt="projection_mesh_api_001.png" style="display:block; margin:0 auto;" title="projection_mesh_api_001.png, fév. 2011"  height="376" width="560" /></a></p>


<p>Also create a third mesh, which will return the geometry of our future node (which will be the projected mesh).</p>


<p>In my case: A pSphere. But it can be anything. As it is a mesh node.</p>


<p>You can even create the mesh node by hand.</p>


<p>Place it to the center of the scene (0,0,0) so there have no offset between the projected mesh and his target.</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_009.png" alt="projection_mesh_api_009.png" style="display:block; margin:0 auto;" title="projection_mesh_api_009.png, fév. 2011"  height="549" width="733" /></p>


<p>To avoid having to create the connections each time, here are two small MEL codes that help you to test your node (your nodes must be well named).</p>


<p>To load all:</p>
<pre class="mel mel">loadPlugin<span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;monRepertoire/projectMesh.py&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
createNode projectMesh<span style="color: #339933;">;</span>
connectAttr <span style="color: #339933;">-</span>f projectMesh1.<span style="color: #202020;">outputMesh</span> pSphereShape2.<span style="color: #202020;">inMesh</span><span style="color: #339933;">;</span>
connectAttr <span style="color: #339933;">-</span>f pPlaneShape1.<span style="color: #202020;">worldMesh</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> projectMesh1.<span style="color: #202020;">inputMeshSrc</span><span style="color: #339933;">;</span>
connectAttr <span style="color: #339933;">-</span>f pSphereShape1.<span style="color: #202020;">worldMesh</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span> projectMesh1.<span style="color: #202020;">inputMeshTarget</span><span style="color: #339933;">;</span></pre>

<p>And unload all:</p>
<pre class="mel mel">delete projectMesh1<span style="color: #339933;">;</span>
flushUndo<span style="color: #339933;">;</span>
unloadPlugin<span style="color: #009900;">&#40;</span> <span style="color: #ff0000;">&quot;projectMesh&quot;</span> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre>


<p>And that's it! Now take a deep breath, we jump!</p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h5>The compute method <a name="theComputeMethod"></a></h5>


<p>The first thing to test is the presence of a connection on your outputMesh attribute. Actually, if your node is connected to anything, it should not be calculated:</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">def</span> compute<span style="color: black;">&#40;</span> <span style="color: #008000;">self</span>, plug, data <span style="color: black;">&#41;</span> :
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">if</span> plug == <span style="color: #008000;">self</span>.<span style="color: black;">outputMesh</span>:
&nbsp;
		<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;compute&quot;</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">else</span>:
		<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MStatus</span>.<span style="color: black;">kUnknownParameter</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MStatus</span>.<span style="color: black;">kSuccess</span></pre>


<p>Once we are sure connections are made, we get input attributes:</p>

<pre class="python python"><span style="color: #ff7700;font-weight:bold;">if</span> plug == <span style="color: #008000;">self</span>.<span style="color: black;">outputMesh</span>:
&nbsp;
	<span style="color: #808080; font-style: italic;"># get the inputMeshTarget (return MDataHandle)</span>
	inMeshSrcHandle = data.<span style="color: black;">inputValue</span><span style="color: black;">&#40;</span> <span style="color: #008000;">self</span>.<span style="color: black;">inputMeshSrc</span> <span style="color: black;">&#41;</span>
	inMeshTargetHandle = data.<span style="color: black;">inputValue</span><span style="color: black;">&#40;</span> <span style="color: #008000;">self</span>.<span style="color: black;">inputMeshTarget</span> <span style="color: black;">&#41;</span></pre>

<p>This is a "connection" to the block of data attributes. This is the first step to get the value (here it's a kMesh so it will be a little different) of an attribute.</p>


<blockquote><p>Python being an untyped language (both its main strength but also its main flaw ...), I tend to write in comments the Maya API type of data that I get.</p>
<p>
Otherwise, it's quick to not knowing at all what type is what variable (types in the Maya API is no lack <img src="/blog/themes/blueSilenceCustom/smilies/aupoil.gif" alt=":aupoil:" class="smiley" /> ).</p>
<p>
However, everyone has their own method! If you have a over-developed cortex, if you want to play the "I dont care types are for noobs", if a code that you are the only person who can read it give you the feeling to be a strong male and if you want to justify your BAC +5 (in this day and age it's certainly not your salary that should do it). Do not hesitate, code as <del>TD</del> pork: No comments, one letter variables and whatnot like that... Your colleagues will return the favor. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>
<p>
But if you're more modest and would quickly learn the Maya API, I urge you to write Maya API types directly in comments of your code. Besides being clearer, it still requires to known/search, when writing variables, what type it is.</p></blockquote>


<p>After that, we check our two connected attributes are meshs:</p>
<pre class="python python"><span style="color: #808080; font-style: italic;">#we check the API type we've got here (we need kMesh)</span>
<span style="color: #ff7700;font-weight:bold;">if</span> inMeshSrcHandle.<span style="color: #008000;">type</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnData</span>.<span style="color: black;">kMesh</span> <span style="color: #ff7700;font-weight:bold;">and</span> inMeshTargetHandle.<span style="color: #008000;">type</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnData</span>.<span style="color: black;">kMesh</span> :
	<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;cool&quot;</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
	<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MStatus</span>.<span style="color: black;">kInvalidParameter</span></pre>


<p>And we get them as such:</p>
<pre class="python python"><span style="color: #808080; font-style: italic;">#we check the API type we've got here (we need kMesh)</span>
<span style="color: #ff7700;font-weight:bold;">if</span> inMeshSrcHandle.<span style="color: #008000;">type</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnData</span>.<span style="color: black;">kMesh</span> <span style="color: #ff7700;font-weight:bold;">and</span> inMeshTargetHandle.<span style="color: #008000;">type</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> == <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnData</span>.<span style="color: black;">kMesh</span> :
&nbsp;
	<span style="color: #808080; font-style: italic;"># return a MObject</span>
	meshSrc = inMeshSrcHandle.<span style="color: black;">asMesh</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	meshTarget = inMeshTargetHandle.<span style="color: black;">asMesh</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">print</span> <span style="color: #483d8b;">&quot;cool&quot;</span>
<span style="color: #ff7700;font-weight:bold;">else</span>:
	<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MStatus</span>.<span style="color: black;">kInvalidParameter</span></pre>

<p>I invite you to look at the <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_data_handle.html">MDataHandle</a> documentation just to see what we can get from an attribute.</p>


<p>As mentioned in the comment, we get a <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_object.html">MObject</a>. This object type is the "all-purpose-type" of Maya.</p>


<p>This MObject is just a transitionnal object. Actually, it is rarely used directly.</p>


<p>In Maya, to modify/malipulate objects, we often use <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_base.html">"Function Set"</a>. They follow the pattern: MFn*Type*.</p>


<p>Here, to manipulate meshs, we will get a function set of mesh: <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_mesh.html">MFnMesh</a>.</p>

<pre class="python python"><span style="color: #808080; font-style: italic;"># get the MFnMesh of the twice attr</span>
mFnMeshSrc = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnMesh</span><span style="color: black;">&#40;</span> meshSrc <span style="color: black;">&#41;</span>
mFnMeshTarget = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnMesh</span><span style="color: black;">&#40;</span> meshTarget <span style="color: black;">&#41;</span></pre>


<p>What interests us now is to have a list of all vertices of the "source mesh" (one which will be projected to the "target mesh") to create another array that will contain changed vertex positions:</p>
<pre class="python python">outMeshMPointArray = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MPointArray</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># create an array of vertex wich will contain the outputMesh vertex</span>
mFnMeshSrc.<span style="color: black;">getPoints</span><span style="color: black;">&#40;</span>outMeshMPointArray<span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># get the point in the space</span></pre>

<p>The first line creates an array of type <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_point_array.html">MPointArray</a>.</p>


<p>The second line fills it with the values ​​of the "source mesh" vertex.</p>


<p>How to write is a bit confusing ("upside down" will say some <img src="/blog/themes/blueSilenceCustom/smilies/reflechi.gif" alt=":reflechi:" class="smiley" /> ) but that's the way <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_mesh.html#54dc2a4415a365c7193936dad6643b47">getPoint</a> works, as many other functions of the Maya API.</p>


<p>Rather than return the result, it is stored in the variable given as argument.</p>


<p>We now have a MPointArray filled with his vertex positions.</p>


<p>The idea now is to change vertex positions to make them matching the projected position on the "target mesh".</p>


<p>But here... The vertex positions that you get in your MPointArray are in "object space". That mean, relative to the center of the object.</p>


<p>Nous allons nous heurter à un vrai problème. The big one! The ultimate: The matrices! *Voix qui résonne* <img src="/blog/themes/blueSilenceCustom/smilies/as253.gif" alt=":enerve:" class="smiley" />
We will face a real problem. The big one! The ultimate: The Matrix! *Voice echoing* <img src="/blog/themes/blueSilenceCustom/smilies/as253.gif" alt=":enerve:" class="smiley" /></p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h5>Matrices explained to CG artists <a name="matricesExplainedToCGArtists"></a></h5>


<p>When you are CG artists, we hear about it without really knowing what it is <img src="/blog/themes/blueSilenceCustom/smilies/bete.gif" alt=":bete:" class="smiley" /> .</p>


<p>Add to that what we find on the net is very academic and "too mathematical" (It shows how to multiply a matrix without explaining why it is necessary to do so).</p>


<p>All this so that we don't necessarily see the connection with our work.</p>


<p>I'll modestly try to explain this from a "CG artist" point of view <img src="/blog/themes/blueSilenceCustom/smilies/mayaProf.gif" alt=":mayaProf:" class="smiley" /> .</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/photoMatrix.jpg" title="photoMatrix.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/.photoMatrix_m.jpg" alt="photoMatrix.jpg" style="display:block; margin:0 auto;" title="photoMatrix.jpg, fév. 2011"  height="416" width="560" /></a></p>
<center><small><i><a href="http://www.flickr.com/photos/trinity-of-one/20562069/">Photography</a> by <a href="http://www.flickr.com/photos/trinity-of-one/">My Melting Brain</a> under Creative Common <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/deed.fr">by-nc-sa</a>. Thanks to him! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></i></small></center>



<p>Create a cube.</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_010.png" alt="projection_mesh_api_010.png" style="display:block; margin:0 auto;" title="projection_mesh_api_010.png, fév. 2011"  height="284" width="463" /></p>


<p>You may have noticed, once your cube is created, that it has a "pivot point" with informations (position, rotation, scale, etc. ...). Well this point can be a "mathematical link" between the vertex points of your cube and "the world" (center coordinates of the "world" are 0,0,0).</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_011.png" alt="projection_mesh_api_011.png" style="display:block; margin:0 auto;" title="projection_mesh_api_011.png, fév. 2011"  height="291" width="404" /></p>


<p>If this "transform" node didn't exist, your object would be at center of the scene. And to move it, it should move the all vertex positions of the cube.</p>


<p>The transform node acts like a "parent" of the vertex of your cube. In this way, the vertex positions of the cube doesn't move. For example, a vertex of a cube placed at 1,1,1 (relative to the pivot of the cube so) will remain at 1,1,1 regardless of the position of the transform.</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_012.png" alt="projection_mesh_api_012.png" style="display:block; margin:0 auto;" title="projection_mesh_api_012.png, fév. 2011"  height="246" width="305" /></p>
<center><i>Here, we move the pivot, not the cube vertices's that they don't change position relative to the pivot, the pivot that changes position relative to the world.</i></center>


<p>But some operations (in our case, get if the vertex is face to a different mesh) requires that the coordinates of all the entities are a common reference, the reference world.</p>


<p>Comic demonstration:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/bd/projection_mesh_api_bd_001.png" alt="projection_mesh_api_bd_001.png" style="display:block; margin:0 auto;" title="projection_mesh_api_bd_001.png, fév. 2011"  height="340" width="553" /></p>
<center><i>- Hi! I am vertex[0] and I'm on (1,1,1).</br>
- Hi! I am vertex[0] and I'm on (1,1,1).</br>
Two vertices at different coordinates in "world space"...</i></center>



<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/bd/projection_mesh_api_bd_002.png" alt="projection_mesh_api_bd_002.png" style="display:block; margin:0 auto;" title="projection_mesh_api_bd_002.png, fév. 2011"  height="340" width="553" /></p>
<center><i>...but at the same place relative to their respective centers.</i></center>



<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/bd/projection_mesh_api_bd_003.png" alt="projection_mesh_api_bd_003.png" style="display:block; margin:0 auto;" title="projection_mesh_api_bd_003.png, fév. 2011"  height="340" width="553" /></p>
<center><i>- (insult)</br>
- (insult)</br>
Not easy to make calculations.</i></center>



<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/bd/projection_mesh_api_bd_004.png" alt="projection_mesh_api_bd_004.png" style="display:block; margin:0 auto;" title="projection_mesh_api_bd_004.png, fév. 2011"  height="340" width="553" /></p>
<center><i>You see the prob?</i></center>



<p>Whereas if we chose, as common reference point, the center of the world.</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/bd/projection_mesh_api_bd_005.png" alt="projection_mesh_api_bd_005.png" style="display:block; margin:0 auto;" title="projection_mesh_api_bd_005.png, fév. 2011"  height="340" width="553" /></p>
<center><i>- Hi! I am vertex[0] and I'm on (4,2,3) relative to world.</br>
- Hi! I am vertex[0] and I'm on (3,1,2) relative to world.</i></center>


<p>It's much easier.</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/bd/projection_mesh_api_bd_006.png" alt="projection_mesh_api_bd_006.png" style="display:block; margin:0 auto;" title="projection_mesh_api_bd_006.png, fév. 2011"  height="340" width="553" /></p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/bd/projection_mesh_api_bd_007.png" alt="projection_mesh_api_bd_007.png" style="display:block; margin:0 auto;" title="projection_mesh_api_bd_007.png, fév. 2011"  height="340" width="553" /></p>
<center><i>- Friend!</br>
- Friend!</i></center>



<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/bd/projection_mesh_api_bd_008.png" alt="projection_mesh_api_bd_008.png" style="display:block; margin:0 auto;" title="projection_mesh_api_bd_008.png, fév. 2011"  height="340" width="553" /></p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/bd/projection_mesh_api_bd_009.png" alt="projection_mesh_api_bd_009.png" style="display:block; margin:0 auto;" title="projection_mesh_api_bd_009.png, fév. 2011"  height="340" width="553" /></p>
<center><i>- Nevertheless, I am still higher than you!</br>
- Whait... What? o_O</i></center>



<p>Okay, now we know the vertex coordinates in their "object space", we must know how get them in "world space".</p>


<p>The basic principle that immediately comes to mind is: We add vertex positions (in object space) to its pivot point (him, in world space).</p>


<blockquote><p>Example:</p>
<p>
If pVertex the position of a vertex and cubePosition the position, in world space, of the pivot point of the cube:</p>
<p>
cubePositionX + pVertexInCubeX = pVertexInWorldX</p></blockquote>


<p>But surely you can imagine, it's more complicated... <img src="/blog/themes/blueSilenceCustom/smilies/siffle.gif" alt=":siffle:" class="smiley" /></p>


<p>Indeed, in the case of rotations and scale, it is not enough of a few additions to solve the problem.</p>


<blockquote><p>Note: Whether a translation, a rotation, or scaling a mesh, all comes down to vertex moves in the world.</p></blockquote>


<p>The truth is that all this "parameters" can be put into a single "object" that we call a matrix. This matrix will help us to make calculations (as Maya saves us but if you're interested, here is an example of <a href="http://jeux.developpez.com/faq/math/?page=bases#Q4">calculates a rotation matrix</a>) to get vertex positions in world space.</p>


<p>As I said, Maya gives us easely access to this object through <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_dag_path.html#7cd82c63d68ff186865b3a2c9340a5ae">inclusiveMatrix</a> (There are several matrix types, we will focus on this one).</p>


<p>So at this stage, we have two things:</p>
<ul>
<li>Vertex positions relative to the object (in "object space").</li>
<li>A matrix of the object (which is world relative, "world space").</li>
</ul>

<p>We need to "convert" vertex positions from "space object" to "world space". A "change of reference" (sorry guys, don't know the english word for that <img src="/blog/themes/blueSilenceCustom/smilies/riva.gif" alt=":pasClasse:" class="smiley" /> ). So you get an absolute position ("world space").</p>


<p>And to get vertex position in the "world space", "simply" multiply vertex position matrix {x, y, z} by inclusion matrix of the object. (I wrote "simply" in quotes because multiplying a matrix is not as simple as 2x2... <img src="/blog/themes/blueSilenceCustom/smilies/redface.gif" alt=":redface:" class="smiley" /> )</p>


<blockquote><p>Note: I would not do demonstration on "how to calculate a matrix", internet is full of examples and explanations.</p></blockquote>


<p>And here's the formula:</p>
<pre>
positionGlobale = positionLocale * inclusiveMatrix
</pre>

<p>It's almost like the Pythagorean theorem. Who cares how it works, until you know when to use it! <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /></p>


<p>Voila! I hope this little explanation you will shed some light on why the matrices are. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h5>Back to the code! <a name="backToTheCode"></a></h5>


<p>Get inclusive matrix is simple.</p>
<pre class="python python"><span style="color: #808080; font-style: italic;"># get MDagPath of the MMesh to get the matrix and multiply vertex to it. If I don't do that, all combined mesh will go to the origin</span>
inMeshSrcMDagPath = mFnMeshSrc.<span style="color: black;">dagPath</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># return MDagPath object</span>
inMeshSrcInclusiveMMatrix = inMeshSrcMDagPath.<span style="color: black;">inclusiveMatrix</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># return MMatrix</span></pre>

<p>The first line retrieves the <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_dag_path.html">dagPath</a> of the source mesh. We can consider the dagPath as the equivalent of the transform node of an object in Maya. Where all the informations about transformations (positions, rotations, scales, etc ...) are stored.</p>


<p>The second line retrieves the <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_dag_path.html#7cd82c63d68ff186865b3a2c9340a5ae">inclusiveMatrix</a> of the source mesh as a <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_matrix.html">MMatrix</a> type.</p>


<p>Now we can go through each vertex:</p>
<ul>
<li><a href="http://download.autodesk.com/us/maya/2011help/API/class_m_point.html#1fdf65c85cf27f6ce4ddef0a72aac5d3">Multiply it by the matrix</a> to get his position in world space.</li>
<li>Get his normal.</li>
<li>Also <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_vector.html#d22edbae3de3e0742534acff6b4f6227">multiply it</a> bye the matrix.</li>
<li>Get the collision point, store it as the current point.</li>
</ul>
<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h5>Go through each vertex and modify it <a name="goThroughEachVertexAndModifyIt"></a></h5>


<p>The beginning of the main loop looks like this:</p>

<pre class="python python"><span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span> outMeshMPointArray.<span style="color: black;">length</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span> :
&nbsp;
	inMeshMPointTmp = outMeshMPointArray<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span> <span style="color: #66cc66;">*</span> inMeshSrcInclusiveMMatrix	<span style="color: #808080; font-style: italic;"># the MPoint of the meshSrc in the worldspace</span></pre>

<p>The loop is quite simple: "i" is incremented by 1 each "lap" to browse the vertex array (MPointArray).</p>


<p>The first thing we do is point multiplication (<em>outMeshMPointArray[i]</em>) by the matrix (<em>inMeshSrcInclusiveMMatrix</em>) to obtain a vertex (<em>inMesgPointTmp</em>) in world space ( with coordinates relatives to the world, 0,0,0).</p>


<p>Now we've (finally) the vertex positioned relative to the world, we will "intersect" it with the target mesh.</p>


<blockquote><p>As chrysl666 told <a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#c3024">in his comment</a>, Maya give a simple way to get informations without have to extract matrix and multiply it yourself. Just call your points (and others stuffs) with:</p>
<p>
getPoints(OpenMaya.MSpace.kWorld).</p>
<p>
This will return points position directly in world space. Thanks to him for this information. <img src="/blog/themes/blueSilenceCustom/smilies/bravo.gif" alt=":bravo:" class="smiley" /></p></blockquote>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/intersection.jpg" title="intersection.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/.intersection_m.jpg" alt="intersection.jpg" style="display:block; margin:0 auto;" title="intersection.jpg, fév. 2011"  height="420" width="560" /></a></p>
<center><small><i><a href="http://www.flickr.com/photos/mynamemattersnot/2470352700/">Photography</a> by <a href="http://www.flickr.com/photos/mynamemattersnot/">MyNameMattersNot</a> under Creative Common <a href="http://creativecommons.org/licenses/by-sa/2.0/deed.fr">by-sa</a>. Thanks to him!</i></small></center>



<p>Well, go look at arguments of the <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_mesh.html#bbb75ee7d06620f430a660ad0017f909">OpenMaya.MFnMesh.closestIntersection()</a> method we <a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#theorie">seen above</a>.
Bon, allez regarder les arguments de la méthode <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_mesh.html#bbb75ee7d06620f430a660ad0017f909">OpenMaya.MFnMesh.closestIntersection()</a> que <a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#theory">nous avont vu plus haut</a>.</p>


<p>You see there are quite a few. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>Don't worry, we can ignore many of them. What interests us is the original vertex, his direction (in our case: normal) and the collision point (the hitPoints).</p>


<p>But more subtle, look at the type of the first argument (raySource) expected by the method.</p>


<p>It's a MFloatPoint!</p>


<p>But how convert <em>inMeshMPointTmp</em> (a MPoint) to a MFloatPoint? It's pretty easy in C++, you have to use doubles. After much research, I found a solution. I give it to you:</p>
<pre class="python python">raySource = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFloatPoint</span><span style="color: black;">&#40;</span> inMeshMPointTmp.<span style="color: black;">x</span>, inMeshMPointTmp.<span style="color: black;">y</span>, inMeshMPointTmp.<span style="color: black;">z</span> <span style="color: black;">&#41;</span></pre>

<p>It's not as complicated but if you don't know...</p>


<p>So we have our raySource.</p>


<p>Now the normal:</p>
<pre class="python python">rayDirection = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MVector</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
mFnMeshSrc.<span style="color: black;">getVertexNormal</span><span style="color: black;">&#40;</span> i, <span style="color: #008000;">False</span>, rayDirection<span style="color: black;">&#41;</span>
rayDirection <span style="color: #66cc66;">*</span>= inMeshSrcInclusiveMMatrix
rayDirection = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFloatVector</span><span style="color: black;">&#40;</span>rayDirection.<span style="color: black;">x</span>, rayDirection.<span style="color: black;">y</span>, rayDirection.<span style="color: black;">z</span><span style="color: black;">&#41;</span></pre>

<p>At this point, you should understand:</p>
<ul>
<li>We create the MVector.</li>
<li>We store the current vertex (i) normal of the source mesh in it.</li>
<li>We multiply by the matrix ot get this vector in space world.</li>
<li>We "convert" it to MFloatVector.</li>
</ul>

<p>The hitPoint  is a simple MFloatPoint:</p>
<pre class="python python">hitPoint = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFloatPoint</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>


<p>And the remaining arguments are:</p>
<pre class="python python"><span style="color: #808080; font-style: italic;"># rest of the args</span>
hitFacePtr = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MScriptUtil</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>.<span style="color: black;">asIntPtr</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
idsSorted    = <span style="color: #008000;">False</span>
testBothDirections = <span style="color: #008000;">False</span>
faceIds      = <span style="color: #008000;">None</span>
triIds       = <span style="color: #008000;">None</span>
accelParams  = <span style="color: #008000;">None</span>
hitRayParam  = <span style="color: #008000;">None</span>
hitTriangle  = <span style="color: #008000;">None</span>
hitBary1     = <span style="color: #008000;">None</span>
hitBary2     = <span style="color: #008000;">None</span>
maxParamPtr  = <span style="color: #ff4500;">99999999</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># http://zoomy.net/2009/07/31/fastidious-python-shrub/</span>
hit = mFnMeshTarget.<span style="color: black;">closestIntersection</span><span style="color: black;">&#40;</span>raySource,
					rayDirection,
					faceIds,
					triIds,
					idsSorted,
					<span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MSpace</span>.<span style="color: black;">kWorld</span>,
					maxParamPtr,
					testBothDirections,
					accelParams,
					hitPoint,
					hitRayParam,
					hitFacePtr,
					hitTriangle,
					hitBary1,
					hitBary2<span style="color: black;">&#41;</span></pre>

<p>Great thanks to <a href="http://zoomy.net/about/">Peter J. Richardson</a>! Sans <a href="http://zoomy.net/2009/07/31/fastidious-python-shrub/">son billet</a>, I would never have succeeded to code this stuff. This is why we need to "share what you know" on the internet! ;)</p>


<p>Once called <em>closestIntersection</em>, you get a hitPoint in MFloatPoint that you convert into MPoint:</p>
<pre class="python python"><span style="color: #ff7700;font-weight:bold;">if</span> hit :
	inMeshMPointTmp = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MPoint</span><span style="color: black;">&#40;</span> hitPoint.<span style="color: black;">x</span>, hitPoint.<span style="color: black;">y</span>, hitPoint.<span style="color: black;">z</span><span style="color: black;">&#41;</span></pre>

<p>We replaces the current point by our new one:</p>
<pre class="python python">outMeshMPointArray.<span style="color: #008000;">set</span><span style="color: black;">&#40;</span> inMeshMPointTmp, i <span style="color: black;">&#41;</span></pre>

<p>And this is the end of the loop! :D</p>


<p>At this point you've got a MPointArray <em>outMeshMPointArray</em> with values of projected vertices on the target mesh.</p>


<p>So now we need to rebuild the mesh.</p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h5>Build a mesh <a name="buildAMesh"></a></h5>


<p>I will not go througt details on "how to create and arrange the variables in the case of the creation of a mesh".</p>


<p>Basically we need:</p>
<ul>
<li>The number of vertices.</li>
<li>Le number of ploygons (polygons + triangles if there is).</li>
<li>A array of points (All vertices one behind others with they XYZ coordinates).</li>
<li>An array listing the number of vertices by polygons (Example: 4,4,4,4,3,4,3,4,3,4,4,etc...).</li>
<li>An array of vertex indices (Example: 1,2,3,4,3,4,5,6,5,6,7,8, etc...).</li>
</ul>

<p>You will have understood, we already have the points array (the third point). Otherwise, we silly gets values from the original mesh.</p>


<p>Let's start! <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></p>


<p>At first, we must create a <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_mesh_data.html">MFnMeshData</a> function set.</p>
<pre class="python python"><span style="color: #808080; font-style: italic;"># create a mesh that we will feed!</span>
newDataCreator = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnMeshData</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span></pre>


<p>This function set will allow us to create a MObject that we can "fill" with data of the future mesh.</p>

<pre class="python python">newOutputData = newDataCreator.<span style="color: black;">create</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># Return MObject</span></pre>


<p>As I said above: We need to get all informations (except the vertex array) of the source mesh:</p>

<pre class="python python">outMeshNumVtx = mFnMeshSrc.<span style="color: black;">numVertices</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># outputMesh will have the same number of vtx and polygons</span>
outMeshNumPolygons = mFnMeshSrc.<span style="color: black;">numPolygons</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># create two array and feed them</span>
outMeshPolygonCountArray = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MIntArray</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
outMeshVtxArray = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MIntArray</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
mFnMeshSrc.<span style="color: black;">getVertices</span><span style="color: black;">&#40;</span>outMeshPolygonCountArray, outMeshVtxArray<span style="color: black;">&#41;</span></pre>


<p><a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_mesh.html#5f014e7c511cf86978a765a932ce04d0">mFnMeshSrc.getVertices()</a> filled two arrays with informations needed to create the mesh. See <a href="http://www.fevrierdorian.com/blog/post/2011/07/31/Project-a-mesh-to-another-with-Maya-API-%28English-Translation%29#construire_un_mesh">above</a>.</p>


<p>Once we have that, we create the mesh:</p>

<pre class="python python">meshFS = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnMesh</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
meshFS.<span style="color: black;">create</span><span style="color: black;">&#40;</span>outMeshNumVtx, outMeshNumPolygons, outMeshMPointArray, outMeshPolygonCountArray, outMeshVtxArray, newOutputData<span style="color: black;">&#41;</span></pre>


<p>The principle is quite simple:</p>
<ul>
<li>We create a <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_mesh.html">MFnMesh</a> function set.</li>
<li>We create the mesh giving all arguments re le mesh en donnant tout les arguments (collected above) via <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_fn_mesh.html#6994886ddf6ea46baf399ff40d30bc32">meshFS.create()</a>.</li>
</ul>

<p>Once the mesh is created, we get the <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_data_handle.html">MDataHandle</a> from the <em>outputMesh</em> connection to put the MObject we just fill <a href="http://download.autodesk.com/us/maya/2011help/API/class_m_data_handle.html#959379b4d93358519ccc99696031756c">in it</a>: The mesh!</p>

<pre class="python python"><span style="color: #808080; font-style: italic;"># Store them on the output plugs</span>
outputMeshHandle = data.<span style="color: black;">outputValue</span><span style="color: black;">&#40;</span> <span style="color: #008000;">self</span>.<span style="color: black;">outputMesh</span> <span style="color: black;">&#41;</span>
outputMeshHandle.<span style="color: black;">setMObject</span><span style="color: black;">&#40;</span> newOutputData <span style="color: black;">&#41;</span></pre>


<p>Once this is done, we say, via <a href="http://download.autodesk.com/us/maya/2010help/api/class_m_data_block.html#0d8faafb64e70cf0a579532bb033c98f">MDataBlock.setClean()</a>, to the dependency graph that the connection has been updated.</p>

<pre class="python python"><span style="color: #808080; font-style: italic;"># tell to the dependency graph the connection is clean</span>
data.<span style="color: black;">setClean</span><span style="color: black;">&#40;</span> plug <span style="color: black;">&#41;</span></pre>


<p>It's over! <img src="/blog/themes/blueSilenceCustom/smilies/youplaBoum.gif" alt=":youplaBoum:" class="smiley" /></p>


<p>If you well followed the tutorial (and if I did not make errors ( <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /> ), you should have a node that works correctly (place the plan so that it "target" the sphere):</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_013.png" alt="projection_mesh_api_013.png" style="display:block; margin:0 auto;" title="projection_mesh_api_013.png, fév. 2011"  height="390" width="635" /></p>


<p>Of course, if vertices aren't projected on the sphere, it return to their original positions:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_014.png" alt="projection_mesh_api_014.png" style="display:block; margin:0 auto;" title="projection_mesh_api_014.png, fév. 2011"  height="406" width="487" /></p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h5>Source code and conclusion <a name="sourceCodeAndConclusion"></a></h5>


<p>At this point, you should have understood the principle of matrices (If this is not the case, don't hesitate to go deeply, you will see 3D in a different way! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /> ), be able to recover components of a mesh and create a mesh from scratch.</p>


<p>There is the source code: <a href="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projectMesh.7z">projectMesh.7z</a></p>


<p>And voila! I just finished another big tutorial. I hope it has been informative and that you can begin to do interesting things with Maya API. <img src="/blog/themes/blueSilenceCustom/smilies/banane-jaune.gif" alt=":banaeyouhou:" class="smiley" /></p>


<p>Such informations is lacking on the Internet on CG web site.</p>


<p>I encourage all seniors who would pass by and who would learn something interesting reading this post to do not hesitate to "give back": If you are competent in a field, share! I did. <img src="/blog/themes/blueSilenceCustom/smilies/hihi.gif" alt=":hihi:" class="smiley" /></p>


<p>If I'm wrong somewhere, if a point does not seem clear or if there is an error, please tell me. <img src="/blog/themes/blueSilenceCustom/smilies/riva.gif" alt=":pasClasse:" class="smiley" /></p>


<p>See you soon!</p>
<center><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></center>



<blockquote><p>Note: As you could read, my english is far from being perfect. Don't hesitate to leave a comment if you found a better way to explain some stuff.</p></blockquote>

<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h5>Update: Do this without Python <a name="doThisWithoutPython"></a></h5>


<p>Well, it's not really the goal but since Kel Solar talk about <a href="http://www.fevrierdorian.com/blog/post/2011/02/20/Projeter-un-mesh-sur-un-autre-avec-l-API-Python-de-Maya#c205">in comments</a> I also give you a way to do this using the built in Maya. <img src="/blog/themes/blueSilenceCustom/smilies/seSentCon.gif" alt=":seSentCon:" class="smiley" /></p>


<p>Select the target mesh:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_016.png" alt="projection_mesh_api_016.png" style="display:block; margin:0 auto;" title="projection_mesh_api_016.png, fév. 2011"  height="453" width="603" /></p>


<p>Select the source mesh:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_017.png" alt="projection_mesh_api_017.png" style="display:block; margin:0 auto;" title="projection_mesh_api_017.png, fév. 2011"  height="409" width="554" /></p>


<p>Open transfert attributes options:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_018.png" alt="projection_mesh_api_018.png" style="display:block; margin:0 auto;" title="projection_mesh_api_018.png, fév. 2011"  height="232" width="259" /></p>


<p>Set options as follow:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_019.png" alt="projection_mesh_api_019.png" style="display:block; margin:0 auto;" title="projection_mesh_api_019.png, fév. 2011"  height="359" width="551" /></p>


<p>Basically, we only transfer the vertex positions in world space by projecting them along their normal.</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_02_05_projection_mesh_api/projection_mesh_api_020.png" alt="projection_mesh_api_020.png" style="display:block; margin:0 auto;" title="projection_mesh_api_020.png, fév. 2011"  height="399" width="622" /></p>


<p>And that's it!</p>


<p>You can rotate the source mesh and it's updated! <img src="/blog/themes/blueSilenceCustom/smilies/laClasse.gif" alt=":laClasse:" class="smiley" /></p>


<p>Voila! That way, people who came to find a quick solution will not be frustrated! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


feed_id: urn:md5:67e0389842c58f3d9b666734b39a3c69
title: Les Contes de la Nuit, résumé d'une supervision technique
uri: Les-Contes-de-la-Nuit-résumé-d-une-supervision-technique
url:
http://www.fevrierdorian.com/blog/post/2011/07/20/Les-Contes-de-la-Nuit-resume-d-une-supervision-technique

content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/lcdln_resume_superviseur_tn.png" alt="lcdln_resume_superviseur_tn.png" style="float:left; margin: 0 1em 1em 0;" title="lcdln_resume_superviseur_tn.png, juil. 2011"  height="150" width="150" />Comme vous le savez peut être déjà, le long métrage <a href="http://www.allocine.fr/film/fichefilm_gen_cfilm=183772.html" hreflang="fr">Les Contes de la Nuit</a> de <a href="http://www.imdb.com/name/nm0643664/" hreflang="en">Michel Ocelot</a> (<a href="http://www.allocine.fr/film/fichefilm_gen_cfilm=18446.html" hreflang="fr">Kirikou</a>, <a href="http://www.allocine.fr/film/fichefilm_gen_cfilm=57417.html" hreflang="fr">Azur et Asmar</a> entre autres) est sorti!</p>


<p>J'ai eu la chance de superviser la partie technique de la production. Au delà du fait que je trouve que ce film est une vraie réussite, ce fut sans hésiter l'une de mes plus belle expérience professionnelle. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>Dans ce billet je vous propose de faire le tour des moyens mis en place pour réaliser ce beau, que dis-je? Magnifique projet!</p>


<p>(Et faire un petit peu de pub aussi <img src="/blog/themes/blueSilenceCustom/smilies/siffle.gif" alt=":siffle:" class="smiley" /> )</p>    <h3>Note</h3>

<blockquote><p>Bien que le contenu de ce blog soit sous licence Créative, toutes les images présentes sur ce billet sont la propriété de leurs auteurs respectifs. Tout contrevenant s'expose à des poursuites judiciaires et pourra se voir kidnappé dans son sommeil, lapidé sur la place publique et privé de bonbons. <img src="/blog/themes/blueSilenceCustom/smilies/evilgrin0002.gif" alt=":gniarkgniark:" class="smiley" /></p></blockquote>


<h3>Mon arrivé sur le projet</h3>

<p>Tout d'abord, une remise en place du contexte me semble intéressante.</p>


<p>Tout commence fin 2009, je suis à <a href="http://www.def2shoot.com/" hreflang="en">Def2Shoot</a> sur le long métrage d'animation <a href="http://www.imdb.com/title/tt1039651/" hreflang="en">Yona Yona</a> (nom du projet à l'époque). A la suite de plusieurs réunions de prod franco-japonaises, le choix de faire l'animation des personnages principaux sous Maya et les décors sous XSI est fait. Je me retrouve à être le seul TD sous Maya (D2S étant sous XSI).</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/yona.jpg" title="yona.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/.yona_m.jpg" alt="yona.jpg" style="display:block; margin:0 auto;" title="yona.jpg, juil. 2011"  height="560" width="411" /></a></p>


<p>Franck Malmin (<a href="http://www.excessif.com/cinema/actu-cinema/dossiers/la-naissance-de-yona-par-franck-malmin-producteur-executif-5668560-760.html">lire son témoignage</a>, très sincère, sur le film), alors directeur du studio, propose au Surfacing TD du projet d'aider "une production" à se lancer. Celui ci commence ainsi à passer quelques après midi à <a href="http://www.nord-ouest.fr/">Nord Ouest Film</a>, ou une partie de "l'équipe de Michel" est déjà en place.</p>


<p>A ce moment là je n'en savais pas plus. Mais les difficultés qu'allaient rencontrer Yona Yona commençaient à se faire ressentir et la production demande le retour à plein temps de son surfacing TD sur le projet.</p>


<p>A Def2Shoot, la partie sous Maya posant de moins en moins de soucis (grâce notamment à l'arrivé d'un second TD), Franck me demande de continuer le travail commencé chez Nord Ouest.</p>


<p>C'est à ce moment là que je rencontre ceux que je connaissais sous l’appellation "l'équipe de Michel", tous des gens formidables. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>Au début, mon travail ne devait pas durer longtemps et était très basique. Il fallait prendre connaissance des besoins du projet et les aiguiller vers des solutions rapides (aide pour convertir les .map de mental ray car les plans des décors étaient monstrueusement grand, définir une hiérarchie de dossier et expliquer le pourquoi du comment de chaque dossier, etc...).</p>


<p>Malgré les besoins techniques assez limité que nécessitait ce projet (Les Contes de la Nuit, ce n'est pas Transformers avec du raytracing partout), l'équipe, finalement assez réduite et composé de <del>peu</del> pas de techniciens, pouvait, à long terme, se retrouver à passer plus de temps à régler des soucis techniques qu'à vraiment travailler sereinement. <img src="/blog/themes/blueSilenceCustom/smilies/reflechi.gif" alt=":reflechi:" class="smiley" /></p>


<p>Il y avait quand même, à ce moment là, 10 épisodes de 13 minutes en Full HD à sortir.</p>


<p>Cette inquiétude était partagée avec le reste de l'équipe et au bout de quelques conversations entre Franck et la production, il fut décidé que je continuerai le projet jusqu'à la fin (le projet durait un an et demi et il est à noter que les délais furent respectés).</p>


<p>Je faisais donc officiellement partie de l'équipe!</p>
<center><img src="/blog/themes/blueSilenceCustom/smilies/youplaBoum.gif" alt=":youplaBoum:" class="smiley" /></center>



<h3>Les grands moyens</h3>


<p>Cette décision allait pas mal changer mon implication sur le projet et je pouvais voir "plus loin", faire des choses plus avancées, gérer des cas plus complexes etc...</p>


<p>L'assistant réal de Michel Ocelot venait de la 2D et avait l'habitude faire un travail de préprod <del>conséquent</del> monstrueux. Ainsi, le storyboard et la mise en scène est déjà faite et un dépouillement technique et d'intention était déjà dans les fichiers Excel de la directrice de production avant même qu'un épisode ne parte en Layout.</p>


<p>Ce genre de chose m'a pas mal rassuré car la perspective de devoir tout changer au dernier moment (mentalité <del>très</del> trop présente dans la pub et le cinéma dit "à l'américaine") ne m'aurait pas incité à prendre certains risques pour améliorer la prod et ces conditions. Forcément quand on a une certaine assurance que ce qu'on souhaite faire est bien ce qu'on va faire, on se prend moins la tête à prévoir du temps pour le bricolage.</p>


<p>C'est à ce moment que j'ai pu commencer à définir les grandes lignes du workflow.</p>


<h3>L'usage du script</h3>


<p>N'y allons pas par quatre chemins: Le script était partout ou personne n'osait s'aventurer. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>L'importance d'une hiérarchie de fichier techniquement cohérente était donc primordiale pour pouvoir automatiser des taches, tout en gardant à en tête qu'elle allait aussi être manipulé par des "humains" et, de ce fait, devait également rester compréhensible.</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/noShowPlans_001.png" alt="noShowPlans_001.png" style="display:block; margin:0 auto;" title="noShowPlans_001.png, juil. 2011"  height="246" width="338" /></p>


<p>Le langage de prédilection fut le MEL pour tout ce qui touche Maya (Je n'étais pas encore à l'aise avec "Python de Maya" à ce moment là) et du Python pour tout ce qui touche la manipulation de fichiers (<em>os</em> et <em>re</em> sont tes amis).</p>


<p>L'utilisation du scripting c'est surtout faite aux "points de passages" des informations/fichiers. J'y ferais souvent référence durant le reste de ce billet car j'ai quasiment passé cette prod mes doigts sur le clavier. <img src="/blog/themes/blueSilenceCustom/smilies/pafOrdi.gif" alt=":pafOrdi:" class="smiley" /></p>



<h3>Résumé du pipeline</h3>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/Schema_pipeline.png" title="Schema_pipeline.png"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/.Schema_pipeline_m.jpg" alt="Schema_pipeline.png" style="display:block; margin:0 auto;" title="Schema_pipeline.png, juil. 2011"  height="215" width="560" /></a></p>
<center><i>Un plan qui résume grosso modo les différentes étapes du pipeline</i></center>



<h4>Les décorateurs</h4>


<p>Les "décorateurs" ("mappeurs") faisaient leurs décors sous Photoshop (dans des fichiers très grands et très lourds ^^ ), ils exportaient le fruit de leur travail sous différentes couches en tiff dans un dossier dédié et suivant une convention de fichier défini à l'avance.</p>


<p>Au début, il convertissaient eux même leurs .tiff en .map (et .dds) mais cette manipulation leur prenait du temps. J'ai donc rapidement fait un script qui passait sur tout le projet en cours et vérifiait que chaque .map (ou .dds) était plus vieille que son .tiff. Dans le cas contraire, il effectuait une conversion. <img src="/blog/themes/blueSilenceCustom/smilies/yeoh.gif" alt=":dentcasse:" class="smiley" /></p>


<h4>Les personnages</h4>


<p>Je n'étais pas directement impliqué dans la création des personnages.</p>


<p>Un graphiste 2D faisait les versions Photoshop des personnages, "les éclatait" sur un plan, un character TD, rejoint temporairement par un animateur avaient mis en place un système de rig automatique pour générer les personnages.</p>


<p>Les images des personnages étaient converties de la même façon que les décors.</p>


<p>Ma partie, dans le pipeline commençait au niveau du Layout avec un outil pour les lister et les importer dans la scène en fonction de l'épisode.</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/layoutGen_001.png" alt="layoutGen_001.png" style="display:block; margin:0 auto;" title="layoutGen_001.png, juil. 2011"  height="341" width="412" /></p>


<p>Ce fut donc un gros travail de communication pour savoir qui lister et dans quel cas ne pas lister tel ou tel personnage.</p>


<h5>Note sur le format .dds</h5>


<p>Michel Ocelot validait l'animation sur les playblasts. Il fallait donc que les playblasts soit "le plus proche possible" du rendu final.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/playblast001.png" title="playblast001.png"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/.playblast001_m.jpg" alt="playblast001.png" style="display:block; margin:0 auto;" title="playblast001.png, juil. 2011"  height="315" width="560" /></a></p>
<center><i>Ceci est un playblast. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></i></center>



<p>Pour ça, les textures utilisées dans les scènes Maya devaient être celles utilisées dans le rendu, moyennant un redimensionnement.</p>


<p>J'ai donc codé un shader cgfx auquel je donnais les version .dds des textures pour diminuer leur charge dans la mémoire du GPU.</p>


<p>Cette technique à très bien fonctionné concernant les décors mais un bug que je n'ai pu résoudre faisait disparaitre certaines textures lors des mouvements des contrôleurs des personnages.</p>


<p>J'ai du bricoler une sorte de surface shader pour le viewport mais on perdait l’intérêt des texture en .dds car il m'a semblé que Maya décompressait puis plaçait entièrement la texture dans la mémoire du GPU. <img src="/blog/themes/blueSilenceCustom/smilies/riva.gif" alt=":pasClasse:" class="smiley" /></p>


<p>C'est dommage car c'était justement les personnages qui prenaient le plus de place en terme de texture. J'ai du faire des version "low" des .dds (qui étaient déjà de la basse def) ainsi qu'un outil pour switcher rapidement entre .dds normal et .dds "low", certains plans ayant pas mal de personnages.</p>


<h4>Le layout</h4>


<p>J'ai donc fait l'importeur de personnage mais aussi le "générateur de décors". Chaque plan du film est en fait une superposition de couches de décors:</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/orgaDesPlans001.png" title="orgaDesPlans001.png"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/.orgaDesPlans001_m.jpg" alt="orgaDesPlans001.png" style="display:block; margin:0 auto;" title="orgaDesPlans001.png, juil. 2011"  height="339" width="560" /></a></p>


<p>Comme la nomenclature des fichiers était claire, il était très simple, via un script, de savoir ou étaient les différentes couches du plan en court.</p>


<p>Il suffisait alors de préciser le numéro de l'épisode ainsi que le numéro du plan qu'on souhaite générer, de valider.</p>


<p>Un rig de décor était importé puis adapté au plan. Les couches du décor étaient chargées sur leur plan respectif et l'image plane de la camera affichait l'animatique exportée du montage.</p>


<p>Il ne restait "plus qu'à" placer les personnages.</p>


<p>J'ai également scripté un "transfert de plan" pour que les "layouteurs" n'ait pas à remplacer tous les personnages alors que deux plans plus tard ils sont dans la même position.</p>


<h4>L'animation</h4>


<p>Il n'y avait rien de "pipeliné" concernant la publication des scènes de layout. Les animateurs copiaient la scène de layout de leur plan et commençaient à animer.</p>


<p>J'ai codé un panel de personnage qui était surtout utilisé pour les mains des personnages. Les mains étaient des textures plaquées sur des faces affichées/masquées au fil de l'animation.</p>


<p>Les textures des mains ainsi que les numéros des attributs à "afficher/masquer" respectaient une nomenclature. Ainsi, à chaque ajout d'une main, il suffisait d'ajouter une ligne pour que le tout apparaisse dans le panel.</p>


<p>En revanche, répondre à la contrainte d'automatisation du rendu nécessitait que les scènes soient publiées dans un dossier ou le script allait pouvoir les récupérer.</p>


<p>J'ai donc fait un outil de publication des animations qui sauvait la scène en cours ainsi qu'un petit fichier vide qui jouait le role de "marqueur" pour préciser que cette scène venait d'être republiée.</p>


<h4>Le rendu</h4>


<p>Sur cette partie il n'y avait quasiment aucune intervention humaine. Tout avait été scripté par mes soins.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/script001.png" title="script001.png"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/.script001_m.jpg" alt="script001.png" style="display:block; margin:0 auto;" title="script001.png, juil. 2011"  height="509" width="560" /></a></p>
<center><i>jEdit était mon copain! <img src="/blog/themes/blueSilenceCustom/smilies/laClasse.gif" alt=":laClasse:" class="smiley" /></i></center>



<p>Je lançais un script qui reprenait toute les scènes des animateurs ayant un marqueur, les ouvrait et leurs appliquait un script qui faisait pas mal de choses (liste non exhaustive):</p>
<ul>
<li>Changer les chemins de texture (remplaçant ".dds" par ".map" entre autre).</li>
<li>Modifier les options des textures (pour utiliser le filtrage elliptique).</li>
<li>Setter des bon paramètres de rendu.</li>
<li>Aller chercher, dans un fichier texte, si le plan en question avait du motion blur et l'activer si c'était le cas.</li>
<li>Appliquer certaines modifications (décalage de l'animation des mains de 0.5 frame en cas de rendu avec motion blur pour éviter d'avoir des sautes durant les rotations sur une image, masquer certains contrôleurs visibles au rendu, etc...).</li>
<li>Faire quelques bricolages propres à l'épisode (Appliquer un blur différent au mains du Garçon Tamtam par exemple).</li>
<li>Générer les fichier de job contenant les lignes de commande à lancer (nous utilisions <a href="http://www.uberware.net/smedge/" hreflang="en">Smedge</a>) ainsi qu'un .bat en cas de rendu en local.</li>
<li>Supprimer le fichier marqueur.</li>
<li>Sauver la scène prête à rendre dans le bon dossier.</li>
</ul>

<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/batchSmedge001.png" alt="batchSmedge001.png" style="display:block; margin:0 auto;" title="batchSmedge001.png, juil. 2011"  height="224" width="238" /></p>
<center><i>Les lanceurs de job généré par mon script</i></center>



<p>Les graphistes, quand ils quittait leur poste le soir ou durant la pause de midi, lançait un client de Smedge et leur machine calculait les rendus.</p>




<p>Mental ray était le moteur utilisé et a très bien joué son rôle (c'était mon moteur de prédilection aussi). Une fois les .map et le filtrage elliptique mis en place, tout à roulé!</p>


<h4>Le compositing</h4>


<p>Le compositing était fait sous After Effect et se divisait en deux parties.</p>
<ul>
<li>Une première contenant tout les "trucs un peu spéciaux" (effets de fumé, transformations, certaines animations aussi) était assuré par un animateur 2D.</li>
<li>La seconde partie représentait le plus gros des plans (80% je dirais) et était principalement de la retouche rapide (patates), des effets globaux (profondeur de champ), etc...</li>
</ul>

<p>J'ai fait un script After Effect (une première expérience) qui créait une compo pour le plan, importait toutes les couches, les empilait dans l'ordre et créait un set d'export.</p>


<p>C'était aussi grâce à ce script qu'on pouvait avoir un retour rapide des rendus "bruts": On lançait le script pour tout les plans rendus, on cliquait sur "Rendu" et le calcul de toute les couches se faisait. Il ne restait plus qu'à vérifier dans le projet de montage (Final Cut) qui se mettait automatiquement à jour.</p>


<p>Un second script (utilisé dans le premier en fait) générait les set d'export depuis les compos sélectionnés dans After Effect ce qui simplifiait le travail des graphistes qui n'avaient plus à perdre de temps sur l'export de leur travail.</p>


<h4>Tout le reste</h4>


<p>Bien entendu, il y avait tout pleins de petites taches qu'il fallait remplir au fil du projet:</p>
<ul>
<li>Backup des épisodes.</li>
<li>Gestion de la place sur le serveur.</li>
<li>Dépouillement technique.</li>
</ul>

<h3>Passage du stade de série au stade de long métrage en relief</h3>


<p>Et oui! Parce que c'est ça qui est particulièrement intéressant sur ce projet. L'idée partait d'une série full HD pour Canal+ et se finit en un long métrage en relief, ce n'est pas un truc qu'on voit tout les jours. <img src="/blog/themes/blueSilenceCustom/smilies/redface.gif" alt=":redface:" class="smiley" /></p>


<p>Je me rappel que c'est suite à une projection pour Canal+ que l'idée d'un long métrage (on ne parlait pas de relief à ce moment là) à commencer à se faire entendre, sans jamais être réellement officielle. Concrètement, cela changeait peu de choses pour nous.</p>


<p>Mais quand on a commencé à parler de relief, les choses ont un peu évolué. <a href="http://www.macguff.fr/fr#/jobs/456-les-contes-de-la-nuit" hreflang="fr">Mac Guff</a> était dans le coup. Nous leur avions donné quelques plans suffisamment représentatif de l'ensemble et ils en ont fait du "vrai" relief.</p>


<p>J'insiste sur le terme "vrai" relief car Mac Guff disposait de toute les couches (et nos fichiers After Effect en fait) et a put travailler le relief sans avoir à recréer artificiellement de la profondeur.</p>


<p>Lors de la première présentation nous étions 5-6 et je dois dire que j'étais particulièrement impressionné par le résultat. La profondeur et le noir donnait un véritable effet de théâtre à l'ensemble. L'équipe du relief avait fait de l'excellent travail et je pense que tout le monde était conquis. (Avatar pouvait aller se rhabiller, il venait de se prendre un low kick rotatif inversé là! <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /> )</p>


<p>Une fois le relief officiellement validé, le nombre de couche à explosé. Il arrivait que les compos After Effect plombe notre petit réseaux. Finalement, calculer les images en local s'est révélé une solution simple, pas cher, et qui solutionnait, en partis, le problème.</p>


<p>La production c'est donc très bien fini, sans douleurs et c'est assez rare pour être précisé.</p>


<h3>Ce que j'aurais aimé faire mieux</h3>


<p>Forcément, avec le recul, je me dis que quelques points aurait mérité un peu plus d'attention.</p>

<ul>
<li>J'aurai aimé résoudre le problème des textures (cgfx + .dds) qui popaient dans le viewport lorsque les animateurs bougeaient leur contrôleurs. La solution trouvé n'était pas optimale et alourdissait la charge de Maya quand il y avait beaucoup de persos. Les <em>seg faults</em> étaient fréquent...</li>
<li>J'ai choisi d'utiliser le .png pour l'ensemble des images du projet (sauf export Photoshop car le .tiff était le seul format qui conservait bien les alphas lors d'une conversion en .map) car ce format était particulièrement "clair" (RGBA et pis c'est tout!) et je voulais éviter le tiff qui était beaucoup plus "opaque" (plusieurs type de compressions possible, nombre de channel, ne s'ouvre pas partout, etc...). C'est quelque chose que je considère comme une erreur de débutant maintenant car le .png est un format de fichier extrêmement lourd à ouvrir. Le .tiff, si il est bien géré, à tout les endroits du pipeline (au moins au rendu), offre un bien meilleur confort.</li>
<li>Surement d'autres choses...</li>
</ul>

<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/yona_contes_de_la_nuit.jpg" title="yona_contes_de_la_nuit.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/.yona_contes_de_la_nuit_m.jpg" alt="yona_contes_de_la_nuit.jpg" style="display:block; margin:0 auto;" title="yona_contes_de_la_nuit.jpg, oct. 2012"  height="373" width="560" /></a></p>


<h3>Conclusion</h3>

<p>Vous l'aurez surement compris, ce fut une belle expérience autant professionnel que personnel. Bosser avec Michel Ocelot c'est presque un cadeau.</p>


<p>Ce fut aussi une première supervision technique sur un long métrage pour moi.</p>


<p>Le film <a href="http://www.allocine.fr/film/fichefilm-183772/palmares/" hreflang="fr">sera nominé 8 fois</a> au festival international de Berlin ce qui est quand même un grande réussite quand je me remémore le nombre de personnes finalement assez faible qui a travaillé sur ce projet (comparé à d'autres productions d'animation cinématographique).</p>


<p>Les critiques de la presse sont très bonnes et j'espère que ce billet un peu technique vous aura donné envie de voir ce film fait avec amour. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>

<div class="external-media" style="margin: 1em auto; text-align: center;">
<iframe width="640" height="390" src="http://www.youtube.com/embed/vjG45ZTFFjM" frameborder="0" allowfullscreen></iframe>
</div>



<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/lescontes.jpg" title="lescontes.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_06_lcdln_resume_superviseur/.lescontes_m.jpg" alt="lescontes.jpg" style="display:block; margin:0 auto;" title="lescontes.jpg, juil. 2011"  height="560" width="411" /></a></p>


<p>Mes contes préféré?</p>
<ul>
<li>Le Loup-Garou: Parce que le travail fait sur les feuilles rend le relief magnifique.</li>
<li>L'élue de la ville d'or: Parce que dans une salle de cinéma, avec la musique et tout, votre cœur d'adulte lâchera obligatoirement quelques larmes de bonheur.</li>
</ul>

<p>A bientôt!</p>


<p>Dorian</p>


<h3>Liens</h3>
<ul>
<li><a href="http://www.imdb.com/title/tt1828229/fullcredits" hreflang="en">Page IMDb des Contes de la nuit</a></li>
<li><a href="http://www.imdb.com/title/tt1723666/fullcredits" hreflang="en">Page IMDb de Dragons et Princesses</a></li>
<li><a href="http://www.allocine.fr/film/fichefilm_gen_cfilm=183772.html" hreflang="fr">Page allocine</a></li>
<li><a href="http://fr.wikipedia.org/wiki/Dragons_et_Princesses" hreflang="fr">Page Wikipedia de Dragons et Princesses</a></li>
</ul>


feed_id: urn:md5:455cc6a0eb98160654cff8c9f149290c
title: Utiliser Graphviz pour générer des graphes de dépendance
uri: Utiliser-Graphviz-pour-générer-des-graphes-de-dépendance
url:
http://www.fevrierdorian.com/blog/post/2011/07/18/Utiliser-Graphviz-pour-g%C3%A9n%C3%A9rer-des-graphes-de-d%C3%A9pendance

content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_07_18_Graphviz/myGraph_tn.png" alt="myGraph_tn.png" style="float:left; margin: 0 1em 1em 0;" title="myGraph_tn.png, juil. 2011"  height="150" width="150" />Aujourd'hui je voudrais vous présenter <a href="http://www.graphviz.org/" hreflang="en">Graphviz</a>, un outil qui génère des graphes depuis des fichiers texte. <img src="/blog/themes/blueSilenceCustom/smilies/seSentCon.gif" alt=":seSentCon:" class="smiley" /></p>


<p>Je m'en suis servi en production pour générer des graphes de dépendance de révision (La révision "machin" du cache "machin" a été généré depuis la révision "machin" du model "machin" et est utilisé dans le set "truc", "bidule" et "bitonio").</p>


<p>Je ne peux bien évidement pas vous montrer les graphes générés ici mais sachez qu'on découvrait pas mal de choses en les regardant... Justement parce que ce genre d'outil permet de visualiser rapidement des choses que notre cerveau a du mal à concevoir tout seul. Dans le cas d'un dataflow un peu compliqué, ça détend les neurones. <img src="/blog/themes/blueSilenceCustom/smilies/cyberjo.gif" alt=":nevroz:" class="smiley" /></p>


<p>(Merci à <a href="http://fr.linkedin.com/in/adrienherubel">Adrien Herubel</a> de m'avoir fait découvrir cet outil)</p>    <p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_07_18_Graphviz/french_pipeline.jpg" alt="french_pipeline.jpg" style="display:block; margin:0 auto;" title="french_pipeline.jpg, juil. 2011"  height="467" width="550" />
D'autres graphiques impressionnants sur cette <a href="http://www2.research.att.com/~yifanhu/GALLERY/GRAPHS/" hreflang="en">magnifique galerie</a>.</p>


<h3>Principe</h3>

<p>Le principe est très simple: Vous générez un fichier texte contenant les informations du graphe.</p>


<p>Vous donnez ensuite ce fichier à un des outils de Graphviz (principalement dot) qui génère ainsi une image de votre graphe. <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></p>


<h3>Un premier exemple, simple</h3>

<p>Installer graphviz pour votre OS, lancez un terminal et c'est parti! <img src="/blog/themes/blueSilenceCustom/smilies/1420.gif" alt=":grenadelauncher:" class="smiley" /></p>


<p>Le langage dot est très simple et il s'apprend quasiment uniquement par la pratique.</p>


<p>Voici un exemple que je vais détailler:</p>

<pre class="dot dot"><span style="color: #000000; font-weight: bold;">digraph</span> g <span style="color: #66cc66;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">graph</span> <span style="color: #66cc66;">&#91;</span>
		<span style="color: #000066;">rankdir</span> <span style="color: #66cc66;">=</span> LR
		<span style="color: #000066;">bgcolor</span><span style="color: #66cc66;">=</span> grey50
	<span style="color: #66cc66;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">node</span> <span style="color: #66cc66;">&#91;</span>
		<span style="color: #000066;">fontsize</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;10&quot;</span>
		<span style="color: #000066;">shape</span> <span style="color: #66cc66;">=</span> <span style="color: #993333;">box</span>
		<span style="color: #000066;">style</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;rounded,filled&quot;</span>
	<span style="color: #66cc66;">&#93;</span>
&nbsp;
	myNode1 <span style="color: #66cc66;">&#91;</span>
		<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Node One&quot;</span>
		<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">lightsalmon</span>
		<span style="color: #000066;">fillcolor</span> <span style="color: #66cc66;">=</span> grey75
	<span style="color: #66cc66;">&#93;</span>
	myNode2 <span style="color: #66cc66;">&#91;</span>
		<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Node Two&quot;</span>
		<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> lightcoral
		<span style="color: #000066;">fillcolor</span> <span style="color: #66cc66;">=</span> grey75
	<span style="color: #66cc66;">&#93;</span>
	myNode3 <span style="color: #66cc66;">&#91;</span>
		<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Node Three&quot;</span>
		<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">lightpink</span>
		<span style="color: #000066;">fillcolor</span> <span style="color: #66cc66;">=</span> grey75
	<span style="color: #66cc66;">&#93;</span>
	myNode4 <span style="color: #66cc66;">&#91;</span>
		<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Node Four&quot;</span>
		<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">orange</span>
		<span style="color: #000066;">fillcolor</span> <span style="color: #66cc66;">=</span> grey75
	<span style="color: #66cc66;">&#93;</span>
&nbsp;
	myNode1 <span style="color: #66cc66;">-&gt;</span> myNode2 <span style="color: #66cc66;">&#91;</span> penwidth <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>, <span style="color: #000066;">fontsize</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">8</span>, <span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Connection One&quot;</span> <span style="color: #66cc66;">&#93;</span>
	myNode2 <span style="color: #66cc66;">-&gt;</span> myNode3 <span style="color: #66cc66;">&#91;</span> penwidth <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>, <span style="color: #000066;">fontsize</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">8</span>, <span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Connection Two&quot;</span> <span style="color: #66cc66;">&#93;</span>
	myNode1 <span style="color: #66cc66;">-&gt;</span> myNode4 <span style="color: #66cc66;">&#91;</span> penwidth <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>, <span style="color: #000066;">fontsize</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">8</span>, <span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Connection Three&quot;</span> <span style="color: #66cc66;">&#93;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">subgraph</span> cluster_sg1 <span style="color: #66cc66;">&#123;</span>
		<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;subGraph One&quot;</span>
		<span style="color: #000066;">style</span> <span style="color: #66cc66;">=</span> rounded
		<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> springgreen4
		myNode1
		myNode4
	<span style="color: #66cc66;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">subgraph</span> cluster_sg2 <span style="color: #66cc66;">&#123;</span>
		<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;subGraph Two&quot;</span>
		<span style="color: #000066;">style</span> <span style="color: #66cc66;">=</span> rounded
		<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> violetred3
		myNode2
		myNode3
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre>


<p>Copiez tout ça dans un fichier <em>monFichier.dot</em> puis faites:</p>

<pre class="bash bash">dot <span style="color: #660033;">-Tpng</span> monFichier.dot <span style="color: #660033;">-o</span> monGraphe.png</pre>


<p>Ici, <em>-Tpng</em> sert à dire à dot de créer un graph au format png. (Il y en a d'autres comme <em>-Tsvg</em>. La liste complète est disponible dans <a href="http://www.graphviz.org/pdf/dot.1.pdf" hreflang="en">la doc de dot</a>, bas de la première page).</p>


<p>Une fois généré, vous devriez avoir ça:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_07_18_Graphviz/myGraph001.png" alt="myGraph001.png" style="display:block; margin:0 auto;" title="myGraph001.png, juil. 2011"  height="243" width="557" /></p>
<center><i>Et voilà le travail! <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></i></center>



<p>Notez qu'on a pas besoin de réfléchir au positionnement des nodes. On déclare, les nodes, les connexions et il génère le graphe. Cette "puissance" peut être bloquante quand justement, on essaye d'organiser un peu les graphes qu'on sort... <img src="/blog/themes/blueSilenceCustom/smilies/reflechi.gif" alt=":reflechi:" class="smiley" /></p>


<p>Et maintenant les explications.</p>


<p>Vous allez voir que Graphviz peut être très flexible quand vous décrivez vos graphes. Il n'y a pas une seule façon de déclarer un graphe, d’où l’intérêt d’expérimenter un maximum. <img src="/blog/themes/blueSilenceCustom/smilies/idee.gif" alt=":idee:" class="smiley" /></p>


<p>C'est aussi la porte ouverte au n'importe quoi. C'est à vous de faire attention. <img src="/blog/themes/blueSilenceCustom/smilies/adodonicoco.gif" alt=":papi:" class="smiley" /></p>

<pre class="dot dot"><span style="color: #000000; font-weight: bold;">digraph</span> g <span style="color: #66cc66;">&#123;</span> ... <span style="color: #66cc66;">&#125;</span></pre>

<p>Il ne doit y en avoir qu'un seul et c'est celui qui contient votre graphe. C'est un peu la racine.</p>


<p><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></p>

<pre class="dot dot"><span style="color: #000000; font-weight: bold;">graph</span> <span style="color: #66cc66;">&#91;</span>
	<span style="color: #000066;">rankdir</span> <span style="color: #66cc66;">=</span> LR
	<span style="color: #000066;">bgcolor</span><span style="color: #66cc66;">=</span> grey50
<span style="color: #66cc66;">&#93;</span></pre>

<p>Contient tout les attributs par défaut du graphe (<a href="http://www.graphviz.org/pdf/dotguide.pdf" hreflang="en">cf dotguide</a>, page 33).</p>
<ul>
<li><em>rankdir</em>: Permet de définir le sens du graphe (ici, Left to Right)</li>
<li><em>bgcolor</em>: La couleur du fond du graphe, à choisir parmi les nombreuses <a href="http://www.graphviz.org/content/color-names" hreflang="en">couleurs disponibles</a>.</li>
</ul>

<p><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></p>

<pre class="dot dot"><span style="color: #000000; font-weight: bold;">node</span> <span style="color: #66cc66;">&#91;</span>
	<span style="color: #000066;">fontsize</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;10&quot;</span>
	<span style="color: #000066;">shape</span> <span style="color: #66cc66;">=</span> <span style="color: #993333;">box</span>
	<span style="color: #000066;">style</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;rounded,filled&quot;</span>
<span style="color: #66cc66;">&#93;</span></pre>

<p>Contient tout les attributs par défaut des nodes (<a href="http://www.graphviz.org/pdf/dotguide.pdf" hreflang="en">cf dotguide</a>, page 30).</p>
<ul>
<li><em>fontsize</em>: La taille de la police de caractère utilisée pour les nodes.</li>
<li><em>shape</em>: La forme des nodes (<a href="http://www.graphviz.org/pdf/dotguide.pdf" hreflang="en">cf dotguide</a>, page 38).</li>
<li><em>style</em>: La "mise en page" des nodes. Ici, bords arrondis (j'aime bien <img src="/blog/themes/blueSilenceCustom/smilies/seSentCon.gif" alt=":seSentCon:" class="smiley" /> ) et bg coloré.</li>
</ul>

<p><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></p>

<pre class="dot dot">myNode1 <span style="color: #66cc66;">&#91;</span>
	<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Node One&quot;</span>
	<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">lightsalmon</span>
	<span style="color: #000066;">fillcolor</span> <span style="color: #66cc66;">=</span> grey75
<span style="color: #66cc66;">&#93;</span></pre>

<p>S'en suit maintenant la description de chaque node.</p>


<p>Par défaut, les valeurs des attributs sont celles définies dans la déclaration <em>node</em>, juste au dessus.</p>


<p>Ensuite, chaque paramètre vient s'ajouter:</p>
<ul>
<li><em>label</em>: Ce qui est écrit dans le node (nous verrons plus loin quand on souhaite faire de la mise en forme plus complexe)</li>
<li><em>color</em>: La couleur des bords du node, à choisir parmi les nombreuses <a href="http://www.graphviz.org/content/color-names" hreflang="en">couleurs disponibles</a>.</li>
<li><em>fillcolor</em>: La couleur du fond du node.</li>
</ul>

<p>On déclare plusieurs nodes comme ça puis on attaque les connections.</p>


<p><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></p>

<pre class="dot dot">myNode1 <span style="color: #66cc66;">-&gt;</span> myNode2 <span style="color: #66cc66;">&#91;</span> penwidth <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">1</span>, <span style="color: #000066;">fontsize</span> <span style="color: #66cc66;">=</span> <span style="color: #cc66cc;">8</span>, <span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Connection One&quot;</span> <span style="color: #66cc66;">&#93;</span></pre>

<p>Les attributs et leurs valeurs par défauts sont dispos sur le <a href="http://www.graphviz.org/pdf/dotguide.pdf" hreflang="en">dotguide</a>, page 32.</p>
<ul>
<li><em>penwidth</em>: La taille du tracé de la connexion (Inutile dans ce cas là car, comme vous pouvez le constater dans la doc, la taille par défaut est déjà à 1). <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /></li>
<li><em>fontsize</em>: La taille du texte de la connexion.</li>
<li><em>label</em>: Ce qui est écrit dans la connection (notez que j’écris rarement un texte sur une connexion).</li>
</ul>

<p><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></p>


<p>Viennent ensuite les subgraphs qui sont tout à fait optionnel mais peuvent servir à donner un peu d'ordre à vos graphes:</p>
<pre class="dot dot"><span style="color: #000000; font-weight: bold;">subgraph</span> cluster_sg1 <span style="color: #66cc66;">&#123;</span>
	<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;subGraph One&quot;</span>
	<span style="color: #000066;">style</span> <span style="color: #66cc66;">=</span> rounded
	<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> springgreen4
	myNode1
	myNode4
<span style="color: #66cc66;">&#125;</span></pre>
<ul>
<li><em>label</em>: Le nom du subgraph qui s'affichera.</li>
<li><em>style</em>: Le "style" du subgraph (comme les nodes).</li>
<li><em>color</em>: La couleur des contours du subgraph.</li>
</ul>
<p>Viennent ensuite la liste des nodes contenu dans le subgraph.</p>


<blockquote><p>Important: Les identifiants des subgraphs doivent toujours commencer par "cluster" sinon ils ne s'afficheront pas. Je m'en suis fait des bosses à me taper la tête contre les murs avec ça. <img src="/blog/themes/blueSilenceCustom/smilies/aupoil.gif" alt=":aupoil:" class="smiley" /></p></blockquote>


<p>Nous avons donc fini avec le premier exemple. Nous allons maintenant prendre un cas plus concret. <img src="/blog/themes/blueSilenceCustom/smilies/as253.gif" alt=":enerve:" class="smiley" /></p>


<h3>Un graphe de dépendance de révision</h3>


<p>Comme je ne m'en suis servi que dans le cadre d'une production CG, je placerai mon exemple dans ce contexte. Peut être existe t'il mille façons d'utiliser dot et que la mienne est bien la dernière, mais après tout, c'est ce qui nous intéresse non? <img src="/blog/themes/blueSilenceCustom/smilies/yeoh.gif" alt=":dentcasse:" class="smiley" /></p>


<p>Nous allons prendre l'exemple d'un graphe de dépendance de révision. L'avantage de ce genre de graph, c'est qu'il est souvent de <a href="http://fr.wikipedia.org/wiki/Arbre_%28graphe%29" hreflang="fr">type tree</a>.</p>


<h4>Avant propos, Python est ton amis</h4>


<p>Je vais passer brièvement sur le "comment" de la génération des fichiers .dot.</p>


<p>Pour générer un tel fichier, je me suis servi des classes en Python auquel je rajoutais des attributs.</p>


<p>Chaque nœud du graphe est en fait un objet Python de type <em>RevNode</em> contenant tous ses attributs ainsi qu'une liste de tous ses enfants.</p>


<p>L'idée est de créer une liste de <em>RevNode</em>, chacun ayant ces propres attributs et les autres Nodes auxquels il se connecte.</p>


<p>Bien entendu, vous récupérez automatiquement ces informations dans la base de donnée de votre pipeline. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>Vous partez donc d'une révision que vous choisissez, puis vous la parcourez en arbre via une fonction récursive.</p>

<pre class="python python"><span style="color: #ff7700;font-weight:bold;">class</span> RevNode<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> :
&nbsp;
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">def</span> <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span> <span style="color: #008000;">self</span> <span style="color: black;">&#41;</span> :
&nbsp;
		<span style="color: #008000;">self</span>.<span style="color: black;">nodeName</span> = <span style="color: #483d8b;">&quot;&quot;</span>	<span style="color: #808080; font-style: italic;"># Ici, un identifiant unique du node, c'est à vous de voir</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">assetName</span> = <span style="color: #483d8b;">&quot;&quot;</span>	<span style="color: #808080; font-style: italic;"># &quot;chaussette&quot;</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">assetType</span> = <span style="color: #483d8b;">&quot;&quot;</span>	<span style="color: #808080; font-style: italic;"># anim, model, etc...</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">rev</span> = <span style="color: #483d8b;">&quot;&quot;</span>	<span style="color: #808080; font-style: italic;"># &quot;Last&quot;, &quot;Validated&quot;, &quot;5&quot;, etc...</span>
		<span style="color: #008000;">self</span>.<span style="color: black;">childrenList</span> = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>	<span style="color: #808080; font-style: italic;"># List de tout les RevNode enfant de celui ci</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">def</span> getAllRevNode<span style="color: black;">&#40;</span> <span style="color: #008000;">self</span> <span style="color: black;">&#41;</span> :
		<span style="color: #483d8b;">&quot;&quot;&quot;Renvoit ce node plus ces enfants&quot;&quot;&quot;</span>
&nbsp;
		revNodeList = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
&nbsp;
		revNodeList.<span style="color: black;">append</span><span style="color: black;">&#40;</span> <span style="color: #008000;">self</span> <span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># on ajoute ce node</span>
&nbsp;
		<span style="color: #ff7700;font-weight:bold;">for</span> revNode <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: black;">childrenList</span> :
&nbsp;
			revNodeList += revNode.<span style="color: black;">getAllAssetNode</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #ff7700;font-weight:bold;">return</span> assetNodeList</pre>
<center><i>Oui je sais, les fonctions récursives en Python, caymal <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /></i></center>



<p>Arrivé à ce stade, vous avez une liste de <em>RevNode</em>.</p>


<p>Il faut ensuite générer le fichier .dot contenant tout ça. Nous allons voir que l'on peut "formater" le contenu d'un node de manière plus personnalisé grâce à une possibilité intéressante de dot qui permet de lui donner un label qui sera interprété en HTML (<a href="http://www.graphviz.org/pdf/dotguide.pdf" hreflang="en">cf dotguide</a>, page 9).</p>


<h4>HTML dans dot</h4>

<p>Il faut préciser à dot que le <em>label</em> que vous lui donnez devra être interprété en HTML.</p>


<p>Pour ça, rien de plus simple, il faut simplement placer le contenu HTML entre &lt; ... &gt;&nbsp;:</p>
<pre class="dot dot"><span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&lt;</span> maDescriptionHTML <span style="color: #66cc66;">&gt;</span></pre>


<p>Le plus dur étant de justement avoir de l'HTML valide. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>Un exemple:</p>

<pre>
&lt;TABLE BORDER=&quot;0&quot; CELLBORDER=&quot;0&quot; CELLSPACING=&quot;0&quot;&gt;
&lt;TR&gt;&lt;TD ALIGN=&quot;right&quot; &gt;&lt;FONT COLOR=&quot;deeppink&quot;&gt;Name:&lt;/FONT&gt;&lt;/TD&gt;&lt;TD ALIGN=&quot;left&quot; &gt;Chausset&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;&lt;TD ALIGN=&quot;right&quot; &gt;&lt;FONT COLOR=&quot;blue4&quot;&gt;Type:&lt;/FONT&gt;&lt;/TD&gt;&lt;TD ALIGN=&quot;left&quot; &gt;Model&lt;/TD&gt;&lt;/TR&gt;
&lt;TR&gt;&lt;TD ALIGN=&quot;right&quot; &gt;&lt;FONT COLOR=&quot;darkorchid4&quot;&gt;Rev:&lt;/FONT&gt;&lt;/TD ALIGN=&quot;left&quot; &gt;&lt;TD&gt;5&lt;/TD&gt;&lt;/TR&gt;
&lt;/TABLE&gt;
</pre>


<p>Mettez tout ça entre &lt; ... &gt;.</p>


<p>Expérimentez! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<h4>Let's go!</h4>


<p>Voici un graphe qui pourrait ressembler à un graphe de dépendance:</p>

<pre class="dot dot"><span style="color: #000000; font-weight: bold;">digraph</span> g <span style="color: #66cc66;">&#123;</span>
	<span style="color: #000000; font-weight: bold;">graph</span> <span style="color: #66cc66;">&#91;</span>
		<span style="color: #000066;">rankdir</span> <span style="color: #66cc66;">=</span> RL
		<span style="color: #000066;">bgcolor</span><span style="color: #66cc66;">=</span> grey50
	<span style="color: #66cc66;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">node</span> <span style="color: #66cc66;">&#91;</span>
		<span style="color: #000066;">fontsize</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;10&quot;</span>
		<span style="color: #000066;">shape</span> <span style="color: #66cc66;">=</span> <span style="color: #993333;">box</span>
		<span style="color: #000066;">style</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;rounded,filled&quot;</span>
	<span style="color: #66cc66;">&#93;</span>
	<span style="color: #000000; font-weight: bold;">edge</span> <span style="color: #66cc66;">&#91;</span>
		<span style="color: #000066;">fontsize</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;8&quot;</span>
	<span style="color: #66cc66;">&#93;</span>
&nbsp;
	myNodeSet1 <span style="color: #66cc66;">&#91;</span>
		<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&lt;&lt;</span>TABLE BORDER<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> CELLBORDER<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> CELLSPACING<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;blue4&quot;</span><span style="color: #66cc66;">&gt;</span>Name:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span>Etagere<span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;blue4&quot;</span><span style="color: #66cc66;">&gt;</span>Type:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span>Set<span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;darkorchid4&quot;</span><span style="color: #66cc66;">&gt;</span>Rev:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span><span style="color: #cc66cc;">7</span><span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;/</span>TABLE<span style="color: #66cc66;">&gt;&gt;</span>
		<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> blue4
		<span style="color: #000066;">fillcolor</span> <span style="color: #66cc66;">=</span> deepskyblue1
	<span style="color: #66cc66;">&#93;</span>
	myNodeModel1 <span style="color: #66cc66;">&#91;</span>
		<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&lt;&lt;</span>TABLE BORDER<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> CELLBORDER<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> CELLSPACING<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;darkgreen&quot;</span><span style="color: #66cc66;">&gt;</span>Name:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span>Chaussette<span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;blue4&quot;</span><span style="color: #66cc66;">&gt;</span>Type:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span>Model<span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;darkorchid4&quot;</span><span style="color: #66cc66;">&gt;</span>Rev:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span><span style="color: #cc66cc;">5</span><span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;/</span>TABLE<span style="color: #66cc66;">&gt;&gt;</span>
		<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">darkgreen</span>
		<span style="color: #000066;">fillcolor</span> <span style="color: #66cc66;">=</span> darkolivegreen4
	<span style="color: #66cc66;">&#93;</span>
	myNodeCache1 <span style="color: #66cc66;">&#91;</span>
		<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&lt;&lt;</span>TABLE BORDER<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> CELLBORDER<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> CELLSPACING<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;deeppink&quot;</span><span style="color: #66cc66;">&gt;</span>Name:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span>Chaussette<span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;blue4&quot;</span><span style="color: #66cc66;">&gt;</span>Type:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span>Cache<span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;darkorchid4&quot;</span><span style="color: #66cc66;">&gt;</span>Rev:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span><span style="color: #cc66cc;">5</span><span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;/</span>TABLE<span style="color: #66cc66;">&gt;&gt;</span>
		<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> violetred3
		<span style="color: #000066;">fillcolor</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">coral</span>
	<span style="color: #66cc66;">&#93;</span>
	myNodeModel2 <span style="color: #66cc66;">&#91;</span>
		<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&lt;&lt;</span>TABLE BORDER<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> CELLBORDER<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> CELLSPACING<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;darkgreen&quot;</span><span style="color: #66cc66;">&gt;</span>Name:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span>Chemise<span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;blue4&quot;</span><span style="color: #66cc66;">&gt;</span>Type:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span>Model<span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;darkorchid4&quot;</span><span style="color: #66cc66;">&gt;</span>Rev:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span><span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;/</span>TABLE<span style="color: #66cc66;">&gt;&gt;</span>
		<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">darkgreen</span>
		<span style="color: #000066;">fillcolor</span> <span style="color: #66cc66;">=</span> darkolivegreen4
	<span style="color: #66cc66;">&#93;</span>
	myNodeCache2 <span style="color: #66cc66;">&#91;</span>
		<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #66cc66;">&lt;&lt;</span>TABLE BORDER<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> CELLBORDER<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span> CELLSPACING<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;0&quot;</span><span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;deeppink&quot;</span><span style="color: #66cc66;">&gt;</span>Name:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span>Chemise<span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;blue4&quot;</span><span style="color: #66cc66;">&gt;</span>Type:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span>Cache<span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;</span>TR<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;right&quot;</span> <span style="color: #66cc66;">&gt;&lt;</span>FONT <span style="color: #000066;">COLOR</span><span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;darkorchid4&quot;</span><span style="color: #66cc66;">&gt;</span>Rev:<span style="color: #66cc66;">&lt;/</span>FONT<span style="color: #66cc66;">&gt;&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;</span>TD ALIGN<span style="color: #66cc66;">=</span><span style="color: #ff0000;">&quot;left&quot;</span> <span style="color: #66cc66;">&gt;</span><span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&lt;/</span>TD<span style="color: #66cc66;">&gt;&lt;/</span>TR<span style="color: #66cc66;">&gt;</span>
<span style="color: #66cc66;">&lt;/</span>TABLE<span style="color: #66cc66;">&gt;&gt;</span>
		<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> violetred3
		<span style="color: #000066;">fillcolor</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">coral</span>
	<span style="color: #66cc66;">&#93;</span>
&nbsp;
	myNodeModel1 <span style="color: #66cc66;">-&gt;</span> myNodeCache1
	myNodeModel2 <span style="color: #66cc66;">-&gt;</span> myNodeCache2
	myNodeCache1 <span style="color: #66cc66;">-&gt;</span> myNodeSet1 <span style="color: #66cc66;">&#91;</span><span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;used in&quot;</span><span style="color: #66cc66;">&#93;</span>
	myNodeModel2 <span style="color: #66cc66;">-&gt;</span> myNodeSet1 <span style="color: #66cc66;">&#91;</span><span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;used in&quot;</span><span style="color: #66cc66;">&#93;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">subgraph</span> cluster_model1 <span style="color: #66cc66;">&#123;</span>
		<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Models&quot;</span>
		<span style="color: #000066;">style</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;rounded, filled&quot;</span>
		<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">darkgreen</span>
		<span style="color: #000066;">fillcolor</span> <span style="color: #66cc66;">=</span> darkolivegreen3
		myNodeModel1
		myNodeModel2
	<span style="color: #66cc66;">&#125;</span>
&nbsp;
	<span style="color: #000000; font-weight: bold;">subgraph</span> cluster_cache1 <span style="color: #66cc66;">&#123;</span>
		<span style="color: #000066;">label</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;Caches&quot;</span>
		<span style="color: #000066;">style</span> <span style="color: #66cc66;">=</span> <span style="color: #ff0000;">&quot;rounded, filled&quot;</span>
		<span style="color: #000066;">color</span> <span style="color: #66cc66;">=</span> violetred3
		<span style="color: #000066;">fillcolor</span> <span style="color: #66cc66;">=</span> <span style="color: #b1b100;">darksalmon</span>
		myNodeCache1
		myNodeCache2
	<span style="color: #66cc66;">&#125;</span>
<span style="color: #66cc66;">&#125;</span></pre>


<p>Le résultat:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_07_18_Graphviz/myGraph002.png" alt="myGraph002.png" style="display:block; margin:0 auto;" title="myGraph002.png, juil. 2011"  height="263" width="528" /></p>


<p>L'objectif est donc de faire un script python capable de générer un tel fichier, de l’exécuter à la volé et de l'afficher à l'utilisateur. <img src="/blog/themes/blueSilenceCustom/smilies/whistle2.gif" alt=":jdicajdirien:" class="smiley" /></p>


<p>Ce graphe est minuscule. Ça commence à devenir intéressant quand les informations abondent (dans le cas d'une "vraie" prod, les infos, il en pleut à torrent! <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /> ).</p>


<h3>Liens</h3>

<p>N'oubliez pas de passer en revue les exemples proposés dans <a href="http://www.graphviz.org/Gallery.php" hreflang="en">la galerie</a> qui sont tous disponibles avec leur code dot.</p>


<p>Le <a href="http://www.graphviz.org/pdf/dotguide.pdf" hreflang="en">guide</a> contient aussi pas mal d'infos.</p>


<p>Sans oublier internet qui regorge d'exemples. <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></p>


<h3>Conclusion</h3>


<p>Et voilà! J'espère que ça vous aura donné envie d'essayer de faire des graphes quand la situation l'exige. <img src="/blog/themes/blueSilenceCustom/smilies/laClasse.gif" alt=":laClasse:" class="smiley" /></p>


<p>Je pense qu'on ne se rend compte de l’intérêt d'un tel truc qu'une fois qu'on en a vu un qui correspond à nos propres besoins.</p>


<p>A bientôt!</p>


<p>Dorian</p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></center>


feed_id: urn:md5:038be63299b2d2f7a738f3dd424e097f
title: Petit script Maya pour utiliser les objectID par particule
uri: Petit-script-Maya-pour-utiliser-les-objectID-par-particule
url:
http://www.fevrierdorian.com/blog/post/2011/07/17/Petit-script-Maya-pour-utiliser-les-objectID-par-particule

content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_07_17_code_particle_objectid/code_particle_objectid_tn.png" alt="code_particle_objectid_tn.png" style="float:left; margin: 0 1em 1em 0;" title="code_particle_objectid_tn.png, juil. 2011"  height="150" width="150" />Et encore un billet express car je fais rarement des particules et j'en avais assez de devoir chercher, à chaque fois, comment créer un système de particule qui instancie des objets aléatoirement.</p>


<p>Je me suis donc fait un bout de code à lancer que je partage avec vous en espérant qu'il fera gagner du temps à certains. <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></p>


<p>Enjoy!</p>    <h3>Le script</h3>


<p>C'est assez basique mais ça évite bien des clics. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>

<pre class="python python"><span style="color: #ff7700;font-weight:bold;">import</span> maya.<span style="color: #dc143c;">cmds</span> <span style="color: #ff7700;font-weight:bold;">as</span> <span style="color: #dc143c;">cmds</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># get the selected nodes</span>
selectionList = <span style="color: #dc143c;">cmds</span>.<span style="color: black;">ls</span><span style="color: black;">&#40;</span> selection=<span style="color: #008000;">True</span> <span style="color: black;">&#41;</span>
&nbsp;
nodeList = selectionList<span style="color: black;">&#91;</span>:<span style="color: #008000;">len</span><span style="color: black;">&#40;</span>selectionList<span style="color: black;">&#41;</span>-<span style="color: #ff4500;">1</span> <span style="color: black;">&#93;</span>	<span style="color: #808080; font-style: italic;"># get all nodes except the last one</span>
myPlane = selectionList<span style="color: black;">&#91;</span> <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>selectionList<span style="color: black;">&#41;</span>-<span style="color: #ff4500;">1</span> <span style="color: black;">&#93;</span>	<span style="color: #808080; font-style: italic;"># get the last node wich should be the plane you want to spread particle on</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># create the particle system</span>
myEmitter = <span style="color: #dc143c;">cmds</span>.<span style="color: black;">emitter</span><span style="color: black;">&#40;</span> myPlane, <span style="color: #008000;">type</span>=<span style="color: #483d8b;">&quot;surface&quot;</span>, speed=<span style="color: #ff4500;">0</span> <span style="color: black;">&#41;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>
myParticleSys = <span style="color: #dc143c;">cmds</span>.<span style="color: black;">particle</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># [u'particle1', u'particleShape1']</span>
&nbsp;
<span style="color: #dc143c;">cmds</span>.<span style="color: black;">connectDynamic</span><span style="color: black;">&#40;</span> myParticleSys<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, emitters=myEmitter <span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># connect the emitter to the particle system</span>
&nbsp;
myInstancer = <span style="color: #dc143c;">cmds</span>.<span style="color: black;">particleInstancer</span><span style="color: black;">&#40;</span> myParticleSys<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, addObject=<span style="color: #008000;">True</span>, <span style="color: #008000;">object</span>=nodeList <span style="color: black;">&#41;</span>	<span style="color: #808080; font-style: italic;"># create instancer from all the selected objects</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># add per particle attributes</span>
<span style="color: #dc143c;">cmds</span>.<span style="color: black;">addAttr</span><span style="color: black;">&#40;</span> myParticleSys<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, ln=<span style="color: #483d8b;">&quot;randIndexPP&quot;</span>, dt=<span style="color: #483d8b;">&quot;doubleArray&quot;</span> <span style="color: black;">&#41;</span>
<span style="color: #dc143c;">cmds</span>.<span style="color: black;">addAttr</span><span style="color: black;">&#40;</span> myParticleSys<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, ln=<span style="color: #483d8b;">&quot;rotPP&quot;</span>, dt=<span style="color: #483d8b;">&quot;vectorArray&quot;</span> <span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># tell the particle system to use attribut &quot;randIndexPP&quot; for objectIndex and &quot;rotPP&quot; for rotation</span>
<span style="color: #dc143c;">cmds</span>.<span style="color: black;">particleInstancer</span><span style="color: black;">&#40;</span> myParticleSys<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, edit=<span style="color: #008000;">True</span>, name=myInstancer, objectIndex=<span style="color: #483d8b;">&quot;randIndexPP&quot;</span> <span style="color: black;">&#41;</span>
<span style="color: #dc143c;">cmds</span>.<span style="color: black;">particleInstancer</span><span style="color: black;">&#40;</span> myParticleSys<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, edit=<span style="color: #008000;">True</span>, name=myInstancer, rotation=<span style="color: #483d8b;">&quot;rotPP&quot;</span> <span style="color: black;">&#41;</span>
&nbsp;
<span style="color: #808080; font-style: italic;"># prepare and create the expression</span>
expressionStr = <span style="color: #483d8b;">&quot;%s.randIndexPP = rand(0,%s.9999999);<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>myParticleSys<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, <span style="color: #008000;">len</span><span style="color: black;">&#40;</span>selectionList<span style="color: black;">&#41;</span>-<span style="color: #ff4500;">2</span><span style="color: black;">&#41;</span>
expressionStr += <span style="color: #483d8b;">&quot;particleShape1.rotPP = &lt;&lt; rand(-15, 15), rand(-15, 15), rand(-15, 15) &gt;&gt;;&quot;</span>
<span style="color: #dc143c;">cmds</span>.<span style="color: black;">dynExpression</span><span style="color: black;">&#40;</span> myParticleSys<span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, creation=<span style="color: #008000;">True</span>, <span style="color: #dc143c;">string</span>=expressionStr <span style="color: black;">&#41;</span></pre>


<h3>Exemple</h3>


<p>Je n'allais tout de même pas balancer le truc sans que vous ayez au moins un aperçu de ce que ça donne en pratique! <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></p>


<p>Voici trois brins d'herbe différents:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_07_17_code_particle_objectid/code_particle_objectid002.png" alt="code_particle_objectid" style="display:block; margin:0 auto;" title="code_particle_objectid002.png, juil. 2011"  height="436" width="252" /></p>
<center><i>Avec points de pivot bien placés et freeze transformés évidement! <img src="/blog/themes/blueSilenceCustom/smilies/redface.gif" alt=":redface:" class="smiley" /></i></center>



<p>Sélectionnez les:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_07_17_code_particle_objectid/code_particle_objectid003.png" alt="code_particle_objectid003.png" style="display:block; margin:0 auto;" title="code_particle_objectid003.png, juil. 2011"  height="135" width="311" /></p>


<p>Puis sélectionnez le plan sur lequel vous souhaitez que les particules soit placées:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_07_17_code_particle_objectid/code_particle_objectid004.png" alt="code_particle_objectid004.png" style="display:block; margin:0 auto;" title="code_particle_objectid004.png, juil. 2011"  height="136" width="307" /></p>


<p>Lancez le script! <img src="/blog/themes/blueSilenceCustom/smilies/1420.gif" alt=":grenadelauncher:" class="smiley" /></p>


<p>Avancez de quelques images:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_07_17_code_particle_objectid/code_particle_objectid005.png" alt="code_particle_objectid005.png" style="display:block; margin:0 auto;" title="code_particle_objectid005.png, juil. 2011"  height="94" width="256" /></p>


<p>Et voyez le résultat:</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_07_17_code_particle_objectid/code_particle_objectid006.png" title="code_particle_objectid006.png"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_07_17_code_particle_objectid/.code_particle_objectid006_m.jpg" alt="code_particle_objectid006.png" style="display:block; margin:0 auto;" title="code_particle_objectid006.png, juil. 2011"  height="361" width="560" /></a></p>


<p>Bon, c'est vrai qu'avec des brins d'herbe ça ne saute pas aux yeux mais essayez avec des formes plus claires et vous verrez de suite les objets que vous avez sélectionné placés de manière aléatoire. <img src="/blog/themes/blueSilenceCustom/smilies/sauteJoie.gif" alt=":sauteJoie:" class="smiley" /></p>


<h3>Conclusion</h3>


<p>En espérant que ce micro-billet-express vous servira.</p>


<p>A bientôt!</p>


<p>Dorian</p>


feed_id: urn:md5:993e273f90a68ceeaf2188d0c0e4ede3
title: My impressions about mental ray's futur (English Translation)
uri: My-impressions-about-mental-ray-s-futur-(English-Translation)
url: http://www.fevrierdorian.com/blog/post/2011/07/21/My-impressions-about-mental-ray-s-futur
content:
<p><img src="http://www.fevrierdorian.com/blog/public/divers/mental_ray_its_over_tn.png" alt="mental_ray_its_over_tn.png" style="float:left; margin: 0 1em 1em 0;" title="mental_ray_its_over_tn.png, juil. 2011"  height="150" width="150" />
I use mental ray since 2004 and it quickly become my favorite render engine. I attended, as a lot of you, to his slow decline over years... I have opportunity to work with Vray for a vfx feature film. The pipeline is around Vray and uses many new features highly "prod oriented" that make our lives easier.</p>


<p>It was my first experience with this engine and I must unfortunately admit it made ​​me realize that mental ray can never back up the hill... <img src="/blog/themes/blueSilenceCustom/smilies/neutral.gif" alt=":neutral:" class="smiley" /></p>


<p>I propose you my little impression on all of that in this post.</p>    <h3>Some illusions...</h3>


<p>At first, I was pretty confident about mental ray's futur. Each new version add somme little cool features and the enemy to be defeated was that Autodesk which was unable to make a correct integration of this engine in they softwares. You had to tinker to use the latest features but you could get by. (<a href="http://forum.mentalimages.com/showthread.php?7835-Why-not!#post_32500" hreflang="en">Read</a>, the very informative history of the integration of mental ray in Maya by one of its devs).</p>


<p>I saw many active <a href="http://forums.cgsociety.org/showthread.php?t=639480" hreflang="en">threads</a> about some "heads" leaving the project or the futur of mental ray following the purchase of Nvidia.</p>


<p>Nvidia had Gelato and, peoples making the project quitting it, found themselves without any GPU rendering solution under hand, hence the acquisition of mental image to retrieve devs of mental ray and make them work with CUDA.</p>


<p><img src="http://www.fevrierdorian.com/blog/public/logos/Nvidia_Cuda_logo.jpg" alt="Nvidia_Cuda_logo.jpg" style="display:block; margin:0 auto;" title="Nvidia_Cuda_logo.jpg, août 2010"  height="303" width="500" /></p>


<p>At first, everyone thought, eyes full of stars, that mental ray went "CUDA accelerated" but just think for two seconds to realize that the problem was actually more complicated... <img src="/blog/themes/blueSilenceCustom/smilies/tuComprendRien.gif" alt=":tuComprendRien:" class="smiley" /></p>


<p>Paolo Berto (<a href="http://forums.cgsociety.org/member.php?u=124550" hreflang="en">jupiterjazz</a>), an influent member <a href="http://www.jupiter-jazz.com/group" hreflang="en">working</a> for the jupiter jazz group (<del>a</del> THE group of vfx dev), and obviously well informed <a href="http://forums.cgsociety.org/showpost.php?p=5203466&amp;postcount=14" hreflang="en">wrote</a> this:</p>


<blockquote><p>No, mental ray won't be ever ported on cuda, there is no intention and it simply can't. Only some parts could, and if so it will be done just for marketing reasons.</p></blockquote>


<p>A member ask him about that and <a href="http://forums.cgsociety.org/showpost.php?p=5204780&amp;postcount=18" hreflang="en">he give</a> a little more details:</p>


<blockquote><p>So, to make things work on cuda you need to have a lot of *coherent* computations to perform: the problem of mental ray is that it is casting one ray then calling a native C shader to shade the intersection then maybe the shader casts another batch of rays and so on. Very non coherent.<br />
This is just not suited for gpu computation unless if a massive rewrite/refactoring of the pipeline is done by mental images, which will not happen soon enough (I am speaking about years).<br />
Some specific task like fast AO could be definitely done though (and also this won't happen soon).<br />
<br />
Also another problem of mental ray is that the codebase is 15 years old (and it's not a Whiskey), native C for the CPU, full of pointers mem alloc and other shit, so to use an euphemism is a fcking mess.</p></blockquote>



<p>It is quite clear:</p>
<ul>
<li>Not GPU thinked.</li>
<li>Too old.</li>
<li>"Stop dreaming!"</li>
</ul>

<p>Everyone wondered what Nvidia was going to do of a full CPU render engine that did not seem to be able to change...</p>


<p>All indulged in some speculations but until then, there was nothing let guessing what would happen.</p>


<p>My doubts really began in 2009 at the Nvidia's <a href="http://www.youtube.com/watch?v=TQsXualxLVs" hreflang="en">GPU Technology Conference</a>. I saw one of the single "old dev" of mental ray and I learned that he had worked "several years" on the thing we all expected (irony): iRay and Reality Server.</p>


<p>Maybe I was the only one but I immediately thought that putting the last "heads" (there is not many) on a project full CUDA that will be used to sell entire plants which are more for "Arch and Viz" than anim/vfx did not bode well for mental ray.</p>


<h3>...to desillusions</h3>


<p><img src="http://www.fevrierdorian.com/blog/public/logos/mental_image_logo.png" alt="mental_image_logo.png" style="display:block; margin:0 auto;" title="mental_image_logo.png, juil. 2011"  height="40" width="175" /></p>


<p>And that's what happened. Nvidia announced, <a href="http://blogs.nvidia.com/2011/05/nvidia-integrates-workstation-software-efforts/" hreflang="en">very politely</a> it <del>dismantled</del> reorganized mental image to, I quote :</p>


<blockquote><p>integrating it into our other activities focused on software solutions for design professionals</p></blockquote>


<p>It follows:</p>


<blockquote><p>The combined group brings together mental images with related efforts in the Quadro group focused on the world’s most demanding design professionals, from feature film artists to architects and product designers.</p></blockquote>


<p>Basically, they bring closer mental picture from "Quadro Group" to "focus" on the needs of film artists... <img src="/blog/themes/blueSilenceCustom/smilies/mad0001.gif" alt=":septic:" class="smiley" /></p>


<p>Mhum... Personally, the more you avoid Quadros, CUDA and other proprietary technologies which are a misery to deploy and very expensive, the more I am satisfied ...</p>


<p>So for this time, it's completely missed... I think many big CAD companies invest in there. But a VFX studio? Seriously?</p>


<p>Nvidia left mental image alone for a while (about four years during which I kept hope), to let them keep their commitments (this is often what happens for big acquisitions) but now they resume the reindeer and <a href="https://twitter.com/#!/virtualritz/status/72603197121896448" hreflang="en">it hurts</a>:</p>


<blockquote><p>Mental images is gone. Rumor has it ~30 people were laid off, management was dispersed. The corporate bullshit version: <a href="http://blogs.nvidia.com/2011/05/nvidia-integrates-workstation-software-efforts/" title="http://blogs.nvidia.com/2011/05/nvidia-integrates-workstation-software-efforts/">http://blogs.nvidia.com/2011/05/nvi...</a></p></blockquote>


<p>As we are in the rumor, it seems that the mental ray team has not been dismantled (although there were some voluntary departures). But insofar Nvidia is a very opaque compagnie you can't have more informations.</p>


<p>That said, I would be in bad faith if I said that <a href="http://www.mentalimages.com/products/mental-ray/mental-ray-39.html" hreflang="en">the latest mental ray features list</a> was empty, far from it!</p>


<p>Mental ray is a very good render engine (I suspect to be faster than Vray in pure raytracing...) but the big studios do not make prods on a "good engine" but rather "an engine they considers to be the best". What mental ray is no longer.</p>


<p>If you have some times, <a href="http://forum.mentalimages.com/showthread.php?7402-Iray-For-OpenCl" hreflang="en">read this four messages's short thread</a>... It summarizes perfectly in what mental image is sinking.</p>



<p>In short, a person asks a simple argued question to iray's devs about OpenCL (it will include reference to Chaos Group). No dev will respond (it's pretty rare, they often take the time to answer, even briefly to such issues) but a person, who appears to be more a Nvidia's commercial than a dev answer a marketing pitch promoting CUDA face OpenCL:</p>


<blockquote><p>iray uses C for CUDA because it needs the highest performance and greatest capabilities available to it.</p>
<p>
While NVIDIA leads the industry in the broadest OpenCL support, the language is several years behind C in both capabilities and tools, and it advances at the speed of open standards. A CPU fallback is unnecessary for iray as it supports x86 directly - far more efficiently than a fallback could. In using C for CUDA, iray ensures you have the very latest GPU capabilities as soon as they come online, while having direct influence on its evolution.</p>
<p>
With C for CUDA, there are over 1/2billion NVIDIA GPUs that can increase iray performance. I believe you would find the %increase from AMD to be quite small as their OpenCL support is limited to their latest offerings.</p>
<p>
As for CPUs, iray runs as well on AMD as Intel, taking full advantage of multiple cores and sockets.</p>
<p>
- Phil
NVIDIA</p></blockquote>


<p>I think, for a support forum, it's stain. Especially as the defenders of CUDA on <a href="http://www.chaosgroup.com/forums/vbulletin/showthread.php?53415-Cuda-4.0&amp;p=451532#post451532" hreflang="en">the Chaos Group forum</a> debit the same kind of nonsense to finally take a big setback from Vlado, senior member of the Chaos Group forum:</p>


<blockquote><p>- (Membre): I had a feeling CUDA is gonna kick OpenCL in the ass and it is ! I hope that OpenCL will be able to share memory too at some point... <br />
- (vlado): We do have a CUDA version of V-Ray RT that we use internally, so if we see that there are significant benefits of going this way, it is certainly something that we would do without too much hesitation.<br />
- (Membre): Wow... Release it ploxxxxxxxxx, isn't it a lot more responsive(refresh speed) then opencl btw?<br />
- (vlado): No, not really. In some of the last tests, OpenCL was a tad bit faster.</p></blockquote>


<p>So here we are: For Chaos Group, released a CUDA version of V-Ray RT is useless because it is less efficient...</p>


<p>And while we're talking about that: The arrival of Vray for Maya could had be done without too much noise... It was expected by many but not necessarily the VFX industrie at that time. Chaos Group seems to have understood that the needs of Maya users are not quite the same as 3dsMax users where Vray was considered as the rendering engine "for archviz"...</p>


<p>Who would have thought, with the release of Vray for Maya that he would serve Digital Domain to make Tron Legacy's shots:</p>

<iframe src="http://player.vimeo.com/video/20014133?title=0&amp;byline=0&amp;portrait=0" width="590" height="332" frameborder="0"></iframe>



<p>Indeed, this version is very "prod oriented". They did not try to "copy" their render engines from 3dsMax to Maya. They didn't try to uniform it, they adapted it. And very cleverly adapted...</p>


<h3>Conclusion</h3>

<p>In short, the purpose of this post was not to praise Vray but to explain why I can't believe in mental ray anymore...</p>


<p>The fact it's still an excellent render engine and it's integrated to Maya and 3ds Max leaves him a bright future and he will not go away at once. But I think the studios will turn away slowly, as though faithful for years, I began to do so.</p>


feed_id: urn:md5:16a24118616e0aaefa3347ce07f05fa6
title: Mes impressions sur mental ray et son futur
uri: Mes-impressions-sur-mental-ray-et-son-futur
url: http://www.fevrierdorian.com/blog/post/2011/07/17/Mes-impression-sur-mental-ray-et-son-futur
content:
<p><img src="http://www.fevrierdorian.com/blog/public/divers/mental_ray_its_over_tn.png" alt="mental_ray_its_over_tn.png" style="float:left; margin: 0 1em 1em 0;" title="mental_ray_its_over_tn.png, juil. 2011"  height="150" width="150" />J'utilise mental ray depuis 2004 et il est rapidement devenu mon moteur de prédilection. J'ai assisté, comme pas mal d'entre vous, à son lent déclin au fil des années... J'ai l'occasion de bosser sous Vray pour les vfx d'un long métrage. Le pipeline tourne autour de Vray et utilise un certain nombre des nouvelles features très orientées prod qui nous facilitent pas mal la vie.</p>


<p>C'était ma première expérience sur ce moteur et je dois malheureusement admettre qu'elle m'a fait prendre conscience que mental ray ne pourra jamais remonter la pente... <img src="/blog/themes/blueSilenceCustom/smilies/neutral.gif" alt=":neutral:" class="smiley" /></p>


<p>Je vous propose ma petite impression sur tout ça dans ce billet.</p>    <h3>Des illusions...</h3>

<p>Au début, j’étais plutôt confiant quand à l'avenir de mental ray. Chaque nouvelle version intégrait des petites features intéressantes et l'ennemi à abattre était Autodesk qui était incapable de faire une intégration correcte de ce moteur dans ses softs. Il fallait souvent bricoler pour pouvoir utiliser les dernières nouveautés mais on pouvait s'en sortir. (<a href="http://forum.mentalimages.com/showthread.php?7835-Why-not!#post_32500" hreflang="en">A lire</a>, l'histoire, très instructive, de l'intégration de mental ray dans Maya par un de ses devs).</p>


<p>Je voyais pas mal de <a href="http://forums.cgsociety.org/showthread.php?t=639480" hreflang="en">threads</a> animés sur CGTalk concernant le départ de telle ou telle "tête" du projet ou l'avenir de mental ray suite au rachat de Nvidia.</p>


<p>Nvidia avait Gelato et, les différentes personnes s'occupant du projet l'ayant quitté, se retrouvaient sans aucune solution de rendu GPU sous la main, d’où le rachat de mental image pour récupérer des membres du développement de mental ray et les faire travailler sur CUDA. <img src="/blog/themes/blueSilenceCustom/smilies/bete.gif" alt=":bete:" class="smiley" /></p>


<p><img src="http://www.fevrierdorian.com/blog/public/logos/Nvidia_Cuda_logo.jpg" alt="Nvidia_Cuda_logo.jpg" style="display:block; margin:0 auto;" title="Nvidia_Cuda_logo.jpg, août 2010"  height="303" width="500" /></p>


<p>Au début, tout le monde à pensé, les yeux pleins d'étoiles, que mental ray allé être "CUDA accelerated" mais il suffit de réfléchir deux secondes pour bien se rendre compte que le problème était en fait plus compliqué... <img src="/blog/themes/blueSilenceCustom/smilies/tuComprendRien.gif" alt=":tuComprendRien:" class="smiley" /></p>


<p>Paolo Berto (<a href="http://forums.cgsociety.org/member.php?u=124550" hreflang="en">jupiterjazz</a>), un membre influent de CGTalk <a href="http://www.jupiter-jazz.com/group" hreflang="en">travaillant</a> notamment pour le groupe jupiter jazz (<del>un</del> LE collectif de développeurs vfx), et visiblement bien informé <a href="http://forums.cgsociety.org/showpost.php?p=5203466&amp;postcount=14" hreflang="en">écrivait</a> ceci:</p>


<blockquote><p>No, mental ray won't be ever ported on cuda, there is no intention and it simply can't. Only some parts could, and if so it will be done just for marketing reasons.</p></blockquote>


<p>Un membre le relance et <a href="http://forums.cgsociety.org/showpost.php?p=5204780&amp;postcount=18" hreflang="en">il rentre</a> un peu plus dans les détails:</p>


<blockquote><p>So, to make things work on cuda you need to have a lot of *coherent* computations to perform: the problem of mental ray is that it is casting one ray then calling a native C shader to shade the intersection then maybe the shader casts another batch of rays and so on. Very non coherent.<br />
This is just not suited for gpu computation unless if a massive rewrite/refactoring of the pipeline is done by mental images, which will not happen soon enough (I am speaking about years).<br />
Some specific task like fast AO could be definitely done though (and also this won't happen soon).<br />
<br />
Also another problem of mental ray is that the codebase is 15 years old (and it's not a Whiskey), native C for the CPU, full of pointers mem alloc and other shit, so to use an euphemism is a fcking mess.</p></blockquote>


<p>C'est assez clair:</p>
<ul>
<li>Pas pensé GPU.</li>
<li>Trop vieux.</li>
<li>"Arrêtez de rêver!"</li>
</ul>

<p>Tout me monde se demandait ce qu'Nvidia allait bien pouvoir foutre d'un moteur full CPU qui n'avait pas l'air de pouvoir en changer...</p>


<p>Tous se laissait aller à ces spéculations mais jusque là, rien ne permettait de deviner ce qui allait ce passer.</p>


<p>Mes doutes ont réellement commencé durant l'année 2009, lors de la <a href="http://www.youtube.com/watch?v=TQsXualxLVs" hreflang="en">GPU Technology Conference</a> de Nvidia. J'y vis l'un des seul et unique "ancien membre" de mental ray et j'y ai appris qu'il avait travaillé depuis "quelques années" sur le truc que nous attendions tous: iRay et son Reality Server. (super... <img src="/blog/themes/blueSilenceCustom/smilies/mad0001.gif" alt=":septic:" class="smiley" /> )</p>


<p>Et bien j'étais peut être le seul, mais j'ai tout de suite pensé que mettre les dernières têtes sur un projet full CUDA qui servira à vendre des installations entières qui sont plus destiné à de "l'Arch and Viz" qu'à de l'anim/fx n'augurait rien de bon pour mental ray. <img src="/blog/themes/blueSilenceCustom/smilies/gne.gif" alt=":gne:" class="smiley" /></p>


<h3>...aux désillusions</h3>


<p><img src="http://www.fevrierdorian.com/blog/public/logos/mental_image_logo.png" alt="mental_image_logo.png" style="display:block; margin:0 auto;" title="mental_image_logo.png, juil. 2011"  height="40" width="175" /></p>


<p>Et c'est ce qui arriva. Nvidia annonça, <a href="http://blogs.nvidia.com/2011/05/nvidia-integrates-workstation-software-efforts/" hreflang="en">très poliment</a>, qu'il <del>démantelait</del> réorganisait mental image pour, je cite:</p>


<blockquote><p>integrating it into our other activities focused on software solutions for design professionals</p></blockquote>


<p>S'en suit:</p>


<blockquote><p>The combined group brings together mental images with related efforts in the Quadro group focused on the world’s most demanding design professionals, from feature film artists to architects and product designers.</p></blockquote>


<p>En gros, ils rapprochent mental image du "Quadro Group" pour se "focuser" sur les besoins des film artists... <img src="/blog/themes/blueSilenceCustom/smilies/mad0001.gif" alt=":septic:" class="smiley" /></p>


<p>Mouai mouai... Personnellement, plus on se tient éloigné des Quadro, CUDA et autres techno proprios qui sont une misère à déployer et coutent très cher, plus je suis satisfait...</p>


<p>Donc pour le coup, c'est complètement raté... Je vois bien des grosses entreprises de CAD investir là dedans. Mais un studio de VFX? Sérieusement?</p>


<p>Nvidia à laissé mental image tranquille pendant quelques temps (quatre années environ durant lesquelles j'ai gardé espoir <img src="/blog/themes/blueSilenceCustom/smilies/riva.gif" alt=":pasClasse:" class="smiley" /> ), sûrement pour les laisser tenir leurs engagements (c'est souvent ce qui arrive lors de grosses acquisitions) mais là ils reprennent les rennes et <a href="https://twitter.com/#!/virtualritz/status/72603197121896448" hreflang="en">ça fait mal</a>:</p>


<blockquote><p>Mental images is gone. Rumor has it ~30 people were laid off, management was dispersed. The corporate bullshit version: <a href="http://blogs.nvidia.com/2011/05/nvidia-integrates-workstation-software-efforts/" title="http://blogs.nvidia.com/2011/05/nvidia-integrates-workstation-software-efforts/">http://blogs.nvidia.com/2011/05/nvi...</a></p></blockquote>


<p>Tant qu'on est dans la rumeur, il semble que l'équipe de mental ray n'ait pas été démantelé (mais qu'il y a eu quelques départs volontaires).</p>


<p>Après, je serais de mauvaise foi si je disais que la <a href="http://www.mentalimages.com/products/mental-ray/mental-ray-39.html" hreflang="en">dernière liste</a> des features de mental ray était vide, loin de là!</p>


<p>Mental ray est un très bon moteur (je le soupçonne d’être plus rapide que Vray en raytracing pur..) mais les gros studios ne font pas des prods sur un "très bon moteur" mais plutôt "le moteur qu'il estime être le meilleur". Et mental ray n'en fait clairement <del>pas</del> plus parti. <img src="/blog/themes/blueSilenceCustom/smilies/lanceUnePierre.gif" alt=":lanceUnePierre:" class="smiley" /></p>


<p>Si vous avez un peu de temps, <a href="http://forum.mentalimages.com/showthread.php?7402-Iray-For-OpenCl" hreflang="en">lisez ce court thread</a> de quatre messages... Il résume parfaitement le n'importe quoi dans lequel est en trains de sombrer mental image. <img src="/blog/themes/blueSilenceCustom/smilies/1420.gif" alt=":grenadelauncher:" class="smiley" /></p>


<p>Pour résumer, une personne pose une question simple et argumentée aux devs de iray concernant OpenCL (il fera notamment référence à Chaos Group). Pas un seul dev ne répondra (c'est assez rare, ils prennent souvent la peine de répondre, même brièvement à ce genre de questions) mais une personne qui semble être plus un commercial de Nvidia qu'un dev répondra un baratin marketing faisant la promotion de CUDA face à OpenCL:</p>


<blockquote><p>iray uses C for CUDA because it needs the highest performance and greatest capabilities available to it.</p>
<p>
While NVIDIA leads the industry in the broadest OpenCL support, the language is several years behind C in both capabilities and tools, and it advances at the speed of open standards. A CPU fallback is unnecessary for iray as it supports x86 directly - far more efficiently than a fallback could. In using C for CUDA, iray ensures you have the very latest GPU capabilities as soon as they come online, while having direct influence on its evolution.</p>
<p>
With C for CUDA, there are over 1/2billion NVIDIA GPUs that can increase iray performance. I believe you would find the %increase from AMD to be quite small as their OpenCL support is limited to their latest offerings.</p>
<p>
As for CPUs, iray runs as well on AMD as Intel, taking full advantage of multiple cores and sockets.</p>
<p>
- Phil
NVIDIA</p></blockquote>


<p>Je trouve que pour un forum de support, ça fait tache. D'autant que des défenseurs de CUDA sur le <a href="http://www.chaosgroup.com/forums/vbulletin/showthread.php?53415-Cuda-4.0&amp;p=451532#post451532" hreflang="en">forum de Chaos Group</a> (inscription nécessaire) débitaient le même genre d’âneries pour finalement se prendre un gros revers de la part de vlado, membre principal sur le forum de Chaos Group (merci <a href="http://deex.info/wordpress2/" hreflang="en">Deex</a> pour l'info):</p>


<blockquote><p>- (Membre): I had a feeling CUDA is gonna kick OpenCL in the ass and it is&nbsp;! I hope that OpenCL will be able to share memory too at some point... <br />
- (vlado): We do have a CUDA version of V-Ray RT that we use internally, so if we see that there are significant benefits of going this way, it is certainly something that we would do without too much hesitation.<br />
- (Membre): Wow... Release it ploxxxxxxxxx, isn't it a lot more responsive(refresh speed) then opencl btw?<br />
- (vlado): No, not really. In some of the last tests, OpenCL was a tad bit faster.</p></blockquote>


<p>Donc voilà, d'après Chaos Group, sortir une version CUDA de V-Ray RT n'est pas utile car il est moins performant... <img src="/blog/themes/blueSilenceCustom/smilies/riva.gif" alt=":pasClasse:" class="smiley" /></p>


<p>Et puisqu'on en parle: L'arrivée de Vray sous Maya aurait pu se faire sans trop de bruit... Elle était attendu par beaucoup mais on ne parlait pas nécessairement de faire du VFX à ce moment là. Chaos Group semble cependant avoir bien compris que les besoins des utilisateurs de Maya ne sont pas tout à fait les mêmes que les utilisateurs de 3dsMax ou Vray était considéré comme le moteur de rendu "pour l'archi"...</p>


<p>Qui aurait pu penser, lors de la sortie de Vray for Maya qu'il servirait Digital Domain pour sortir les plans de Tron Legacy:</p>

<iframe src="http://player.vimeo.com/video/20014133?title=0&amp;byline=0&amp;portrait=0" width="590" height="332" frameborder="0"></iframe>



<p>En effet, cette version est très orienté prod. Ils n'ont pas essayé de "copier" leur moteur depuis 3dsMax dans Maya. Ils l'ont adapté. Et adapté très intelligemment...</p>


<h3>Conclusion</h3>

<p>Bref, le but de ce billet n'était pas de faire l'éloge de Vray mais d'expliquer pourquoi je ne crois plus à mental ray...</p>


<p>Le fait qu'il reste un excellent moteur et qu'il soit intégré à Maya et 3dsMax lui laisse de beaux jours devant lui et il ne va pas disparaître d'un coup. Mais je pense que les studios vont s'en détourner petit à petit, comme, bien que fidèle depuis des années, j'ai commencé à le faire. <img src="/blog/themes/blueSilenceCustom/smilies/riva.gif" alt=":pasClasse:" class="smiley" /></p>


<p>Dorian</p>


feed_id: urn:md5:6168a9562a2049b7f08c890294ed56ac
title: Les render layers de Maya: "Global", le petit attribut magique
uri: Les-render-layers-de-Maya-Global-le-petit-attribut-magique
url:
http://www.fevrierdorian.com/blog/post/2011/07/16/Les-render-layers-de-Maya-Global-le-petit-attribut-magique

content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_07_12_renderLayer_Attr_Global/renderLayer_Attr_Global_tn.png" alt="renderLayer_Attr_Global_tn.png" style="float:left; margin: 0 1em 1em 0;" title="renderLayer_Attr_Global_tn.png, juil. 2011" />Bonjours à tous, on m'a récemment montré à quoi servait un petit attribut présent depuis longtemps dans les render layers de Maya: "Global". Je vous propose donc un énième billet express (j'en fais un peu trop ces derniers temps, je sais...) pour vous faire partager cette "découverte".</p>


<p>Ceux qui savent déjà ce que c'est vont se moquer de moi je le sent. <img src="/blog/themes/blueSilenceCustom/smilies/seSentCon.gif" alt=":seSentCon:" class="smiley" /></p>


<p>Vous allez voir, c'est basique comme tout mais c'est le genre de truc qu'on ne peut pas vraiment deviner au premier coup d’œil.</p>    <h3>Das problème</h3>

<p>Comme vous le savez, quand vous créez un nouveau render layer, il est vide et vous devez y ajouter des objets pour que ceux ci soit pris en compte dans le rendu du render layer courant.</p>


<p>Les problèmes viennent sur de grosses scènes car, je ne sais pas si vous avez regardez comment ça ce passe "sous le capot", mais à chaque changement de layer, Maya fait des connection/déconnections qui, en cas de manipulations de nombreux objets (90% des cas en fait), peuvent lamentablement échouer et vous casser vos render layer.</p>


<p>Il ne reste plus donc qu'à recommencer vos render layer en priant le ciel que cette fois ci sera la bonne. <img src="/blog/themes/blueSilenceCustom/smilies/aupoil.gif" alt=":aupoil:" class="smiley" /></p>


<p>C'est particulièrement rageant quand on souhaite utiliser les render layers uniquement pour overrider quelques paramètres de rendu bien précis et qu'on se retrouve avec des soucis due à la manipulation de tonnes d'objets.</p>


<h3>Das solution</h3>

<p>Et bien l'attribut "Global" est fait pour ça:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_07_12_renderLayer_Attr_Global/renderLayer_Attr_Global001.png" alt="renderLayer_Attr_Global001.png" style="display:block; margin:0 auto;" title="renderLayer_Attr_Global001.png, juil. 2011" /></p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_07_12_renderLayer_Attr_Global/renderLayer_Attr_Global002.png" alt="renderLayer_Attr_Global002.png" style="display:block; margin:0 auto;" title="renderLayer_Attr_Global002.png, juil. 2011" /></p>


<p>Comme la documentation est très bien faite, je me permet une traduction:</p>


<blockquote><p>L'attribut Global convertie le layer courant en "layer global". Un layer global n'a pas de membres. Au lieu de ça, il contient tous les objets de la scène. Quand vous cochez cette case, tout les objets présent dans la scène apparaissent dans le layer.<br />
Par exemple, si vous avez modélisé une voiture et que vous souhaitez tester différentes couleurs pour le material, vous pouvez créer cinq ou six render layer globaux et, dans l'Attribute Editor du shader, overrider l'attribut color pour chacun de ces render layer. Vous pouvez ensuite rendre le tout en batch.</p></blockquote>


<p>Vous l'aurez compris, l’intérêt principal quand on utilise cet attribut est de privilégier des overrides ce qui, mine de rien, diminue les manipulations des connections.</p>


<p>En espérant que ce "mini truc" vous aidera! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>A bientôt!</p>


<p>Dorian</p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></center>


feed_id: urn:md5:078f4cb6e1da7c482a88196d721eb8df
title: Achat d'un Opteka 0.20X AF Fisheye pour Canon EOS 550D, les choses à savoir
uri: Achat-d-un-Opteka-0-20X-AF-Fisheye-pour-Canon-EOS-550D-les-choses-à
url:
http://www.fevrierdorian.com/blog/post/2011/06/28/Achat-d-un-Opteka-020X-AF-Fisheye-pour-Canon-EOS-550D-les-choses-a-savoir

content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_22_fisheye_opteka/opteka_fisheye_tn.jpg" alt="opteka_fisheye_tn.jpg" style="float:left; margin: 0 1em 1em 0;" title="opteka_fisheye_tn.jpg, juin 2011"  height="150" width="150" />Hello tous! Un billet express pour les amateurs de photo qui souhaiteraient s'essayer au fisheye "pour le fun", sans se ruiner dans un objectif dédié. <img src="/blog/themes/blueSilenceCustom/smilies/siffle.gif" alt=":siffle:" class="smiley" /></p>


<p>J'ai acheté, presque sur un coup de tête (en voyant <a href="http://www.flickr.com/photos/37386299@N08/sets/72157621490988266/with/3721076510/">cette galerie</a> en fait), un Opteka 0.20X AF Fisheye <a href="http://www.amazon.fr/gp/product/B001LZJB9Y/">sur Amazon</a>.</p>


<p>Les résultats sont chouettes mais j'ai rencontré pas mal de soucis avant d'arriver à utiliser la bête... <img src="/blog/themes/blueSilenceCustom/smilies/0010.gif" alt=":joue:" class="smiley" /></p>    <h3>Gros n00b lolptdr++!</h3>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_22_fisheye_opteka/1491276059_c4a756472e_z.jpg" title="1491276059_c4a756472e_z.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_22_fisheye_opteka/.1491276059_c4a756472e_z_m.jpg" alt="1491276059_c4a756472e_z.jpg" style="display:block; margin:0 auto;" title="1491276059_c4a756472e_z.jpg, juin 2011"  height="420" width="560" /></a></p>
<center><small><i><a href="http://www.flickr.com/photos/mattgrimm/1491276059/">Photo</a> par <a href="http://www.flickr.com/photos/mattgrimm/">Matt Grimm</a> sous licence Créative <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/deed.fr" rel="license">by-nc-sa</a>. Merci à lui! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></i></small></center>



<p>La mention racoleuse:</p>


<blockquote><p>Pour Canon Modèles: EOS 1D, 5D, 7D, 10D, 20D, 30D, 40D, 50D, 60D, 300D, 350D, 400D, 450D, 500D, 550D &amp; 1000D Appareils Photo Reflex</p></blockquote>


<p>m'ayant particulièrement rassuré, je lis les <a href="http://www.amazon.fr/product-reviews/B001LZJB9Y/" hreflang="fr">deux seuls commentaires</a> en diagonale et je valide l'achat (notez le "en diagonal" qui me reviendra droit dans la gueule à la réception du colis <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /> ).</p>


<p>A la réception de l'objet, je remarque sa taille que je trouve bizarrement petite... <img src="/blog/themes/blueSilenceCustom/smilies/reflexionIntense.gif" alt=":reflexionIntense:" class="smiley" /></p>


<p>Je remarque vite qu'il va être impossible de le visser sur mon <a href="http://www.sigma-photo.fr/site/boutique/FicheProduit.aspx?idGenerique=0000123&amp;idTypeProduit=0000008" hreflang="en">Sigma 17-70''mm'' F2,8-4 DC Macro OS HSM</a> de 72mm de diamètre...</p>


<p>En effet, le diamètre que cet "adaptateur fisheye" est de 52mm... Des bagues 52mm vers 55mm et 52mm vers 58mm sont livré avec mais on est loin des 72mm requis par mon objectif... <img src="/blog/themes/blueSilenceCustom/smilies/mad0001.gif" alt=":septic:" class="smiley" /></p>


<p>Et forcément, c'était clairement indiqué dans le premier commentaire de l'objet:</p>


<blockquote><p>attention pas compatible avec tous les zoom canon juste une bague de 55/58 ne se monte pas sur les 62 faut racheter une bague</p></blockquote>


<p>Un peu déçu (me sentant un peu con surtout), je ne me laisse pas abattre pour autant et commence à chercher une bague de 72mm vers 58mm...</p>


<p>Et là, c'est le drame...</p>


<p>Il existe des tonnes de bagues 58mm vers 72mm... Mais l'inverse, il faut y aller pour les trouver! <img src="/blog/themes/blueSilenceCustom/smilies/dtc2.gif" alt=":dtcFuckSmile:" class="smiley" /></p>


<p>Je cherche sur eBay et <a href="http://cgi.ebay.fr/Bague-de-reduction-adapt-camescope-Optique-72mm-58mm-/280542348231?pt=FR_IQ_PhotoVideo_Accesoires_Accessoires_Vid%C3%A9o&amp;hash=item4151a083c7" hreflang="fr">une seul offre</a>, à 45€+2.50€ de FDP sans compter la description contradictoire... Mouai mouai... Bof!</p>


<h3>La solution</h3>


<p>A force de recherche, je tombe sur le site <a href="http://www.digitaltoyshop.com" hreflang="fr">www.digitaltoyshop.com</a> qui propose toutes sortes de bagues, pour tout les calibres (<a href="http://www.digitaltoyshop.com/Bague_adaptatrice_Appareils_Photo_Reflex_t1001_5050_3" hreflang="fr">regardez</a>, c'est juste drôle la taille de la liste).</p>


<p>J'ai pris la M72-F58mm (AR7258) et aucun soucis. Il faut juste prévoir un petit nettoyage sur la bague car le filetage est assez dur... (J'ai mis un quart de demi goutte d'huile de coude sur un ancien chiffon et j'ai frotté le bord de la bague pour que ça passe mieux).</p>


<p>Donc voila! Si vous aussi vous êtes un abrutis fini qui ne se renseigne pas avant de sortir sa carte de crédit (riez pas, je suis sur que ça nous est tous arrivé un jour <img src="/blog/themes/blueSilenceCustom/smilies/yeoh.gif" alt=":dentcasse:" class="smiley" /> ), j'espère que ce site vous aidera à profiter de ce petit fisheye (qui existe dans <a href="http://www.amazon.fr/Opteka-Objectif-Hypergone-Fisheye-Appareils/dp/B00281IQRI/" hreflang="fr">une version </a> moins puissante et un peu moins chère).</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_22_fisheye_opteka/5360343501_6fdddf49d2_o.jpg" title="5360343501_6fdddf49d2_o.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_22_fisheye_opteka/.5360343501_6fdddf49d2_o_m.jpg" alt="5360343501_6fdddf49d2_o.jpg" style="display:block; margin:0 auto;" title="5360343501_6fdddf49d2_o.jpg, juin 2011"  height="375" width="560" /></a></p>
<center><small><i><a href="http://www.flickr.com/photos/photographphil/5360343501/">Photo</a> par <a href="http://www.flickr.com/photos/photographphil/">Philip Ray</a> sous licence Créative <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/deed.fr" rel="license">by-nc-sa</a>. Merci à lui!</i></small></center>



<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_22_fisheye_opteka/5055523911_6277609db2_o.jpg" title="5055523911_6277609db2_o.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_22_fisheye_opteka/.5055523911_6277609db2_o_m.jpg" alt="5055523911_6277609db2_o.jpg" style="display:block; margin:0 auto;" title="5055523911_6277609db2_o.jpg, juin 2011"  height="560" width="407" /></a></p>
<center><small><i><a href="http://www.flickr.com/photos/intherough/5055523911/">Photo</a> par <a href="http://www.flickr.com/photos/intherough/">Wendell</a> sous licence Créative <a href="http://creativecommons.org/licenses/by-nc-nd/2.0/deed.fr" rel="license">by-nc-nd</a>. Merci à lui!</i></small></center>



<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_22_fisheye_opteka/277795316_811d25a48c_b.jpg" title="277795316_811d25a48c_b.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_22_fisheye_opteka/.277795316_811d25a48c_b_m.jpg" alt="277795316_811d25a48c_b.jpg" style="display:block; margin:0 auto;" title="277795316_811d25a48c_b.jpg, juin 2011"  height="560" width="557" /></a></p>
<center><small><i><a href="http://www.flickr.com/photos/jonspage/277795316/">Photo</a> par <a href="http://www.flickr.com/photos/jonspage/">Jon Page</a> sous licence Créative <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/deed.fr" rel="license">by-nc-sa</a>. Merci à lui!</i></small></center>



<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_22_fisheye_opteka/3848184356_900eb2a3f4_o.jpg" title="Over the Field"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_22_fisheye_opteka/.3848184356_900eb2a3f4_o_m.jpg" alt="Over the Field" style="display:block; margin:0 auto;" title="Over the Field, juin 2011"  height="560" width="560" /></a></p>


<h3>Bonus, explication du 0.20X et 0.35X des fisheyes</h3>


<p>C'est tout simplement un multiplicateur de votre focale. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>Exemple appliqué à un objectif 17mm, avec le fisheye:</p>

<ul>
<li>17 x 0,20 = 3,4mm</li>
<li>17 x 0,35 = 5,95mm</li>
</ul>

<p>Voilà, c'était juste pour l'info (et confirmer implicitement que j'y connais pas grand chose tellement ça doit sembler évident à certains. <img src="/blog/themes/blueSilenceCustom/smilies/riva.gif" alt=":pasClasse:" class="smiley" /> ).</p>


<p>Dernier détail à savoir: Il vaut mieux avoir l'ouverture la plus petite possible pour avoir des images nets (f16, f22 toussa). En intérieur et en soirée, il faut donc monter à bloc les isos... <img src="/blog/themes/blueSilenceCustom/smilies/seSentCon.gif" alt=":seSentCon:" class="smiley" /></p>


<h3>Little coup de gueule</h3>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_22_fisheye_opteka/2495419255_aa851bf8be_o.png" alt="2495419255_aa851bf8be_o.png" style="display:block; margin:0 auto;" title="2495419255_aa851bf8be_o.png, juin 2011"  height="512" width="512" /></p>
<center><small><i><a href="http://www.flickr.com/photos/vantazy/2495419255/">Photo</a> par <a href="http://www.flickr.com/photos/vantazy/">Vance Reeser</a> sous licence Créative <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/deed.fr" rel="license">by-nc-sa</a>. Merci à lui!</i></small></center>



<p>Je profite d'avoir quelques potentiels propriétaires de galerie <a href="http://www.flickr.com/">Flickr</a> (<a href="http://www.photographybay.com/2007/12/03/flickr-alternatives/" hreflang="en">ou autres</a>) pour vous inciter à mettre vos photos sous licence <a href="http://creativecommons.org/licenses/by-nc-sa/2.0/deed.fr" hreflang="fr">Creative Common</a> dès que c'est possible. De cette manière, vous autorisez (suivant les variations de la licence) les utilisateurs à utiliser vos photos dans un cadre non commercial (comme ce blog) sous conditions de vous citer (comme je le fais).</p>


<p>Flickr essaye de <a href="http://www.flickr.com/commons/">miser sur ces licences</a> pour permettre aux photos de "sortir" de son site et d'être utilisées.</p>


<h3>Et voilà!</h3>


<p>Ce sera tout pour ce billet express! J'espère qu'il aidera quelques uns à se dépatouiller avant leur achat et évitera les mauvaises surprises. <img src="/blog/themes/blueSilenceCustom/smilies/whistle2.gif" alt=":jdicajdirien:" class="smiley" /></p>


<p>A bientôt!</p>


<p>Dorian</p>
<center><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></center>


feed_id: urn:md5:7468b699b20b39fe38a00e078c6632c7
title: Taille d'un fichier humainement compréhensible en Python
uri: Taille-d-un-fichier-humainement-compréhensible-en-Python
url:
http://www.fevrierdorian.com/blog/post/2011/06/26/Taille-d-un-fichier-humainement-comprehensible-en-Python

content:
<p><img src="http://www.fevrierdorian.com/blog/public/logos/Python_logo_150.png" alt="Python_logo_150.png" style="float:left; margin: 0 1em 1em 0;" title="Python_logo_150.png, mar. 2009"  height="150" width="150" />Aujourd'hui je voudrais vous faire partager un minuscule morceau de code Python qui permet de faire, en cinq lignes, un print de la taille d'un fichier humainement compréhensible a partir d'une taille donné en octet.</p>


<p><a href="http://blogmag.net/blog/read/38/Print_human_readable_file_size" hreflang="en">La solution</a> vient d'un certain <a href="http://blogmag.net/blog/fred" hreflang="en">Fred Cirera</a>. Merci à lui! <img src="/blog/themes/blueSilenceCustom/smilies/bravo.gif" alt=":bravo:" class="smiley" /></p>


<p>C'est diaboliquement simple mais c'est un soucis assez récurent quand on souhaite afficher des informations sur un fichier en script!</p>    <p>Voici la procédure:</p>

<pre class="python python"><span style="color: #ff7700;font-weight:bold;">def</span> sizeof_fmt<span style="color: black;">&#40;</span>num<span style="color: black;">&#41;</span>:
	<span style="color: #ff7700;font-weight:bold;">for</span> x <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: black;">&#91;</span><span style="color: #483d8b;">'bytes'</span>,<span style="color: #483d8b;">'KB'</span>,<span style="color: #483d8b;">'MB'</span>,<span style="color: #483d8b;">'GB'</span>,<span style="color: #483d8b;">'TB'</span><span style="color: black;">&#93;</span>:
		<span style="color: #ff7700;font-weight:bold;">if</span> num <span style="color: #66cc66;">&lt;</span> <span style="color: #ff4500;">1024.0</span>:
			<span style="color: #ff7700;font-weight:bold;">return</span> <span style="color: #483d8b;">&quot;%3.1f%s&quot;</span> <span style="color: #66cc66;">%</span> <span style="color: black;">&#40;</span>num, x<span style="color: black;">&#41;</span>
		num /= <span style="color: #ff4500;">1024.0</span></pre>



<p>Exemple:</p>
<pre class="python python"><span style="color: #66cc66;">&gt;&gt;&gt;</span> sizeof_fmt<span style="color: black;">&#40;</span><span style="color: #ff4500;">168963795964</span><span style="color: black;">&#41;</span>
<span style="color: #483d8b;">'157.4GB'</span></pre>


<p>Trop facile! <img src="/blog/themes/blueSilenceCustom/smilies/laClasse.gif" alt=":laClasse:" class="smiley" /></p>


feed_id: urn:md5:22b70aedf8e34a8c8ac988d39dbf82f0
title: Fabriquer un reflecteur de flash pour Canon EOS 550D
uri: Fabriquer-un-reflecteur-de-flash-pour-Canon-EOS-550D
url:
http://www.fevrierdorian.com/blog/post/2011/06/24/Fabriquer-un-reflecteur-de-flash-pour-Canon-EOS-550D

content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5698_tn.jpg" alt="IMG_5698_tn.jpg" style="float:left; margin: 0 1em 1em 0;" title="IMG_5698_tn.jpg, juin 2011"  height="150" width="150" />Bonjours à tous! Étant l'heureux possesseur d'un Reflex <a href="https://secure.wikimedia.org/wikipedia/fr/wiki/Canon_EOS_550D" hreflang="fr">Canon EOS 550D</a>, il m'est souvent arrivé d'avoir à shooter dans des endroits peut éclairé.</p>


<p>Cet appareil est équipé d'un flash mais j'ai toujours trouvé les résultats très décevants (c'est vraiment la lumière "en pleine face", pas super esthétique). Même mon petit compact fait de meilleurs photos avec son flash... Il existe des flashs externes dédiés mais ils sont souvent très cher.</p>


<p>Un jour, j'ai essayé de placer ma mains devant le flash, légèrement penché pour éclairer le plafond et simuler l'effet des flash externes que l'on peu pivoter pour se servir du plafond comme réflecteur de lumière. La lumière créé était très intéressante et j'ai commencé à réfléchir à une façon de diriger ce flash ver le haut et je vous propose une présentation de mon petit bricolage qui marche très bien! <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></p>    <h3>Ce qu'il faut</h3>
<ul>
<li>Une plaque de fer rigide assez grande (ici, la plaque de fer viens d'une boite de lait en poudre).</li>
<li>Une plaque de fer assez petite (typiquement, le "chapeau" d'une boite de conserve tout ce qu'il y a de plus simple).</li>
<li>Du carton un peu rigide (boite de céréale).</li>
<li>Des ciseaux.</li>
<li>Du scotch.</li>
<li>Une pince.</li>
<li>Un peu de temps devant soit. <img src="/blog/themes/blueSilenceCustom/smilies/siffle.gif" alt=":siffle:" class="smiley" /></li>
</ul>

<p>La grande plaque de fer:</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_4738.jpg" title="IMG_4738.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_4738_m.jpg" alt="IMG_4738.jpg" style="display:block; margin:0 auto;" title="IMG_4738.jpg, juin 2011"  height="373" width="560" /></a></p>


<p>Le carton et les ciseaux:</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5664.JPG" title="IMG_5664.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5664_m.jpg" alt="IMG_5664.JPG" style="display:block; margin:0 auto;" title="IMG_5664.JPG, juin 2011"  height="420" width="560" /></a></p>


<p>Le scotch (pour les neuneus qui voient pas ce que c'est... <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /> )&nbsp;:</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5696.JPG" title="IMG_5696.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5696_m.jpg" alt="IMG_5696.JPG" style="display:block; margin:0 auto;" title="IMG_5696.JPG, juin 2011"  height="420" width="560" /></a></p>


<h3>Le carton pour prototyper, toujours!</h3>


<p>Avant de partir bille en tête il vaut mieux savoir exactement ce qu'on souhaite faire. <img src="/blog/themes/blueSilenceCustom/smilies/reflechi.gif" alt=":reflechi:" class="smiley" /></p>


<p>Je me suis servi du morceau de carton en le découpant à plusieurs reprises pour trouver une façon de faire tenir le réflecteur sur l’appareil.</p>


<p>Après quelques tests, j'avais quelque chose qui tenait la route et se glissait correctement sur l'appareil.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5666.JPG" title="IMG_5666.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5666_m.jpg" alt="IMG_5666.JPG" style="display:block; margin:0 auto;" title="IMG_5666.JPG, juin 2011"  height="560" width="420" /></a></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5667.JPG" title="IMG_5667.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5667_m.jpg" alt="IMG_5667.JPG" style="display:block; margin:0 auto;" title="IMG_5667.JPG, juin 2011"  height="420" width="560" /></a></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5668.JPG" title="IMG_5668.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5668_m.jpg" alt="IMG_5668.JPG" style="display:block; margin:0 auto;" title="IMG_5668.JPG, juin 2011"  height="420" width="560" /></a></p>


<p>Cette étape est importante. Prenez le temps qu'il faut et avancez doucement. Ce morceau de carton deviendra le patron de votre pièce finale. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5669.JPG" title="IMG_5669.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5669_m.jpg" alt="IMG_5669.JPG" style="display:block; margin:0 auto;" title="IMG_5669.JPG, juin 2011"  height="420" width="560" /></a></p>


<h3>Le patron</h3>


<p>L'idée maintenant est de reporter le découpage du carton sur la plaque de métal.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5670.JPG" title="IMG_5670.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5670_m.jpg" alt="IMG_5670.JPG" style="display:block; margin:0 auto;" title="IMG_5670.JPG, juin 2011"  height="420" width="560" /></a></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5671.JPG" title="IMG_5671.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5671_m.jpg" alt="IMG_5671.JPG" style="display:block; margin:0 auto;" title="IMG_5671.JPG, juin 2011"  height="420" width="560" /></a></p>


<p>Je me suis servi d'un crayon tout ce qu'il y a de plus simple mais on peu utiliser un feutre. <img src="/blog/themes/blueSilenceCustom/smilies/whistle2.gif" alt=":jdicajdirien:" class="smiley" /></p>


<h3>Le découpage</h3>


<p>Attention aux mains! Encore une fois, il faut avancer doucement. <img src="/blog/themes/blueSilenceCustom/smilies/redface.gif" alt=":redface:" class="smiley" /></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5672.JPG" title="IMG_5672.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5672_m.jpg" alt="IMG_5672.JPG" style="display:block; margin:0 auto;" title="IMG_5672.JPG, juin 2011"  height="420" width="560" /></a></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5673.JPG" title="IMG_5673.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5673_m.jpg" alt="IMG_5673.JPG" style="display:block; margin:0 auto;" title="IMG_5673.JPG, juin 2011"  height="420" width="560" /></a></p>


<p>Une fois la coupe faite, servez vous de la pince pour "réaplatir" certains bords qui sortent un peu trop.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5674.JPG" title="IMG_5674.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5674_m.jpg" alt="IMG_5674.JPG" style="display:block; margin:0 auto;" title="IMG_5674.JPG, juin 2011"  height="420" width="560" /></a></p>


<p>A ce stade, vous pouvez vérifier que le tout s'emboite bien.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5675.JPG" title="IMG_5675.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5675_m.jpg" alt="IMG_5675.JPG" style="display:block; margin:0 auto;" title="IMG_5675.JPG, juin 2011"  height="420" width="560" /></a></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5676.JPG" title="IMG_5676.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5676_m.jpg" alt="IMG_5676.JPG" style="display:block; margin:0 auto;" title="IMG_5676.JPG, juin 2011"  height="420" width="560" /></a></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5677.JPG" title="IMG_5677.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5677_m.jpg" alt="IMG_5677.JPG" style="display:block; margin:0 auto;" title="IMG_5677.JPG, juin 2011"  height="560" width="420" /></a></p>


<p>Vous pouvez éventuellement peaufiner un peu le découpage pour le rendre plus "doux" pour votre appareil (personnellement, j'ai utilisé du scotch, deux épaisseurs, pour éviter de rayer l'appareil au niveau des bords de la plaque de fer).</p>


<h3>La pliure</h3>


<p>A ce stade, la plaque est trop proche du flash et renverrait la lumière vers l'arrière. <img src="/blog/themes/blueSilenceCustom/smilies/mad0001.gif" alt=":septic:" class="smiley" /></p>


<p>Il faut donc plier le tout!</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5678.JPG" title="IMG_5678.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5678_m.jpg" alt="IMG_5678.JPG" style="display:block; margin:0 auto;" title="IMG_5678.JPG, juin 2011"  height="420" width="560" /></a></p>


<p>Tracez un trais pour y voir plus clair.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5679.JPG" title="IMG_5679.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5679_m.jpg" alt="IMG_5679.JPG" style="display:block; margin:0 auto;" title="IMG_5679.JPG, juin 2011"  height="420" width="560" /></a></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5680.JPG" title="IMG_5680.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5680_m.jpg" alt="IMG_5680.JPG" style="display:block; margin:0 auto;" title="IMG_5680.JPG, juin 2011"  height="560" width="420" /></a></p>


<p>Prenez votre pince et commencer à plier sur la ligne.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5681.JPG" title="IMG_5681.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5681_m.jpg" alt="IMG_5681.JPG" style="display:block; margin:0 auto;" title="IMG_5681.JPG, juin 2011"  height="560" width="420" /></a></p>


<p>La pliure doit se faire en plusieurs passages et sur toute la longueur pour éviter de casser le métal.</p>


<h3>Le "crochet"</h3>


<p>Nous allons maintenant nous servir du second chapeau de boite de conserve pour faire une "bande" en métal.</p>


<p>Celle ci servira à "accrocher" le flash de l’appareil pour maintenir la grande plaque.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5682.JPG" title="IMG_5682.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5682_m.jpg" alt="IMG_5682.JPG" style="display:block; margin:0 auto;" title="IMG_5682.JPG, juin 2011"  height="420" width="560" /></a></p>


<p>Servez vous de la pince pour aplatir au maximum la bande.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5683.JPG" title="IMG_5683.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5683_m.jpg" alt="IMG_5683.JPG" style="display:block; margin:0 auto;" title="IMG_5683.JPG, juin 2011"  height="420" width="560" /></a></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5686.JPG" title="IMG_5686.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5686_m.jpg" alt="IMG_5686.JPG" style="display:block; margin:0 auto;" title="IMG_5686.JPG, juin 2011"  height="560" width="420" /></a></p>


<p>Récupérez les zones de pliure de la bande en carton.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5687.JPG" title="IMG_5687.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5687_m.jpg" alt="IMG_5687.JPG" style="display:block; margin:0 auto;" title="IMG_5687.JPG, juin 2011"  height="420" width="560" /></a></p>


<p>Et placez le tout sur la grande plaque:</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5688.JPG" title="IMG_5688.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5688_m.jpg" alt="IMG_5688.JPG" style="display:block; margin:0 auto;" title="IMG_5688.JPG, juin 2011"  height="420" width="560" /></a></p>


<blockquote><p>Important: J'ai utilisé du scotch Chaterton sur la photo car je souhaitait mettre une feuille blanche sur l'intégralité de la plaque. Mais après pas mal de test, il s’avère qu'utiliser directement le métal comme réflecteur du flash est plus efficace. J'ai donc utilisé un scotch transparent pour laisser le métal apparent. <img src="/blog/themes/blueSilenceCustom/smilies/zinzin.gif" alt=":zinzin:" class="smiley" /></p></blockquote>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5690.JPG" title="IMG_5690.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5690_m.jpg" alt="IMG_5690.JPG" style="display:block; margin:0 auto;" title="IMG_5690.JPG, juin 2011"  height="420" width="560" /></a></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/IMG_5698.JPG" title="IMG_5698.JPG"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_06_24_reflecteur_flash/.IMG_5698_m.jpg" alt="IMG_5698.JPG" style="display:block; margin:0 auto;" title="IMG_5698.JPG, juin 2011"  height="420" width="560" /></a></p>


<p>C'est clairement pas esthétique mais le rapport qualité prix est imbattable! <img src="/blog/themes/blueSilenceCustom/smilies/aupoil.gif" alt=":aupoil:" class="smiley" /></p>


<h3>Amélioration possibles</h3>


<p>A ce stade, l'objet me convient mais il peut être grandement amélioré:</p>
<ul>
<li>Faire passer un élastique par dessous pour mieux fixer la plaque à l'appareil.</li>
<li>Mettre de fines couches de scotche sur les bords et endroit une peut coupant qui sont en contact avec l'appareil.</li>
<li>Appliquer un miroir (brossé ou non) autocollant sur toute la surface de la plaque (et ainsi pouvoir fixer le crocher avec le Chaterton qui est plus puissant.</li>
<li>Faire un trou en longueur sur la plaque pour faire passer le crochet derrière et ainsi, scotcher le crochet derrière la partie face au flash.</li>
<li>Etc...</li>
</ul>

<p>Je pense ajouter l'élastique parce que pour le moment, je ne peut pas tourner l'appareil sans que le réflecteur se casse la figure... <img src="/blog/themes/blueSilenceCustom/smilies/whistle2.gif" alt=":jdicajdirien:" class="smiley" /></p>


<h3>Conclusion</h3>


<p>J'espère que ce petit article vous aura aidé et éventuellement donnée l’envie d'expérimenter d'autres trucs et de gouter aux joies du <a href="https://secure.wikimedia.org/wikipedia/fr/wiki/Do_it_yourself" hreflang="fr">"Do It Yourself" (DIY)</a>.</p>


<p>En bonus: Voici un liens qui présente <a href="http://www.diyphotography.net/how-to-build-24-diy-softboxes" hreflang="en">24 façons de fabriquer une softbox à la main</a>. <a href="http://www.tysonjosey.com/diysoftbox/index.html" hreflang="en">Certaines</a> débordent d'ingéniosité et sont très simple à faire... (Merci <a href="http://www.linkedin.com/profile/view?id=15668331" hreflang="fr">Fredo</a>! <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /> )</p>


<p>A bientôt!</p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></center>



<p>EDIT 29 Mars 2012: Après presque un an, je l'utilise toujours autant <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /> . Il m'arrive même de le trimbaler chez des amis. Ducoup, mes photos d’intérieur, le soir ou il y a pas forcement beaucoup de lumière, sont vraiment très bonne. Franchement c'est vraiment quelque chose a avoir.</p>


<p>De plus, ce réflecteur envoi de la lumière un peu partout de manière un peu archaïque ce qui fait qu'on a jamais cette sensation d'avoir <a href="http://www.photoromandie.ch/download/file.php?id=17242">un plafond qui illumine</a>.</p>


<p>Je ne regrette pas mon petit bricolage. <img src="/blog/themes/blueSilenceCustom/smilies/aupoil.gif" alt=":aupoil:" class="smiley" /></p>


feed_id: urn:md5:8d37f8fae77bf65c91dfd3417d89e27d
title: Mental ray 3.9: L'Unified Sampling, explications
uri: Mental-ray-3-9-L-Unified-Sampling-explications
url: http://www.fevrierdorian.com/blog/post/2011/05/10/Mental-ray-3.9-L-Unified-Sampling-explications
content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/2011_04_23_Unified_Sampling_tn.png" alt="2011_04_23_Unified_Sampling_tn.png" style="float:left; margin: 0 1em 1em 0;" title="2011_04_23_Unified_Sampling_tn.png, mai 2011"  height="150" width="150" />Ce billet est la traduction d'<a href="http://forums.cgsociety.org/showthread.php?t=970700">un thread</a> de CGTalk lancé par <a href="http://forums.cgsociety.org/member.php?u=34231">Bitter</a> ou il explique le principe de la nouvelle technique de sampling utilisé dans mental ray 3.9: L'<a href="http://docs.autodesk.com/MENTALRAY/2012/ENU/mental%20ray%203.9%20Help/files/manual/node76.html?highlighting=unified#unified_sampling">Unified Samplig</a>.</p>


<p>Cette nouvelle technique est beaucoup plus efficace car elle prend en compte les samples et leur direction, alors que l'ancienne méthode ne se basait que sur le contraste de la couleur des samples dans l'image finale.</p>


<p>Cette technique est plus ou moins déjà utilisé dans Vray (au d'autres raytracers) mais c'est un vrai plaisir de voir cette nouvelle méthode de sampling dans mental ray.</p>    <h3>Sommaire</h3>

<ul>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/05/10/Mental-ray-3.9-L-Unified-Sampling-explications#la_methode_de_monte_carlo">La méthode de Monte Carlo</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/05/10/Mental-ray-3.9-L-Unified-Sampling-explications#les_traductions">Les traductions</a>
<ul>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/05/10/Mental-ray-3.9-L-Unified-Sampling-explications#unified_sampling_maya_2012">L'Unified Sampling de Maya 2012 dans mental ray</a>
<ul>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/05/10/Mental-ray-3.9-L-Unified-Sampling-explications#trois_controleur_principaux">Les trois contrôleurs principaux</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/05/10/Mental-ray-3.9-L-Unified-Sampling-explications#autres_controleurs">Autres contrôleurs</a></li>
</ul></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/05/10/Mental-ray-3.9-L-Unified-Sampling-explications#error_control">Error Control</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/05/10/Mental-ray-3.9-L-Unified-Sampling-explications#undersampling">Undersampling</a></li>
</ul></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/05/10/Mental-ray-3.9-L-Unified-Sampling-explications#conclusion">Conclusion</a></li>
</ul>

<h3>La méthode de Monte Carlo <a name="la_methode_de_monte_carlo"></a></h3>


<p>Avant de commencer, sachez que ce thread aborde la méthode de Quasi Monte Carlo...</p>


<p>Vu que je suis curieux, j'ai cherché un peu et je vous propose une <del>misérable</del> petite explication.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/3020447896_c836a6058f_o.jpg" title="3020447896_c836a6058f_o.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/.3020447896_c836a6058f_o_m.jpg" alt="3020447896_c836a6058f_o.jpg" style="display:block; margin:0 auto;" title="3020447896_c836a6058f_o.jpg, avr. 2011"  height="373" width="560" /></a></p>
<center><small><i><a href="http://www.flickr.com/photos/harmrhebergen/3020447896/">Photo</a> par <a href="http://www.flickr.com/photos/harmrhebergen/">Harm Rhebergen</a> sous licence Créative <a href="http://creativecommons.org/licenses/by-nc-nd/2.0/deed.fr">by-nc-nd</a>. Merci à lui! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></i></small></center>



<p>Je vais modestement tenter de vous éclaircir un peu sur ce qu'est la méthode de Monte Carlo, ainsi que ses variantes.</p>


<blockquote><p>Si vous connaissez un site qui parle de la chose de manière clair, sans trop de blah blah mathématique, n'hésitez pas à me laisser un commentaire. Je me ferai un plaisir, si j'arrive à comprendre le truc, à approfondir mon billet. <img src="/blog/themes/blueSilenceCustom/smilies/yeoh.gif" alt=":dentcasse:" class="smiley" /></p></blockquote>


<p>D'après ce que j'en ai compris, <a href="https://secure.wikimedia.org/wikipedia/fr/wiki/M%C3%A9thode_de_Monte-Carlo">la méthode de Monte Carlo</a> est un moyen d'obtenir un résultat le plus juste possible en se basant sur des probabilités. Normalement, cette méthode ne fait "que ça".</p>


<p>Dans le cas du sampling, ce qu'on cherche à obtenir ("le résultat") est un endroit ou lancer un sample le plus "utile" possible.</p>


<p>Ce qui fait office de probabilité est "la signature" des samples. (Position+Direction).</p>


<p>Plus cette signature semble aléatoire, plus il faut, à priori, ajouter de sample.</p>


<p>Il existe plusieurs variantes des algorithmes de Monte Carlo (Quasi Monte Carlo, Deterministic Monte Carlo).</p>


<p>La doc officiel sur <a href="http://www.spot3d.com/vray/help/150SP1/render_params_dmc.htm">le DMC Sampler de Vray</a> aborde un peu les différences:</p>


<blockquote><p>The difference between pure Monte Carlo sampling and deterministic Monte Carlo is that the first uses pseudo-random numbers which are different for each and every evaluation (and so re-rendering a single image will always produce slightly different results in the noise), while deterministic Monte Carlo uses a pre-defined set of samples (possibly optimized to reduce the noise), which allows re-rendering an image to always produce the exact same result.</p></blockquote>


<p>La doc officiel de Blender tente aussi <a href="http://www.blender.org/development/release-logs/blender-246/qmc-sampling/">une petite démystification</a> du principe de QMC.</p>


<p>Si je comprend bien:</p>
<ul>
<li>MC renvoi toujours un résultat un peu différent, même si les valeurs données en entré (les probabilités) sont identiques.</li>
<li>DMC renvoie toujours le même résultat si les probabilités données en entré sont identiques. D’où le <em>D</em> pour <em>Deterministic</em> (un peu comme, en Python, si on utilise <a href="http://docs.python.org/release/2.6.3/library/random.html">un random avec un seed</a>).</li>
<li>QMC est un équivalent à DMC mais avec un méthode différente.</li>
</ul>

<p>Je serais bien incapable de vous donner plus de détails.</p>


<p>Après ce fiasco d'explication (quoi que j'ai personnellement appris pas mal de choses en cherchant), je vous propose de passer à la traduction! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<h3>Les traductions <a name="les_traductions"></a></h3>


<blockquote><p>Ndt: Ceci est la traduction du <a href="http://forums.cgsociety.org/showpost.php?p=6936586">premier post</a> de <a href="http://forums.cgsociety.org/member.php?u=34231">Bitter</a></p></blockquote>


<h4>L'Unified Sampling de Maya 2012 dans mental ray <a name="unified_sampling_maya_2012"></a></h4>


<p>L'Unified Sampling est une méthode de sampling se basant sur des calculs de probabilités (QMC pour Quasi-Monte-Carlo) sur "le plan" de l'image (le plan de la camera ou est rendu l'image en fait).</p>


<p>A la différence de l'Anti-Aliasing classique, qui fonctionne sur la base d'une grille (les pixels) et d'un contraste des couleurs sur cette même grille, l'US (Unified Sampling) est basé, par couche, sur une distance optimale entre les samples, qui sont envoyés en se basant sur des modèles de probabilité (de type QMC), et une estimation de l'erreur.</p>


<p>Ce qui veut dire que vous pouvez calculer de la géométrie fine tel que des hairs et des furs en utilisant le raytrace au lieu du rasterizer, tout en conservant une bonne qualité.</p>


<p>L'US samplera de la géométrie plus petite qu'un pixel tout en nécessitant, généralement, moins de samples en interne.</p>



<p>Il résout également les problèmes de noise en générant son propre grain adaptatif.</p>


<p><strong>Maintenant, le DOF et le Motion Blur raytracé est plus doux et plus rapide à calculer.</strong></p>


<p>Vous pouvez rendre du Motion Blur raytracé. Le Motion Blur est maintenant <em>visually adaptive</em>.</p>


<p>En mode US, vous pouvez ignorer les <em>time samples</em>. Les zones avec peu de détails et/ou ayant des couleurs <em>plates</em> recevront le minimum de sample, indépendamment de leur quantité de Motion Blur.</p>


<p>La quantité de mémoire utilisé par le Motion Blur est maintenant minimal comparé à avant.</p>



<h5>Les trois contrôleurs principaux <a name="trois_controleur_principaux"></a></h5>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/mental_ray_box.png" title="mental_ray_box.png"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/.mental_ray_box_m.jpg" alt="mental_ray_box.png" style="display:block; margin:0 auto;" title="mental_ray_box.png, mai 2011"  height="372" width="560" /></a></p>
<center><small><i><a href="http://www.flickr.com/photos/29745333@N02/2827317485/">Photo originale</a> par <a href="http://www.flickr.com/photos/29745333@N02/">gwenflickr</a> sous licence Créative <a href="http://creativecommons.org/licenses/by-sa/2.0/deed.fr">by-nc-sa</a>. Merci à lui! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></i></small></center>



<p><em><strong>samples min</strong></em> = Le nombre minimum de samples utilisé par pixels (les valeurs en dessous de 1 sous-sampleront les pixels). Ces valeurs ne seront pas soumis à des puissance comme l'Anti-Aliasing standard. Ce sont des valeurs absolues.</p>


<p><em><strong>samples max</strong></em> = Le nombre maximum de samples utilisé par pixel.</p>


<p><em><strong>samples quality</strong></em> = Le <em>potar</em> principal de l'US. Plus il est grand, meilleur c'est. 1.0 Peut être considéré comme une valeur de production. Il m'arrive de monter ce paramètre plus haut, 2 ou 3, cela dépend de la quantité de noise/petits détails que j'ai. 0.3 est une bonne valeur pour la preview.</p>


<p>Si vous trouvez que le Motion Blur ou le DOF est granuleux, augmenter le <em>samples max</em>.</p>


<p>Mais dans la plupart des cas, vous pouvez augmenter le <em>samples quality</em> et laisser vos valeurs de samples assez large.</p>


<p>Ce potar de qualité est maintenant votre contrôleur de rendu!</p>


<p>Basiquement, la technique consiste à setter un min et un max et à utiliser le potar pour jauger la qualité.</p>


<p>Vous pouvez utiliser les <em>diagnostics</em> pour voir comment/ou vos samples sont envoyés et prendre une décision à partir de là.</p>


<p>Les diagnostiques sont embarquées dans un EXR, dans différents channels (voir plus bas).</p>


<blockquote><p>Ndt: Le diagnostique joue un role important pour déterminer les valeurs optimales de rendu. On y reviendra.</p></blockquote>


<h5>Autres contrôleurs <a name="autres_controleurs"></a></h5>


<p><em><strong>sample error cutoff</strong></em> = Défini quand arrêter de sampler. C'est une tolérance de couleur qui commence "par le bas" (couleur noire). Plus la valeur est haute, plus les zones claires sont ignoré. C'est un paramètre très sensible qui est rarement utilisé.</p>


<p><em><strong>samples per object</strong></em> = Utilise les valeurs de sampling setté "par objet". Au même titre que précédemment, ces valeurs de min et max sample par objet doivent être absolue (et non des puissances de deux).</p>


<p>Noter qu'il est fortement conseillé de désactiver le Scanline afin de ne pas diminuer les performances.</p>


<p>Le Scanline ralenti le rendu et ne devrait pas être activé par défaut dans Maya.</p>



<p>Il y a également trois channels intéressants de diagnostiques dans l'EXR quand vous rendez avec l'option <em>diagnose samples</em>.</p>


<p>Ils sont:</p>
<ul>
<li>L<em>'error color</em> estimé par pixel.</li>
<li>Le nombre (absolue) de samples envoyé par pixels.</li>
<li>Le temps passer à rendre le pixel (en secondes).</li>
</ul>

<p>Démonstration (Ndt: C'est moi qui ai fait ces images pour rendre le truc plus évident...):</p>



<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/2011_04_23_Unified_Sampling_009.png" alt="2011_04_23_Unified_Sampling_009.png" style="display:block; margin:0 auto;" title="2011_04_23_Unified_Sampling_009.png, avr. 2011"  height="480" width="640" /></p>
<center><i>L'image originale (Image HDR de <a href="http://smartibl.com/sibl/archive.html">sIBL Archive</a> sous licence <a href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative by-nc-sa</a>. Merci à eux! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /> ).</i></center>




<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/2011_04_23_Unified_Sampling_001.png" alt="2011_04_23_Unified_Sampling_001.png" style="display:block; margin:0 auto;" title="2011_04_23_Unified_Sampling_001.png, avr. 2011"  height="220" width="599" /></p>
<center><i>Le fichier en question</i></center>




<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/2011_04_23_Unified_Sampling_002.png" alt="2011_04_23_Unified_Sampling_002.png" style="display:block; margin:0 auto;" title="2011_04_23_Unified_Sampling_002.png, avr. 2011"  height="360" width="337" /></p>
<center><i>La liste des channels disponibles.</i></center>




<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/2011_04_23_Unified_Sampling_003.png" alt="2011_04_23_Unified_Sampling_003.png" style="display:block; margin:0 auto;" title="2011_04_23_Unified_Sampling_003.png, avr. 2011"  height="223" width="120" /></p>



<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/2011_04_23_Unified_Sampling_004.png" alt="2011_04_23_Unified_Sampling_004.png" style="display:block; margin:0 auto;" title="2011_04_23_Unified_Sampling_004.png, avr. 2011"  height="271" width="457" /></p>
<center><i>Il faut bricoler un peu pour visualiser chaque channel. <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></i></center>




<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/2011_04_23_Unified_Sampling_006.png" alt="2011_04_23_Unified_Sampling_006.png" style="display:block; margin:0 auto;" title="2011_04_23_Unified_Sampling_006.png, avr. 2011"  height="398" width="601" /></p>
<center><i>Le nombre de sample au pixel (Le chiffre en bas à droite. Ici: 13 samples)</i></center>




<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/2011_04_23_Unified_Sampling_007.png" alt="2011_04_23_Unified_Sampling_007.png" style="display:block; margin:0 auto;" title="2011_04_23_Unified_Sampling_007.png, avr. 2011"  height="578" width="711" /></p>
<center><i>Le temps (en secondes) passer par pixel. (Le chiffre en bas à droite. Ici: 0.03 sec). Notez qu'on voit la forme de la bounding box. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></i></center>


<blockquote><p>Note: Les points blancs sont surement due à la <a href="http://www.siteduzero.com/tutoriel-3-14136-maitrisez-le-temps.html#ss_part_1">granularité du temps</a>.</p></blockquote>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/2011_04_23_Unified_Sampling_008.png" alt="2011_04_23_Unified_Sampling_008.png" style="display:block; margin:0 auto;" title="2011_04_23_Unified_Sampling_008.png, avr. 2011"  height="512" width="677" /></p>
<center><i>L'error color estimé. (Encore un truc de Monte Carlo d'mes fesses <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /> ).</i></center>




<p>Voici la ligne MEL pour créer les string options:</p>
<pre class="mel mel">select miDefaultOptions<span style="color: #339933;">;</span>
<span style="color: #993333;">int</span> $idx <span style="color: #339933;">=</span> `getAttr <span style="color: #339933;">-</span>size miDefaultOptions.<span style="color: #202020;">stringOptions</span>`<span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;unified sampling&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">value</span> <span style="color: #ff0000;">&quot;on&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">type</span> <span style="color: #ff0000;">&quot;boolean&quot;</span><span style="color: #339933;">;</span>
$idx <span style="color: #339933;">=</span> `getAttr <span style="color: #339933;">-</span>size miDefaultOptions.<span style="color: #202020;">stringOptions</span>`<span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;samples min&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">value</span> <span style="color: #ff0000;">&quot;1.&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">type</span> <span style="color: #ff0000;">&quot;float&quot;</span><span style="color: #339933;">;</span>
$idx <span style="color: #339933;">=</span> `getAttr <span style="color: #339933;">-</span>size miDefaultOptions.<span style="color: #202020;">stringOptions</span>`<span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;samples max&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">value</span> <span style="color: #ff0000;">&quot;64.&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">type</span> <span style="color: #ff0000;">&quot;float&quot;</span><span style="color: #339933;">;</span>
$idx <span style="color: #339933;">=</span> `getAttr <span style="color: #339933;">-</span>size miDefaultOptions.<span style="color: #202020;">stringOptions</span>`<span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;samples quality&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">value</span> <span style="color: #ff0000;">&quot;0.5&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">type</span> <span style="color: #ff0000;">&quot;scalar&quot;</span><span style="color: #339933;">;</span>
$idx <span style="color: #339933;">=</span> `getAttr <span style="color: #339933;">-</span>size miDefaultOptions.<span style="color: #202020;">stringOptions</span>`<span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;sample error cutoff&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">value</span> <span style="color: #ff0000;">&quot;0 0 0&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">type</span> <span style="color: #ff0000;">&quot;color&quot;</span><span style="color: #339933;">;</span>
$idx <span style="color: #339933;">=</span> `getAttr <span style="color: #339933;">-</span>size miDefaultOptions.<span style="color: #202020;">stringOptions</span>`<span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;samples per object&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">value</span> <span style="color: #ff0000;">&quot;off&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> miDefaultOptions.<span style="color: #202020;">stringOptions</span><span style="color: #009900;">&#91;</span>$idx<span style="color: #009900;">&#93;</span>.<span style="color: #202020;">type</span> <span style="color: #ff0000;">&quot;boolean&quot;</span><span style="color: #339933;">;</span></pre>


<blockquote><p>Ndt: Pour vous simplifier la vie, je vous invite à utiliser mon outil: <a href="http://forums.cgsociety.org/showthread.php?p=6941790">enjoyMentalRayStringOptions</a></p></blockquote>


<p>Techniquement, <em>sample quality</em> est une couleur. Mais pour pas mal de raisons, on préfèrera combiner les trois valeurs en une seule.</p>


<p>A noter: Il s'agit d'une première implémentation et je trouve qu'elle est bonne sur pas mal de points. Vous remarquerez que les hards edges ne sont pas définies du mieux possible (surtout en Arch Viz). C'est un point à améliorer qui a déjà été mentionné. Tout comme le reste, je suppose que cette feature s’améliora dans le temps.</p>


<h4>Error Control <a name="error_control"></a></h4>


<blockquote><p>Ndt: Ceci est la traduction d'un <a href="http://forums.cgsociety.org/showpost.php?p=6964385&amp;postcount=19">autre post</a> de <a href="http://forums.cgsociety.org/member.php?u=34231">Bitter</a></p></blockquote>


<p>Voici une explication plus clair de l'error control de l'Unified Sampling</p>


<p>Les images qui suivent ont été générées via des paramètres de qualité graduel: 0.25 -&gt; 0.75 -&gt; 1.5</p>


<p>Vous remarquerez comment l'erreur perçu diminue à chaque valeur. Les zones ayant le plus d'erreurs sont les plus colorées. Vous pouvez voir les erreurs de chaque couleur en regardant chaque channel (RGB).</p>


<p>0.25
<a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/quality0250.jpg" title="quality0250.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/.quality0250_m.jpg" alt="quality0250.jpg" style="display:block; margin:0 auto;" title="quality0250.jpg, mai 2011"  height="315" width="560" /></a></p>


<p>0.75
<a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/quality0750.jpg" title="quality0750.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/.quality0750_m.jpg" alt="quality0750.jpg" style="display:block; margin:0 auto;" title="quality0750.jpg, mai 2011"  height="315" width="560" /></a></p>


<p>1.5
<a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/quality15.jpg" title="quality15.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/.quality15_m.jpg" alt="quality15.jpg" style="display:block; margin:0 auto;" title="quality15.jpg, mai 2011"  height="315" width="560" /></a></p>


<p>Vous trouverez le fichier de diagnostic du rendu de qualité 1.5 ici:</p>


<p><a href="http://www.mediafire.com/?v2tvv4ja25wark4">diagnostic.exr</a></p>


<p>Elle contient les 4 layers de diagnostique. Vous pouvez l'ouvrir avec imf_disp pour voir ces layers.</p>


<p>Pour le layer <em>samples</em>, vous serez amené à ramener l'exposition à -5.0 pour voir l'image. Placez ensuite votre curseur sur les pixels pour récupérer différentes valeurs.</p>


<p>Le rendu prend tout juste 11 minutes en 1280x720 à une qualité de 1.5 (sans compter le calcul du final gather).</p>


<p>J'utilise des shader BSDF avec du glossiness (visible sur les bureaux).</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/quality15beauty.jpg" title="quality15beauty.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/.quality15beauty_m.jpg" alt="quality15beauty.jpg" style="display:block; margin:0 auto;" title="quality15beauty.jpg, mai 2011"  height="315" width="560" /></a></p>

<pre class="bash bash">RC   <span style="color: #000000;">0.3</span>  info : rendering statistics
RC   <span style="color: #000000;">0.3</span>  info :   <span style="color: #7a0874; font-weight: bold;">type</span>                           number   per eye ray
RC   <span style="color: #000000;">0.3</span>  info :   eye rays                      <span style="color: #000000;">4618306</span>          <span style="color: #000000;">1.00</span>
RC   <span style="color: #000000;">0.3</span>  info :   transparent rays                <span style="color: #000000;">63490</span>          <span style="color: #000000;">0.01</span>
RC   <span style="color: #000000;">0.3</span>  info :   reflection rays              <span style="color: #000000;">30493569</span>          <span style="color: #000000;">6.60</span>
RC   <span style="color: #000000;">0.3</span>  info :   shadow rays                 <span style="color: #000000;">335052362</span>         <span style="color: #000000;">72.55</span>
RC   <span style="color: #000000;">0.3</span>  info :   <span style="color: #7a0874; font-weight: bold;">fg</span> points interpolated       <span style="color: #000000;">33898517</span>          <span style="color: #000000;">7.34</span>
RC   <span style="color: #000000;">0.3</span>  info : on average <span style="color: #000000;">65.38</span> finalgather points used per interpolation
RC   <span style="color: #000000;">0.3</span>  info : wallclock  <span style="color: #000000;">0</span>:<span style="color: #000000;">10</span>:<span style="color: #000000;">30.95</span> <span style="color: #000000; font-weight: bold;">for</span> rendering
RC   <span style="color: #000000;">0.3</span>  info : allocated <span style="color: #000000;">124</span> MB, max resident <span style="color: #000000;">166</span> MB
GAPM <span style="color: #000000;">0.3</span>  info : triangle count <span style="color: #7a0874; font-weight: bold;">&#40;</span>including retessellation<span style="color: #7a0874; font-weight: bold;">&#41;</span> :      <span style="color: #000000;">247606</span></pre>


<p>Le truc qui prend le plus de temps à calculer c'est les shadow rays. 72.55 rayons "eye ray" (Ndt: Sample?)</p>


<p>J'ai des portal lights sur les fenètres avec un High Samples seulement à 16. Cela dit, j'ai un rendu clean. J'ai quelques artefacts de final gather mais ils ne serait pas difficile de s'en occuper.</p>


<h4>Undersampling <a name="undersampling"></a></h4>


<blockquote><p>Ndt: Ceci est la traduction d'un <a href="http://forums.cgsociety.org/showpost.php?p=6964394&amp;postcount=20">autre post</a> de <a href="http://forums.cgsociety.org/member.php?u=34231">Bitter</a></p></blockquote>

<pre class="bash bash">samples min <span style="color: #000000;">0.1</span>
samples max <span style="color: #000000;">1</span>.
samples quality <span style="color: #000000;">0.1</span></pre>


<p>Vous pouvez jouer avec comme il vous plait.</p>


<p>Mon paramètre de <em>samples min</em> sample maintenant tout les 10 pixels avec un max de 1 sample par pixel. Je pourrai augmenter le maximum mais ça utilisera plus de samples si ma quality augmente aussi.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/undersample.jpg" title="undersample.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_23_Unified_Sampling/.undersample_m.jpg" alt="undersample.jpg" style="display:block; margin:0 auto;" title="undersample.jpg, mai 2011"  height="315" width="560" /></a></p>


<h3>Conclusion <a name="conclusion"></a></h3>


<p>J'espère que vous aurez apprécié ces traductions qui m'ont personnelement pas mal éclairées sur le sujet.</p>


<p>C'est toujours interessant de savoir comment fonctionne une "nouvelle" technique (je met des guillemets car mental ray est surement un des derniers raytracer "high end" qui intègre cette méthode de sampling. Enfin bon... <img src="/blog/themes/blueSilenceCustom/smilies/riva.gif" alt=":pasClasse:" class="smiley" /> ).</p>


<p>A bientôt!</p>


<p>Dorian</p>


<p><strong>EDIT 2011 - 11 - 19:</strong>
Il semble que je n'ai pas bien abordé la theorie qui entour le <em>DMC sampler</em>. Voici <a href="http://fevrierdorian.com/wiki/index.php?title=V-Ray_-_Le_DMC_Sampler_d%C3%A9mystifi%C3%A9_%28Traduction%29" hreflang="fr">ma traduction</a> sur le <em>DMC sampler</em> de Vray. C'est beaucoup plus précis (par un ancien de chez <a href="http://www.blur.com/" hreflang="en">Blur</a>).</p>


<center><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></center>


feed_id: urn:md5:fe10cc69f865e5894c24dd563fa6dff4
title: Mental ray 3.9: Les User Data Shaders (ou Shader Package)
uri: Mental-ray-3-9-Les-User-Data-Shaders-(ou-Shader-Package)
url:
http://www.fevrierdorian.com/blog/post/2011/04/16/Mental-ray-3.9-Les-User-Data-Shaders-ou-Shader-Package

content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/mental_ray_3_9_Les_User_Data_Shaders_tn.png" alt="mental_ray_3_9_Les_User_Data_Shaders_tn.png" style="float:left; margin: 0 1em 1em 0;" title="mental_ray_3_9_Les_User_Data_Shaders_tn.png, avr. 2011"  height="150" width="150" />Comme vous le savez tous, Maya 2012 est sorti. Et comme chaque nouvelle version de Maya, mental ray est mis à jour (v3.9.1.36). Dans ce billet, je ne ferai pas le tour des nouvelles features. Elles sont <a href="http://forums.cgsociety.org/showthread.php?t=967451">présentées ici</a> (<a href="http://docs.autodesk.com/MENTALRAY/2012/ENU/mental%20ray%203.9%20Help/files/manual/upgrading39.html">page officielle</a>). Je m'attarderai en revanche sur l'une d'elle que je trouve très intéressante: Les shaders packages.</p>


<p>Concrètement, cela consiste à appliquer un attribut spécifique à un élément de la scène pour que son shader puisse utiliser la valeur donné dans l'attribut.</p>


<p>Un exemple: Si vous avez un shader sur des objets et que la seule chose qui change en fonction de ses objets est la texture, il est dommage de dupliquer tout le shader pour ça, et, en cas de modifications de devoir l'appliquer sur tous les shaders dupliqués de la scène... Sur des grosses scènes ça devient vite ingérable... <img src="/blog/themes/blueSilenceCustom/smilies/redface.gif" alt=":redface:" class="smiley" /></p>


<p>Je vous propose ici un billet rapide sur le principe ainsi que des bouts de script, un peu en vrac, que vous pourrez essayer. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>    <h3>Sommaire</h3>
<ul>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/04/16/Mental-ray-3.9-Les-User-Data-Shaders-ou-Shader-Package#a_savoir">A savoir</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/04/16/Mental-ray-3.9-Les-User-Data-Shaders-ou-Shader-Package#la_feature">La feature</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/04/16/Mental-ray-3.9-Les-User-Data-Shaders-ou-Shader-Package#la_limitation">La limitation</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/04/16/Mental-ray-3.9-Les-User-Data-Shaders-ou-Shader-Package#script_dexemple">Scripts d'exemples</a>
<ul>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/04/16/Mental-ray-3.9-Les-User-Data-Shaders-ou-Shader-Package#script_1">Script 1: Overrider une valeur</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/04/16/Mental-ray-3.9-Les-User-Data-Shaders-ou-Shader-Package#script_2">Script 2: Overrider une couleur</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/04/16/Mental-ray-3.9-Les-User-Data-Shaders-ou-Shader-Package#script_3">Script 3: Overrider un "shader"</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/04/16/Mental-ray-3.9-Les-User-Data-Shaders-ou-Shader-Package#les_textures">Les textures</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/04/16/Mental-ray-3.9-Les-User-Data-Shaders-ou-Shader-Package#over_plusieurs_params">Overrider plusieurs paramètres</a></li>
</ul></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/04/16/Mental-ray-3.9-Les-User-Data-Shaders-ou-Shader-Package#bonus">Bonus</a></li>
<li><a href="http://www.fevrierdorian.com/blog/post/2011/04/16/Mental-ray-3.9-Les-User-Data-Shaders-ou-Shader-Package#conclusion">Conclusion</a></li>
</ul>
<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h3>A savoir <a name="a_savoir"></a></h3>

<p>Comme d'habitude avec TotoDesk, c'est mal implémenté, caché, etc... Cette solution n'est donc pas à privilégier sur de la prod pour l'instant (m'est d'avis).</p>


<p>Je vous invite à aller voir <a href="http://forums.cgsociety.org/showthread.php?t=971291">ce billet sur CGTalk</a> pour voir comment il a fallu "déterrer" (c'est presque le bon mot) ces nodes.</p>


<p>Pour résumé, la dll est disponible dans les dossiers de mental ray:</p>

<pre class="bash bash">C:\Program Files\Autodesk\Maya2012\mentalray\lib</pre>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/mental_ray_3_9_Les_User_Data_Shaders_001.png" alt="mental_ray_3_9_Les_User_Data_Shaders_001.png" style="display:block; margin:0 auto;" title="mental_ray_3_9_Les_User_Data_Shaders_001.png, avr. 2011"  height="410" width="604" /></p>


<p>Mais il ne sont pas définit dans les .mi (fichiers qui sont les déclarations des shaders pour que mental ray sache ce qu'il y a dans la dll).</p>


<p>Donc il faut les ajouter à la mains. <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /></p>


<p>Ne vous embêtez pas, Je vous donne mon fichier.</p>


<blockquote><p><a href="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/userdata.zip">Télécharger userdata.zip</a></p></blockquote>


<p>Placez le fichier userData.mi dans:</p>

<pre class="bash bash">C:\Program Files\Autodesk\Maya2012\mentalray\include</pre>


<p>Et lancez Maya 2012.</p>


<p>Allez dans le Shader Manager:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/mental_ray_3_9_Les_User_Data_Shaders_002.png" alt="mental_ray_3_9_Les_User_Data_Shaders_002.png" style="display:block; margin:0 auto;" title="mental_ray_3_9_Les_User_Data_Shaders_002.png, avr. 2011"  height="255" width="566" /></p>


<p>Vous voyez votre userData.mi</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/mental_ray_3_9_Les_User_Data_Shaders_003.png" alt="mental_ray_3_9_Les_User_Data_Shaders_003.png" style="display:block; margin:0 auto;" title="mental_ray_3_9_Les_User_Data_Shaders_003.png, avr. 2011"  height="473" width="415" /></p>


<p>Cliquez sur le "i" vert:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/mental_ray_3_9_Les_User_Data_Shaders_004.png" alt="mental_ray_3_9_Les_User_Data_Shaders_004.png" style="display:block; margin:0 auto;" title="mental_ray_3_9_Les_User_Data_Shaders_004.png, avr. 2011"  height="643" width="560" /></p>


<p>Ça en fait des nodes!</p>


<p>Rassurez vous, dans la pratique on en utilise assez peu. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<blockquote><p>Autodesk corrigera surement ce soucis lors de son prochain service pack. Il vaudra mieux supprimer ce fichier (userData.mi) avant d'installer la mise à jour. :)</p></blockquote>

<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h3>La feature <a name="la_feature"></a></h3>


<p>Voici une courte description qui résume bien le principe:</p>


<blockquote><p>New Shader Package</p>
<p>
A new shader package userdata is now part of mental ray. It supports special workflows with large scene, where dynamic attributes attached to scene elements can indirectly drive parameters of the assigned shader(s).</p></blockquote>


<p>Si vous en voulez plus, je vous invite à aller directement lire les quelques lignes de la doc:</p>


<p><a href="http://docs.autodesk.com/MENTALRAY/2012/ENU/mental%20ray%203.9%20Help/files/shaders/userdata/userdata.html#intro" title="http://docs.autodesk.com/MENTALRAY/2012/ENU/mental%20ray%203.9%20Help/files/shaders/userdata/userdata.html#intro">http://docs.autodesk.com/MENTALRAY/...</a></p>


<p>En gros, on met un attribut spécial sur un objet de la scène et le shader de cet objet utilisera cet attribut dans ses paramètres. Un peu comme les overrides des render layers de Maya, mais à l'échelle d'un objet au niveau de son shader. <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h3>La limitation <a name="la_limitation"></a></h3>


<p>Vous allez voir qu'elle est de taille! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>Si vous venez juste d'ouvrir Maya, ouvrez votre script editor:</p>

<pre class="bash bash"><span style="color: #000000; font-weight: bold;">//</span> parsing C:<span style="color: #000000; font-weight: bold;">/</span>Program Files<span style="color: #000000; font-weight: bold;">/</span>Autodesk<span style="color: #000000; font-weight: bold;">/</span>Maya2012<span style="color: #000000; font-weight: bold;">/</span>mentalray<span style="color: #000000; font-weight: bold;">/</span>include<span style="color: #000000; font-weight: bold;">/</span>userdata.mi
<span style="color: #000000; font-weight: bold;">//</span> loading C:<span style="color: #000000; font-weight: bold;">/</span>Program Files<span style="color: #000000; font-weight: bold;">/</span>Autodesk<span style="color: #000000; font-weight: bold;">/</span>Maya2012<span style="color: #000000; font-weight: bold;">/</span>mentalray<span style="color: #000000; font-weight: bold;">/</span>lib<span style="color: #000000; font-weight: bold;">/</span>userdata.dll
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_bool&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_int&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_scalar&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_vector&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_color&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_string&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_texture&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_shader&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_bool_array&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_int_array&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_scalar_array&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_vector_array&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_color_array&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_string_array&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_texture_array&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_shader_array&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_get_bool&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_get_int&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_get_scalar&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_get_vector&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_get_color&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_get_string&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_get_texture&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_get_shader&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_get_shader_bool&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_get_shader_int&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_get_shader_scalar&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_get_shader_vector&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span> 
<span style="color: #000000; font-weight: bold;">//</span> Warning: <span style="color: #7a0874; font-weight: bold;">&#40;</span>Mayatomr.Nodes<span style="color: #7a0874; font-weight: bold;">&#41;</span> : Node <span style="color: #ff0000;">&quot;mib_data_get_shader_color&quot;</span> has no ID, assigning a temporary ID. Scene should be saved <span style="color: #c20cb9; font-weight: bold;">as</span> .ma <span style="color: #7a0874; font-weight: bold;">&#40;</span>ASCII<span style="color: #7a0874; font-weight: bold;">&#41;</span>. <span style="color: #000000; font-weight: bold;">//</span></pre>


<p>Qu'est ce que ça veut dire tout ça? <img src="/blog/themes/blueSilenceCustom/smilies/reflechi.gif" alt=":reflechi:" class="smiley" /></p>


<p>Et bien tout simplement que les nodes en question n'ont pas "d'identifiants internes". Ce code binaire qui est donné à un node quand on sauvegarde sa scène en .mb. D’où la "demande" de Maya qui vous incite à sauvegarder votre scène en .ma. Le .ma, comme vous le savez surement est un fichier texte. Le type du node y est écrit en dur donc pas besoin d'identifiants.</p>


<p><a href="http://forums.cgsociety.org/showpost.php?p=6942517&amp;postcount=29">D'après Rachid</a>, ce n'est pas un problème. En effet, après tests j'ai pu rouvrir une scène en .mb contenant quelques uns de ces nodes.</p>


<p>A vous de voir. Personnellement je n'ai pas encore super confiance (mais je suis du genre méfiant <img src="/blog/themes/blueSilenceCustom/smilies/redface.gif" alt=":redface:" class="smiley" /> ). Faut voir à l'usage. :)</p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h3>Scripts d'exemples <a name="script_dexemple"></a></h3>


<p>Voici quelques scripts d'exemples à lancer dans le script editor avec un mental ray chargé dans votre session Maya.</p>


<h4>Script 1: Overrider une valeur <a name="script_1"></a></h4>


<p>(Et oui, c'est du MEL... <img src="/blog/themes/blueSilenceCustom/smilies/siffle.gif" alt=":siffle:" class="smiley" /> )</p>
<pre class="mel mel"><span style="color: #666666; font-style: italic;">// Creation d'une nouvelle scene</span>
file <span style="color: #339933;">-</span>f <span style="color: #339933;">-</span>new<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* On cree trois spheres.
Les deux premières auront chacune un paramètre qui leur est spécifique,
la troiseme n'aura aucun parametre.*/</span>
polySphere<span style="color: #339933;">;</span>	<span style="color: #666666; font-style: italic;">// pSphere1</span>
polySphere<span style="color: #339933;">;</span>	<span style="color: #666666; font-style: italic;">// pSphere2</span>
move <span style="color: #339933;">-</span>r <span style="color: #339933;">-</span><span style="color:#800080;">2.341048</span> <span style="color:#800080;">0.785068</span> <span style="color:#800080;">1.752246</span> <span style="color: #339933;">;</span>
polySphere<span style="color: #339933;">;</span>	<span style="color: #666666; font-style: italic;">// pSphere3 default sphere</span>
move <span style="color: #339933;">-</span>r <span style="color:#800080;">2.341048</span> <span style="color:#800080;">0.785068</span> <span style="color: #339933;">-</span><span style="color:#800080;">1.752246</span> <span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// place la cam</span>
setAttr <span style="color: #ff0000;">&quot;persp.translateX&quot;</span> <span style="color:#800080;">8.053</span><span style="color: #339933;">;</span>
setAttr <span style="color: #ff0000;">&quot;persp.translateY&quot;</span> <span style="color:#800080;">6.607</span><span style="color: #339933;">;</span>
setAttr <span style="color: #ff0000;">&quot;persp.translateZ&quot;</span> <span style="color:#800080;">8.083</span><span style="color: #339933;">;</span>
setAttr <span style="color: #ff0000;">&quot;persp.rotateX&quot;</span> <span style="color: #339933;">-</span><span style="color:#800080;">27.938</span><span style="color: #339933;">;</span>
setAttr <span style="color: #ff0000;">&quot;persp.rotateY&quot;</span> <span style="color: #0000dd;">45</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* ajoute l'attribut special: &quot;miData&quot; sur les deux spheres a modifier,
celles qui recevront une valeur custom */</span>
addAttr <span style="color: #339933;">-</span>ln <span style="color: #ff0000;">&quot;miData&quot;</span> <span style="color: #339933;">-</span>at message pSphere1<span style="color: #339933;">;</span>
addAttr <span style="color: #339933;">-</span>ln <span style="color: #ff0000;">&quot;miData&quot;</span> <span style="color: #339933;">-</span>at message pSphere2<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Cree les deux nodes qui contiendront les valeurs customs que le shader recuperera</span>
createNode mib_data_scalar<span style="color: #339933;">;</span>
createNode mib_data_scalar<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Important: Un &quot;name&quot; commun doit etre donne pour faire la relation
entre les attributs (voir plus loin)
Ici c'es SCALAR qui est utilise */</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_scalar1.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;SCALAR&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_scalar2.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;SCALAR&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// On leur definit ensuite une valeur custom</span>
setAttr <span style="color: #ff0000;">&quot;mib_data_scalar1.value&quot;</span> <span style="color:#800080;">0.1</span><span style="color: #339933;">;</span>
setAttr <span style="color: #ff0000;">&quot;mib_data_scalar2.value&quot;</span> <span style="color:#800080;">1.0</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// On connecte les deux nodes contenant les valeurs customs aux spheres</span>
connectAttr mib_data_scalar1.<span style="color: #202020;">message</span> pSphere1.<span style="color: #202020;">miData</span><span style="color: #339933;">;</span>
connectAttr mib_data_scalar2.<span style="color: #202020;">message</span> pSphere2.<span style="color: #202020;">miData</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">// Le shader maintenant</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// On cree le node qui recuperera les valeurs customs</span>
createNode mib_data_get_scalar<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Pour faire la relation avec les nodes précédents, on lui assigne aussi le &quot;name&quot; SCALAR
Et surtout, une valeur par défaut */</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_get_scalar1.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;SCALAR&quot;</span><span style="color: #339933;">;</span>
setAttr mib_data_get_scalar1.<span style="color: #b1b100;">default</span> <span style="color:#800080;">0.5</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// On cree le shader</span>
mrCreateCustomNode <span style="color: #339933;">-</span>asShader <span style="color: #ff0000;">&quot;&quot;</span> mia_material_x<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// On selectionne les trois spheres et on leurs assigne le shader</span>
select pSphere1 pSphere2 pSphere3<span style="color: #339933;">;</span>
hyperShade <span style="color: #339933;">-</span>assign mia_material_x1<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// L'etape final, on connecte le node de get (celui qui recupere les valeurs customs) sur l'attribut a modifier</span>
connectAttr mib_data_get_scalar1.<span style="color: #202020;">outValue</span> mia_material_x1.<span style="color: #202020;">diffuse_weight</span><span style="color: #339933;">;</span></pre>

<p>Lisez bien les commentaires pour voir un peu ce qu'il fait (dsl, je n'ai pas mis d'accents ni rien pour éviter les syntax error <img src="/blog/themes/blueSilenceCustom/smilies/aupoil.gif" alt=":aupoil:" class="smiley" /> ).</p>


<p>Lancez le rendu:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/mental_ray_3_9_Les_User_Data_Shaders_005.png" alt="mental_ray_3_9_Les_User_Data_Shaders_005.png" style="display:block; margin:0 auto;" title="mental_ray_3_9_Les_User_Data_Shaders_005.png, avr. 2011"  height="480" width="640" /></p>

<ul>
<li>La sphère du centre est la sphère 1 (valeur: 0.1)</li>
<li>Celle de gauche est la sphère 2 (valeur: 1.0)</li>
<li>Celle de droite est la sphère 3 (valeur: 0.5)</li>
</ul>

<p>En général, c'est là qu'on commence à tilter.</p>


<p>Pas convaincu? Mettons un peu de couleur la dedans. <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></p>


<h4>Script 2: Overrider une couleur <a name="script_2"></a></h4>


<p>Un autre avec les colors (Je n'ai mis les commentaires que là ou c'était différent de l'exemple précédent):</p>

<pre class="bash bash"><span style="color: #c20cb9; font-weight: bold;">file</span> <span style="color: #660033;">-f</span> <span style="color: #660033;">-new</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Sphères
polySphere;
polySphere;
move <span style="color: #660033;">-r</span> -<span style="color: #000000;">2.341048</span> <span style="color: #000000;">0.785068</span> <span style="color: #000000;">1.752246</span> ;
polySphere;	<span style="color: #000000; font-weight: bold;">//</span> default sphere
move <span style="color: #660033;">-r</span> <span style="color: #000000;">2.341048</span> <span style="color: #000000;">0.785068</span> -<span style="color: #000000;">1.752246</span> ;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Camera
setAttr <span style="color: #ff0000;">&quot;persp.translateX&quot;</span> <span style="color: #000000;">8.053</span>;
setAttr <span style="color: #ff0000;">&quot;persp.translateY&quot;</span> <span style="color: #000000;">6.607</span>;
setAttr <span style="color: #ff0000;">&quot;persp.translateZ&quot;</span> <span style="color: #000000;">8.083</span>;
setAttr <span style="color: #ff0000;">&quot;persp.rotateX&quot;</span> -<span style="color: #000000;">27.938</span>;
setAttr <span style="color: #ff0000;">&quot;persp.rotateY&quot;</span> <span style="color: #000000;">45</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Attributs
addAttr <span style="color: #660033;">-ln</span> <span style="color: #ff0000;">&quot;miData&quot;</span> <span style="color: #660033;">-at</span> message pSphere1;
addAttr <span style="color: #660033;">-ln</span> <span style="color: #ff0000;">&quot;miData&quot;</span> <span style="color: #660033;">-at</span> message pSphere2;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Cree deux nodes de color
createNode mib_data_color;
createNode mib_data_color;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Leur donne le name
setAttr <span style="color: #660033;">-type</span> <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_color1.name <span style="color: #ff0000;">&quot;COLOR&quot;</span>;
setAttr <span style="color: #660033;">-type</span> <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_color2.name <span style="color: #ff0000;">&quot;COLOR&quot;</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Ainsi que des valeurs de couleur <span style="color: #7a0874; font-weight: bold;">&#40;</span>rouge, vert<span style="color: #7a0874; font-weight: bold;">&#41;</span>
setAttr <span style="color: #ff0000;">&quot;mib_data_color1.value&quot;</span> <span style="color: #660033;">-type</span> double3 <span style="color: #000000;">0</span> <span style="color: #000000;">1</span> <span style="color: #000000;">0</span> ;
setAttr <span style="color: #ff0000;">&quot;mib_data_color2.value&quot;</span> <span style="color: #660033;">-type</span> double3 <span style="color: #000000;">1</span> <span style="color: #000000;">0</span> <span style="color: #000000;">0</span> ;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> On les connectes aux spheres
connectAttr mib_data_color1.message pSphere1.miData;
connectAttr mib_data_color2.message pSphere2.miData;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Le shader
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Cree le node qui va recuperer les informations de couleurs des objets
createNode mib_data_get_color;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Set le name ainsi que sa valeur par defaut <span style="color: #7a0874; font-weight: bold;">&#40;</span>bleu<span style="color: #7a0874; font-weight: bold;">&#41;</span>
setAttr <span style="color: #660033;">-type</span> <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_get_color1.name <span style="color: #ff0000;">&quot;COLOR&quot;</span>;
setAttr <span style="color: #ff0000;">&quot;mib_data_get_color1.default&quot;</span> <span style="color: #660033;">-type</span> double3 <span style="color: #000000;">0</span> <span style="color: #000000;">0</span> <span style="color: #000000;">1</span> ;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Cree le shader et l<span style="color: #ff0000;">'assigne au trois spheres
mrCreateCustomNode -asShader &quot;&quot; mia_material_x;
&nbsp;
select pSphere1 pSphere2 pSphere3;
hyperShade -assign mia_material_x1;
&nbsp;
// Connecte le node de get (celui qui recupere les valeurs customs) sur le shader
connectAttr mib_data_get_color1.outValue mia_material_x1.diffuse;</span></pre>


<p>Lancez le rendu:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/mental_ray_3_9_Les_User_Data_Shaders_006.png" alt="mental_ray_3_9_Les_User_Data_Shaders_006.png" style="display:block; margin:0 auto;" title="mental_ray_3_9_Les_User_Data_Shaders_006.png, avr. 2011"  height="480" width="640" /></p>


<p>Tadaa!</p>


<p>Bon, si vous continuez avec le node de color, la première chose que vous allez vouloir faire est de lui connecter d'autres nodes Maya (a priori des textures mais ici, nous utiliseront de simples multiplyDivides qui renvoient des couleurs différentes):</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/mental_ray_3_9_Les_User_Data_Shaders_007.png" alt="mental_ray_3_9_Les_User_Data_Shaders_007.png" style="display:block; margin:0 auto;" title="mental_ray_3_9_Les_User_Data_Shaders_007.png, avr. 2011"  height="285" width="346" /></p>


<p>Tatataaaaa... <img src="/blog/themes/blueSilenceCustom/smilies/nannan.gif" alt=":nannan:" class="smiley" /></p>


<p>Et non, ça ce passe pas comme ça! Je ne vais pas rentrer dans les détails mais en gros, n'importe quel autre node de Maya est considéré comme un "shader" par mental ray. Et non comme une couleur.</p>


<p>Voyons voir comment s'en sortir:</p>


<h4>Script 3: Overrider un "shader" <a name="script_3"></a></h4>

<pre class="bash bash"><span style="color: #c20cb9; font-weight: bold;">file</span> <span style="color: #660033;">-f</span> <span style="color: #660033;">-new</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Sphere
polySphere;
polySphere;
move <span style="color: #660033;">-r</span> -<span style="color: #000000;">2.341048</span> <span style="color: #000000;">0.785068</span> <span style="color: #000000;">1.752246</span> ;
polySphere;	<span style="color: #000000; font-weight: bold;">//</span> default sphere
move <span style="color: #660033;">-r</span> <span style="color: #000000;">2.341048</span> <span style="color: #000000;">0.785068</span> -<span style="color: #000000;">1.752246</span> ;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Camera
setAttr <span style="color: #ff0000;">&quot;persp.translateX&quot;</span> <span style="color: #000000;">8.053</span>;
setAttr <span style="color: #ff0000;">&quot;persp.translateY&quot;</span> <span style="color: #000000;">6.607</span>;
setAttr <span style="color: #ff0000;">&quot;persp.translateZ&quot;</span> <span style="color: #000000;">8.083</span>;
setAttr <span style="color: #ff0000;">&quot;persp.rotateX&quot;</span> -<span style="color: #000000;">27.938</span>;
setAttr <span style="color: #ff0000;">&quot;persp.rotateY&quot;</span> <span style="color: #000000;">45</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Attributs
addAttr <span style="color: #660033;">-ln</span> <span style="color: #ff0000;">&quot;miData&quot;</span> <span style="color: #660033;">-at</span> message pSphere1;
addAttr <span style="color: #660033;">-ln</span> <span style="color: #ff0000;">&quot;miData&quot;</span> <span style="color: #660033;">-at</span> message pSphere2;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> On cree les nodes de multiply divide auquels on donne une couleur
createNode multiplyDivide;
createNode multiplyDivide;
createNode multiplyDivide;
&nbsp;
setAttr <span style="color: #ff0000;">&quot;multiplyDivide1.input1X&quot;</span> <span style="color: #000000;">1</span>;	<span style="color: #000000; font-weight: bold;">//</span> <span style="color: #c20cb9; font-weight: bold;">red</span>
setAttr <span style="color: #ff0000;">&quot;multiplyDivide1.input1Y&quot;</span> <span style="color: #000000;">0</span>;
setAttr <span style="color: #ff0000;">&quot;multiplyDivide1.input1Z&quot;</span> <span style="color: #000000;">0</span>;
&nbsp;
setAttr <span style="color: #ff0000;">&quot;multiplyDivide2.input1X&quot;</span> <span style="color: #000000;">0</span>;	<span style="color: #000000; font-weight: bold;">//</span> green
setAttr <span style="color: #ff0000;">&quot;multiplyDivide2.input1Y&quot;</span> <span style="color: #000000;">1</span>;
setAttr <span style="color: #ff0000;">&quot;multiplyDivide2.input1Z&quot;</span> <span style="color: #000000;">0</span>;
&nbsp;
setAttr <span style="color: #ff0000;">&quot;multiplyDivide3.input1X&quot;</span> <span style="color: #000000;">0</span>;	<span style="color: #000000; font-weight: bold;">//</span> blue
setAttr <span style="color: #ff0000;">&quot;multiplyDivide3.input1Y&quot;</span> <span style="color: #000000;">0</span>;
setAttr <span style="color: #ff0000;">&quot;multiplyDivide3.input1Z&quot;</span> <span style="color: #000000;">1</span>;
&nbsp;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> On cree un mib_data_SHADER cette fois
createNode mib_data_shader;
createNode mib_data_shader;
&nbsp;
setAttr <span style="color: #660033;">-type</span> <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_shader1.name <span style="color: #ff0000;">&quot;COLOR&quot;</span>;
setAttr <span style="color: #660033;">-type</span> <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_shader2.name <span style="color: #ff0000;">&quot;COLOR&quot;</span>;
&nbsp;
connectAttr multiplyDivide1.output mib_data_shader1.value;
connectAttr multiplyDivide2.output mib_data_shader2.value;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Connection
connectAttr mib_data_shader1.message pSphere1.miData;
connectAttr mib_data_shader2.message pSphere2.miData;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Le material
<span style="color: #000000; font-weight: bold;">//</span> On cree le node qui recuperera les shaders par objet
createNode mib_data_get_shader_color;
&nbsp;
setAttr <span style="color: #660033;">-type</span> <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_get_shader_color1.name <span style="color: #ff0000;">&quot;COLOR&quot;</span>;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> valeur par defaut: bleu
connectAttr multiplyDivide3.output mib_data_get_shader_color1.default;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Cree le material et assigne aux sphere
mrCreateCustomNode <span style="color: #660033;">-asShader</span> <span style="color: #ff0000;">&quot;&quot;</span> mia_material_x;
&nbsp;
<span style="color: #000000; font-weight: bold;">select</span> pSphere1 pSphere2 pSphere3;
hyperShade <span style="color: #660033;">-assign</span> mia_material_x1;
&nbsp;
<span style="color: #000000; font-weight: bold;">//</span> Connection final <span style="color: #c20cb9; font-weight: bold;">du</span> node de get au shader
connectAttr mib_data_get_shader_color1.outValue mia_material_x1.diffuse;</pre>


<p>Finalement c'est assez proche du script précédent sauf qu'on utilise un mip_data_shader au lieu d'un mip_data_color:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/mental_ray_3_9_Les_User_Data_Shaders_008.png" alt="mental_ray_3_9_Les_User_Data_Shaders_008.png" style="display:block; margin:0 auto;" title="mental_ray_3_9_Les_User_Data_Shaders_008.png, avr. 2011"  height="480" width="640" /></p>


<p>Ce qui fait qu'on peut entrer n'importe quel node Maya, mental ray le prendra bien.</p>


<h4>Les textures <a name="les_textures"></a></h4>


<p>Et oui, c'est quasiment la finalité de ce genre d'outils.</p>


<p>Ça peut paraitre simple mais en fait pas du tout! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>Le bon sens voudrait qu'on les connecte au mip_data_shader comme on le ferait pour le <em>multiplyDivide</em>...</p>


<p>Haha, pauvre naïf! <em>Pas assez compliqué mon fils</em>...</p>


<p>Je me suis pas mal <a href="http://forum.mentalimages.com/showthread.php?t=8093">arraché les cheveux</a> là dessus en bricolant avec une bonne partie des nodes alors que finalement la réponse était toute simple:</p>


<blockquote><p>If you're talking about what I think you're talking about, there's a translation issue with textures.</p>
<p>
They need to pass through another node like a multiply/divide. Just be sure to multiply by 1.</p></blockquote>


<p>Tu m'étonne que j'y ai pas pensé... C'est à la fois tellement évident et tellement n'importe quoi... <img src="/blog/themes/blueSilenceCustom/smilies/riva.gif" alt=":pasClasse:" class="smiley" /></p>


<p>En gros, pour faire joujou avec les textures, il faut les passer dans un autre node (J'entend les Vray users qui glousse au fond... Ils ont bien raison <img src="/blog/themes/blueSilenceCustom/smilies/mad0001.gif" alt=":septic:" class="smiley" /> ).</p>


<p>Il ne faut donc pas connecter directement les node de file Maya au mip_data_shader mais au <em>multiplyDivide</em> (par exemple) avec une multiplicateur à 1.0...</p>


<p>Voilà grossièrement ce que ça donne:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/mental_ray_3_9_Les_User_Data_Shaders_009.png" alt="mental_ray_3_9_Les_User_Data_Shaders_009.png" style="display:block; margin:0 auto;" title="mental_ray_3_9_Les_User_Data_Shaders_009.png, avr. 2011"  height="423" width="610" /></p>
<center>Pas de commentaires svp... <img src="/blog/themes/blueSilenceCustom/smilies/seSentCon.gif" alt=":seSentCon:" class="smiley" /></center>



<p>Et le rendu:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/mental_ray_3_9_Les_User_Data_Shaders_010.png" alt="mental_ray_3_9_Les_User_Data_Shaders_010.png" style="display:block; margin:0 auto;" title="mental_ray_3_9_Les_User_Data_Shaders_010.png, avr. 2011"  height="480" width="640" /></p>


<p>Et tout ça avec un seul shader dans la scène:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/mental_ray_3_9_Les_User_Data_Shaders_011.png" alt="mental_ray_3_9_Les_User_Data_Shaders_011.png" style="display:block; margin:0 auto;" title="mental_ray_3_9_Les_User_Data_Shaders_011.png, avr. 2011"  height="219" width="615" /></p>
<center>Votre hypershade vous dit merci! <img src="/blog/themes/blueSilenceCustom/smilies/laClasse.gif" alt=":laClasse:" class="smiley" /></center>


<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h4>Overrider plusieurs paramètres <a name="over_plusieurs_params"></a></h4>


<p>C'est bien joli. Mais quand on souhaite overrider plusieurs paramètres on fait comment? <img src="/blog/themes/blueSilenceCustom/smilies/reflechi.gif" alt=":reflechi:" class="smiley" /></p>


<p>En effet, il n'y a, qu'un attribut <em>miData</em> par objet. Donc à priori on ne peut overrider qu'un seul paramètre.</p>


<p>Qu'à cela de tienne, il suffit que l'attribut <em>miData</em> soit de type multi. <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /></p>

<pre class="mel mel">addAttr <span style="color: #339933;">-</span>ln <span style="color: #ff0000;">&quot;miData&quot;</span> <span style="color: #339933;">-</span>at message <span style="color: #339933;">-</span>multi pSphere1<span style="color: #339933;">;</span></pre>


<p>Et on assigne avec:</p>
<pre class="mel mel">connectAttr mib_data_shader1.<span style="color: #202020;">message</span> pSphere1.<span style="color: #202020;">miData</span><span style="color: #009900;">&#91;</span>x<span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span></pre>


<p>Ou <em>x</em> est le numéro dans le tableau.</p>


<p>Le code complet:</p>

<pre class="mel mel">file <span style="color: #339933;">-</span>f <span style="color: #339933;">-</span>new<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Sphères</span>
polySphere<span style="color: #339933;">;</span>
polySphere<span style="color: #339933;">;</span>
move <span style="color: #339933;">-</span>r <span style="color: #339933;">-</span><span style="color:#800080;">2.341048</span> <span style="color:#800080;">0.785068</span> <span style="color:#800080;">1.752246</span> <span style="color: #339933;">;</span>
polySphere<span style="color: #339933;">;</span>	<span style="color: #666666; font-style: italic;">// default sphere</span>
move <span style="color: #339933;">-</span>r <span style="color:#800080;">2.341048</span> <span style="color:#800080;">0.785068</span> <span style="color: #339933;">-</span><span style="color:#800080;">1.752246</span> <span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Cameras</span>
setAttr <span style="color: #ff0000;">&quot;persp.translateX&quot;</span> <span style="color:#800080;">8.053</span><span style="color: #339933;">;</span>
setAttr <span style="color: #ff0000;">&quot;persp.translateY&quot;</span> <span style="color:#800080;">6.607</span><span style="color: #339933;">;</span>
setAttr <span style="color: #ff0000;">&quot;persp.translateZ&quot;</span> <span style="color:#800080;">8.083</span><span style="color: #339933;">;</span>
setAttr <span style="color: #ff0000;">&quot;persp.rotateX&quot;</span> <span style="color: #339933;">-</span><span style="color:#800080;">27.938</span><span style="color: #339933;">;</span>
setAttr <span style="color: #ff0000;">&quot;persp.rotateY&quot;</span> <span style="color: #0000dd;">45</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Vous remarquez la présence du flag &quot;multi&quot; qui créé
l'attribut comme un tableau */</span>
addAttr <span style="color: #339933;">-</span>ln <span style="color: #ff0000;">&quot;miData&quot;</span> <span style="color: #339933;">-</span>at message <span style="color: #339933;">-</span>multi pSphere1<span style="color: #339933;">;</span>
addAttr <span style="color: #339933;">-</span>ln <span style="color: #ff0000;">&quot;miData&quot;</span> <span style="color: #339933;">-</span>at message <span style="color: #339933;">-</span>multi pSphere2<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// On cree les nodes de multiply divide auquels on donne une couleur</span>
createNode multiplyDivide<span style="color: #339933;">;</span>
createNode multiplyDivide<span style="color: #339933;">;</span>
createNode multiplyDivide<span style="color: #339933;">;</span>
&nbsp;
setAttr <span style="color: #ff0000;">&quot;multiplyDivide1.input1X&quot;</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>	<span style="color: #666666; font-style: italic;">// red</span>
setAttr <span style="color: #ff0000;">&quot;multiplyDivide1.input1Y&quot;</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
setAttr <span style="color: #ff0000;">&quot;multiplyDivide1.input1Z&quot;</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
setAttr <span style="color: #ff0000;">&quot;multiplyDivide2.input1X&quot;</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>	<span style="color: #666666; font-style: italic;">// green</span>
setAttr <span style="color: #ff0000;">&quot;multiplyDivide2.input1Y&quot;</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
setAttr <span style="color: #ff0000;">&quot;multiplyDivide2.input1Z&quot;</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
setAttr <span style="color: #ff0000;">&quot;multiplyDivide3.input1X&quot;</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>	<span style="color: #666666; font-style: italic;">// blue</span>
setAttr <span style="color: #ff0000;">&quot;multiplyDivide3.input1Y&quot;</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
setAttr <span style="color: #ff0000;">&quot;multiplyDivide3.input1Z&quot;</span> <span style="color: #0000dd;">1</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">// On cree un mib_data_shader</span>
createNode mib_data_shader<span style="color: #339933;">;</span>
createNode mib_data_shader<span style="color: #339933;">;</span>
&nbsp;
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_shader1.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;COLOR&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_shader2.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;COLOR&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Connect la couleur au node d'override</span>
connectAttr multiplyDivide1.<span style="color: #202020;">output</span> mib_data_shader1.<span style="color: #202020;">value</span><span style="color: #339933;">;</span>
connectAttr multiplyDivide2.<span style="color: #202020;">output</span> mib_data_shader2.<span style="color: #202020;">value</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Et on connecte les nodes d'override au premier élément
du tableau des attributs de l'objet */</span>
connectAttr mib_data_shader1.<span style="color: #202020;">message</span> pSphere1.<span style="color: #202020;">miData</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
connectAttr mib_data_shader2.<span style="color: #202020;">message</span> pSphere2.<span style="color: #202020;">miData</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">0</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">/* On créé les deux nodes d'override suivant
et on leur assigne une valeur */</span>
createNode mib_data_scalar<span style="color: #339933;">;</span>
createNode mib_data_scalar<span style="color: #339933;">;</span>
&nbsp;
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_scalar1.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;SCALAR&quot;</span><span style="color: #339933;">;</span>
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_scalar2.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;SCALAR&quot;</span><span style="color: #339933;">;</span>
&nbsp;
setAttr <span style="color: #ff0000;">&quot;mib_data_scalar1.value&quot;</span> <span style="color:#800080;">0.15</span><span style="color: #339933;">;</span>
setAttr <span style="color: #ff0000;">&quot;mib_data_scalar2.value&quot;</span> <span style="color:#800080;">0.25</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #808080; font-style: italic;">/* Puis on connecte les nodes d'override au second élément
du tableau des attributs de l'objet */</span>
connectAttr mib_data_scalar1.<span style="color: #202020;">message</span> pSphere1.<span style="color: #202020;">miData</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
connectAttr mib_data_scalar2.<span style="color: #202020;">message</span> pSphere2.<span style="color: #202020;">miData</span><span style="color: #009900;">&#91;</span><span style="color: #0000dd;">1</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">// Le material</span>
<span style="color: #808080; font-style: italic;">/* On cree le node qui récupérera
les shaders de couleurs par objet */</span>
createNode mib_data_get_shader_color<span style="color: #339933;">;</span>
&nbsp;
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_get_shader_color1.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;COLOR&quot;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Connect la valeur par défaut: bleu</span>
connectAttr multiplyDivide3.<span style="color: #202020;">output</span> mib_data_get_shader_color1.<span style="color: #b1b100;">default</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #808080; font-style: italic;">/* On cree le node qui récupérera
les valeurs scalaire par objet */</span>
createNode mib_data_get_scalar<span style="color: #339933;">;</span>
&nbsp;
setAttr <span style="color: #339933;">-</span>type <span style="color: #ff0000;">&quot;string&quot;</span> mib_data_get_scalar1.<span style="color: #202020;">name</span> <span style="color: #ff0000;">&quot;SCALAR&quot;</span><span style="color: #339933;">;</span>
setAttr mib_data_get_scalar1.<span style="color: #b1b100;">default</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">;</span>
&nbsp;
&nbsp;
<span style="color: #666666; font-style: italic;">// Cree le material et assigne aux sphères</span>
mrCreateCustomNode <span style="color: #339933;">-</span>asShader <span style="color: #ff0000;">&quot;&quot;</span> mia_material_x<span style="color: #339933;">;</span>
&nbsp;
select pSphere1 pSphere2 pSphere3<span style="color: #339933;">;</span>
hyperShade <span style="color: #339933;">-</span>assign mia_material_x1<span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// On met l'anisotropy à 0.1 pour voir l'effet</span>
setAttr <span style="color: #ff0000;">&quot;mia_material_x1.anisotropy&quot;</span> <span style="color:#800080;">0.1</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #666666; font-style: italic;">// Connection final des nodes de get au shader</span>
connectAttr mib_data_get_shader_color1.<span style="color: #202020;">outValue</span> mia_material_x1.<span style="color: #202020;">diffuse</span><span style="color: #339933;">;</span>
connectAttr mib_data_get_scalar1.<span style="color: #202020;">outValue</span> mia_material_x1.<span style="color: #202020;">anisotropy_rotation</span><span style="color: #339933;">;</span></pre>


<p>Et le rendu:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/mental_ray_3_9_Les_User_Data_Shaders_012.png" alt="mental_ray_3_9_Les_User_Data_Shaders_012.png" style="display:block; margin:0 auto;" title="mental_ray_3_9_Les_User_Data_Shaders_012.png, avr. 2011"  height="480" width="640" /></p>
<center><i>Remarquez comment chaque objet a une rotation de l'anisotropy différente</i></center>



<p>Et on peut faire ça sur tous les paramètres. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h3>Bonus <a name="bonus"></a></h3>


<p>Voici quelques images que j'avais <a href="http://forums.cgsociety.org/showthread.php?t=971291&amp;p=6944417">posté sur CGTalk</a> en montrant les connections. C'est le genre de references à avoir sous la mains.</p>


<p>Le système "de base" (color):</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/test_shaderAttrOverride001.png" alt="test_shaderAttrOverride001.png" style="display:block; margin:0 auto;" title="test_shaderAttrOverride001.png, avr. 2011"  height="480" width="640" /></p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/test_shaderAttrOverride002.png" alt="test_shaderAttrOverride002.png" style="display:block; margin:0 auto;" title="test_shaderAttrOverride002.png, avr. 2011"  height="250" width="632" /></p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/test_shaderAttrOverride003.png" alt="test_shaderAttrOverride003.png" style="display:block; margin:0 auto;" title="test_shaderAttrOverride003.png, avr. 2011"  height="391" width="420" /></p>


<p>Les multi attritbutes <em>miData</em>:</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/test_shaderAttrOverride004.png" alt="test_shaderAttrOverride004.png" style="display:block; margin:0 auto;" title="test_shaderAttrOverride004.png, avr. 2011"  height="480" width="640" /></p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_04_13_mental_ray_3_9_Les_User_Data_Shaders/test_shaderAttrOverride005.png" alt="test_shaderAttrOverride005.png" style="display:block; margin:0 auto;" title="test_shaderAttrOverride005.png, avr. 2011"  height="318" width="874" /></p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/longBar.png" alt=":longBar:" class="smiley" /></center>



<h3>Conclusion <a name="conclusion"></a></h3>


<p>J'espère que vous aurez apprécié ce speed billet (pas si speed que ça en fait...). Et que vous saurez maintenant qu'il existe une astuce qui peut vous dépanner (voir plus si intelligemment utilisé).</p>


<p>Il faudra que j'éssai de voir si ça tiens la charge... <img src="/blog/themes/blueSilenceCustom/smilies/evilgrin0002.gif" alt=":gniarkgniark:" class="smiley" /></p>


<p>Autodesk nous a habitué au fil de ses releases à devoir bidouiller comme un porc pour avoir accès à certaines fonctionnalités de mental ray.</p>


<p>Maya 2012 ne déroge pas à la règle et la nouveauté "User Data Shaders" est sans doute LA feature de sur lesquels des nerds (moi?) peuvent se brosser en se disant "Cool! Il ne m'a fallu que deux soirées pour pouvoir l'utiliser" pendant que d'autres seront en train de faire des images, des vrais avec également les dernières features de leur package de rendu favoris... Sans douleurs ni rien...</p>


<p>Ouai... Faut aimer se faire du mal pour utiliser mental ray dans Maya. <img src="/blog/themes/blueSilenceCustom/smilies/nexath.gif" alt=":smileFou:" class="smiley" /></p>


<p>Pourtant, j'adore! <img src="/blog/themes/blueSilenceCustom/smilies/siffle.gif" alt=":siffle:" class="smiley" /></p>


<p>N'hésitez pas à me signaler si un code fournit ne fonctionne pas. <img src="/blog/themes/blueSilenceCustom/smilies/mechantCrash.gif" alt=":mechantCrash:" class="smiley" /></p>


<p>Pour info. Il y a peut être <a href="http://forum.mentalimages.com/showthread.php?p=32500#post32500">un espoir</a> que mental image récupère l'intégration de mental ray dans Maya. Mais rien n'est moins sûr et si ça se fait, ça ne sera pas pour tout de suite...</p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></center>



<p><strong>MAJ 2011-05-11</strong>: Je viens d'installer Le Hotfix de Maya 2012 et toujours aucune trace des userData dans un quelconque .mi...</p>


feed_id: urn:md5:abf47916c2d3468ca29e6f5228bc0cea
title: Petite astuce pour filtrer les nodes par attributs via la commande ls de Maya
uri: Petite-astuce-pour-filtrer-les-nodes-par-attributs-via-la-commande-ls
url:
http://www.fevrierdorian.com/blog/post/2011/04/15/Petite-astuce-pour-filtrer-les-nodes-par-attributs-via-la-commande-ls-de-Maya

content:
<p><img src="http://www.fevrierdorian.com/blog/public/logos/pythonVsMaya_tn150.png" alt="pythonVsMaya_tn150.png" style="float:left; margin: 0 1em 1em 0;" title="pythonVsMaya_tn150.png, oct. 2010"  height="150" width="150" />Billet express: Je viens de découvrir une façon d'utiliser la commande ls que je ne connaissais pas. C'était pourtant évidant. <img src="/blog/themes/blueSilenceCustom/smilies/casseTeteMur.gif" alt=":casseTeteMur:" class="smiley" /></p>


<p>La technique consiste à utiliser * dans le nom de l'objet...</p>


<p>Bon, ça je le savais déjà. Mais là ou ça devient intéressant, c'est quand il s'agit de récupérer tous les objets ayant un attribut bien spécifique.</p>


<p>Cela évite d'avoir à utiliser une boucle! <img src="/blog/themes/blueSilenceCustom/smilies/sauteJoie.gif" alt=":sauteJoie:" class="smiley" /></p>    <p>Je vous propose de voir quelques cas d'utilisation.</p>


<h3>Exemples</h3>


<p>Récupérer tous les objets de la scène ayant l'attribut "message":</p>
<pre class="python python"><span style="color: #dc143c;">cmds</span>.<span style="color: black;">ls</span><span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;*.message&quot;</span> <span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;"># Result: [u'node1.message', u'node2.message', u'node3.message', u'node4.message' ]</span></pre>


<p>Masquer les noms des attributs dans les valeurs renvoyées:</p>
<pre class="python python"><span style="color: #dc143c;">cmds</span>.<span style="color: black;">ls</span><span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;*.message&quot;</span>, objectsOnly=<span style="color: #008000;">True</span> <span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;"># Result: [u'node1', u'node2', u'node3', u'node4' ]</span></pre>


<p>Vous remarquerez peut être que ces deux exemples ne renvoient aucun objet dans un namespace.</p>


<p>Pour également vérifier les objets dans les namespaces:</p>
<pre class="python python"><span style="color: #dc143c;">cmds</span>.<span style="color: black;">ls</span><span style="color: black;">&#40;</span> <span style="color: #483d8b;">&quot;*.message&quot;</span>, objectsOnly=<span style="color: #008000;">True</span>, recursive=<span style="color: #008000;">True</span> <span style="color: black;">&#41;</span>
<span style="color: #808080; font-style: italic;"># Result: [u'ns1:node1', u'ns2:node1', u'node2', u'node3' ]</span></pre>


<p>Et voilà!</p>


<h3>Conclusion</h3>


<p>J'espère que ce petit billet vous aura appris un truc.</p>


<p>Personnellement, depuis, je n'utilise plus que ça! <img src="/blog/themes/blueSilenceCustom/smilies/banane-jaune.gif" alt=":banaeyouhou:" class="smiley" /></p>


<p>A bientôt!</p>


<p>Dorian</p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></center>


feed_id: urn:md5:912013d3913b678655c3562e58a746b3
title: Récupérer rapidement la position des vertices d'un mesh Maya
uri: Récupérer-rapidement-la-position-des-vertices-d-un-mesh-Maya
url:
http://www.fevrierdorian.com/blog/post/2011/03/30/Recuperer-rapidement-la-position-des-vertices-d-un-mesh-Maya

content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2011_03_30_Recuperer_Position_Vertex_Rapidement/recuperer_Position_Vertex_Rapidement_tn.png" alt="recuperer_Position_Vertex_Rapidement_tn.png" style="float:left; margin: 0 1em 1em 0;" title="recuperer_Position_Vertex_Rapidement_tn.png, mar. 2011"  height="150" width="150" />Si vous avez déjà été amené à récupérer la position dans l'espace de tous les vertices d'un objet, vous avez surement dû vous heurter à la commande <em>xform</em> et à sa lenteur légendaire. <img src="/blog/themes/blueSilenceCustom/smilies/baffed.gif" alt=":baffed:" class="smiley" /></p>


<p>Dans ce billet, je vous propose un petit bout de script Python utilisant l'API Maya en Python qui permet de récupérer, plus rapidement, la liste de toutes les positions des vertices d'un objet.</p>


<p>Principalement didactique, ces codes, pourront intéresser les personnes qui souhaitent regarder un peu plus profondément comment utiliser l'API tout en ayant un cas concret d'application. <img src="/blog/themes/blueSilenceCustom/smilies/laClasse.gif" alt=":laClasse:" class="smiley" /></p>    <h3>En utilisant xform</h3>


<p>Voici la version du script qui utilise la commande <a href="http://download.autodesk.com/us/maya/2011help/Commands/xform.html">xform</a>:</p>

<pre class="python python"><span style="color: #ff7700;font-weight:bold;">def</span> getVtxPos<span style="color: black;">&#40;</span> shapeNode <span style="color: black;">&#41;</span> :
&nbsp;
	vtxWorldPosition = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>    <span style="color: #808080; font-style: italic;"># contiendra les positions dans l'espace de tout les vertex de l'objet</span>
&nbsp;
	vtxIndexList = <span style="color: #dc143c;">cmds</span>.<span style="color: black;">getAttr</span><span style="color: black;">&#40;</span> shapeNode+<span style="color: #483d8b;">&quot;.vrts&quot;</span>, multiIndices=<span style="color: #008000;">True</span> <span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> vtxIndexList :
		curPointPosition = <span style="color: #dc143c;">cmds</span>.<span style="color: black;">xform</span><span style="color: black;">&#40;</span> <span style="color: #008000;">str</span><span style="color: black;">&#40;</span>shapeNode<span style="color: black;">&#41;</span>+<span style="color: #483d8b;">&quot;.pnts[&quot;</span>+<span style="color: #008000;">str</span><span style="color: black;">&#40;</span>i<span style="color: black;">&#41;</span>+<span style="color: #483d8b;">&quot;]&quot;</span>, query=<span style="color: #008000;">True</span>, translation=<span style="color: #008000;">True</span>, worldSpace=<span style="color: #008000;">True</span> <span style="color: black;">&#41;</span>    <span style="color: #808080; font-style: italic;"># [1.1269192869360154, 4.5408735275268555, 1.3387055339628269]</span>
		vtxWorldPosition.<span style="color: black;">append</span><span style="color: black;">&#40;</span> curPointPosition <span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #ff7700;font-weight:bold;">return</span> vtxWorldPosition</pre>


<h3>La version avec l'API Maya</h3>


<p>Alternative à xform.</p>

<pre class="python python"><span style="color: #ff7700;font-weight:bold;">import</span> maya.<span style="color: #dc143c;">OpenMaya</span> <span style="color: #ff7700;font-weight:bold;">as</span> <span style="color: #dc143c;">OpenMaya</span>
&nbsp;
<span style="color: #ff7700;font-weight:bold;">def</span> particleFillSelection<span style="color: black;">&#40;</span>  <span style="color: black;">&#41;</span>:
&nbsp;
	<span style="color: #808080; font-style: italic;"># get the active selection</span>
	selection = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MSelectionList</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
	<span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MGlobal</span>.<span style="color: black;">getActiveSelectionList</span><span style="color: black;">&#40;</span> selection <span style="color: black;">&#41;</span>
	iterSel = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MItSelectionList</span><span style="color: black;">&#40;</span>selection, <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFn</span>.<span style="color: black;">kMesh</span><span style="color: black;">&#41;</span>
&nbsp;
	<span style="color: #808080; font-style: italic;"># go througt selection</span>
	<span style="color: #ff7700;font-weight:bold;">while</span> <span style="color: #ff7700;font-weight:bold;">not</span> iterSel.<span style="color: black;">isDone</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>:
&nbsp;
		<span style="color: #808080; font-style: italic;"># get dagPath</span>
		dagPath = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MDagPath</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
		iterSel.<span style="color: black;">getDagPath</span><span style="color: black;">&#40;</span> dagPath <span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #808080; font-style: italic;"># create empty point array</span>
		inMeshMPointArray = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MPointArray</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #808080; font-style: italic;"># create function set and get points in world space</span>
		currentInMeshMFnMesh = <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MFnMesh</span><span style="color: black;">&#40;</span>dagPath<span style="color: black;">&#41;</span>
		currentInMeshMFnMesh.<span style="color: black;">getPoints</span><span style="color: black;">&#40;</span>inMeshMPointArray, <span style="color: #dc143c;">OpenMaya</span>.<span style="color: black;">MSpace</span>.<span style="color: black;">kWorld</span><span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #808080; font-style: italic;"># put each point to a list</span>
		pointList = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span>
&nbsp;
		<span style="color: #ff7700;font-weight:bold;">for</span> i <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">range</span><span style="color: black;">&#40;</span> inMeshMPointArray.<span style="color: black;">length</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> <span style="color: black;">&#41;</span> :
&nbsp;
			pointList.<span style="color: black;">append</span><span style="color: black;">&#40;</span> <span style="color: black;">&#91;</span>inMeshMPointArray<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>, inMeshMPointArray<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">1</span><span style="color: black;">&#93;</span>, inMeshMPointArray<span style="color: black;">&#91;</span>i<span style="color: black;">&#93;</span><span style="color: black;">&#91;</span><span style="color: #ff4500;">2</span><span style="color: black;">&#93;</span><span style="color: black;">&#93;</span> <span style="color: black;">&#41;</span>
&nbsp;
		<span style="color: #ff7700;font-weight:bold;">return</span> pointList</pre>


<blockquote><p>Note j'ai pensé qu'en spécifiant la taille de la liste dès le départ on gagnerait encore du temps mais ça ne change rien. Il semblerait que <a href="http://stackoverflow.com/questions/311775/python-create-a-list-with-initial-capacity">Python gère ça bien</a>. Du coup, j'ai appris un nouveau dicton: <em>Premature optimization is the root of all evil</em>. <img src="/blog/themes/blueSilenceCustom/smilies/evilgrin0002.gif" alt=":gniarkgniark:" class="smiley" /></p></blockquote>


<h3>Les temps</h3>

<p>Bon, c'est bien beau de dire que c'est plus rapide. Mais de combien? <img src="/blog/themes/blueSilenceCustom/smilies/reflexionIntense.gif" alt=":reflexionIntense:" class="smiley" /></p>


<p>Voici les temps que j’obtiens pour une pSphere 50x50 smoothée 4 (soit 633602 vertices):</p>
<ul>
<li>Avec xform: 39 sec</li>
<li>Avec l'API Python de Maya: 4 sec</li>
</ul>

<p>10x plus rapide mine de rien. Ça me donnerait presque envie de le coder en C++, juste pour voir! <img src="/blog/themes/blueSilenceCustom/smilies/1420.gif" alt=":grenadelauncher:" class="smiley" /></p>


<h3>Conclusion</h3>


<p>Bon, et bien maintenant c'est à vous de voir quoi en tirer.</p>


<p>Vous pouvez essayer d'optimiser <a href="http://www.fevrierdorian.com/blog/post/2011/03/14/Remplir-un-mesh-de-spheres-dans-Maya-La-methode-d-un-senior">l’algorithme de Djelloul</a> et me faire part de vos résultats! <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p>


<p>Toujours est t'il que personnellement, je ne pourrais plus me passer de l'API si j'ai à récupérer la position des vertices d'un mesh c'est beaucoup plus rapide! Moyennant une complexité supérieur, je veux bien l'avouer, mais quand on a ce bout de code, on le garde et on le ressort au bon moment! <img src="/blog/themes/blueSilenceCustom/smilies/aupoil.gif" alt=":aupoil:" class="smiley" /></p>


<p>A bientôt!</p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></center>


feed_id: urn:md5:ad3b04d6d82f1d6616825258a2f871db
title: Neo N64 Myth: Douleur, pleurs, joie!
uri: Neo-N64-Myth-Douleur-pleurs-joie
url: http://www.fevrierdorian.com/blog/post/2012/09/30/Neo-N64-Myth-Douleur-pleurs-joie
content:
<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/IMG_2231_tn.jpg" alt="IMG_2231_tn.jpg" style="float:left; margin: 0 1em 1em 0;" title="IMG_2231_tn.jpg, sept. 2012"  height="150" width="150" />Et un petit billet détente pour vous parler non pas de pipeline mais de <a href="http://fr.wikipedia.org/wiki/Retrogaming" hreflang="fr">retrogaming</a> et plus spécifiquement d'une console qui me tiens particulièrement à cœur: La Nintendo 64. <img src="/blog/themes/blueSilenceCustom/smilies/yeoh.gif" alt=":dentcasse:" class="smiley" /></p>


<p>Ici je vais vous parler du <em>Neo N64 Myth</em> et des galères que j'ai rencontrées en l'utilisant.</p>


<p>On est déjà loin des problématiques de displacement mapping et de render pass là!</p>    <h3>Ma vie</h3>

<p>Ma première console fut la Super Nintendo (SNES). Je vous passe la nostalgie des interminables parties de <a href="http://www.sitesnes.com/test/ptl$$Super_Mario_World$$Elie46.htm" hreflang="fr">Super Mario World</a>/<a href="http://www.sitesnes.com/test/crs$$Super_Mario_Kart$$Elie46.htm" hreflang="fr">Super Mario Kart</a>/<a href="http://www.scrolling.fr/test-international-superstar-deluxe-snes/2011/03/15" hreflang="fr">ISS Deluxe</a>/<a href="http://www.sitesnes.com/test/ptl$$Donkey_Kong_Country$$Elie46.htm" hreflang="fr">Donkey Kong Country</a>/etc... Quelques années plus tard, nous achetâmes une Nintendo 64 (N64) qui restera surement la console sur laquelle je passa (perdis? <img src="/blog/themes/blueSilenceCustom/smilies/seSentCon.gif" alt=":seSentCon:" class="smiley" /> ) le plus de temps.</p>


<p>Début 2010, l'envie me revint de faire une partie de Super Mario 64. <img src="/blog/themes/blueSilenceCustom/smilies/0010.gif" alt=":joue:" class="smiley" /> La recherche d'un émulateur open source de qualité m'amena à <a href="http://code.google.com/p/mupen64plus/" hreflang="en">mupen64plus</a> sur lequel je codais brièvement. Puis à la suite d'une bonne affaire sur Priceminister je me rachetais quelques titres (le marché de l'occasion de la N64 étant bien fourni et très accessible financièrement parlant).</p>


<p>Vivant à Paris, j'ai pris l'habitude d’économiser l'espace et un énième joujou, aussi nécessaire soit il (forcement <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /> ), n'allait pas dans ce sens. Je me suis donc demandé si il n'existait pas un moyen d'avoir tout ses jeux sur une seule et même cartouche.</p>


<p>Ceci m'amena sur le chemin tortueux des linkers N64 (le mot est lâché).</p>


<h3>Linkers N64?</h3>


<p>En fait, il y en a eu très peu (ça change doucement, le retrogaming étant un vrai marché) et ça existe depuis longtemps, c'est juste cher et introuvable.</p>


<p>Le premier fut le <a href="http://en.wikipedia.org/wiki/Doctor_V64" hreflang="en">Doctor V64</a> (ou V64) sorti grosso modo en même temps que la N64 (1996):</p>


<p><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/Dv64-n64.jpg" alt="Dv64-n64.jpg" style="display:block; margin:0 auto;" title="Dv64-n64.jpg, sept. 2012"  height="406" width="412" /></p>
<center><i>V'la le pavé!</i></center>


<p>Review en français <a href="http://www.gamekult.com/blog/jimmy130/143714/essai-du-linker-nintendo-64-doctor-v64-junior.html" hreflang="fr">ici</a>.</p>


<p>Le second fut <a href="http://en.wikipedia.org/wiki/Z64" hreflang="en">Mr. Backup Z64</a> (ou Z64):</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/Z64-1.jpg" title="Z64-1.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.Z64-1_m.jpg" alt="Z64-1.jpg" style="display:block; margin:0 auto;" title="Z64-1.jpg, sept. 2012"  height="462" width="560" /></a></p>
<center><i>Très jolie sur une cheminée...</i></center>



<blockquote><p>Notez que si vous avez déjà eu affaire à des roms de jeux N64, vous avez surement déjà dut tomber sur les extensions .z64 et .v64. Ces extensions viennent de la machine qui a servi à "dumper" les cartouches. Les roms .v64 ayant l'alignement des bits du Doctor V64 (<a href="http://fr.wikipedia.org/wiki/Endianness#Little_endian" hreflang="en">little endian</a>) et les .z64 l'alignement des bits du Mr. Backup Z64 (<a href="http://fr.wikipedia.org/wiki/Endianness#Big_endian" hreflang="en">big endian</a>). Ça vous la coupe hein! <img src="/blog/themes/blueSilenceCustom/smilies/yeoh.gif" alt=":dentcasse:" class="smiley" /></p></blockquote>


<p>En dehors de ces deux gros objets qui ne sont plus fabriqués depuis longtemps, sont très rare et donc hors de prix, il n'y avait rien. Nada. Que dalle. Peanut. Peau de balle. <img src="/blog/themes/blueSilenceCustom/smilies/triste.gif" alt=":triste:" class="smiley" /></p>


<p>Mais les choses ont changé avec l'arrivée du <a href="https://en.wikipedia.org/wiki/NEO_N64_Myth_Cart" hreflang="en">Neo N64 Myth</a>. D’après mes recherches, il semble qu'ils bossaient déjà dessus <a href="http://gueux-forum.net/index.php?showtopic=165341&amp;view=findpost&amp;p=1141290" hreflang="fr">en 2006</a>!</p>


<p>C'est un produit qui s'est fait attendre et qui est sorti pile-poil au moment ou j'en cherchais un...</p>


<h3>Neo N64 Myth, c'est bien?</h3>

<p>Autant le dire tout de suite: C'est galère! Si vous comptez brancher vos jeux, vous affaler dans votre canapé à tapoter le bouton <em>START</em> d'impatience avec un paquet de chips entre les jambes vous n'y êtes pas du tout! Sérieusement, il marche impeccablement bien mais le temps nécessaire pour le rendre utilisable et la douleur qu'il a fallu est sans nom. <img src="/blog/themes/blueSilenceCustom/smilies/nervous.gif" alt=":nervous:" class="smiley" /></p>


<p>Pour comprendre pourquoi tant de pleurs, il faut revoir l'historique de ce linker, que j'ai subi, bien malgré moi...</p>


<p>Quand le <em>Neo N64 Myth</em> est sorti, c’était une hardware "vide". Juste un truc avec des connecteurs qui pouvait faire booter des roms N64... Un truc cher pour bidouilleurs avertis.</p>


<p>Comme je suis du genre tête brulée (c'est pas toujours une qualité hein! <img src="/blog/themes/blueSilenceCustom/smilies/nannan.gif" alt=":nannan:" class="smiley" /> ), je me suis renseigné vite fait, ça avait l'air de marcher, j'ai foncé!</p>


<p>Quand j'ai reçu le bouzin, j'ai vite déchanté. Aucun manuel, aucune doc, rien! Les adeptes du retrogaming sont surement habitués à recevoir des bidules électroniques sans mode d'emploi mais ça fait quand même tout drôle quand on voit le prix. <img src="/blog/themes/blueSilenceCustom/smilies/bete.gif" alt=":bete:" class="smiley" /></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/NEON64MythCartPackaging.jpg" title="NEON64MythCartPackaging.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.NEON64MythCartPackaging_m.jpg" alt="NEON64MythCartPackaging.jpg" style="display:block; margin:0 auto;" title="NEON64MythCartPackaging.jpg, sept. 2012"  height="560" width="420" /></a></p>
<center><i>Avouez que ça ne donne pas confiance pour la suite...</i> <img src="/blog/themes/blueSilenceCustom/smilies/seSentCon.gif" alt=":seSentCon:" class="smiley" /></center>



<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/IMG_2223.jpg" title="IMG_2223.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.IMG_2223_m.jpg" alt="IMG_2223.jpg" style="display:block; margin:0 auto;" title="IMG_2223.jpg, sept. 2012"  height="373" width="560" /></a></p>
<center><i>Au moins on ne peut pas leur reprocher de claquer de la tune en marketing...</i></center>



<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/IMG_2225.jpg" title="IMG_2225.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.IMG_2225_m.jpg" alt="IMG_2225.jpg" style="display:block; margin:0 auto;" title="IMG_2225.jpg, sept. 2012"  height="373" width="560" /></a></p>
<center><i>Le slot pour brancher la mémoire flash (on y reviendra), le connecteur USB à gauche et un bouton inutile à droite.</i></center>



<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/IMG_2224.jpg" title="IMG_2224.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.IMG_2224_m.jpg" alt="IMG_2224.jpg" style="display:block; margin:0 auto;" title="IMG_2224.jpg, sept. 2012"  height="373" width="560" /></a></p>
<center><i>Et un slot pour brancher une cartouche N64 d'origine.</i></center>



<blockquote><p>Sur cette dernière image, je vais parler d'un point qui me semble important: Pour lutter contre le piratage, Nintendo a toujours utilisé des puces "certifiées" (dont le fonctionnement était gardé secret) intégrées aux cartouches. Bien qu'il semble que des bidouilleurs aient <a href="http://www.emutalk.net/threads/53217-N64-PIF-CIC-NUS-6105-Algorithm-Finally-Reversed" hreflang="en">récemment</a> réussi à émuler certaines de ces puces par <a href="https://fr.wikipedia.org/wiki/R%C3%A9troing%C3%A9nierie" hreflang="fr">rétroingénierie</a>, il n'y a pour l'instant pas beaucoup de possibilités pour réussir à booter un programme sur la N64... C'est la raison pour laquelle vous devez brancher un jeu officiel. Juste pour pouvoir faire booter le linker. <img src="/blog/themes/blueSilenceCustom/smilies/sourit.gif" alt=":sourit:" class="smiley" /></p></blockquote>


<p>Je me suis donc mis à déambuler sur le <a href="http://www.neoflash.com/forum/" hreflang="en">forum officiel</a> (qui ramait comme pas permis à l’époque) et commençais à me faire la main sur le truc.</p>


<p>Comme vous le savez (ou pas, dans ce cas vous allez apprendre des choses <img src="/blog/themes/blueSilenceCustom/smilies/hehe.gif" alt=":hehe:" class="smiley" /> ), la N64 utilise des cartouches à base de mémoire flash pour avoir un accès rapide aux données (pas de loading sur N64!).</p>


<p>La team à l'origine du <em>Neo N64 Myth</em> a donc décidé de séparer le hardware flash du circuit principale (une bonne chose) et de livrer la cartouche avec un "bloc" de mémoire flash (le machin blanc sur l'image) de 512Mb, soit 64Mo ce qui est très peu si vous comptez mettre toutes vos roms dessus. La ou ils n'ont pas été malin (ça peut se comprendre, ils ont été les premiers et ont donc eu à "tâter" le marché), c'est qu'il n'y a pas de slot pour carte SD ou de truc simple à manipuler, juste une mémoire flash brute.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/IMG_2222.jpg" title="IMG_2222.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.IMG_2222_m.jpg" alt="IMG_2222.jpg" style="display:block; margin:0 auto;" title="IMG_2222.jpg, sept. 2012"  height="373" width="560" /></a></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/IMG_2220.jpg" title="IMG_2220.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.IMG_2220_m.jpg" alt="IMG_2220.jpg" style="display:block; margin:0 auto;" title="IMG_2220.jpg, sept. 2012"  height="373" width="560" /></a></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/IMG_2227.jpg" title="IMG_2227.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.IMG_2227_m.jpg" alt="IMG_2227.jpg" style="display:block; margin:0 auto;" title="IMG_2227.jpg, sept. 2012"  height="373" width="560" /></a></p>


<p>Le problème c'est que mettre une rom la dessus relève du chemin de croix. <img src="/blog/themes/blueSilenceCustom/smilies/1420.gif" alt=":grenadelauncher:" class="smiley" /> Il faut utiliser un soft moisi avec des drivers moisis qui chient dans la colle avec Vista et plus (oui, sur le forum officiel on m'a conseillé d’utiliser XP... <img src="/blog/themes/blueSilenceCustom/smilies/riva.gif" alt=":pasClasse:" class="smiley" /> ). Bref, c'est dur, très dur.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/Neo2_Ultra_Menu_N64.png" title="Neo2_Ultra_Menu_N64.png"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.Neo2_Ultra_Menu_N64_m.jpg" alt="Neo2_Ultra_Menu_N64.png" style="display:block; margin:0 auto;" title="Neo2_Ultra_Menu_N64.png, sept. 2012"  height="389" width="560" /></a></p>
<center><i>Le premier soft.</i></center>



<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/Neo2_Pro_Manager_N64.png" title="Neo2_Pro_Manager_N64.png"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.Neo2_Pro_Manager_N64_m.jpg" alt="Neo2_Pro_Manager_N64.png" style="display:block; margin:0 auto;" title="Neo2_Pro_Manager_N64.png, sept. 2012"  height="350" width="560" /></a></p>
<center><i>Le second...</i></center>



<p>Les choses ont évolué au fil du temps et un nouveau produit est sorti: Le <a href="http://www.ic2005.com/shop/product.php?productid=119&amp;cat=0&amp;featured=Y" hreflang="en">NEO2 Pro 1024M Flash Cart</a>.</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/IMG_2228.jpg" title="IMG_2228.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.IMG_2228_m.jpg" alt="IMG_2228.jpg" style="display:block; margin:0 auto;" title="IMG_2228.jpg, sept. 2012"  height="373" width="560" /></a></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/IMG_2229.jpg" title="IMG_2229.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.IMG_2229_m.jpg" alt="IMG_2229.jpg" style="display:block; margin:0 auto;" title="IMG_2229.jpg, sept. 2012"  height="373" width="560" /></a></p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/IMG_2230.jpg" title="IMG_2230.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.IMG_2230_m.jpg" alt="IMG_2230.jpg" style="display:block; margin:0 auto;" title="IMG_2230.jpg, sept. 2012"  height="373" width="560" /></a></p>
<center><i>C'est Inception...</i></center>



<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/IMG_2231.jpg" title="IMG_2231.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.IMG_2231_m.jpg" alt="IMG_2231.jpg" style="display:block; margin:0 auto;" title="IMG_2231.jpg, sept. 2012"  height="373" width="560" /></a></p>
<center><i>La cartouche dans la cartouche dans la...</i></center>



<p>Ce produit est une mémoire flash qui dispose d'un slot pour carte SD. Bien entendu, un second passage en caisse est nécessaire (de toute façon, le retrogaming c'est un truc de riche! <img src="/blog/themes/blueSilenceCustom/smilies/redface.gif" alt=":redface:" class="smiley" /> ).</p>


<p>Avec lui est livré le "USB SlimLoader IV". Un truc qu'on est sensé utiliser pour brancher le <em>Neo2 Pro</em> sur son PC mais qui n'a jamais marché chez moi (on peut utiliser directement le <em>Neo N64 Myth</em> à la place)...</p>


<p>Le dev: ChillyWilly (je n'ai aucune idée de si il s'agit d'un dev de l’équipe principale mais il est en tout cas très respecté) proposa donc ce qui aurait du être en standard depuis le début: Un menu directement sur la N64 qui va chercher les roms sur la carte SD, les copie dans la mémoire flash de la carte et lance le jeu! (Rien que de le dire ça fait du bien).</p>


<p>Mais voila, à force de développer son menu, il se retrouva bloqué par le design du firmware du <em>Neo N64 Myth</em>. Qu'a cela ne tienne, la team qui écoutait ces remarques, proposa un nouveau firmware pour la carte... Le problème c'est que pour pouvoir flasher sa carte, il faut encore acheter quelque chose: Le <a href="http://www.ic2005.com/shop/product.php?productid=98&amp;cat=0&amp;featured=Y" hreflang="en">Neo Dual Programmer</a>. (Putain mais... <img src="/blog/themes/blueSilenceCustom/smilies/1420.gif" alt=":grenadelauncher:" class="smiley" /> ).</p>


<p><a href="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/IMG_2236.jpg" title="IMG_2236.jpg"><img src="http://www.fevrierdorian.com/blog/public/billets/2012_09_29_Neo_N64_Myth/.IMG_2236_m.jpg" alt="IMG_2236.jpg" style="display:block; margin:0 auto;" title="IMG_2236.jpg, sept. 2012"  height="373" width="560" /></a></p>


<p>Et si vous voulez avoir une idée de la procédure:</p>

<div class="external-media" style="margin: 1em auto; text-align: center;">
<iframe width="480" height="360" src="http://www.youtube.com/embed/T2DNRSAjJ2s" frameborder="0" allowfullscreen></iframe>
</div>




<p>Elle est encore loin la partie de Mario Kart 64 dans mon canap'... T_T</p>


<p>Mais on commence à voir le bout <del>de notre compte bancaire</del>. Encore une fois, rien n'est expliqué nulle part et on chope les infos et les binaires sur le forum. D'ailleurs, pour les <del>heureux</del> possesseurs de ce linker, je vous conseille de suivre cette <a href="http://www.neoflash.com/forum/index.php/topic,6273.0.html" hreflang="en">FAQ</a>. Elle est très bien faite, très bien expliqué. Dès que je dois faire une modif sur le truc je repasse par là.</p>


<p>Le dernier soucis que j'ai eu a failli définitivement me décourager (en fait il m'a découragé quelques mois). J'ai <a href="http://www.neoflash.com/forum/index.php/topic,7430.msg53471.html#msg53471" hreflang="en">trouvé la solution</a> récemment après une énième tentative et ça m'a fait bien bizarre:</p>


<blockquote><p>Si vous branchez le <em>Neo2 Pro</em> trop "fort" sur le <em>Neo N64 Myth</em> (jusqu'au "click" qui peut naturellement vous faire croire que "c'est bon!"), il n'est plus reconnu par votre PC... En fait, il est reconnu une fraction de seconde et s’éteint directement après. Personne d'autre ne semble avoir eu le soucis et je suis bien content d'avoir trouvé le truc. Mais voila... Encore une fois: Galère...</p></blockquote>


<h3>Pourquoi je vous parle de tout ça?</h3>

<p>C'est une question qu'on peut se poser... Si le <em>Neo N64 Myth</em> est si mauvais que ça, pourquoi en parler? <img src="/blog/themes/blueSilenceCustom/smilies/whistle2.gif" alt=":jdicajdirien:" class="smiley" /></p>


<p>Et bien parce qu'une fois que vous avez fait le plus dur: Ça marche! Vous mettez vos backups de jeu sur votre carte SD, vous branchez le tout ensemble, vous allumez et vous <em>enjoyez</em>! (J'adore cet anglicisme!).</p>


<p>Le second point, et pas des moindres, c'est que le succès du <em>Neo N64 Myth</em> malgré le prix a lancé pas mal de team sur des projets similaires.</p>


<p>Il semble que les plus connus soient:</p>
<ul>
<li>Le <a href="http://krikzz.com/index.php?route=product/product&amp;product_id=54" hreflang="en">Everdrive 64</a>. Fait par une team qui à l'habitude des linkers. Il y a une review et des infos sur <a href="http://www.metagames-eu.com/forums/oldies/everdrive-64-a-128711.html" hreflang="fr">un thread</a> du forum Metagames.</li>
<li>Le <a href="http://64drive.retroactive.be/" hreflang="en">64drive</a>. Ressemble beaucoup au Everdrive 64 dans le principe. Notez que c'est le même gars qui a lancé une campagne de fond pour faire une radio au rayon X des puces CIC 6102, 6105 et PIF de la N64 par <a href="http://decap.mameworld.info/" hreflang="en">Dr Decap</a>. Il semble être tout seul sur ce projet mais pour m’intéresser depuis longtemps à la N64 et son émulation, ce n'est pas la première fois que j’entends parler de ce mec.</li>
<li>Le <a href="http://www.ed64plus.com/" hreflang="en">ED64PLUS</a>. Aucune info la dessus. Je ne sais pas qui est derrière. Il semble très intéressant sur le papier mais je vous conseillerai d'attendre des retours avant de vous jeter dessus.</li>
</ul>

<p>En plus d’être constamment en rupture de stock, le <em>Everdrive 64</em> et le <em>64drive</em> proposent des modèles sans CIC, il faut bien <a href="http://shop.retrogate.com/EverDrive-64-v2-ED64.htm" hreflang="en">se renseigner</a> avant. Le <em>ED64PLUS</em> semble fonctionner comme le <em>Neo N64 Myth</em>. C'est donc à vous de brancher un jeux original disposant d'une puce CIC.</p>


<p>Le <em>Everdrive 64</em> et le <em>64drive</em> se valent. Le <em>ED64PLUS</em> semble être une pale copie des deux premiers. Le <em>Neo N64 Myth</em> est a oublier. Trop compliqué. Il aura eu le mérite d'être le premier du genre mais, en tant que tel, souffre de soucis de maturité.</p>


<p>Avec le recul, si je devais en prendre un maintenant, je choisirai le 64drive. Le (les?) gars de <a href="http://www.retroactive.be/" hreflang="en">Retroactive</a> est réputé et fiable. Dans tout les cas, s'inscrire sur un forum avec des users utilisant le même linker que vous ne sera pas du luxe si vous galérez.</p>


<h3>Intérêt</h3>

<p>L’intérêt de tels Linkers, est a relativiser.</p>


<p>Voici grosso modo mon avis:</p>


<p>Points positifs:</p>
<ul>
<li>Tous les jeux sur une seule cartouche, c'est un gain de place non négligeable.</li>
<li>La plupart du temps ces linkers offrent la possibilité de sauvegarder sur la carte SD ce qui permet de backuper ses saves sur son ordi.</li>
<li>Jouer à des <a href="http://www.romhacking.net/?page=hacks&amp;genre=&amp;platform=27&amp;hacksearch=Go" hreflang="en">roms hackées</a>. Certaines sont excellentes (<a href="http://www.youtube.com/watch?v=DaSMuON5-QU">Super Mario 74</a>, extrêmement difficile, et <a href="http://www.youtube.com/watch?v=Te4c4Am0LIs" hreflang="en">Goldeneye: X</a> le multi de Goldeneye avec le moteur de Perfect Dark et plus encore! <img src="/blog/themes/blueSilenceCustom/smilies/bravo.gif" alt=":bravo:" class="smiley" /> ).</li>
<li>Les anciens forums des joueurs de N64 se <a href="http://www.shootersforever.com/forums_message_boards/viewforum.php?f=46" hreflang="en">réveillent</a> et commencent doucement à parler de ces linkers.</li>
</ul>

<p>Points négatifs:</p>
<ul>
<li>Le prix. Le <em>Neo N64 Myth</em> était très cher (200$), même si une concurrence commence à apparaitre et que les prix vont surement descendre, ils restent élevés. Les prix des jeux N64 sont <a href="http://www.amazon.fr/s/ref=sr_hi_3?rh=n%3A530490%2Cn%3A!548014%2Cn%3A3327551%2Cn%3A548022&amp;bbn=548022&amp;ie=UTF8&amp;qid=1348764906" hreflang="fr">relativement bas</a> et il n'est pas rare de trouver des offres sur ebay de personnes cherchant à se débarrasser de leur collection. En cherchant bien vous devriez pouvoir récupérer <a href="http://www.reddit.com/r/n64/comments/zn6dv/rn64s_favorite_games_list_results/" hreflang="en">les</a> <a href="http://www.jeuxvideo.com/forums/1-9-7565575-1-0-1-0-votre-top-10-des-meilleurs-jeux-64.htm" hreflang="fr">principaux</a> <a href="http://retro-sanctuary.com/TOP%20100%20N64%20GAMES%20page%205.html" hreflang="en">titres</a> de la console pour moins de 100euros.</li>
<li>Le bidouillage. Encore une fois, plus il y aura de Linkers N64 qui apparaitront plus ils tendrons à être facile d’accès mais ils y a toujours deux trois petites choses à savoir.</li>
<li>Le <em>Neo N64 Myth</em> ne supporte pas la sauvegarde externe (celle sur *Controller Pack*) directement sur SD. Il faut donc avoir une carte mémoire pour les jeux la nécessitant (Top Gear Rally, ISS64, etc...).</li>
<li>Le prix.</li>
<li>Le prix.</li>
<li>Le prix.</li>
</ul>

<h3>Conclusion</h3>

<p>J’espère que ce petit billet vous aura apprit des choses et servira aux aficionados de la Nintendo 64 qui souhaiteraient s'y remettre.</p>


<p>A bientôt!</p>


<p>Dorian</p>

<center><img src="/blog/themes/blueSilenceCustom/smilies/marioCours.gif" alt=":marioCours:" class="smiley" /></center>



<h3>Liens intéressants</h3>
<ul>
<li><a href="http://64dd.net/modules/hardware/index.php?system=n64&amp;section=main&amp;id=46" hreflang="en">Review du Neo N64 Myth par 64dd.net</a></li>
<li><a href="http://www.dcemu.co.uk/vbulletin/threads/284897-Review-NEO-N64-Myth-Flash-Cart-SPEC-v2" hreflang="en">Review: NEO N64 Myth Flash Cart SPEC v2</a></li>
<li><a href="http://forums.benheck.com/viewtopic.php?f=5&amp;t=35583&amp;p=415099" hreflang="en">Dr Neo, The Myth 64 cart (nintendo 64 flash cart)</a>. Milieu de page.</li>
<li><a href="http://www.nesworld.com/n64-64drive-final.php" hreflang="en">The only Nintendo64 cartridge you'll ever need!</a></li>
</ul>


