Boutique Cinema 4D
Affichage des résultats 1 à 14 sur 14

Discussion: Questions diverses sur l'ecriture de plug-ins

  1. #1
    Pilier Avatar de Floc
    Date d'inscription
    novembre 2012
    C4D version
    R15 Studio
    OS
    WindOSX
    Messages
    1 617

    Questions diverses sur l'ecriture de plug-ins

    Hello
    J''essaye donc de me lancer dans l'ecriture de plug-in, et pour moi en tout cas c'est pas de la tarte.
    j'ouvre donc ce fil pour poser mes questions. Et il va y en avoir pas mal je pense.

    il faut dire quand même, que autant pour l’écriture de scripts on trouve pas mal d'infos, des tutoriaux etc…
    mais sur l'ecriture de plug-ins c'est un peu le désert.
    Voici ce que j'ai trouvé (a part la doc bien sur)
    deux videos de pim Grooff https://www.youtube.com/watch?v=47VYjmmijHQ et https://www.youtube.com/watch?v=hbeRQDh-Gsc
    et une video de Michael Auerswald : http://www.908video.de/lab_project/t...k-and-plugins/
    Mais honnêtement et c'est pas pour critiquer, vu qu'ils ont fait l'effort de le faire et je les en remercie, mais t'en apprend pas beaucoup plus qu'en regardant la doc et des examples.
    Le site smart-page : http://www.smart-page.net/blog/2011/05/09/advanced-python-plugin-coding-for-cinema-4d/
    Mais comme annoncé c'est pas trop pour les débutants.
    Il y avait le site de Pim Grooff que j'avais bookmarqué il y a un certain temps http://blog.grooff.eu/ mais apparemment il n'est plus accessible.
    Et finalement celui que j'ai trouvé le plus intéressant, le site de microbion
    http://www.microbion.co.uk/graphics/...e_plugins1.htm
    les exemples sont en C++, mais il y a pas mal d'explications, notamment sur le mécanisme des fichiers de ressources.

    Si vous avez d'autre bonnes sources je suis vraiment preneur.


    Ma premiere question donc, est la suivante.
    Dans l'ecriture d'un fichier res pour un plug-in de type shader, dans les exemple que j'ai vu, le premier Group est presque toujours acompagné d'un ID_SHADERPROPERTIES.
    Dans la doc du SDK C++ il y a ecrit :
    "groupid is a constant from the descriptionname.h file. It is used for the name of the group in the string table, and as an identifier for the group. If no group ID is specified the group is just used for structuring".
    Dans mon Plugin de test la présence de ID_SHADERPROPERTIES generai une erreur, et comme manifestement c'est pas obligatoire je l'ai suprimé. Donc tout va bien. Mais comme dans les différents exemple il n'y en a aucune trace dans les descriptionname.h, en cherchant un peu j'ai trouvé que c'etait en fait une constante prédéfinie dans xbase.h mais j'ai trouvé aucune info sur l'utilisation ou l'utilité de cette constante.
    D'ou ma question quand ou pourquoi faut il utilser cet ID prédéfini sur un groupe ?

    Je vois bien que xbase semble etre un type de shader au même titre que xbrick ou xcloud, mais est ce que c'est celui qu'on est censé utiliser quand on développe son propre shader ?


    [edit] Ah tiens et j'en rajoute une. Les préfixes pour les nom des fichiers de ressources O pour objet, T pour Tag ect...
    C'est obligatoire ou c'est juste une convention ?
    Dernière modification par Floc ; 30/01/2018 à 20h31.

  2. #2
    Gourou Avatar de César Vonc
    Date d'inscription
    avril 2006
    C4D version
    Autre
    OS
    Windows 10
    Messages
    2 483
    Ce groupe ID_SHADERPROPERTIES va servir à afficher ton menu Catactéristiques de la Matière, quand tu cliqueras sur ton shader dans C4D.

    As-tu inclus Xbase dans ton .res ?


    Ajouter un autre GROUP au même niveau que le GROUP ID_SHADERPROPERTIES ajoutera un nouvel onglet, si je dis pas de bêtise.


    Code:
    CONTAINER MONSHADER {
    
        NAME MONSHADER_NOM;
    
    
        INCLUDE Mpreview;
        INCLUDE Xbase;
    
    
        GROUP ID_SHADERPROPERTIES
        {
            // Ici se trouvera le menu de ton shader
            REAL MONSHADER_POURCENTAGE { UNIT PERCENT; MIN 0.0; MAX 100.0; CUSTOMGUI REALSLIDER; }
        }
    
    
        GROUP MONSHADER_UNAUTREONGLET
        {
            // Ici se trouvera un autre onglet pour ton shader
        }
    }
    Les constantes que tu créés dans ton .res doivent être déclarées et énumérées dans ton .h dans le dossier description.

    Code:
    #ifndef monshader_avecunsuffixetotalementarbitrairepourledifferencierdesautresincludespossibles_H__
    #define monshader_avecunsuffixetotalementarbitrairepourledifferencierdesautresincludespossibles_H__
    
    int const MONSHADER = 1037432; // Plugin ID unique à créer sur plugincafe.com
    
    enum
    {
        MONSHADER_NOM = 1000,
        MONSHADER_UNAUTREONGLET,
        MONSHADER_POURCENTAGE,
        __DUMMY_ELEMENT_PEUIMPORTESONNOM__ // Sert juste à pouvoir écrire une virgule à la fin de chaque énumération au-dessus pour copier, ajouter facilement.
    };
    
    #endif

    Ensuite, pour leur associer un nom, tu alimentes ton fichier .str dnas le dossier description :

    Code:
    STRINGTABLE
    {
        MONSHADER_NOM "Mon shader";
        MONSHADER_UNAUTREONGLET "Un onglet";
        MONSHADER_POURCENTAGE "Un champ pourcentage avec curseur";
    }

    Le Oobjet, Ttag etc. est une convention, tout comme les constantes en majuscules.

    Tu peux t'inspirer de mon shader C++ ici aussi, perso je ne suis pas un adepte des tutos vidéos (je ne saurais t'en conseiller) mais plutôt des examples :
    https://code.vonc.fr/?a=70
    Dernière modification par César Vonc ; 31/01/2018 à 00h12.

  3. #3
    Pilier Avatar de Floc
    Date d'inscription
    novembre 2012
    C4D version
    R15 Studio
    OS
    WindOSX
    Messages
    1 617
    Ok Merci pour ces précisions

    Je ne suis pas fan non plus des tutos videos, et surtout pour le developement, mais c'est tout ce que j'ai trouvé.

    et tes exemple sont evidement deja en haut de mes "sujet d'études"

    Pour xbase.h et ID_SHADERPROPERTIES maintenant que je sais a quoi ca sert je vais le réintegrer.

    Mais juste pour finir le type shader xbase c'est bien une sorte de "template" vide à remplir ? celui qu'on est censé utiliser, ou est ce qu'on peu partir d'un autre type ?
    Dernière modification par Floc ; 31/01/2018 à 00h24.

  4. #4
    Pilier Avatar de Floc
    Date d'inscription
    novembre 2012
    C4D version
    R15 Studio
    OS
    WindOSX
    Messages
    1 617
    Est ce qu'un dev charitable pourrait jeter un oeil a ce code et me dire pourquoi
    dans la partie recup des donnée j'obtiens systematiquement cette erreur : "TypeError: an integer is required".
    Au depart c'etait des bool. Je lui ai donné du Long, car du Int apparement y a pas. Mais marche pas Je comprend pas. l'erreur vient probablement d'ailleurs, mais je trouve pas
    Et c'est peut etre evident mais les different init s'execute bien dans cet ordre ?
    _Init_ de la classe
    init de nodeData
    renderInit de shaderData
    C'est un peu comme si la case init (du nodeData) etait zappée.
    Fichiers attachés Fichiers attachés

  5. #5
    Gourou Avatar de César Vonc
    Date d'inscription
    avril 2006
    C4D version
    Autre
    OS
    Windows 10
    Messages
    2 483
    Quelques remarques :

    Les méthodes Set/GetLong et Set/GetReal sont dépréciées, utilise Set/GetInt32 et Set/GetFloat.

    Je te conseille de mettre toutes tes propriétés dans le groupe ID_SHADERPROPERTIES, il ajoute par défaut par exemple, l'échantillonage et l'échelle du flou de la texture (que tu peux utiliser ou non). Après je n'ai pas la réponse à toutes tes questions concernant ce groupe. ^^


    L'erreur ne vient pas du type du champ mais de la déclaration de tes constantes :

    Code:
    FPLUGTWO_TEXTURE = 1000,
    FPLUGTWO_FLIPX = 1010,
    FPLUGTWO_FLIPY = 1020,
    FPLUGTWO_WORLD = 1030,
    FPLUGTWO_LOCAL = 1050
    Tu as laissé une virgule à la fin de chaque nombre, du coup Python interprète ça comme un tuple avec un second élément vide (1000,) au lieu d'un entier.

    Code:
    FPLUGTWO_TEXTURE = 1000
    FPLUGTWO_FLIPX = 1010
    FPLUGTWO_FLIPY = 1020
    FPLUGTWO_WORLD = 1030
    FPLUGTWO_LOCAL = 1050



    Ça marche mieux.


    C'est tout à fait ça, pour l'ordre des appels des init.
    Dernière modification par César Vonc ; 01/02/2018 à 00h37.

  6. #6
    Pilier Avatar de Floc
    Date d'inscription
    novembre 2012
    C4D version
    R15 Studio
    OS
    WindOSX
    Messages
    1 617
    Je comprend pas.
    Dans tous les exemple que j'ai vu y compris ceux de la doc et dans ton matiere-python il y a bien des virgule en fin de ligne ?
    Et je viens de tenter mais même sans virgule toujours la même erreur

    [Edit] ok autant pour moi. tu parles de la declaration qui est dans le pyp, mas dans .h
    Effectivement ca devrait aller mieux
    Dernière modification par Floc ; 01/02/2018 à 00h46.

  7. #7
    Gourou Avatar de César Vonc
    Date d'inscription
    avril 2006
    C4D version
    Autre
    OS
    Windows 10
    Messages
    2 483
    C'est dans le fichier Python qu'il faut les enlever les virgules hein, pas le .h !

    Code:
    import os
    import math
    
    
    import c4d
    from c4d import plugins, bitmaps, utils
    
    
    
    
    PLUGIN_ID = 1040539
    
    
    FPLUGTWO_TEXTURE = 1000
    FPLUGTWO_FLIPX = 1010
    FPLUGTWO_FLIPY = 1020
    FPLUGTWO_WORLD = 1030
    FPLUGTWO_LOCAL = 1050
    
    
    
    
    class FPlugTwo(c4d.plugins.ShaderData):
    
    
        print "FPlugTwo ok"
            
        def __init__(self):
            #debug color
            self.ape = True
            self.mode = 0
            #self.theTex = 0.0
            self.flipx = 0
            self.flipy = 0
            self.worldSpace = True
            self.localSpace = False
            
            self.SetExceptionColor(c4d.Vector(1,0,0))
        
        def Init(self, node):
            donnees = node.GetDataInstance()
            donnees.SetReal(FPLUGTWO_TEXTURE, self.theTex)
            donnees.SetInt32(FPLUGTWO_FLIPX, self.flipx)
            donnees.SetInt32(FPLUGTWO_FLIPY, self.flipy)
            donnees.SetBool(FPLUGTWO_WORLD, self.worldSpace)
            donnees.SetBool(FPLUGTWO_LOCAL, self.localSpace)
            return True
    
    
        def recup(self, sh):
            donnees = sh.GetDataInstance()
            self.theTex = donnees.GetReal(FPLUGTWO_TEXTURE)
            self.flipx = donnees.GetInt32(FPLUGTWO_FLIPX)
            self.flipy = donnees.GetInt32(FPLUGTWO_FLIPY)
            self.worldSpace = donnees.GetBool(FPLUGTWO_WORLD)
            self.localSpace = donnees.GetBool(FPLUGTWO_LOCAL)
    
    
        def InitRender(self, sh, irs):
            self.recup(sh)
            self.irs = irs
            return 0
    
    
        def Output(self, sh, cd):
            pos = c4d.Vector()
            nor = c4d.Vector()
            space = 0
            if self.mode == space : # Espace Monde
                if cd.vd : # 3D
                    pos = cd.vd.p
                    nor = cd.vd.bumpn
                else : # Aperçu
                    if self.ape : pos = (cd.p - 0.5) * 100.0
                    else : return pos
            
            elif self.mode == space : # Espace UV
                pos = cd.p
            
            elif self.mode == space : # Espace Objet
                if cd.vd : # 3D
                    pos = cd.vd.p
                else : # Aperçu
                    if self.ape : pos = (cd.p - 0.5) * 100.0
                    else : return pos
        
        
            #color = c4d.Vector(cd.p[0], cd.p[1], 0)
            #color = c4d.Vector(cd.n[0], cd.n[1], cd.n[2])
            color = nor
            return color
        
        def FreeRender(self, sh):
            #Free any resources used for the precalculated data from InitRender().
            return
        
        
    
    
    def registerThePlug():
        #c4d.plugins.RegisterShaderPlugin(id, str, info, g, description[, disklevel][, res])
        
        IDS_FPLUGTWO=10000
        name = plugins.GeLoadString(IDS_FPLUGTWO);
        return plugins.RegisterShaderPlugin(PLUGIN_ID, name, 0, FPlugTwo, "FPlugTwo", 0)
        
    if __name__ == "__main__":
        registerThePlug()

  8. #8
    Pilier Avatar de Floc
    Date d'inscription
    novembre 2012
    C4D version
    R15 Studio
    OS
    WindOSX
    Messages
    1 617
    Ah grillé j'ai pas tilté assez vite

    [edit] Et oui ca va nettement mieux !
    Merci
    Dernière modification par Floc ; 01/02/2018 à 00h50.

  9. #9
    Pilier Avatar de Floc
    Date d'inscription
    novembre 2012
    C4D version
    R15 Studio
    OS
    WindOSX
    Messages
    1 617
    Hello. La question du soir.

    Est ce qu'il y a une condition particulière en python pour transformer un shader via les uv. Les exemple en C++ paraissent évident, mais en python rien ne se passe.

    exemple C++ qui est censé flipper l'image.
    Code:
        if(!shader) return Vector(1.0, 0.0, 0.0);        // return red if no bitmap present
    
        uv = cd->p;
        cd->p.x = 1.0 - cd->p.x;
        res = shader->Sample(cd);
        cd->p = uv;
    
        return res;
    Ma version python qui ne donne rien
    Code:
        def Output(self, sh, cd):
        
            .....
       
            uv = c4d.Vector()
            
            .....
                    
            elif self.mode == FPLUGTWO_UV : # Espace UV            
                if self.shader :
                    uv = cd.p
                    cd.p.x = 1.0 - cd.p.x
                    cd.p.y = cd.p.y * 2.0
                    color = self.shader.Sample(cd)
                    cd.p = uv
                else :
                    color = cd.p
            
            ......
            
            return color
    [Edit] Bon y a rien a faire. j'ai tourné le truc dans tous les sens, c'est comme si cd.p (la position dans l'espace uv) ne pouvait pas etre modifié. Avec cd.n en revanche pas de souci.
    Dernière modification par Floc ; 03/02/2018 à 02h16.

  10. #10
    Pilier Avatar de gr4ph0s
    Date d'inscription
    mai 2013
    C4D version
    R16 Studio
    OS
    win 7 X64
    Messages
    964
    En regardant vite fait il semblerait que tu n'es pas accès directement aux paramètres du vecteur(x, y, z), du moins tu n'écris pas sur le même vecteur.

    Bref en passant directement par une assignation du vecteur et non des membres de celui-ci ça fonctionne
    Code:
                if self.shader :
                    uv = cd.p
                    cd.p = c4d.Vector(1.0 - cd.p.x, cd.p.y * 2.0, cd.p.z)
                    color = self.shader.Sample(cd)
                    cd.p = uv
                else :
                    color = cd.p
    Je verrais lundi si on peux corriger ça
    Dernière modification par gr4ph0s ; 05/02/2018 à 10h06.
    SDK Specialist
    MAXON Computer GmbH

  11. #11
    Pilier Avatar de Floc
    Date d'inscription
    novembre 2012
    C4D version
    R15 Studio
    OS
    WindOSX
    Messages
    1 617
    Coooool !!
    Ca marche.

    Je l'aurai pas trouvé tout seul ça.
    Merci gr4ph0s

  12. #12
    Pilier Avatar de pxlntwrk
    Date d'inscription
    janvier 2012
    C4D version
    Autre
    OS
    7x64
    Messages
    1 122
    salut Floc,
    admiratif je suis...courageuse est la démarche..
    ::::::::::::::
    pxlntwrk.net

  13. #13
    Pilier Avatar de Floc
    Date d'inscription
    novembre 2012
    C4D version
    R15 Studio
    OS
    WindOSX
    Messages
    1 617
    merci pxl, oui et semée d'embuche


    Bon c'est a peine une version zéro, mais c'est quand même un premier pas vers le shader textureBombing.
    Rien d'impressionnant pour le moment (surtout pour les Cesar, Graphos et consors ), et vous allez me dire qu'on peu faire presque pareil avec un simple tilling.
    Et moi je je vous répondrai ouaip… mais c'est pas pareil.
    C'est au moins 1000 fois plus long a faire .

    Disons que la j'ai la base. il me reste a intégrer du blending, de la rotation, et un masque autre que rectangulaire.

    Avec une texture ou on voit bien le "zonage".
    Cliquez sur l'image pour la voir en taille réelle 

Nom : 		F_TexBombTest_0002.jpg 
Affichages :	6 
Taille :		185,6 Ko 
ID : 			21122


    Avec une texture de roche et étonnement ça marche déjà plutôt pas trop mal.
    Cliquez sur l'image pour la voir en taille réelle 

Nom : 		F_TexBombTest_Stone.jpg 
Affichages :	5 
Taille :		218,8 Ko 
ID : 			21123


    Alors j'ai évidement quelques questions.
    Notement niveau optimisation. parce que la c'est extremement lent, et pourtant le technique utilisé est plutôt légère en terme de cout calcul, mais pour la suite ca risque de se compliquer.

    - Aparement il n'y a pas de gestion de Matrices 2D ni en python ni en C4D. Donc je me demande en terme de performance si il vaut mieux utilser les matrices 3D de C4D ou écrire ma propre fonction de rotation.

    - en GLSL pratiquement toute les fonction mathematiques (floor, cos, etc… même rand) supporte les vecteur 2d, 3d, ou 4d. Je suis quasi sur que ce n'est pas le cas ni dans c4d, ni en python ( un truc peu m'echaper).
    En python on peu ecrirre a, b = 0.2, 1.5.
    Est ce qu'il n'y aurai pas une sintaxe pour ecrire genre : x, y = floor(a, b).
    Ou quelque chose de plus élégant que de toujours séparer et réassambler les composantes.

    - Question plutot a cesar (mais pas que)
    Dans ton shader matiere-python il y a un mecanisme pour gerer les preview dans le cas d'appels a volumeData.
    if cd.vd : # 3D
    UVs = cd.vd.p
    else : # Aperçu
    if self.ape : UVs = (cd.p - 0.5) * 100.0
    else : return UVs
    Comment ca fonctionne ? puisque cd.cd.p existe on ne devrait jamais passer par else. Est ce que C4d evalue deux fois
    la metode Output une fois avec cd.vd existant et une deuxieme fois cd.vd inexistant ? du coup on passe par la case
    else : # Aperçu
    Ou alors est ce que c'est magique ?
    Fichiers attachés Fichiers attachés
    Dernière modification par Floc ; 05/02/2018 à 20h22.

  14. #14
    Pilier Avatar de gr4ph0s
    Date d'inscription
    mai 2013
    C4D version
    R16 Studio
    OS
    win 7 X64
    Messages
    964
    Effectivement pas de matrices, ni de vecteur 2D.
    Mais une matrice/vecteur 2D n'est qu'un matrice/vecteur 3D dont un des axes ne bouge pas (0).
    Apres tu as une classe de Vecteur 4D dans C4D.

    Pour ce qui est des performances, déjà vire tout les print ceci ralentit fortement, essaye de "baker" le plus de choses possibles lors du InitRender
    Pas sur de comprendre ton problème de floor. Mais en tout cas tu as le module math.
    Code:
    import math
    
    a, b = 0.2, 1.5x, y = map(math.floor, [a, b])
    map va exécuter une fonction sur une liste
    SDK Specialist
    MAXON Computer GmbH

Discussions similaires

  1. [Question] Questions diverses
    Par Brice4D dans le forum Nouveaux membres
    Réponses: 2
    Dernier message: 27/06/2012, 23h49
  2. Diverses questions de modelisation
    Par AdrienPG dans le forum Modélisation
    Réponses: 10
    Dernier message: 07/01/2011, 11h58
  3. diverses questions...
    Par pg.design dans le forum Nouveaux membres
    Réponses: 5
    Dernier message: 20/02/2008, 19h36
  4. Diverses questions
    Par Brice_ dans le forum Général Cinema 4D
    Réponses: 20
    Dernier message: 10/02/2005, 11h22
  5. Questions diverses
    Par link83 dans le forum Général Cinema 4D
    Réponses: 16
    Dernier message: 26/04/2004, 01h03

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •  
Mediaworks - Logiciels 3D | Design Internet - Creation site internet