PDA

Voir la version complète : Rendu récursif et boucle de frames en COFFEE



ZOZO
08/07/2009, 18h05
Bonjour tout le monde, ça fait un bout de temps que j'ai pas posté alors je me fait tout discret. :roll:

Je fais mes premiers pas en COFFEE et c'est pas de la tarte.
J'ai l'habitude du mel sous maya et les syntaxes ne sont pas tout à fait les mêmes...

Je vous expose mon problème :
Je dois faire une série de rendus pour avoir un QTVR objet de ma scène par frame... :arg: (comprend rien...)
Alors en français, j'ai par exemple une scène contenant une boucle d'anim de 10 frames (1 à 10), j'aimerais faire 10 QTVR incrémentés.
J'ai la construction de mon script en tête mais pas les connaissances pour l'écrire.

------
//Déclaration des variables
frame d'entrée
frame de sortie
nombre d'étapes verticales du QTVR
nombre d'étapes horizontales du QTVR
nom

//Boucle
var i;
for (i=entrée, i<sortie, i++)
{
frame = i;
set[nom du fichier de sortie]=nom + i;
rendu
}
---------

voilà, c'est même faisable avec un if sur le numéro de frame.


Mon problème majeur c'est qu'après avoir farfouillé sur le net je commence à comprendre comment ça fonctionne mais je n'arrive toujours pas à aller à une frame i en COFFEE. J'ai cru comprendre que c'était la variable d'environnement Time qu'il fallait "setter" mais je n'y parvient pas.

C'est certainement une grosse étourderie de ma part. De même j'arrive à récupérer la variable pour le nom de sortie mais pas à le setter. par contre j'arrive à cocher/décocher un case dans les paramettres de rendu.

Si une bonne âme peut m'éclairer (ou m'envoyer ballader)...

signé le noob du COFFEE. :odile:

shtl
08/07/2009, 18h43
Tiens hello Zozo.
Ça me fait penser, en parlant de QTVR...
Si jamais tu croises Bruno, donnes lui ce lien ça devrai l'interresser:
http://www.tcastudios.com/ -> Xfiles -> SteadyQTVR

Il faut placer le dossier dans les plugin et redemarrer.
Puis ouvrir le fichier joint dans le dossier du plugin "SteadyQTVRv1.c4d".

Il comprendra :wink:

ZOZO
08/07/2009, 20h02
Bon je progresse un peu je commence à comprendre la structure du code, c'est pas très souple mais ça a le mérite d'être précis.

j'arrive à faire des sets de valeurs "float", pour les frames je contine de creuser.

Sinon côté script, coder avec des mouffles ça force à être inventif... Je pourrais changer la frame dans les prefs de rendu entre chaque rendu plutôt que d'avancer dans la timeline.
je poste un bout de code demain.



Sinon corentin, le plug est installé, on fouille ça demain.

shtl
08/07/2009, 20h10
T'avais pas RV à 19h toi! :nono:


:wink:


désolé de pas pouvoir aider plus pour ton coffee :?

xs_yann
08/07/2009, 22h50
Avec la structure de ton code tu vas te heurter à un problème : le rendu de la frame 2 va se lancer pendant le rendu de la frame 1 et va donc générer un message "The external renderer is calculating an image. Do you want to stop it?".

Je te donne quand même le code qui va bien pour ton algorithme :



main(doc,op)
{
// Time variables
var t = doc->GetTime();
var fps = doc->GetFps();

var min = doc->GetMinTime()->GetFrame(fps);
var max = doc->GetMaxTime()->GetFrame(fps);

// Render variables
var rd = doc->GetFirstRenderData();
var f = (rd#RDATA_PATH)->GetClone();
var path = f->GetFullString();

var i;
for(i=min; i<max; i++)
{
t->SetFrame(i, fps);
doc->SetTime(t);
f->SetFullString(path+tostring(int(i+1)));
rd#RDATA_PATH = f;
CallCommand(12099);
}

}


Commenté :



main(doc,op)
{
// Time variables
var t = doc->GetTime();
var fps = doc->GetFps(); // Nombre d'image par seconde

var min = doc->GetMinTime()->GetFrame(fps); // Nombre de frames minimal
var max = doc->GetMaxTime()->GetFrame(fps); // Nombre de frames maximal

// Render variables
var rd = doc->GetFirstRenderData();
var f = (rd#RDATA_PATH)->GetClone(); // Chemin d'enregistrement (instance de Filename)
var path = f->GetFullString(); // Chemin d'enregistrement (instance de String)

var i;
for(i=min; i<max; i++) // Pour chaque frame
{
t->SetFrame(i, fps); // On va à la frame i sur la timeline
doc->SetTime(t);
f->SetFullString(path+tostring(int(i+1))); // Renommage : path+n° de frame
rd#RDATA_PATH = f;
CallCommand(12099); // Rendu dans le visualiseur
}

}


A suivre...

clemz
09/07/2009, 00h56
merci XS_Yann :prie:

ZOZO
09/07/2009, 14h18
Bon alors 4 choses :

1/ merci ! :prie:

2/ j'ai lu le code 3 ou 4 fois et je me rend compte que j'ai encore du chemin à faire et que ce que je pensais avoir compris hier, c'était pas tout à fait ça... Mais ça progresse.

3/ je teste ça dans l'aprèm et je poste un retour.

4/ merci ! :prie: :prie: :prie:


ps : à mon avis pour le problème que tu soulève si c4d sait voir quand il y a un rendu on doit pouvoir soit le tester toute les X secondes soit récupérer le message de fin de rendu (le même message qui lance quicktime à la fin d'une preview par exemple). Je vais creuser...

ZOZO
09/07/2009, 18h43
Bon alors je farfouille je farfouille.

j'ai 2 solutions pour les rendus qui s'empilent :

-un timer qui se paramettre au lancement (pas méga clââsss mais efficace)
pour ça je comprend pas bien pourquoi mon SetTimer marche 1 fois sur 5 ni comment il doit se placer dans le code.

-lancer le script en post effect (yann j'ai vu que t'avais fait un truc de ce genre en c++ mais ça lançait du coffee ou tout était en C++ ?)

je comprend pas trop la hiérarchie du coffee en fait, j'ai potassé le sdk mais c'est dejà pas super limpide.
par exemple le "->" parfois j'ai l'impression que ça définit une variable, parfois j'ai l'impression que ça va chercher dans une class ou un objet...

:cry2: :coup: :wip:

......waaaatchaaaaaa :bounce:

xs_yann
10/07/2009, 03h11
par exemple le "->" parfois j'ai l'impression que ça définit une variable, parfois j'ai l'impression que ça va chercher dans une class ou un objet...


Le "->" sert juste à appeler une méthode d'un objet, cette méthode peut retourner différents types, objets ou void, je pense que c'est ça qui doit te troubler.
Exemple :



chat->Miaule(); // Miaule renvoi void, la méthode sert à exécuter une action
var couleur = chat->GetColor(); // La méthode renvoi la couleur du chat, la valeur de retour peut donc être stockée dans une variable

oli_d
10/07/2009, 08h49
Salut,

Pas grand chose à rajouter sur le COFFEE, maître XS a déjà frappé ...(merci à lui à chacune de ses interventions, j'apprends beaucoup)

Par contre je croyais que sous Maya c'était du Python (connais pas mel) donc si jamais : http://www.frenchcinema4d.fr/forum/index.php?topic=23682.msg440770#msg440770 (j'ai pas encore testé)


Avec la structure de ton code tu vas te heurter à un problème : le rendu de la frame 2 va se lancer pendant le rendu de la frame 1 et va donc générer un message "The external renderer is calculating an image. Do you want to stop it?".

Je ne vois pas comment contourner ce problème en COFFEE (cela doit être faisable en C++, mais je vois quand même pas comment :D).

Je vais peut-être dire une connerie, mais un simple "Batch rendering" (rendu par lot) avec une copie de ton fichier par frame, ne serait pas plus simple (vu que tu en as apparemment pas plus d'une dizaine) ?

xs_yann
10/07/2009, 10h59
Je vais peut-être dire une connerie, mais un simple "Batch rendering" (rendu par lot) avec une copie de ton fichier par frame, ne serait pas plus simple (vu que tu en as apparemment pas plus d'une dizaine) ?


Ce n'est pas une connerie, c'est bien vu et c'est peut-être la solution. :poucehaut:

ZOZO
10/07/2009, 11h39
merci à vous deux.

yann :
oui c'est bien ça qui me chiffonnait dans le ->.
pour le problème de la fin de rendu j'ai toujours pas trouvé comment utiliser le timer (nooooob) ni comment balancer un bout de coffee en fin de rendu (re-nooob).
du coup je vais utiliser le script pour enregistrer une séquence de fichiers c4d et les lancer en batch.
je donnerai des nouvelles dans la matinée.

oli_d :
sous maya il y a le python et le mel, le mel est beaucoup plus simple car c'est l'équivalent du coffee pour maya.
exemple : la commande "sphere" crée une sphère. après tu peux évidemment rentrer très loin dans les détails.
jamais essayé le python. mon expérience scriptique est assez pauvre : applescript, html, javascript, php (dans l'ordre chronologique)
j'avais vu le post de shtl sur le plug pour faire du python mais je préfère déjà me mettre au coffee.

encore merci

xs_yann
10/07/2009, 13h03
Voici le plug pour enregistrer un fichier par frame : http://www.xsyann.com/plugins/xsFileByFrame.cof

Il va créer un dossier Frames au même niveau auquel le fichier est enregistré, contenant un fichier par frame (1 pour la frame 1, 2 pour la frame 2, etc). Il incrémente aussi le render path.

Le code commenté :



// (c) xs_yann July 2009

var PLUGIN_ID = 1024207; // ID obtenue sur plugincafe

class xsFileByFrame : MenuPlugin // On fait hériter la classe xsFileByFrame de la classe MenuPlugin
{
public:
xsFileByFrame();

GetID();
GetIcon();
GetName();
GetHelp();
Execute(doc);

}

xsFileByFrame::xsFileByFrame()
{
super(); // On appelle le constructeur parent (xsFileByName hérite de MenuPlugin, le constructeur appelé est celui de la classe MenuPlugin
}

xsFileByFrame::GetID()
{
return PLUGIN_ID; // L'id du plug définie plus haut en variable globale
}

xsFileByFrame::GetName()
{
return "xsFileByFrame";
}

xsFileByFrame::GetHelp()
{
return "xsFileByFrame";
}
xsFileByFrame::GetIcon()
{

return NULL;
}

xsFileByFrame::Execute(doc)
{
// Time variables
var t = doc->GetTime();
var fps = doc->GetFps(); // Nombre d'image par seconde

var min = doc->GetMinTime()->GetFrame(fps); // Nombre de frames minimal
var max = doc->GetMaxTime()->GetFrame(fps); // Nombre de frames maximal

// Render variables
var rd = doc->GetFirstRenderData();
var f = (rd#RDATA_PATH)->GetClone(); // Chemin d'enregistrement (instance de Filename)
var rdpath = f->GetFullString(); // Chemin d'enregistrement (instance de String)

// "Frames" folder creation
var fpath = doc->GetFilename(); // Le filename du document ouvert (filename = path+nom de fichier) C:\Toto\dossier\monfichier.c4d
fpath->RemoveLast(); // On enlève le nom du fichier pour ne garder que le path C:\Toto\dossier\
var dir = fpath->GetClone(); // C:\Toto\dossier\
dir->AddLast("Frames"); // On créer le chemin du dossier "Frames" C:\Toto\dossier\Frames\
fpath = doc->GetFilename(); // On réaffecte le filename à la variable pour pouvoir la réutiliser
if(GeFileExist(dir,TRUE)) GeFileKill(dir,TRUE); // Si le dossier Frame existe on le supprime (cette ligne n'a pas l'air de fonctionner...)
if(!GeFileCreateDir(dir)) // Si on ne peut pas créer le dossier on affiche un message d'erreur, sinon le dossier est créé
{
TextDialog("Directory creation failed", DLG_OK + DLG_ICONEXCLAMATION);
return;
}

var i;
for(i=min; i<=max; i++)
{
t->SetFrame(i, fps); // On va à la frame i
doc->SetTime(t);
f->SetFullString(rdpath+tostring(int(i))); // On incrémente le nom du render path avec le numéro de frame
rd#RDATA_PATH = f;
var dest = dir->GetClone(); // C:\Toto\dossier\Frames\
dest->AddLast(tostring(int(i))); // C:\Toto\dossier\Frames\i
dest->SetSuffix("c4d"); // C:\Toto\dossier\Frames\i.c4d
doc->Save(dest); // On enregistre le fichier
}
f->SetFullString(rdpath); // On reviens
rd#RDATA_PATH = f; // au fichier
doc->Save(fpath); // de départ

}

main()
{
println("xsFileByFrame loaded - xsFileByFrame (c) xs_yann, July 2009");
Register(xsFileByFrame); // On enregistre le plug
}

ZOZO
10/07/2009, 17h31
Waou ! :shock:

c'est pas permis d'être aussi réactif. :prie:

ton plug marche nikel, merci beaucoup :odile: