PDA

Voir la version complète : question généralE sur les plugs



paspas
10/02/2013, 10h16
salut

Je me lance enfin dans la confection de plug in avec l 'interface jolie et tout et tout !

quelle que question me taraude :

1 - le plug comportera plusieurs tag , suivant ce que l'on veut on placera le tag que l' on souhaite
- 1A) faut il tout coder dans le même programme ou peut il y avoir plusieurs fichier .res dans le même dossier ?
- 1B ) si plusieurs programme faut il plusieurs ID

2 - j' ai un souci quand je lance le plug ( la première fois que je place un tag sur un objet ) il me met un message " dialogue corrompu " il faut que je le l' efface plusieurs fois avant que celui-ci ne revienne plus , ensuite le tag fonctionne correctement


d' avance merci

paspas

xs_yann
11/02/2013, 12h10
Salut,

1A) Tu peux avoir plusieurs .res dans le même dossier (exemple : plugins > cinema4dsdk > res > description). Il suffit juste que tu passes la bonne description en paramètre quand tu fais ton RegisterTagPlugin.
Après, pour le code, tu peux soit tout coder dans le même fichier, soit modulariser un peu. Par exemple un fichier pour le Register, un fichier pour la classe du tag et un fichier pour tes fonctions "utilitaires" indépendantes du plugin (style fonction de parcours de hiérarchie et toute fonction susceptible d'être réutilisée dans un autre plugin). Ca te permet également de coder tes différents tags chacun dans un fichier respectif tout en utilisant les même fonctions présentes dans ton fichier "utilitaire".
En règle générale de toute façon il est préférable de n'avoir qu'une classe par fichier.

Tu peux trouver des exemples qui se rapprochent de ça ici (si tu codes en Python): http://www.smart-page.net/blog/

1B) Oui il te faut plusieurs ID.

2 - Comme ça je vois pas trop, si tu peux m'envoyer le dossier res de ton plugin je pourrais y jeter un oeil. ;)

valkaari
12/02/2013, 01h49
J'irais même jusqu'à dire qu'il faut parfois plusieurs IDs pour un plugins.
Dans le SDK il t'indique en général quand il faut utiliser une ID unique.

Dans le cas d'un basecontainer perso sur un objet par exemple, il te faut une ID unique pour le basecontainer, mais les IDs à l'intérieur tu peux les gérer comme tu veux.

paspas
26/02/2013, 08h47
bonjour

merci pour vos réponse rapide et désolé pour ma réponse tardive :)

pour ce qui est du " dialogue corrompu " j'ai trouvé après beaucoup de tâtonnement c' était une mauvaise dénomination dans mes fichiers " str" .

pour ce qui est de l'autre souci j' ai zieuté le lien que ma fourni yann et après moult essai je sèche

dans les exemples il place :




# add this plugin to the python search path
folder = os.path.dirname(__file__)
if folder not in sys.path:
sys.path.insert(0, folder)

...
....

from "plugin" import "fichier.py "


il place un dossier dans le plugins et dans ce dossier il place des fichier.py

mais perso çà marche pas

mon plug place bien le dossier dans le liste path , mais impossible d 'atteindre le fichier py qui se trouve a l' intérieure

j' ai vu dans le sdk les commande " GeRessource " mais je comprend pas trop

paspas qui cherche ( lentement mais qui cherche )

encore merci

xs_yann
26/02/2013, 10h48
Salut,

Je t'ai fais un exemple pour un tag : My Tag (http://www.xsyann.com/fc4d/MyTag.zip)


# Add this plugin to the python search path
folder = os.path.dirname(__file__)
if folder not in sys.path:
sys.path.insert(0, folder)

import c4d

from mytag import ids
from mytag import tag


Normalement ce code ne pose pas de soucis tant que tu as respecté l'arborescence des fichiers :

mytag
--- __init__.py
--- tag.py
MyTag.pyp

Le fichier __init__.py vide spécifie que le dossier mytag est un package.

Pour le GeResource tu n'as pas à t'en préoccuper directement. Il suffit juste de préciser le bon objet GeResource pour tes modules (module.__res__ = __res__) si tu veux avoir accès aux ressources dedans (par exemple pour le GeLoadString dans tag.py).

paspas
26/02/2013, 11h51
merci ! merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !


je teste ça , des que le boulot me le permet

encore
merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !merci !

paspas super content

paspas
28/02/2013, 13h16
hello

encore une petite question

comment on récupère l' iD d 'un plugin tag je suppose avec BaseContainer.GetId() mais que prendre comme BaseContainer

allez promis après cette question j' ai assez de matière pour m'atteler pour finir mon plug ( enfin j" espère )

paspas reconnaissant

xs_yann
28/02/2013, 13h44
Salut paspas,


tag.GetType()

C'est ça que tu cherches non ?

paspas
28/02/2013, 17h55
yess

c 'est ca que je cherchai,

heuuu une autre question ( j 'ai vraiment du mal a mis retrouver dans ce sdk )

comment on fait pour rendre invisible ou inactive une des entrée du tag

paspas
allez après j' arrête :)

xs_yann
28/02/2013, 19h01
Pour une 'description' c'est un peu plus compliqué que pour un 'dialog'.
Déjà je crois que tu ne peux pas rendre invisible un élément (GetDDescription en C++), si tu trouves préviens moi ça fait longtemps que j'attend cette fonctionnalité. :whistling:
Pour désactiver c'est avec la méthode NodeData.GetDEnabling(node, id, t_data, flags, itemdesc) (SDK : c4d.plugins.NodeData) qui est apparue en R13.029.
C'est une méthode que tu dois surcharger au même titre que Init() ou Execute() par exemple.
Pour comprendre comment ça fonctionne tu peux regarder dans le SDK C++ à la section Plugin Hooks > NodeData et tenter une recherche sur PluginCafe, je crois qu'il y a un thread qui traite de ça.

Je n'ai jamais utilisé cette méthode en Python mais si tu es bloqué reviens ici j'y jetterais un oeil. ;)

paspas
11/03/2013, 13h18
oki oki

merci je zieute

il est possible mettre un dialogue sur un plug tag en plus de la description ? ( si oui tu sait me dire ou trouver un exemple ?)


paspas reconnaissant

oli_d
11/03/2013, 15h27
Je pense que tu es obligé de passer par un bouton dans la description pour ouvrir ton dialogue

valkaari
11/03/2013, 15h53
je crois pas c'est comme le tag xpresso, tu peux ouvrir une boite de dialogue avec un double clic. Faudrait que je vérifie j'étais tombé sur un sujet de ce type sur c4dcafémachin. (Me souviens pas de la conclusion par contre, possible ou pas possible T.T)


edit : Après quelques recherche, il faudrait utiliser la fonction Message du tag et de réagir à l'évènement "MSG_EDIT" pour lancer l'ouverture d'une boite de dialogue. Comme avec un plugin command, créer la class de boite de dialogue et la variable et faire un dlg.Open(...)


Juste une piste puisqu'il n'y a pas vraiment beaucoup d'info sur ce genre de plugins.

oli_d
12/03/2013, 08h37
je crois pas c'est comme le tag xpresso, tu peux ouvrir une boite de dialogue avec un double clic...

...., il faudrait utiliser la fonction Message du tag et de réagir à l'évènement "MSG_EDIT" ...

c'est vrai que j'avais jamais pensé à ça, j'ai testé juste avec un print et ça à l'air de fonctionner parfaitement.

Merci Valkaari :thumbup1:

paspas
13/03/2013, 11h22
hello

merci pour l' aide

2 piste que je parcours
- il est possible dans la description de mettre le paramètre HIDDEN et le paramètre est invisible dans l 'onglet mais c 'est pas très dynamique lol
ex : VECTOR N_noms{HIDDEN;}

- dans le sdk il parle de description dynamique avec des paramètre du type DTYPE_VECTOR modifiable avec avec la class Dynamicdescription ( qui n' existe pas en python ) mais bon perso je n' y suis toujours pas arrivé mais je continue les recherches

mais ce retrouve en python dans c4d.DescLevel à creuser

a bientot

paspas

valkaari
13/03/2013, 13h39
C'est ce que disait yann, en c++ on a une fonction GetDDescription et ses copines pour gérer dynamiquement les interfaces Descriptions. (qui ne fonctionnent pas comme les dialogues).

En python, ces fonctions n'ont pas été implémenté. Il y a la possibilité de masquer des Données Utilisateurs, mais uniquement les DU.

Par contre tu peux désactiver (griser) les champs comme dit yann.

tu devrais avoir une class hérité de ToolData --> DescriptionToolData

Ce qui n'est pas le cas en python.

paspas
03/09/2013, 10h16
Re salut ( et merci encore pour toute les infos passée et futur )

le plug TAG avance mais une petite question ,

le plugin (comme je l' imagine ) devrait être compose de plusieurs tag ( on met celui que l' on veut pour avoir le résultat obtenu )

j ' ai déjà la structure commune du programme mais

j' aimerai savoir si il set possible d' avoir en commun les paramètre ?
en gros deux description peuvent elle pointer la même liste de paramètre ? ça m éviterais de multiplier les fichier.h et fichiet .str et autre fichier commun

d 'avance merci

César Vonc
06/09/2013, 09h27
Tu as essayé en inscrivant les mêmes arguments str et description dans la fonction RegisterTagPlugin de tes différents modules ?

paspas
06/09/2013, 10h16
Tu as essayé en inscrivant les mêmes arguments str et description dans la fonction RegisterTagPlugin de tes différents modules ?

oui, le souci est que les descriptions des différent Tag sont différents , ils ont une base commune mais quelque arguments changes , du coup j' ai plusieurs descriptions et c4d vas automatiquement chercher les fichier .str et et .h qui ont le même noms . et comme il est difficile voir même impossible de faire une description dynamique je me suis résolu à avoir pour les descriptions et les str qui y sont attaché séparer.

remarque c' est pas la mort y en a 4 en comptant la description lol

encore merci

paspas

valkaari
06/09/2013, 10h54
il faudrait essayer avec le mot clef "INCLUDE"


Include flag

The description of parent nodes can be included with this flag:


Flag Explanation
INCLUDE parentdesc; Element name or text

parentdesc should be the identifier for the parent description. The parent description must have been registered with CINEMA 4D
before this description is registered for the lookup to work.

All elements of the parent description are inserted before the elements of this description, in the various groups.

Note: It is recommended that you always include at least the base description for the node type you're creating, for exampe Tbase for tags
Tu peux aussi utiliser SHOW elementid; et HIDE elementid; avec ça pour ben .... afficher ou masquer certains élément.

Par contre je n'ai jamais essayé à l'intérieur d'un même plugin.

paspas
06/09/2013, 18h14
yessssssssssssssssssssssssssssssssss ca maaaaaaaaaaaaaaaaaaaaaaaaaaaaaaarche !

oupssssss D'abord bonjour et merci pour le tuyau !

Genial , Ca ne change pas le nombre de fichier MAIS par contre ça évite de coder deux fois les même ligne de code et ça c'est du bonheur !

encore merciiiiiiii !!!!!

paspas super heureux

valkaari
06/09/2013, 18h53
je ne sais pas ce que tu es en train de faire, mais tant que j'y suis, il y a une autre petite "astuce" (uniquement pour les descriptions)
Dans ton fichier .res, lorsque tu crées tes groupes pour créer des onglets, il faut nommer un des objets avec ID_OBJECTPROPERTIES
Il sera sélectionné par défaut.


Oinstance.res


CONTAINER Oinstance
{
NAME Oinstance;
INCLUDE Obase;

GROUP ID_OBJECTPROPERTIES
{
LINK INSTANCEOBJECT_LINK
{
ACCEPT
{
Obase;
}
}
}
}

paspas
25/11/2013, 17h15
hello et merci pour l' aide précieuse que vous m' apporter

une chite question ,

il est possible en python de crée une extrusion interne sur un polygone ?

et par extension d' utiliser tout les outils de modélisation des polygones



paspas toujours reconnaissant

oli_d
25/11/2013, 18h24
Salut,

Regarde dans la doc du côté de c4d.utils la fonction SendModelingCommand()

Ci-dessous un exemple qui utilise l'extrusion interne sur les polygones sélectionnés de l'objet sélectionné (pour les paramètre du BaseContainer regarde du côté du fichier toolextrudeinner.h):



import c4d
from c4d import utils

def main():
settings = c4d.BaseContainer()
settings[c4d.MDATA_EXTRUDEINNER_OFFSET] = 50.0

res = utils.SendModelingCommand(command = c4d.ID_MODELING_EXTRUDE_INNER_TOOL,
list = [op],
mode = c4d.MODELINGCOMMANDMODE_POLYGONSELECTION,
bc = settings,
doc = doc)
c4d.EventAdd()

if __name__=='__main__':
main()

paspas
27/11/2013, 16h55
hello

merci pour la réponse

mais y a un truc que je pige pas : quand je fait , " settings = c4d.BaseContainer() " j ' ai un container vide ??

quelle container doit je prendre pour trouver la DU : [c4d.MDATA_EXTRUDEINNER_OFFSET]

autre petite question ( en espérant ne pas abuser ) comme on fait pour sélectionner 1 polygone particulier d' un objet ?

paspas perplexe

César Vonc
27/11/2013, 17h34
settings = c4d.BaseContainer()
Créé un BaseContainer vide, oui, qui est une sorte de tableau.

settings[c4d.MDATA_EXTRUDEINNER_OFFSET] = 50.0
Permet de remplir la case c4d.MDATA_EXTRUDEINNER_OFFSET avec la valeur 50.

Tu peux aussi utiliser settings.SetFloat(c4d.MDATA_EXTRUDEINNER_OFFSET, 50.0), cela revient au même.

Ce BaseContainer permet de préciser certains paramètres de l'outil, tu peux retrouver quels sont les paramètres possibles en regardant la doc qui te renvoie généralement au fichier .H utilisé par l'outil (ici, toolextrudeinner.h).



Pour sélectionner un polygone, c'est assez simple, tu récupères la variable BaseSelect (http://code.vonc.fr/c4d/python/help/modules/c4d/BaseSelect/index.html) avec GetPolygonS, puis sélectionne avec la fonction Select.
voici un exemple qui sélectionne, par exemple, le poly d'indice n (ici, 5) :



bs = op.GetPolygonS()
n = 5
bs.Select(n)



Version complète :



if not op or not op.CheckType(c4d.Opolygon) : return

doc.StartUndo()
doc.AddUndo(c4d.UNDOTYPE_CHANGE_SELECTION, op)

bs = op.GetPolygonS()
n = 5
bs.Select(n)

doc.EndUndo()
c4d.EventAdd()


Pour les points, c'est pariel mais avec GetPointS. Pour les segments, c'est différent, on utilise Get et SetSelectedEdges à initialiser avec un objet Neighbor. Il y a pas mal d'exemples de sélections sur mon site : http://code.vonc.fr/?a=14

paspas
03/12/2013, 12h38
merci merci

mais j ai tj un souci

pour résumer dans le programme

je crée un polygone qui a N point

je place les points jusque la pas de souci , après je doit mettre à jour le poly avec :

polygon.setpolygon(0,c4d.Cpolygon)

la est le souci car c4d.Cpolygon est une variable finie , je doit mettre c4d.Cpolygon(0,1,2,3) pour un polugone a 4 coté et la ca marche sinon ca marche pas seulement voila j ai des poly avec un nombre de plus de 4 point

en gros comment fait on pour crée une polygone a n point ?

paspas

oli_d
03/12/2013, 14h56
A ma connaissance il n'y a toujours pas moyen de créer des ngons comme en C++. Ce que je fais pour contourner le problème, je crée un objet LinearObject, puis ensuite avec la méthode triangulate() j'obtiens un objet polygonal, ensuite je fusionne tous mes objets polygonaux et j'optimise. C'est vraiment du gros bricolage et évidemment c'est pas du tout rapide et optimisé.

A chaque mise à jour, le premier truc que je regarde c'est si on peut créer des ngons. Si quelqu'un à trouvé une solution hors C++, j'achète très cher ...

paspas
10/11/2014, 16h50
re hello ( et grand merci a tous pour l' aide)

Comment fait on en python pour crée une copie d 'un objet ( une spline en particulier) , je ne veut pas le faire apparaitre dans le document ,

juste crée une copie parfaite dans le programme pour ensuite le manipuler en extraire des valeurs le tout sans avoir a toucher a l' original ,


d avance merci

oli_d
10/11/2014, 19h30
Salut,

Regarde du côté de C4DAtom.GetClone() dans la doc. Mais en même temps je n'ai pas bien compris, si tu veux juste récupérer les valeurs de paramètres ou de points, tu n'as pas besoin de copie, non ?

César Vonc
10/11/2014, 20h14
Si tu veux une copie parfaite, c'est assez chiant car faut prendre en compte le fait qu'elle peut être déformée par un déformateur ou des dynamiques, ou créée avec un quelconque générateur .


Tu as la commande SendModelingCommand(command=c4d.MCOMMAND_CURRENTST ATETOOBJECT, list=[op], doc=doc),
GetDeformCache, GetCache.


Perso j'utilise les trois à la suite pour être sûr du résultat car dans certains cas une seule de ces fonctions ne suffit pas.

Bon c'est assez lourd, mais si vous avez une meilleure méthode et 100% fiable, je prends. : P


Mais note que pour les splines, je te recommande très très fortement d'utiliser plutôt c4d.utils.SplineHelp en précisant de prendre en compte les déformateurs dans sa fonction Init, dans laquelle tu entres ta spline telle quelle, même si elle n'est pas convertie :

http://www.maxonexchange.de/sdk/CINEMA4DPYTHONSDK/help/modules/c4d.utils/SplineHelp/index.html?highlight=splinehelp

SplineHelp.InitSpline(op, [up=c4d.Vector(0.0)][, rail=None][, target_rail=True][, use_deformed_points=True][, force_update=False][, use_global_space=True])

paspas
11/11/2014, 07h51
Salut,

Regarde du côté de C4DAtom.GetClone() dans la doc. Mais en même temps je n'ai pas bien compris, si tu veux juste récupérer les valeurs de paramètres ou de points, tu n'as pas besoin de copie, non ?

En fait je ai besoin d une copie de spline car , je doit lui apporter des modification puis ensuite récupérer des valeurs , le souci si je modifie la spline d' origine , celle-ci après ça remise en état est légèrement différente du départ surtout (les courbe de bezier ne sont plus identique ) ,
d' ou mon besoin de crée une copie parfaite


Cesar

je zuite tout ça et un grand merci a vous deux


perso j avait trouver des fonction dans c4d.plugins.ObjectData mais comment les utilise t' on ??

en autre

ObjectData.GetVirtualObjects(self, op, hh)

voici la page (http://www.maxonexchange.de/sdk/CINEMA4DPYTHONSDK/help/modules/c4d.plugins/BaseData/NodeData/ObjectData/index.html?highlight=object#ObjectData.GetVirtualO bjects)


paspas

oli_d
11/11/2014, 09h01
Il y a également pour les splines BaseObject.GetRealSpline() (http://www.maxonexchange.de/sdk/CINEMA4DPYTHONSDK/help/modules/c4d/C4DAtom/GeListNode/BaseList2D/BaseObject/index.html?highlight=getrealspline#BaseObject.GetR ealSpline) qui te permet de récupérer les splines paramétrique ou non (et même de vérifier par la même occasion que c'est bien une spline). Il y a un bout de code en exemple dans la doc qui copie ensuite la spline.

Mais ça c'est sans les déformateurs, sinon c'est les méthodes décrite pas César.

Pour GetVirtualObjects c'est une méthode que l'on surcharge lors de la création d'un plugin de type objet, et c'est là que l'on renvoie le résultat "géométrique" du générateur