Très bonne initiative, ce tuto !
En revanche, ce serait chouette de corriger les anciens messages qui ne disent pas la même chose que les suivants.
Par exemple :
C'est bizarre, je n'ai pas les mêmes résultats que toi dans Py4D.En fait, vous avez vu au début il y a bien import c4d, mais dans mes codes précédents j'avais rajouté ensuite "from c4d import * ". En fait je vous avais raconté n'importe quoi, ce truc ça importe pas tout les modules, ça évite simplement de marquer c4d. devant chaque fonction ou instruction de la bibliothèque.
Tu parles de 4 espaces à mettre, mais ça fonctionne tout aussi bien avec un seul.
La fonction pour récupérer le document actif doc = c4d.documents.get_active_document() m'indique une erreur dans la console : « L'objet 'module' n'a pas d'attribut 'get_active_document'. », pourtant j'ai copié coller ton code pour créer un objet dans c4d mot pour mot.
Tout ça vient peut-être d'un problème de version, j'ai téléchargé la dernière en date, la 0.9.9983, et j'ai carrément moins de choses dans le menu de Py4d que toi (ni même l'onglet « Extras » du gestionnaire de script (« Script Manager ») :? (j'ai pourtant bien installé dans le dossier Plugins de c4d et installé le truc de microsoft avant comme c'est indiqué sur le site).
Je suis sous Windows 7 32 bits.
Je n'ai pas installé la dernière version, car je suis entrain de développer un truc et j'ai pas envie que tout foire. Et en fait j'ai bien fait !
Tout à changé ! Il est passé d'une convention de nommage à une autre !
c4d.documents.get_active_document() est devenu c4d.documents.GetActiveDocument() !!!!
Ce qui fait que l'ensemble du tuto est obsolète, j'ai bien fait de pas aller trop loin !
Je te dis pas comme je suis content car je suis entrain de faire un truc de gestion de flux piétons, voitures et cie, j'ai plus de 1000 lignes de code que je vais pouvoir me retapper mot par mot ! Plus plein de scripts ....
Les joies de travailler avec une version béta.
Moralité je vais attendre la version1.0 pour réécrire et finaliser le tuto.
A part ça j'ai écrit ce truc à mes débuts en python, j'ai du dire plein de petites bêtises que je corrigerais plus tard quand je serai vraiment plus "pro"
Pour les espaces c'est vrai que cela fonctionne avec moins (je l'ai appris il n'y a pas si longtemps), mais on conseille 4 pour que cela soit plus lisible.
De plus visiblement il n'existe plus qu'une version pour C4D 11.5. :poucebas:
Étant resté à la 11 je pense que le coffee pour l'instant fera très bien l'affaire.
Tourne même sur la CE 6. :nono:
SMC fan.
Python et la R12
Python est maintenant intégré a la R12. D'après ce que j'ai pu en voir Python offre une très bonne alternative au C++ pour écrire des plugins assez évolués en bénéficiant d'un langage interprété, ce qui évite de recompiler pour chaque OS.
Je vais donc essayer de faire avancer ce thread en postant mes recherches étant donné que je pense m'orienter vers des plugs python en priorité.
Le SDK R12 Python : http://http.maxon.net/pub/sdk/12/Pyt...umentation.zip
Voici donc le code pour créer un Command Plugin (Une commande dans le menu plugin) :
Ce code est a placer dans un fichier testplugin.pyp dans le dossier plugins de Cinema 4D.Code:import c4d from c4d import plugins class TestPlugin(c4d.plugins.CommandData): def Execute(self, doc): print "Hello World" return True # be sure to use a unique ID obtained from www.plugincafe.com PLUGIN_ID = 1000002 if __name__ == "__main__": c4d.plugins.RegisterCommandPlugin(PLUGIN_ID, "My First Python Plugin", 0, None, "A Test Plugin", TestPlugin())
Au chargement le plugin apparaîtra dans le Menu Python > Plugins.
Lorsqu'il est exécuté le texte "Hello world" est affiché dans la Console Python (Menu Python > Console (Python)...).
Dernière modification par xs_yann ; 26/09/2010 à 12h13.
Super,
Si XS-Yann se met au Python ça va faire mal ! Je posterai prochainement mes avancées, j'ai programmé un système automatique d'animation de circulation de voitures, piétons transport public tout en python (avec la version béta). Je confirme que c'est vraiment génial, j'ai complètement laisssé tomber le C++.
Dès que j'ai un peu de temps il faut que je mette à jour le tuto, pour que ce soit compatible avec la version de la R12
Hâte de voir ça.
Voici comment on ajoute un Dialogue non-modal (asynchrone) :
Pour tout ce qui est des constantes, elles ont changées de place depuis Py4D R11 :Code:import c4d from c4d import plugins, gui # be sure to use a unique ID obtained from www.plugincafe.com PLUGIN_ID = 1000002 class TestPluginDialog(gui.GeDialog): def CreateLayout(self): self.SetTitle("Test Plugin Dialog") self.AddStaticText(0, c4d.BFH_CENTER, 0, 0, "Hello", c4d.BORDER_NONE) return True class TestPlugin(c4d.plugins.CommandData): dialog = None def Execute(self, doc): if self.dialog is None: self.dialog = TestPluginDialog() return self.dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, -1, -1) if __name__ == "__main__": c4d.plugins.RegisterCommandPlugin(PLUGIN_ID, "My First Python Plugin", 0, None, "A Test Plugin", TestPlugin())
Il ne faut donc pas oublié le c4d. : 'c4d.CONSTANTE'The biggest change: Python in R12 contains no built-in module called c4d.symbols and all constants were moved to the c4d main module.
La suite :
Un bouton cliquable :
J'ai ajouté un groupe pour pouvoir espacer mon bouton des bords de la fenêtre.Code:import c4d from c4d import plugins, gui # be sure to use a unique ID obtained from www.plugincafe.com PLUGIN_ID = 1000002 MY_BUTTON = 1001 class TestPluginDialog(gui.GeDialog): def CreateLayout(self): self.SetTitle("Test Plugin Dialog") self.GroupBegin(0, c4d.BFH_SCALEFIT) self.AddButton(MY_BUTTON, c4d.BFH_SCALEFIT, 0, 0, "Click me") self.GroupBorderSpace(4, 4, 4, 4) self.GroupEnd() return True def Command(self, id, msg): if id == MY_BUTTON: print "My button clicked" return True class TestPlugin(c4d.plugins.CommandData): dialog = None def Execute(self, doc): if self.dialog is None: self.dialog = TestPluginDialog() return self.dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, -1, -1) if __name__ == "__main__": c4d.plugins.RegisterCommandPlugin(PLUGIN_ID, "My First Python Plugin", 0, None, "A Test Plugin", TestPlugin())
Voici maintenant un exemple qui affiche un bouton 'Add button' qui, lorsqu'il est cliqué, ajoute un nouveau bouton 'Add button'
Créer des boutons dynamiquement
Les méthodes possédant le préfix '_' sont des méthode privées :Code:import c4d from c4d import plugins, gui # be sure to use a unique ID obtained from www.plugincafe.com PLUGIN_ID = 1000002 BUTTON_GROUP = 1001 GADGET_BUTTON = 1002 class TestPluginDialog(gui.GeDialog): def __init__(self): self.button_count = 1 def _CreateButtonGroup(self): i = 0 while i < self.button_count: self.AddButton(GADGET_BUTTON + i, c4d.BFH_SCALEFIT, 0, 0, "Add Button") i += 1 def _ReLayout(self): self.LayoutFlushGroup(BUTTON_GROUP) self._CreateButtonGroup() self.LayoutChanged(BUTTON_GROUP) def CreateLayout(self): self.SetTitle("Test Plugin Dialog") self.GroupBegin(BUTTON_GROUP, c4d.BFH_SCALEFIT) self._CreateButtonGroup() self.GroupBorderSpace(4, 4, 4, 4) self.GroupEnd() return True def Command(self, id, msg): i = 0 while i < self.button_count: if id == GADGET_BUTTON + i: print "My button clicked" self.button_count += 1 self._ReLayout() i += 1 return True class TestPlugin(c4d.plugins.CommandData): dialog = None def Execute(self, doc): if self.dialog is None: self.dialog = TestPluginDialog() return self.dialog.Open(c4d.DLG_TYPE_ASYNC, PLUGIN_ID, -1, -1) if __name__ == "__main__": c4d.plugins.RegisterCommandPlugin(PLUGIN_ID, "My First Python Plugin", 0, None, "A Test Plugin", TestPlugin())
Je vais m'arrêter la et me documenter un peu plus sur le langage Python avant de donner de mauvais conseils.Like most languages, Python has the concept of private functions, which can not be called from outside their module; private class methods, which can not be called from outside their class; and private attributes, which can not be accessed from outside their class. Unlike most languages, whether a Python function, method, or attribute is private or public is determined entirely by its name.
Dernière modification par xs_yann ; 27/09/2010 à 11h54.
Wow...Envoyé par oli_d
Dire que pour la ville je me suis fade ça 'a la main' avec des trajectoires vectorielles et le plugin Drive... Et vu le temps que ça prenait ma circulation est vraiment light ! Pas de bouchon !
... Ton système gere aussi les feux ? Passage au rouge et arrêt des véhicule et démarrage de ceusses qui sont au vert ?
Parce que ça j'ai laisse tomber pour le coup...
Edit : oui je sais c'est hors sujet
Je continue mes recherches :
Les constantes
C'est désormais possible et il faut utiliser les constantes des que possible pour des raisons d'implémentation et de clarté.
Exemple :
Code:op[c4d.ID_BASEOBJECT_USECOLOR] = 3 # mauvais op[c4d.ID_BASEOBJECT_USECOLOR] = c4d.ID_BASEOBJECT_USECOLOR_LAYER # bonDocstringCode:if tag.GetType() == 5616 # mauvais if tag.GetType() == c4d.Ttexture # bon
En python, il est d'usage de fournir une doc pour les fonctions, cela se présente sous la forme :
Truc et astuces :Code:def myFunction(): """Useless function without parameters """ pass
Swap de deux variables :
Declaration et définition de plusieurs variables :Code:foo = 42 bar = 1337 foo, bar = bar, foo
En python il est possible de passer une valeur au 2e param tout en laissant la valeur par defaut du 1er param :Code:foo, bar = 42, 1337 # foo = 42 bar = 1337
Il est possible de passer un nombre négatif a l'operateur [] :Code:def myFunction(a = 5, b = 12, c = 15): pass myFunction(c = 5) # a = 5, b = 12, c = 5 myFunction(b = 8, c = 5) # a = 5, b = 8, c = 5
Simuler une boucle for type C avec indicesCode:str = "salut" # str[-1] == 't'
Les classesCode:print range(5) # [0, 1, 2, 3, 4] # on peut donc écrire for i in range(5): print i
Attribut de classe (static) :
Methode de classe (static) :Code:class MaClasse: cnt = 0 def __init__(self): MaClasse.cnt += 1 ... MaClasse.cnt
Attribut / Methode privés :Code:class MaClasse: def maMeth(): #without self param pass ... MaClass.maMeth()
Surcharge d'operateurs :Code:class MaClasse: def _maMeth(): #private self._mon_attr #private ... MaClass.maMeth()
http://docs.python.org/py3k/referenc...l-method-names
Dernière modification par xs_yann ; 27/09/2010 à 11h33.
Excellent tout ça.
Bon, c'est juste pour les yeux, car la R12 c'est pour les pros, mais je suis avec intérêt.
SMC fan.
Oli... Quand ça devient publique fais moi suivre ca par mail
... Ave le prix
a suivre ...
Donc en fait si jamais on se lance dans le développement d'un plugin en Python, il faut décider si l'on souhaite le faire compatible pour la R12, ou bien pour les versions précédentes ? Ou alors si on veut le faire compatible partout il faut faire dans un autre langage ?
Si tu écris un plug en Python il ne sera compatible que R12. En C++ il suffit de compiler ce qui va bien (il faut donc compiler une version mac R12, une version mac >R12, deux versions PC (R12 64bits + R12 32bits) + deux versions PC (>R12 64bits + >R12 32 bits)), cela fait donc : (cdl, cdl64, dylib) x 2.
En COFFEE, pour la plupart des plugs il faudra faire deux versions étant donné qu'il y a eu quelques changements dans le SDK, notamment :
-UNDO_... IDs renamed to UNDOTYPE_...
-Because of the R12 Dual Transformation funcionality, there are new BaseObject members: GetAbsPos, SetAbsPos, GetAbsScale, SetAbsScale, GetAbsRot, GetAbsRot, GetFrozenPos, SetFrozenPos, GetFrozenScale, SetFrozenScale, GetFrozenRot, GetFrozenRot, GetRelPos, SetRelPos, GetRelScale, SetRelScale, GetRelRot, SetRelRot, GetFrozenMln, GetRelMln, GetRelMl, SetRelMl, CopyMatrixTo
R12 Development Transition PDF
Bonjour à vous tous,
J'invite les nuls comme moi à consulter ce site qui à pour vocation les bases du Python.
Le traitement des cours est en vidéo avec un ton humoristique.
http://www.siteduzero.com/tutoriel-3...html#ss_part_1
Le bœuf est lent, mais la terre est patiente.
PHAB
Merci Fabrice !
Ça c'est sympa : j'espère qu'il passe aussi une pré-couche sur le concept de dev objet car je ne suis pas sur d'avoir encore vraiment compris... J'm'en veux !
J'aurais du prendre ça comme module a la fac :-/
a suivre ...
merci XS-Yann de faire partager tes avancées . c'est super intéressant !
faut que je m'y mette ! depuis le temps