PDA

Voir la version complète : Problème de rendu



tabou
19/01/2005, 13h48
Bonjour tous :odile:
Je suis en train de programmer une grille dans laquelle des anneaux apparaissent et disparaissent de façon aléatoire, à chaque image les anneaux sont créés ou effacés à la volée. Jusque là tout va bien, si je fais un preview dans l'éditeur les anneaux changent de place à chaque image. Si je fais le rendu "à la main", en avançant d'une image puis en lançant le rendu, ça marche aussi.
Le problème se pose lorsque je fais créer un aperçu ou le rendu définitif de l'animation : les anneaux ne bougent plus, c'est toujours la même image qui est calculée :roll:
J'ai placé ce code à la fin de la routine qui crée les objets et de celle qui les efface :

doc->MultiMessage(MSG_UPDATE);
GeEventAdd(REDRAW_ALL); mais ça ne change rien.
J'ai également jonglé avec les priorités dans tous les sens, sans succès. Si quelqu'un à une idée, parce que là je sèche complètement :(

Aurety
19/01/2005, 14h26
J'ai placé ce code à la fin de la routine qui crée les objets et de celle qui les efface :

doc->MultiMessage(MSG_UPDATE);
GeEventAdd(REDRAW_ALL);

c'est pas plutôt :

doc->MultiMessage(MSG_UPDATE);
GetEventAdd(REDRAW_ALL);

je dis ça, je dis rien, hein !! C'est juste que d'habitude on voit des get, pas des ge... :oops:

base80
19/01/2005, 14h31
la syntaxe de coffee est plutot bégayeur il y a des GeBaseDialog et d'autres, d'donc

GeEventAdd
GeExecuteFile
GeExeuteProgram
GeFileCopy
GeFileCreateDir
GeFileExist
GeFileKill
GeFileRename
GeGetByteOrder
GeGetCurrentOS
GeGetLineEnd
GeGetMovieFrameCount
GeGetMovieFrameRate
GeGetRootFilename
GeGetStartupPath
GeGetSysTime

tabou
19/01/2005, 14h36
Merci mon lapin mais si je met GetEventAdd(REDRAW_ALL); j'ai un message d'erreur :roll:

Kaldera Lake
19/01/2005, 14h41
Par hasar, ca ne serait pas un probleme de priorité du tag coffee? J'ai eu ça une fois... :roll: il faut trouver le bon reglage...

Tengaal
19/01/2005, 15h07
Le rafraichissement d'écran REDRAW_ALL, et les fonctions d'actualisation en général (MSG_UPDATE et autres...), ne sont pas super efficace depuis la version C4D 8, car l'architecture du soft est différente des versions précédentes.
J'ai notamment eu ce genre de soucis sur des plugins perso à monter sur C4D 8, les actualisations de matériaux par exemple, ne se font pas de manière aussi évidente et rapide que dans les versions antérieures de C4D. Comme si le code qui les génère passait en second plan... C'est C4D 8 qui décide quand le rafraichissement peut se faire, même si on a un code qui est sensé le forcer...
En fait les codes en Coffee ne s'éxécutent que lors d'une action dans C4D 8+ (le document s'actualise et en même temps on execute les scripts), alors que dans les versions antérieures, un script coffee s'exécute en permanence, donc les fonctions de rafraichissement sont forcément déclenchées de manière plus "forcée", puisque C4D 6-7 est "soumis" à ce script. Dans C4D 8+ c'est le contraire, C4D contrôle les scripts, c'est lui qui décide quand le code peut s'executer.

tabou
19/01/2005, 15h20
Merci pour tes explications Tengaal, je vais arrêter de perdre du temps, je vais plutôt tenter une autre approche en créant tous les objets à l'avance puis en jouant sur la visibilité. J'espère que ça marchera...

Majoul
22/01/2005, 21h53
Est ce que l’action qui exécute la création ou la suppression est liée à un DU.
Si c’est le cas, normalement d’après mes expériences on obtient le même résultat au rendu et pas besoin d'utiliser les fonctions d'actualisation .

tabou
28/01/2005, 14h06
:oops: Désolé de te répondre si tard, je n'avais pas vu ton message.
Je crée et j'efface les objets en comparant la valeur de deux tableaux, si les deux valeurs coïncident un objet est créé, dans le cas contraire, et si il existe, l'objet est supprimé.
La variable tirage est un tableau qui contient 6 variables aléatoires qui changent à chaque image, grille contient les nombres de 1 à 24.

while &#40;i<6&#41;
&#123;
while &#40;j<25&#41;
&#123;
switch &#40;tirage&#91;i&#93;==grille&#91;j&#93;&#41;
&#123;
case TRUE&#58;
affich&#40;i,j&#41;;
break;
case FALSE&#58;
efface&#40;i,j&#41;;
break;
&#125;
j=j+1;
&#125;
i = i+1;
j=0;
&#125;

Les fonctions qui créent et effacent les objets (j'ai enlevé les paramètres des container pour simplifier) :

affich&#40;x,y&#41;
&#123;
var nom = "anneau."+&#40;tostring&#40;x&#41;&#41;+&#40;tostring&#40;y&#41;&#41;+"G1";
var doc=GetActiveDocument&#40;&#41;;
var test=doc->FindObject&#40;nom&#41;;
if &#40;!test&#41;
&#123;
var extru = new&#40;ExtrudeObject&#41;;
var extruC = extru->GetContainer&#40;&#41;;
var parent=doc->FindObject&#40;"anneaux"&#41;;
extru->SetName&#40;nom&#41;;
extru->SetContainer&#40;extruC&#41;;
doc->InsertObject&#40;extru,parent,NULL&#41;;

var cercle = new&#40;SplineCircleObject&#41;;
var cercleC = cercle->GetContainer&#40;&#41;;
cercle->SetContainer&#40;cercleC&#41;;
doc->InsertObject&#40;cercle,extru,NULL&#41;;
doc->MultiMessage&#40;MSG_UPDATE&#41;;
&#125;
&#125;

efface&#40;x,y&#41;
&#123;
var doc=GetActiveDocument&#40;&#41;;
var nom = "anneau."+&#40;tostring&#40;x&#41;&#41;+&#40;tostring&#40;y&#41;&#41;+"G1";
var efface =doc->FindObject&#40;nom&#41;;
if &#40;!efface&#41; return;
efface->Remove&#40;&#41;;
doc->MultiMessage&#40;MSG_UPDATE&#41;;
return;
&#125;
Je viens de faire un essai en injectant une DU animée dans la routine d'affichage pour faire varier un décalage mais ça ne règle pas le problème :roll:

Tengaal
28/01/2005, 15h06
Je viens de relire ce sujet et je me demande si tu ne peux pas utiliser une autre méthode...
Enfin, si j'ai bien compris ce que tu souhaite faire, c'est à dire on a un anneau qui apparait, puis, il disparait puis un autre apparait puis disparait...

Dans ce cas là, si on a uniquement un anneau affiché, pourquoi ne pas gérer uniquement un anneau, et ensuite changer sa position, et contrôler sa visibilité avec :

anneau->SetEditorMode(MODE_ON); //visible dans l'editeur
anneau->SetEditorMode(MODE_OFF); //invisible dans l'editeur

anneau->SetRenderMode(MODE_ON); //visible au rendu
anneau->SetRenderMode(MODE_OFF); //invisible au rendu

MODE_ON = point vert
MODE_OFF = point rouge
MODE_UNDEF = point gris (defaut)

Je n'ai pas testé pour vérifier si ça passe au rendu de l'anim et je ne sais pas si ça convient à ce que tu cherches...
Mais ça me semble moins lourd que l'action de créer un objet puis de l'effacer par programme.

tabou
28/01/2005, 16h50
Non ce n'est pas tout à fait ça, en fait ce que je veux obtenir c'est ça :
http://tabou.free.fr/tabou/hasard.gif
Il peut y avoir jusqu'à 6 anneaux affichés simultanément.
Et j'ai une autre contrainte, il faut que je puisse contrôler le hasard et placer à un moment donné les anneaux dans des cases choisies à l'avance.

Tengaal
28/01/2005, 17h55
Et bien dans ce cas tu peux utiliser le même principe mais en utilisant un tableau pour stocker les pointeurs des 6x4 anneaux créés d'abord dans ton projet. (1 anneau par case)
Tu créés un tableau à 2 dimensions du genre :
var stock_objets=new(array,5,3); // colonnes 0 à 5 , lignes 0 à 3

Au début de ton script tu scannes tous les anneaux (dans un groupe par exemple), et tu stockes chacun de leur pointeur dans le tableau.

// on pointe sur le groupe des 24 anneaux
var groupe=doc->FindObject("groupe_anneaux);
if (!groupe) return;

// on lit le 1er anneau du groupe
var anneau_tmp=groupe->GetDown();
if (!anneau_tmp) return;

for (a=0;a<6;a++)
for (b=0;b<4;b++)
{
stock_objets[a,b]=anneau_tmp;
anneau_tmp=anneau_tmp->GetNext(); // anneau suivant
}

En partant du principe que les anneaux du groupe sont classé comme ça:
0,0
1,0
2,0
3,0
4,0
5,0
0,1
1,1
2,1
3,1
4,1
5,1
2,0
2,1
2,2
...
...
...
5,3


ensuite tu peux écrire une routine qui va s'occuper de masquer ou afficher un élément du tableau en lui fournissant les 2 index de la grille:

anneau_ON(colonne,ligne) // pour afficher un anneau de la grille
{
var objet_tmp=stock_objets[colonne,ligne];
objet_tmp->SetRenderMode(MODE_ON);
objet_tmp->SetEditorMode(MODE_ON);
}

anneau_OFF(colonne,ligne) // pour masquer un anneau de la grille
{
var objet_tmp=stock_objets[colonne,ligne];
objet_tmp->SetRenderMode(MODE_OFF);
objet_tmp->SetEditorMode(MODE_OFF);
}

Tu n'as donc qu'à gérer tes cases 0 à 5 (colonnes) et 0 à 3 (lignes) et tu affiche/masque en fournissant ces index.
Par exemple pour afficher l'anneau en (3,2)
anneau_ON(3,2);

Pour masquer l'anneau en (1,3)
anneau_OFF(1,3)



NOTE: il faut que le tableau "stock_objets" soit déclaré comme valeur globale utilisable par toutes les fonctions que tu créés et qui l'utilisent.
Sinon, si le tableau est créé dans "main", il faut transmettre directement dans ce cas la valeur du tableau comme unique paramètre de ta fonction.

ex: anneau_ON(stock_objets[3,2])
et le code de ta fonction sera:
anneau_ON(objet_tmp) // pour afficher un anneau de la grille
{
objet_tmp->SetRenderMode(MODE_ON);
objet_tmp->SetEditorMode(MODE_ON);
}

tabou
28/01/2005, 18h16
Merci beaucoup pour tes explications détaillées Tengaal :poucehaut: je n'avais pas pensé à créer un tableau à 2 dimensions, c'est plus pratique, je vais réécrire mon code en utilisant ta méthode.
Mais c'est quand même dommage d'être obligé de refaire une expression qui marchait bien :|

Tengaal
28/01/2005, 19h14
En effet, je ne comprend toujours pas pourquoi au rendu de l'anim ton code n'est pas géré correctement.
Tu as essayé éventuellement de passer ton code sur la version 7 ?
Juste pour vérifier que c'est bien un soucis au niveau de la gestion du code en 8.5 (ou 9)...

D'ailleurs, même si ma méthode est différente, rien ne dis qu'elle ne posera pas le même problème pendant le calcul de l'animation...

tabou
28/01/2005, 19h32
Oui c'est ce que je pense aussi, je vais essayer quand même, pour voir, sinon j'utiliserai le masquage/affichage.

Pour la version 7 il va falloir que je fouille dans mes archives, je dois en avoir une qui traîne quelque part :roll:

Majoul
28/01/2005, 21h20
Juste une question simple, avec quelle méthode l’expression accède à la valeur Temps, par code ou par l’intermédiaire d’un nœud Temps .

tabou
29/01/2005, 11h35
Je n'utilise pas du tout le Temps, ce sont des nœuds Bruit qui font varier les valeurs du tableau tirage.

Majoul
29/01/2005, 19h27
J’ai posé cette question, parce que j’ai remarqué lorsqu’on accède au temps par code dans un nœud coffee l’expression fonctionne correctement à l’affichage mais par contre au rendu l’image reste fixe. Alors qu’avec une entrée dans le nœud coffee connecté a un nœud temps tout fonctionne correctement.

Sinon Pour ton expression je pense qu’une simple routine qui permet dans un premier temps de masquer tous les objets et dans un deuxième temps de pointer l’objet tiré au sort pour l’affichage avec par exemple le numéro tiré = ordre hiérarchique.

Petite Remarque si j’ai bien compris, la valeur de j est comprise entre 0 et 24 ce qui nous donne 25 objets alors que ton model contient que 24 objet c’est a vérifier.

Majoul
29/01/2005, 22h00
Je pensais à quelque chose comme cela dans le cas ou ton tirage est un array.




Masquer&#40;le_groupe&#41;
&#123;
var obj = le_groupe->GetDown&#40;&#41; ;
while&#40;obj&#41;
&#123;
obj->SetEditorMode&#40;MODE_OFF&#41; ;
obj->SetRenderMode&#40;MODE_OFF&#41; ;
obj = obj->GetNext&#40;&#41; ;
&#125;
&#125;


Afficher_num&#40;le_groupe, a&#41;
&#123;
var i = 0 ;
var obj = le_groupe->GetDown&#40;&#41; ;
while&#40;obj&#41;
&#123;
i++ ;
if&#40;i==a&#41;
&#123;
obj->SetEditorMode&#40;MODE_ON&#41; ;
obj->SetRenderMode&#40;MODE_ON&#41; ;
break ;
&#125;
obj = obj->GetNext&#40;&#41; ;
&#125;
&#125;


Aleatoire&#40;le_groupe, tirage&#41;
&#123;
Masquer&#40;le_groupe&#41; ;
var nb = sizeof&#40; tirage &#41; ;
var i ;
for &#40;i=0; i<nb; i++&#41;
&#123;
Afficher_num&#40;le_groupe, tirage&#91;i&#93;&#41; ;
&#125;
&#125;

Majoul
29/01/2005, 23h39
Je viens de tester le script il fonctionne reste à peaufiner les valeurs, j’ais fait cela très rapidement.

Le fichier (http://perso.wanadoo.fr/archizone/DIVERS/Tabou.c4d)

http://perso.wanadoo.fr/archizone/DIVERS/tabou.gif

tabou
30/01/2005, 01h50
Quelle efficacité Majoul :efface: merci beaucoup je n'en demandais pas tant :poucehaut:

J'ai refait la routine principale à ma sauce mais en utilisant tes fonctions et ça ne marche pas, enfin ça marche dans l'éditeur mais pas au rendu, toujours le même problème :o
Je dois vraiment m'y prendre comme un pied parce que j'ai fait aussi un essai avec le code de Tengaal et je n'obtiens pas mieux :oops:

Voilà le fichier que j'ai fait à partir de ton code
probleme_rendu.c4d (http://tabou.free.fr/tabou/2005/probleme_rendu.c4d)

P.S. Merci pour l'info sur le temps, c'est bon à savoir
P.P.S. Rien ne t'échappe, c'est bien j<24 et non pas 25

Majoul
30/01/2005, 02h10
Le problème vient tout simplement de la fonction FindObject() qui n'est plus vraiment valable depuis la V8 dans ces cas de figure, il vaut mieux pointer autrement soit avec les fonctions classique GetNext() .... soit une DU lien. Désolé j'aurais du te dire avant :oops: .
Sinon je ne sais si tu as télécharger le bon fichier avec la case de contrôle.

Majoul
30/01/2005, 02h27
Si tu as vraiment besoin d'utiliser la méthode de pointer les objet par leurs noms, la solution est de faire une routine qui te scanne la liste d'objet et te renvois l'objet nommer X.

tabou
30/01/2005, 22h11
Ah c'est donc FindObject() le coupable, j'éviterai de le fréquenter à l'avenir :mrgreen:
Je vais laisser tomber le pointage par le nom, je le faisais par facilité mais grâce à tes explications je peux maintenant faire autrement :poucehaut: