PDA

Voir la version complète : Résolu Random numbers ou 1 nombre aléatoire par objet



istef
02/02/2012, 01h59
une petite question à la con... forcément ;)

comment générer un nombre différent pour chaque objet null

1 nombre constant sur la timeline

j'ai essayé plusieurs trucs, parcouru le net, trouvé des soluces assez tarabiscotées, y'a pas un truc tout simple franchement !
j'ai bien vu ça aussi, mais qui m'avance pas bcp :

http://frenchcinema4d.fr/showthread.php?51513-Un-vrai-random...&highlight=nombre+al%E9atoire

C'est pas possible, y'a forcément un truc tout bête ???

je mets mon fichier avec

Aurety
02/02/2012, 02h29
et un noeud bruit comme source de randomisation pour ton noeud valeur aléatoire, ca fait un aléatoire dans l'aléatoire, non ? et mode de random Libre plutôt que temporel.

Edit : et tu peux passer par un math modulo pour éviter d'avoir la même sortie je pense.

Fluffy
02/02/2012, 04h47
J'ai pas le temps de chercher plus longtemps, mais voici un début de piste pour affecter une liste d'objets aléatoirement.
Reste plus qu'à fixer les valeurs données dans le temps, au lieu de donner une valeur qui change.

oli_d
02/02/2012, 06h43
Sinon solution avec un noeud python :

istef
02/02/2012, 15h18
et un noeud bruit comme source de randomisation pour ton noeud valeur aléatoire, ca fait un aléatoire dans l'aléatoire, non ? et mode de random Libre plutôt que temporel.

Edit : et tu peux passer par un math modulo pour éviter d'avoir la même sortie je pense.


ben nan, j'ai essayé ça, a marche pas, le blem c'est que dès que tu rentres une valeur autre que 0, le random se fait sur chaque frame, qq soit le mode choisi, libre ou temps

a moins que je ne sois à côté de la plaque grave... ;)

istef
02/02/2012, 15h25
ben nan, j'ai essayé ça, a marche pas, le blem c'est que dès que tu rentres une valeur autre que 0, le random se fait sur chaque frame, qq soit le mode choisit, libre ou temps

a moins que je ne sois à côté de la plaque grave... ;)

ooops, ah oui, je pensais avoir bien indiqué, j'ai pas précisé dans le titre : "1 nombre constant sur la timeline"

istef
02/02/2012, 15h27
J'ai pas le temps de chercher plus longtemps, mais voici un début de piste pour affecter une liste d'objets aléatoirement.
Reste plus qu'à fixer les valeurs données dans le temps, au lieu de donner une valeur qui change.

oui, en effet, un bon début de piste, mais je viens de tester vite fait...
et en activant l'entrée temps du noeud bruit et en lui indiquant une valeur, le résultat, c'est pas encore ça...
mon principal besoin est JUSTEMENT de fixer un random UNIQUE PAR OBJET sur toute la longueur de la timeline.
peut être en mettant une condition ça peut le faire, je vais creuser l'idée

merci en tout cas ;)

istef
02/02/2012, 15h28
Sinon solution avec un noeud python :

ah bah oui, là tout de suite, avec un noeud Pyhton... c'est tout de suite plus facile ;))

donc là, je m'incline...... et moa j'dis chapô ;)

istef
03/02/2012, 14h30
hello everybody,
je reviens à la charge, d'abord merci à tous pr vos contributions, sinon, je cherchais à trouver une soluce en Xpresso.
La soluce d'oli_d en python est nickel, mais je ne suis pas certain de pouvoir la reproduire chez un client au besoin si je n'ai pas le preset sous la main ou la mémoire fraîche de son code.
Non codeur, je préfère la souplesse et l'interface graphique d'Xpresso, donc à l'occase si l'un d'entre vous trouve la combine pour générer un nombre aléatoire différent par objet, un nombre qui ne varie pas sur la longueur de la timeline, je suis tjs preneur.

Mais rien d'urgent dans cette demande ;)

Aurety
03/02/2012, 16h35
Avec Mograph, un simple effecteur randomisation en mode aléatoire, c'est un "bruit" figé... Pas taper, aie...

istef
06/02/2012, 20h44
Alors, après qqs essais, je re-reviens à la charge.


Sinon solution avec un noeud python :
oli_d, j'avais pas fais gaffe la dernière fois, la solution en python est top, à ceci près que le chiffre se ré-initalise à chaque nouveau passage sur la timeline.
Pour info, ce qui a suscité ce post de ma part était de pouvoir entrer une valeur d'intensité aléatoire, différente et unique dans un grand nombre de bend deformer. Sachant que cette valeur ne doit plus variée une fois qu'elle a été définie. Et ne pas changer à la ré-ouverture du fichier.


Avec Mograph, un simple effecteur randomisation en mode aléatoire, c'est un "bruit" figé... Pas taper, aie...
Oui, of course, l'effecteur randomisation, c'est le premier truc auquel j'ai pensé, à part que c'est le même hic qu'avec le noeud Random, si tu le mets sur différents objets, le random sorti est le même à chaque fois, donc on revient sur le problème du début (avec le noeud Random), il faut changer la valeur de la source (de randomisation).

Je mets la soluce à laquelle je suis arrivé, à savoir incrémenter la valeur de la source en jouant sur "l'indice" (plutôt la position et le nom) de chaque objet dans le Gest Objets. Le défaut de cette soluce, il faut nommer spécifiquement chaque objet dans le GO, même si le process peut toujours s'automatiser en Xpresso.
A noter, ça fonctionne uniquement avec un bruit gaussien...

Mais je trouve que cette soluce, c'est de la bricole, je pensais qu'il y avait plus simple en fait, beaucoup plus simple. Comme quoi.

oli_d
06/02/2012, 22h47
Sachant que cette valeur ne doit plus varier une fois qu'elle a été définie. Et ne pas changer à la ré-ouverture du fichier.Dans ce cas pour le python il faudrait le faire via un script. Je ne sais pas exactement quels paramètre du bend deformer tu veux modifier.

Je te mets un exemple qui modifie aléatoirement le strength et l'angle de tous les bend deformer du document si il n'y a rien de sélectionné, et si il y a un objet sélectionné agit uniquement sur les bend dans la hiérarchie de l'objet.

Attention c'est fait à la va vite, il n'y a pas de undo possible

code à coller dans le script manager:

import c4d
import math
import random

def modifyBend(obj,start):
while obj:
if obj.CheckType(c4d.Obend):
obj[c4d.DEFORMOBJECT_STRENGTH]= random.random()*math.pi*2
obj[c4d.DEFORMOBJECT_ANGLE]= random.random()*math.pi*2
modifyBend(obj.GetDown(),start)
if start :
if obj==start:return
obj = obj.GetNext()
return


def main():
if op :
obj = op
start = op
else :
obj = doc.GetFirstObject()
start = None
modifyBend(obj,start)
c4d.EventAdd()
if __name__=='__main__':
main()
Bon mais ça reste du python, tu ne pourras pas forcément l'adapter, à moins de te lancer et de rejoindre le club (je continue à jouer le missionnaire qui tente de convertir cette bande d'hérétiques !)

Par contre je suis une bille en xpresso et en mograph donc je peux pas t'aider de ce côté là

istef
07/02/2012, 01h07
Dans ce cas pour le python il faudrait le faire via un script. Je ne sais pas exactement quels paramètre du bend deformer tu veux modifier...


Si tu voulais m'impressionner oli_d, c'est bon.... c'est fait ! ;)

Bingo, je voulais modifier le strength, donc c'est nickel, de plus quand je vire la ligne qui concerne l'angle, qu'il ne m'intéresse pas de modifier, le script fonctionne toujours, donc, c'est parfait ;)

Sinon, comme ça, j'ai voulu convertir la valeur retournée en entier en rajoutant des int :
genre int (random.random()*math.pi*2)
ou des math.round et autres math.floor, ici et là, mais a marche pôh :(


Sinon, one more question de débutant, pourquoi le script ne fonctionne qu'à partir du script manager et pas sur un tag python ou via le python generator ?


Et pour finireuh, ché pas si tu vas me convertir, mais je dois dire que, suite à ta première réponse, j'avais déjà bookmarké c'te page du site :

http://frenchcinema4d.fr/showthread.php?69711-Py4D-le-language-python-dans-C4D

et que chui même allé jusqu'à fouiner par là :

http://docs.python.org/library/functions.html

Le virus serait-il en moi ?

C'est possible, mais pas sûr qu'il fasse grand chose tant je suis hermétique au coding, malheureusement.

oli_d
07/02/2012, 06h56
Sinon, comme ça, j'ai voulu convertir la valeur retournée en entier en rajoutant des int :
genre int (random.random()*math.pi*2)
ou des math.round et autres math.floor, ici et là, mais a marche pôh :(

A l'interne c4d utilise des valeurs d'angle en radians, ou pi(3.1416) = 180°. Pour un 360° on a pi*2, soit 6.28, quand tu fais int() tu vas arrondir à l'entier vers le bas, donc peu d'angles différents possibles

Si tu veux travailler en degré, il y a une fonction qui convertit les degrés en radians : c4d.utils.Rad(angle_en_degre).
Pour le random il y a une fonction qui renvoie directement un entier compris entre deux bornes: random.randint(mini,maxi)

Donc si tu remplaces =random.random()*math.pi*2
par : =c4d.utils.Rad(random.randint(0,90)) tu obtiendra des angles entiers entre 0 et 90 degrés

Pour ce qui est du tag, je ne pense pas que cela soit la meilleure solution, dans la mesure ou tu veux toujours garder la même valeur. On pourrait bien évidemment fixer le seed du random à une certaine valeur, mais pourquoi faire refaire à c4d à chaque fois un calcul pour renvoyer la même chose (ou j'ai pas tout compris).

Si c'est vraiment ce que tu veux, je te mets en pièce jointe un exemple de tag, où tu peux modifier le seed, le mini et le maxi dans des userdata du tag

istef
07/02/2012, 15h53
Fantastique !!!
Je joue avec tes scripts depuis un moment...
Le tag me convient tout à fait car je peux animer la déformation en mettant des clés sur les mini/maxi des user data.
Franchement c'est super, merci infiniment oli, c'est terrible, terrible ;)

istef
07/02/2012, 20h10
J'utilise le tag pour créer une animation sur l'intensité de tous mes deformers, par exemple sur 100 frames, je pars de F0 avec 0 intensité, je mets le max d'intensité à F50 pour revenir en position 0 à F100.
Total j'ai une animation différente sur chacun de mes deformers
Une fois que j'ai ce mouvement, est-il possible de baker (conformer) l'animation obtenue en clés d'animation et de supprimer le tag python ?

oli_d
08/02/2012, 06h51
Une fois que j'ai ce mouvement, est-il possible de baker (conformer) l'animation

Oui théoriquement, mais c'est un peu plus complexe, car je n'ai jamais joué avec les pistes d'animation.

Donc si j'ai le temps, plus tard ...

oli_d
08/02/2012, 08h34
Bon ça m'énerve quand j'sais pas faire, donc j'ai quand même fait.

Alors en résumé j'ai rajouté un userdata deformation et une case à cocher conformer qui sert de bouton.

Mais il y a quelques petits soucis, je n'arrive à récupérer par le code que la première UserData animée, donc si tu veux conformer anime uniquement déformation et clique sur conformer

Ensuite si la clef de la frame 0 est en mode AutoTangent, je n'arrive pas à récupérer la tangente de droite (mystère)

Enfin bref ça marche plus ou moins, c'est pas très stable, si ton ordinateur commence à fumer, jette lui un seau d'eau glacé ...

Bon maintenant il faut que j'arrête, j'ai plein d'autres trucs à faire ;)

istef
09/02/2012, 20h16
Bon ça m'énerve quand j'sais pas faire, donc j'ai quand même fait.


Ah ah, bienvenue au club ;)

Te prend pas la tête si t'as pas le temps, no soucy, c'est pas urgent...

Mais au cazou, qd même ;) je comprends pas trop, ton dernier tag, y'a plus rien qui marche ici ???
J'ai ouvert sous 12 et 13 au cas ou, mais nada !
En fait, je ne peux plus rien changer, ni modifier, ni utiliser ni ré-utiliser le tag en aucune manière,
Bizarre, vous avez dit bizarre...

Sinon, pour info, hier je suis tombé sur un script pr baker des objets Mograph, c'est pas du python, mais je me dit que ça peut peut être te servir, script de Bandini qui sort de cette discussion :
http://forums.cgsociety.org/archive/index.php/t-742967.html

var userStartTime = 0;
var userEndTime = 90;

var fps = doc->GetFps();
var bakeStartTime = GetActiveDocument()->GetTime(); //needed to initialize a BaseTime object
bakeStartTime->SetFrame(userStartTime, fps);

doc->SetTime(bakeStartTime); //set the time slider to the user's start time
var currentFrame = GetActiveDocument()->GetTime()->GetFrame(fps);

while(currentFrame <= userEndTime)
{
StopAllThreads();
CallCommand(12410);//record
userStartTime++;
bakeStartTime->SetFrame(userStartTime, fps); //needed to convert frame to BaseTime
doc->SetTime(bakeStartTime);//SendPlayhead to next frame
var redraw = DrawViews(DA_STATICBREAK);
EventAdd(EVENT_ANIMATE);
if(redraw == TRUE) currentFrame = GetActiveDocument()->GetTime()->GetFrame(fps);
}

oli_d
09/02/2012, 20h54
Active l'animation, j'ai rajouté un UserData déformation qui applique plus ou moins la déformation, qui est à 0 à la frame 0, c'est pour cela que rien ne se passe.

C'était juste pour te montrer comment conformer l'animation ...

istef
09/02/2012, 22h42
Active l'animation, j'ai rajouté un UserData déformation qui applique plus ou moins la déformation, qui est à 0 à la frame 0, c'est pour cela que rien ne se passe.

C'était juste pour te montrer comment conformer l'animation ...

ben voui j'ai vu tous les UD que tu avais ajouté, mais "active l'animation", je vois pas de quoi tu parles ?
Dans la timeline tous les boutons d'animation sont sur on, il n'y a pas de calque ou l'animation serait désactivée non plus, ...

Qu'est-ce que j'ai oublié de dieu ?
De quelle animation tu parles, je capte pas !?!
Je peux tjs rien modifier, rien utiliser, rien changer ??? Grrrrrr

oli_d
09/02/2012, 23h10
active l'animation = play , simplement mais ça doit être plus grave que ça....

istef
09/02/2012, 23h39
active l'animation = play , simplement mais ça doit être plus grave que ça....

en effet, c'est beaucoup plus grave ;) ;) ;)

Ah mède alo', moi qui pensais que tu allais me donner l'explication pourquoi ça veut plus rien savoir ici ! ;)

Pour info, en fait, je ne peux plus rien faire de l'animation conformée, que je supprime les clés d'animation du tag ou des bend, l'animation joue toujours à l'identique, elle est comme figée !

Idem, j'ai voulu utiliser le tag dans un autre projet, comme avec le précédent fichier, mais là, il veut rien savoir non plus !
Voilà, tu sais tout.

istef
10/02/2012, 01h45
Je viens de refaire tout un tas d'essais, je pige pas !
Je peux absolument rien faire avec ton dernier tag, celui avec pourcentage de déformation et bouton de conformation ???

J'ai viré tous mes plug-in pr vérifier, histoire de, mais ça n'a rien changé.

Pourtant, j'ai fait un preset de ton 1er tag, celui avec juste les 3 UD : seed - mini - maxi, et, dans le même document, je peux utiliser ce tag, aors que le nouveau ne veut rien savoir, il reste "muet" à toutes mes manip'

So sad and lonely...

Aaah, mais attends, je viens de me rendre compte d'un truc, j'avais pas fais gaffe, en utilisant les deux tag ensemble, je m'aperçois que le nouveau à son icône porteur d'une croix, je pense que cela provient de la conformation, je te mets les copies d'écran.

Peut-on ré-initialiser le tag après conformation, autrement cela expliquerait pourquoi il est "bloqué" ?

oli_d
10/02/2012, 04h34
La petite croix veut dire qu'il y a une erreur lors de l'exécution du code, il me faudrait le message qu'il y a dans script/console

Si tu lance l'anim de mon fichier sans rien modifier ça marche ?

Qu'est ce que tu as dans la hiérarchie de ton neutre cloner ?

Si c'est uniquement ton fichier qui marche pas, envoie le moi ça sera plus simple

istef
10/02/2012, 12h31
Voilà, on y est, c'est ce que je pressentais en fait...

Ben oui le problème c'est que l'erreur est direct à l'ouverture du fichier, je l'avais d'ailleurs téléchargé plusieurs fois hier pour être sûr.

Pour info, je viens à nouveau de télécharger ton dernier fichier :

- bend_python_tag.c4d (214,0 Ko, x affichages)

et l'ai ouvert sans RIEN toucher.

Je t'ai fait une copie d'écran en essayant que tu aies le max de trucs visibles à l'écran, mais sans rien modifier, juste avoir ouvert l'éditeur python et lancer un "execute" pour ton info.
Alors voilà, et c'est précisément ce qui m'a surpris depuis le début, il indique "No Errors!", c'est pour ça que j'ai cherché partout ailleurs depuis 2 jours !!! Ah ah ah !

Mais, et dis-moi si je me trompe STP, je commence à comprendre où plutôt deviner, cette indication n'est pas toujours fiable, notamment dans le cas présent, avec l'étape de conformation. Le tag se figeant mais après la conformation, le script est paradoxalement indiqué correct !?

Sinon, ça viendrait de ma machine ?

oli_d
10/02/2012, 12h45
Le no errors signale qu'il n'y a pas de faute de syntaxe, pour voir les vrais messages il faut ouvrir la console dans le menu script

istef
10/02/2012, 16h06
ah ok, ben ça dit ça :

Traceback (most recent call last):
File "'Python'", line 50, in main
TypeError: FindCTrack() takes no arguments (1 given)

oli_d
10/02/2012, 18h07
Alors c'est bien ça, il faut que tu fasses la dernière mise à jour à la version 13.051 (je me souviens avoir eu des déboires avec cette fonction FindCTrack() à la sortie de la 13

valkaari
10/02/2012, 18h58
note de la mise à jour 13.051 --> FindCTrack argument now accepts arguments

me semblait bien avoir vu passer un truc aussi.

istef
10/02/2012, 19h54
Ben voui, après l'update ça fonctionne de suite maintenant >>> Grrrrrr

Bon ben je vais enfin pouvoir m'amuser un peu avec ce nouveau fichier
et voir si ses fonctions peuvent m'être utile ;)

Thank you biloute

istef
12/02/2012, 18h10
Au fait, c'est une tuerie ton petit script oli, merci encore ;)
Ca fonctionne nickel maintenant, en tenant compte des restrictions que tu mentionnais, animation seule de l'UD deformation.

Dernière petite question, que signifie le parametre "op" que tu utilises, j'ai pas trouvé la réponse en ligne :

random.seed(op[c4d.ID_USERDATA,1])
obj=op.GetObject()
mini = op[c4d.ID_USERDATA,2]
maxi = op[c4d.ID_USERDATA,3]


Pour finir, je me suis amusé à essayer de récupérer le random en Xpresso;
J'ai fini par y arriver, c'est mon premier noeud en python, waouah, trop content le stef ! ;)

Merci encore pour le temps passé ;)

oli_d
13/02/2012, 19h04
Dernière petite question, que signifie le parametre "op" que tu utilises

op représente l'objet, donc dans le cas d'un tag python c'est le tag lui-même (BaseTag).
Donc op.GetObject() renvoie l'objet sur lequel le tag est appliqué (voir dans la doc BaseTag.GetObject() )
op[c4d.ID_USERDATA,2] renvoie le UserData 2(tu peux glisser-déposer le titre du UD directement dans le gestionnaire de code pour l'obtenir)

Dans le cas d'un générateur d'objet python, op représente l'objet lui-même (BaseObject), dans le cas d'une noeud xpresso le noeud lui-même (GvNode) et pour finir dans le cas d'un script op représente l'objet sélectionné

istef
14/02/2012, 11h46
Ah ok ok ok ok (c'est pas moi qui le dit, c'est jpp ;)
Voilà, tout s'explique !
...
J'ai enregistré tous tes scripts et tags dans mes presets, bien au chaud, vraiment très, très utile.
Merci encore
Et, en effet, le python, ça donne envie ;)