IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

[Blender] appel d'une fonction non reconnue


Sujet :

Python

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2018
    Messages : 4
    Par défaut [Blender] appel d'une fonction non reconnue
    Bonjour,
    Actuellement en stage, je travaille sur le développement d'un addon sous blender et je rencontre un problème lors de l'appel d'une fonction dans un script différent malgré l'import.
    Le premier fichier est supposé ouvrir l'explorateur de fichier et j'aimerais récupérer dans le deuxième script le path du fichier sélectionné par l'utilisateur le hic est que lorsque je sélectionne le fichier et que j'essaye de créer le graphique j'ai l'erreur suivante

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Traceback (most recent call last):
      File "/home/wquentel/.config/blender/2.79/scripts/addons/create_custom_graph/CustomGraphOperator.py", line 45, in execute
        self.a()
      File "/home/wquentel/.config/blender/2.79/scripts/addons/create_custom_graph/CustomGraphOperator.py", line 15, in a
        f = open(CustomDrawOperator.getPath(),"r")
    AttributeError: module 'create_custom_graph.CustomDrawOperator' has no attribute 'getPath'
     
    location: <unknown location>:-1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    import bpy
    import struct
    import os
    from bpy.types import Panel, Operator
     
     
    #---------------------------------
    #FileOpener and selector
    #---------------------------------
    #will contain the file from CustomDrawOperator for CustomGraphOperator
    class CustomDrawOperator(bpy.types.Operator):
        bl_idname = "object.custom_opener"
        bl_label = "Import"
        filepath = bpy.props.StringProperty(subtype="FILE_PATH")
        my_float = bpy.props.FloatProperty(name="Float")
        my_bool = bpy.props.BoolProperty(name="Toggle Option")
        my_string = bpy.props.StringProperty(name="String Value")
     
        def getPath(self):
            return self.filepath
     
        def execute(self, context):
            print()
            return {'FINISHED'}
     
        def invoke(self, context, event):
            context.window_manager.fileselect_add(self)
            return {'RUNNING_MODAL'}
     
        def draw(self, context):
            layout = self.layout
            col = layout.column()
            col.label(text="Custom Interface!")
            row = col.row()
            row.prop(self, "my_float")
            row.prop(self, "my_bool")
            col.prop(self, "my_string")
     
     
     
    def register():        
        bpy.utils.register_class(CustomDrawOperator)
    def unregister():        
        bpy.utils.unregister_class(CustomDrawOperator)
    et voici le deuxième fichier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    import bpy
    import bmesh
    import struct
    from . import CustomDrawOperator
    from bpy.types import Panel, Operator
    #--------------------------------------------------
    #Custom Operator to make Graph from data file
    #--------------------------------------------------  
    class CustomGraphOperator(bpy.types.Operator):
        bl_idname = "object.custom_draw"
        bl_label = "Import"
     
        #Will use raw data file to create uvsphere and place them
        def a(self):
            f = open(CustomDrawOperator.getPath(),"r")
            for line in f: 
                objName=line.split()[0]
                strX=line.split()[1]
                strY=line.split()[2]
                strZ=line.split()[3]
                x=float(strX)
                y=float(strY)
                z=float(strZ)
                print(objName," ",x," ",y," ",z)
                bpyscene = bpy.context.scene
                # Create an empty mesh and the object.
                mesh = bpy.data.meshes.new(objName)
                basic_sphere = bpy.data.objects.new(objName, mesh)
                # Add the object into the scene.
                bpyscene.objects.link(basic_sphere)
                bpyscene.objects.active = basic_sphere
                basic_sphere.select = True
                # Construct the bmesh cube and assign it to the blender mesh.
                bm = bmesh.new()
                bmesh.ops.create_uvsphere(bm, u_segments=32, v_segments=16, diameter=1)
                bm.to_mesh(mesh)
                bm.free()
                bpy.ops.object.modifier_add(type='SUBSURF')
                bpy.ops.object.shade_smooth()
                bpy.data.objects[objName].location.x += x
                bpy.data.objects[objName].location.y += y
                bpy.data.objects[objName].location.z += z
            f.close()
        def execute(self,context):
            self.a()
            return {'FINISHED'}
    def register():
        bpy.utils.register_class(CustomGraphOperator)
    def unregister():
        bpy.utils.unregister_class(CustomGraphOperator)

    Je pense que ma démarche est bonne pour la récupération du path mais j'avoue être incapable de comprendre pour quelle raison cela ne fonctionne pas
    Merci d'avance pour vos réponse !

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Salut,

    Relisez le message d'erreur, vous avez un module CustomDrawOperator.py qui contient une class CustomDrawOperator. Pour accéder à la class, il faudrait écrire CustomDrawOperator.CustomDrawOperator.
    Mais revoir le nommage de vos différents objets serait bien plus sain.... Et si vous n'avez pas d'idée sur comment procéder, le PEP8 est un bon début.
    note: revoir les class serait aussi nécessaire car cela corrigé, çà plantera encore (pour une autre raison).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2018
    Messages : 4
    Par défaut
    Ok merci, je viens de tester cela fonctionne mais pas moyen de récupérer la variable filepath, autrement quand vous dites revoir les class que voulez vous dire ?

  4. #4
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Tu fais

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    class CustomDrawOperator(bpy.types.Operator):
        bl_idname = "object.custom_opener"
        bl_label = "Import"
        filepath = bpy.props.StringProperty(subtype="FILE_PATH")
        my_float = bpy.props.FloatProperty(name="Float")
        my_bool = bpy.props.BoolProperty(name="Toggle Option")
        my_string = bpy.props.StringProperty(name="String Value")
     
        def getPath(self):
            return self.filepath
    puis

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    f = open(CustomDrawOperator.getPath(),"r")
    Sauf que la méthode getPath nécéssite une instance de la classe CustomDrawOperator pour être appelée ! Tu l'as définie ainsi.

    Donc soit tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    draw_op = CustomDrawOperator()
    f = open(draw_op.getPath(),"r")
    soit tu modifies ta classe pour que la méthode getpath soit appellable sans qu'on ait a créer une instance de l'objet (on appelle ca des méthodes statiques) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    @classmethod
    def getPath(cls):
            return cls.filepath
    EDIT : Du coup, j'évoque certainement l'autre raison de plantage auquel wiztricks pense.

  5. #5
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2018
    Messages : 4
    Par défaut
    Ok je viens de changer et de regarder les méthodes statiques que je ne connaissais pas vraiment, je résonnais toujours en Java par habitude d'où le CustomDrawOperator.getPath().
    Je reposte le code modifié avec un renommage "correct"
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    import bpy
    import struct
    import os
    from bpy.types import Panel, Operator
     
     
    #---------------------------------
    #FileOpener and selector
    #---------------------------------
    #will contain the file from CustomDrawOperator for CustomGraphOperator
    class FileOpener(bpy.types.Operator):
        bl_idname = "object.custom_opener"
        bl_label = "Import"
        filepath = bpy.props.StringProperty(subtype="FILE_PATH")
        my_float = bpy.props.FloatProperty(name="Float")
        my_bool = bpy.props.BoolProperty(name="Toggle Option")
        my_string = bpy.props.StringProperty(name="String Value")
     
        @staticmethod
        def getPath(self):
                return self.filepath
     
        def execute(self, context):
            print()
            return {'FINISHED'}
     
        def invoke(self, context, event):
            context.window_manager.fileselect_add(self)
            return {'RUNNING_MODAL'}
     
        def draw(self, context):
            layout = self.layout
            col = layout.column()
            col.label(text="Custom Interface!")
            row = col.row()
            row.prop(self, "my_float")
            row.prop(self, "my_bool")
            col.prop(self, "my_string")
     
     
     
    def register():        
        bpy.utils.register_class(FileOpener)
    def unregister():        
        bpy.utils.unregister_class(FileOpener)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    import bpy
    import bmesh
    import struct
    from . import CustomDrawOperator
    from bpy.types import Panel, Operator
    #--------------------------------------------------
    #Custom Operator to make Graph from data file
    #--------------------------------------------------  
    class CustomGraphOperator(bpy.types.Operator):
        bl_idname = "object.custom_draw"
        bl_label = "Import"
     
        #Will use raw data file to create uvsphere and place them
        def graphGenerator(self):
     
            f = open(CustomDrawOperator.getPath(),"r")
     
            #For each line will create a sphere and place it
            for line in f: 
                objName=line.split()[0]
                strX=line.split()[1]
                strY=line.split()[2]
                strZ=line.split()[3]
                x=float(strX)
                y=float(strY)
                z=float(strZ)
                print(objName," ",x," ",y," ",z)
                bpyscene = bpy.context.scene
                # Create an empty mesh and the object.
                mesh = bpy.data.meshes.new(objName)
                basic_sphere = bpy.data.objects.new(objName, mesh)
                # Add the object into the scene.
                bpyscene.objects.link(basic_sphere)
                bpyscene.objects.active = basic_sphere
                basic_sphere.select = True
                # Construct the bmesh cube and assign it to the blender mesh.
                bm = bmesh.new()
                bmesh.ops.create_uvsphere(bm, u_segments=32, v_segments=16, diameter=1)
                bm.to_mesh(mesh)
                bm.free()
                bpy.ops.object.modifier_add(type='SUBSURF')
                bpy.ops.object.shade_smooth()
                bpy.data.objects[objName].location.x += x
                bpy.data.objects[objName].location.y += y
                bpy.data.objects[objName].location.z += z
            f.close()
     
        def execute(self,context):
            self.graphGenerator()
            return {'FINISHED'}
    def register():
        bpy.utils.register_class(CustomGraphOperator)
    def unregister():
        bpy.utils.unregister_class(CustomGraphOperator)
    Par contre maintenant Python me soulève 1 erreurs dans les deux cas que tu m'as proposé
    Citation Envoyé par lg_53 Voir le message
    Donc soit tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    draw_op = CustomDrawOperator()
    f = open(draw_op.getPath(),"r")
    soit tu modifies ta classe pour que la méthode getpath soit appellable sans qu'on ait a créer une instance de l'objet (on appelle ca des méthodes statiques) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    @staticmethod
        def getPath(cls):
            return cls.filepath
    avec le premier j'ai
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Traceback (most recent call last):
      File "/home/wquentel/.config/blender/2.79/scripts/addons/create_custom_graph/CustomGraphOperator.py", line 50, in execute
        self.graphGenerator()
      File "/home/wquentel/.config/blender/2.79/scripts/addons/create_custom_graph/CustomGraphOperator.py", line 16, in graphGenerator
        draw_op=FileOpener()
    NameError: name 'FileOpener' is not defined
     
    location: <unknown location>:-1
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    location: <unknown location>:-1
     
    Traceback (most recent call last):
      File "/home/wquentel/.config/blender/2.79/scripts/addons/create_custom_graph/CustomGraphOperator.py", line 49, in execute
        self.graphGenerator()
      File "/home/wquentel/.config/blender/2.79/scripts/addons/create_custom_graph/CustomGraphOperator.py", line 16, in graphGenerator
        f = open(CustomDrawOperator.getPath(),"r")
    AttributeError: module 'create_custom_graph.CustomDrawOperator' has no attribute 'getPath'
     
    location: <unknown location>:-1
    Je ne comprend pas bien comment je peux récupérer filepath vu que dans ma méthode j'ai besoin du self, de plus quand j'essaye de la récupérer sans getPass() le compilateur me ressort le type de filepath ALORS que si je fais f=open(self.filepath,'r') dans CustomDrawOperator cela fonctionne

  6. #6
    Membre Expert

    Homme Profil pro
    Ingénieur calcul scientifique
    Inscrit en
    Mars 2013
    Messages
    1 229
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Alpes Maritimes (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur calcul scientifique

    Informations forums :
    Inscription : Mars 2013
    Messages : 1 229
    Par défaut
    Il faut aussi changer ton import si tu changes le noms de tes classes.

    Si le fichier qui contient la classe FileOpener s'appelle mettons toto.py, dans ton autre fichier il faut écrire

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    from toto import FileOpener
     
    a=FileOpener()  ###Et je fait un appel pour tester
    et remplacer tout les CustomDrawOperator par des FileOpener.
    Sinon si tu veux importer juste le module

    ou juste

    et après tu accèdes au fonctions de toto en procédant comme suit :

    PS : J'ai édité mon précédent message (c'est du mot-clé @classmethod que tu as besoin ici et non @staticmethod). Tu dois d'abord résoudre ton problème d'import avant.

  7. #7
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 741
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 741
    Par défaut
    Citation Envoyé par Alkaladur Voir le message
    Ok merci, je viens de tester cela fonctionne mais pas moyen de récupérer la variable filepath, autrement quand vous dites revoir les class que voulez vous dire ?
    Vous voyez bien combien vous pataugez malgré toutes les indications qui vous sont données...
    Poser le crayon, prendre le temps d'ouvrir un tuto pour voir ou revoir module, class, portée des variables s'inventer des exercices pour voir si on a bien compris tout çà est probablement frustrant mais si vous ne comprenez pas trop ce que fait le code que vous avez écrit ni les messages d'erreurs, c'est nécessaire.
    A vous de voir.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  8. #8
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Janvier 2018
    Messages
    4
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 28
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Service public

    Informations forums :
    Inscription : Janvier 2018
    Messages : 4
    Par défaut
    Citation Envoyé par wiztricks Voir le message
    Vous voyez bien combien vous pataugez malgré toutes les indications qui vous sont données...
    Poser le crayon, prendre le temps d'ouvrir un tuto pour voir ou revoir module, class, portée des variables s'inventer des exercices pour voir si on a bien compris tout çà est probablement frustrant mais si vous ne comprenez pas trop ce que fait le code que vous avez écrit ni les messages d'erreurs, c'est nécessaire.
    A vous de voir.

    - W
    J'ai compris le code que j'ai écrit, le soucis est que je l'avais écrit d'un seul bloc pour me familiariser avec l'API sous blender que je trouve très mal documentée car peu de gens travaillent dessus, les choses se sont vu compliquées quand j'ai voulu séparer en plusieurs fichiers mon code pour une meilleure lecture, étant développeur JAVA à la base je pensais à tord que l'import fonctionnait de la même manière ce qui m'a causé les soucis de lecture de variable.
    Actuellement j'ai du mal à cerner
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
     filepath = bpy.props.StringProperty(subtype="FILE_PATH")
    Car j'ai trouver cette exemple de code d'ouverture de fichier sur la DOC blender et quand je regarde les fonctions de bpy.props.StringProperty, je ne vois aucun moyen de récupérer le path complet de fichier car blender "simplifie" par des // les dossiers,etc..
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    Traceback (most recent call last):
      File "/home/wquentel/.config/blender/2.79/scripts/addons/create_custom_graph/CustomGraphOperator.py", line 49, in execute
        self.graphGenerator()
      File "/home/wquentel/.config/blender/2.79/scripts/addons/create_custom_graph/CustomGraphOperator.py", line 16, in graphGenerator
        f = open(CustomDrawOperator.FileOpener.filepath,"r")
    TypeError: invalid file: (<built-in function StringProperty>, {'subtype': 'FILE_PATH', 'attr': 'filepath'})
     
    location: <unknown location>:-1
    et quand j'essaye de faire un print de ma variable je reçois son type sois le code ci-dessus et non le le path de mon fichier, ce qui est étrange car je peux faire un f=open(self.filepath, 'r') dans mon fichier.
    Résultat je suis bloqué lorsque j'essaye "d'externaliser" cette variable pour l'utiliser dans mon second fichier car pour utiliser le filepath je suis obliger de faire un self.

    EDIT: j'ai rajouté l'erreur ressortie par le compilateur

Discussions similaires

  1. [Débutant] Appel d'une fonction non statique
    Par cool dans le forum Général Java
    Réponses: 3
    Dernier message: 21/08/2011, 19h20
  2. appel à une fonction non précédement déclarée
    Par adeltimple dans le forum Langage
    Réponses: 4
    Dernier message: 16/07/2010, 19h09
  3. Réponses: 10
    Dernier message: 31/03/2010, 23h34
  4. copie d'une variable non reconnue dans une fonction
    Par paragoge dans le forum ActionScript 3
    Réponses: 1
    Dernier message: 27/10/2009, 13h30
  5. Réponses: 2
    Dernier message: 13/11/2006, 06h42

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo