PDA

Voir la version complète : Modifier les paramètres d'import/export



César Vonc
26/02/2014, 18h29
Bonjour,

Je cherche à modifier les propriétés des paramètres d'import d'un filtre que j'ai créé, j'ai vu qu'on ne pouvait pas les modifier avec Get et SetWorldPluginData (la modification n'a aucun effet), mais en envoyant un message de type MSG_RETRIEVEPRIVATEDATA chargé de récupérer ces infos :


To get and set an exporter’s settings, you do not have to call GetWorldPluginData() and SetWorldPluginData() (a common pitfall for CINEMA 4D plugins developers), but a MSG_RETRIEVEPRIVATEDATA message has to be sent to the exporter instead. This is because the loader/saver plugins hold their data within their BasePlugin object.
Here is an example that shows how to setup an Alembic export in C++:
http://c4dprogramming.wordpress.com/2012/10/03/accessing-and-changing-importersexporters-settings/


Seulement voilà, ça ne semble pas marcher en Python, l'objet censé rassembler les données reste vide. Alors qu'on retrouve ce même exemple dans le fichier ExportAlembic.py de la doc :




# Get Alembic export plugin, 1028082 is its ID
plug = plugins.FindPlugin(1028082, c4d.PLUGINTYPE_SCENESAVER)
if plug is None:
return

op = {}
# Send MSG_RETRIEVEPRIVATEDATA to Alembic export plugin
if plug.Message(c4d.MSG_RETRIEVEPRIVATEDATA, op):
print op

http://code.vonc.fr/c4d/python/help/examples/scripts/ExportAlembic.py

Or op reste désespérément vide...

Donc je pige pas, ça ne marche tout simplement pas alors que l'exemple officiel s'en sert. : /

Y a-t-il une autre solution pour modifier ces paramètres ?

xs_yann
26/02/2014, 19h59
Salut César,

C'est une intégration récente au SDK qui est fonctionnelle en R14.041.
Malheureusement il y a un bug de régression qui fait que cela ne fonctionne plus en R15.

Selon mes tests :

14.034 : Ne fonctionne pas
14.041 : Fonctionne
15.037 : Ne fonctionne pas
15.057 : Ne fonctionne pas



plug = <c4d.plugins.BasePlugin object called 'Alembic (*.abc)' with ID 16 at 0x10fb66b10>
op = {'imexporter': <c4d.BaseList2D object called 'Alembic (*.abc)/Alembic (*.abc)' with ID 1028082 at 0x10fb66b30>}


Le thread le plus récent que j'ai pu trouver à ce sujet :
http://www.plugincafe.com/forum/forum_posts.asp?TID=7787

César Vonc
26/02/2014, 20h07
Ah zut, reste plus qu'à attendre qu'ils corrigent ça, j'imagine.


Merci infiniment de t'être donné la peine de vérifier sous d'autres versions. T'as l'air d'avoir un arsenal de versions de C4D assez fourni, dis donc !

xs_yann
26/02/2014, 20h21
Ah zut, reste plus qu'à attendre qu'ils corrigent ça, j'imagine.

Je pense qu'il faudrait commencer par le signaler.
Peut-être que la façon de faire a changé, mais je pense que l'exemple aurait été mis à jour.


Merci infiniment de t'être donné la peine de vérifier sous d'autres versions. T'as l'air d'avoir un arsenal de versions de C4D assez fourni, dis donc !
;)

En réalité j'ai testé sur une R14 Student et une R15 Demo (14.034 et 15.037) et j'en ai profité pour faire la mise à jour R15 pour tester sur la dernière version et la mise à jour R14 pour correspondre à la version de eoffermann, pour qui ça avait l'air de fonctionner.
Sinon j'ai aussi une R13, une R12 et une R11.5 d'installée, une de chaque quoi. :biggrin:

edit : J'ai remonté le thread sur plugincafe, t'auras surement une réponse plus précise. ;)

César Vonc
26/02/2014, 20h42
J'ai laissé un petit message sur Plugincafé. J'espère qu'il ne passera pas inaperçu. : P


Édit : Ah j'avais pas vu ton message, j'ai du coup posté dans leur rubrique de rapports de bogues. Bon ben ce qui est fait est fait, hein !

valkaari
27/02/2014, 00h33
tant que vous êtes là

http://frenchcinema4d.fr/showthread.php?77978-Sculpt-duplication-de-calque&p=1028812&viewfull=1#post1028812

vous pouvez me confirmer ce bug de m$#@e ?


(oui je sais je squat ton thread spa bien rhooo)

xs_yann
27/02/2014, 00h40
Salut Valkaari,

Je confirme que la méthode qui devrait prendre un Vector attend un int, mais je connais pas du tout les outils de sculpt, donc je ne pourrais pas t'aider à trouver une solution alternative.

Bonne soirée.

edit : SculptLayerBase.SetStrength(strength) à l'air de modifier un slider même grisé.

César Vonc
27/02/2014, 10h50
En effet, impossible d'ajouter des vecteurs, j'ai pas trouvé d'autres solutions.


Enfin, à un moment, avec CopyTo j'avais obtenu un résultat pour dupliquer un calque, mais il avait le même id que celui de base, du coup ça rendait C4D assez instable, mais peut-être qu'en creusant un peu ça pourrait passer... pas sûr que ce soit bien propre.

valkaari
27/02/2014, 17h02
ok, je ferais un petit post/report à ce sujet chez c4dcafé.

Merci, vous pouvez reprendre le cours de ce thread :whistling:

César Vonc
04/03/2014, 00h45
J'en profite pour souligner que la méthode Message marche avec d'autres genres de modules en R15 que les filtres d’import/export, et est un moyen bien pratique pour envoyer ou récupérer des variables sans être limité aux types que le BaseContainer ne gère pas (comme les listes, les bitmaps, les classes persos...).

Dans le module :

def Message(self, node, type, data):
if type == c4d.MSG_RETRIEVEPRIVATEDATA :
data["chose"] = "bidule"
return True

Ailleurs :


dic = {}
op.Message(c4d.MSG_RETRIEVEPRIVATEDATA, dic)
print dic # chose : bidule


Notez qu'il faut forcément utiliser un dictionnaire ou une liste, si on essaie d'envoyer un nombre ou une chaine, la méthode Message du module récupérera None.
Ceci dit, ça marche aussi si on envoie un BaseBitmap(). J'ai pas essayé d'autres types mais y a sûrement une logique.


On peut aussi utiliser un message autre que c4d.MSG_RETRIEVEPRIVATEDATA si on veut éviter les interférences, ou faire un message qui récupère et un autre qui définit, ou s'en servir pour appeler une fonction interne au module... bref, un petit truc bien utile !

xs_yann
04/03/2014, 02h51
Merci pour l'astuce César.



Notez qu'il faut forcément utiliser un dictionnaire ou une liste, si on essaie d'envoyer un nombre ou une chaine, la méthode Message du module récupérera None.
Ceci dit, ça marche aussi si on envoie un BaseBitmap(). J'ai pas essayé d'autres types mais y a sûrement une logique.

En python il y a des types mutable et immutable, ce qui signifie que certains peuvent être modifiés et d'autres non. Par exemple un int, une string ou un tuple sont immutable alors qu'une liste, un dictionnaire ou une classe sont mutable.
Il faut considérer les variables comme des références, si tu modifies un tableau, l'objet pointé sera modifié (car il est mutable) et ta référence pointera toujours sur la même variable. Par contre si tu modifies une variable int, ta référence pointera sur une autre variable parce qu'il n'est pas possible de modifier un int (type immutable).

>>> i = 1
>>> id(i)
4297273504
>>> i += 1
>>> id(i)
4297273536
>>> tab = [1, 2]
>>> id(tab)
4301791384
>>> tab.append(3)
>>> tab
[1, 2, 3]
>>> id(tab)
4301791384

L'id représente en quelque sorte l'adresse mémoire de la variable pointée par la référence. On voit bien que lorsque l'on modifie un int l'adresse pointée change alors que lorsque l'on modifie un tableau elle ne change pas.

Dans notre cas, on doit passer un objet en paramètre à la méthode Message qui va le modifier. Ensuite on doit pouvoir utiliser cet objet modifié, après l'appel, sans le récupérer par le retour de la méthode.
Pour que l'objet modifié soit utilisable en dehors de la méthode il faut qu'il y ait modification de la valeur pointée (ce qu'il se passe quand on modifie un tableau) et pas seulement modification de vers où pointe la référence (ce qu'il se passe quand on modifie un int).

Explication en anglais ici : http://stackoverflow.com/questions/986006/python-how-do-i-pass-a-variable-by-reference

César Vonc
04/03/2014, 09h45
Merci pour les explications, Yann, je me doutais bien que c'était quelque chose dans ce genre là. ^^

Du coup on peut utiliser un entier dans une liste pour le transformer en pointeur, si j'ai bien compris.