User Tools

Site Tools


doc_opener

====== Differences ====== This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
doc_opener [2015/08/19 14:46]
swann
doc_opener [2015/08/20 12:07] (current)
swann [c. custompath operator]
Line 32: Line 32:
 Dans cette partie, nous allons éclaircir le fonctionnement de certaines fonctions clef de l'​addon. Dans cette partie, nous allons éclaircir le fonctionnement de certaines fonctions clef de l'​addon.
  
-=== a. initSceneProperties ===+==== a. initSceneProperties ​====
 C'est ici que ce déroule l'​enregistrement des variables de scènes, nécessaires à toutes sortes de choses. On retrouve par exemple tous les champs, que ce soit la séquence, l'​asset ou autre sous forme de variable de scène ici. C'est ici que ce déroule l'​enregistrement des variables de scènes, nécessaires à toutes sortes de choses. On retrouve par exemple tous les champs, que ce soit la séquence, l'​asset ou autre sous forme de variable de scène ici.
 Cette fonction de divise en deux parties, l'​instentiations de variables déstinées à être **dynamiques** ou **statiques**.\\ Cette fonction de divise en deux parties, l'​instentiations de variables déstinées à être **dynamiques** ou **statiques**.\\
Line 91: Line 91:
 Cette dernière consiste à appeler la fonction **update_naming(self,​context)** __à chaque modification de la propriété__. Ce qui nous amène à cette fonction. Cette dernière consiste à appeler la fonction **update_naming(self,​context)** __à chaque modification de la propriété__. Ce qui nous amène à cette fonction.
  
-=== b. update_naming ===+==== b. update_naming ===
 +Comme précédement expliqué, Opener utilise la librairie de Naming. Cette dernière est mise en place dans le module interface.py,​ la fonction update_naming est chargé de préparer le dictionnaire avec tous les champs avant de le charger avec la librairie. 
 +<code python>​ 
 +#Copie du dictionnaire pour des vérifications 
 +temp = ressources.path.copy() 
 +     
 +#Nettoyage du dictionnaire path 
 +ressources.path.clear() 
 +     
 +#​Séparation des éléments en fonction de l'OS 
 +if sys.platform == '​win32':​ 
 +   dest = bpy.context.scene.drives.split('​\\'​) 
 +else: 
 +   dest = bpy.context.scene.drives.split('/'​) 
 +#Mise à jour du dictionnaire 
 +if bpy.context.scene.roots == '​LIB':​ 
 +   ​ressources.path['​Lib'​] = '​LIB'​ 
 +   ​ressources.path['​Family'​]=bpy.context.scene.famille 
 +   #Si jamais l'​asset sélectinné dans la liste est Other lors de la MAJ, on l'​ajoute aux assets 
 +   if bpy.context.scene.asset == '​other':​ 
 +      #​Construction du tuple temporaire pour vérifier son unicité dans la liste des asset 
 +      tempAsset = (str(bpy.context.scene.newA),​str(bpy.context.scene.newA),''​) 
 +      #Si il n'​existe pas alors on l'​ajoute 
 +      if tempAsset not in ressources.Items_asset:​ 
 +         #On récupère le nouvel asset à ajouter dans le dictionnaire 
 +         ​ressources.path['​Asset'​]=bpy.context.scene.newA 
 +         #On ajoute cet asset à la liste 
 +         ​ressources.Items_asset.append((str(bpy.context.scene.newA),​str(bpy.context.scene.newA),''​)) 
 +         ​UpdateEnum('',​ressources.Items_asset,'​asset','',''​) 
 +         ​bpy.context.scene.asset = bpy.context.scene.newA 
 +       
 +      else: 
 +         ​bpy.context.scene.newA = ""​ 
 +           
 +  else: 
 +     ​ressources.path['​Asset'​]=bpy.context.scene.asset 
 +</​code>​ 
 + 
 +Dans les lignes suivantes, les champs dynamique sont mis à jour, si modification il y a eu. 
 +<code python>​ 
 +#​................Quelques lignes plus tard.............. 
 +#Si jamais lors de l'​execution de la fonction, on se trouve dans la fenêtre MOVIE alors: 
 +elif (bpy.context.scene.roots == '​MOVIE'​) and (bpy.context.scene.drives != '​none'​) and (temp['​Dept'​] == ressources.path['​Dept'​]) and ('​Shot'​ in temp) and ('​Sequence'​ in temp): 
 +   temps = persistence.load_seq() 
 +   for i in range(len(temps)):​ 
 +      y = (str(temps[i]),​str(temps[i]),''​) 
 +      if y not in ressources.Items_seq:​ 
 +        ressources.Items_seq.append((str(temps[i]),​str(temps[i]),''​)) 
 +        change = True 
 +   #Si il y a de nouvelles séquences, on les ajoutes 
 +   if change: 
 +      UpdateEnum('',​ressources.Items_seq,'​seq','','​none'​) 
 +      bpy.context.scene.shot = ressources.Items_shot[0][0] 
 +   #Si jamais le shot n'a pas changé 
 +   elif temp['​Shot'​] == bpy.context.scene.shot:​ 
 +      #On va scanner les dossier pour vérifier la présence de nouveaux shots 
 +      temps = persistence.load_shots() 
 +      ressources.Items_shot.clear() 
 +      ressources.Items_shot.append(('​none','​none',''​)) 
 +      for i in range(len(temps)):​ 
 +         y = (str(temps[i]),​str(temps[i]),''​) 
 +         #Si jamais il y en a des nouveaux, on les ajoutes 
 +         if y not in ressources.Items_shot:​ 
 +            ressources.Items_shot.append((str(temps[i]),​str(temps[i]),''​)) 
 +     #On met à jour la liste des shots 
 +     ​UpdateEnum('',​ressources.Items_shot,'​shot','','​none'​)  
 +</​code>​ 
 + 
 +Ces dernières lignes sont également très importantes,​ c'est ici que l'on va appeler la fonction qui, à l'aide de la librairie Naming et du dictionnaire ressource.path va génerer et vérifier l'​authenticité du chemin et des nom par rapport à une syntax précise. 
 + 
 +<code python>​ 
 +#​................Quelques lignes plus tard.............. 
 +try: 
 +   ​bpy.context.scene.newF = create_naming(self,​context,'',​ressources.path,​ressources.command) ​   
 +   ​files.Update_ListFile(bpy.context.scene.newF) 
 +except: 
 +   ​print('​naming no setup, clearing list'​) 
 +   #​Nettoyage de la liste des fichier 
 +   ​bpy.context.scene.custom.clear() 
 +   ​ressources.command.append("​! missing field !") 
 +    
 +</​code>​ 
 + 
 +Nous allons maintenant parcourir un des opérateurs crée pour l'​addon. Il faut savoir que dans Blender, les Operateurs représentent un des outils les plus pratiques pour le développement pour de nombreuses raisons( ils sont facilement accessible pour l'​utilisateur,​ ils peuvent prendre des arguments,​etc,​...).\\ 
 +Dans l'​Opener,​ j'​utilise aussi les opérateurs à des fins ergonomiques pour mettre en place des boutons. En fin de compte, chaque boutons est un opérateur auquel on a assigné une icône lors de son appel dans l'​interface. 
 + 
 + 
 +==== c. custompath operator==== 
 + 
 +Pour apprendre à faire un opérateur de base, suivez le lien suivant:​[[http://​www.blender.org/​api/​blender_python_api_2_57_release/​bpy.types.Operator.html|Blender Operator Guide]]\\ 
 + 
 +La première partie de l'​opérateur consiste naturellement à déclarer les différents champs est variables nécessaire:​ 
 +<code python>​ 
 +#Entête avec héritage de l'​object Operator de blender, nécessaire à chaque fois que l'on créer un opérateur 
 +class OBJECT_OT_custompath(bpy.types.Operator):​ 
 + ​bl_idname = "​object.custom_path"​ 
 + ​bl_label = "​open"​ 
 + ​__doc__ = "" ​   
 +     
 + ​filename_ext = ""​ 
 + ​filter_glob = StringProperty(default="",​ options={'​HIDDEN'​},​subtype='​DIR_PATH'​) ​    
 +         
 + 
 + #​Variable stockant le chemin choisi 
 + ​filepath = StringProperty(name="​File Path", description="​Filepath importing store dir", maxlen= 1024) 
 + #​optionnel,​ récupère les fichiers séléctionnés  
 + files = CollectionProperty( 
 +  name="​File Path",​ 
 +  type=bpy.types.OperatorFileListElement) 
 +</​code>​ 
 + 
 +Ici il s'agit du corps de l'​opérateur,​ la fonction execute va s'​éxecuter à chaque appel de l'​opérateur. Il en est de même ,pour les fonctions draw et invoke.  
 +<code python>​ 
 + def execute(self,​ context): 
 +  #ajout du chemin sélectionné ​    
 +  ressources.Items.append((str(self.properties.filepath),​str(self.properties.filepath),""​)) 
 +  #Création du tuple temporaire 
 +  t=(str(self.properties.filepath),​str(self.properties.filepath))) 
 +  #Mise à jour de la liste des dossier racine 
 +  interface.UpdateEnum(bpy.types.Scene,​ressources.Items,'​Store',​t) 
 +         
 +  #Sauvegarde du dossier sélectionné de manière persistante 
 +  persistence.write_config() 
 +  #Find de fonction 
 +  return {'​FINISHED'​} 
 +   
 +  #Fonction d'​affichage de l'​explorateur de fichier 
 +  def draw(self, context): 
 +   ​self.layout.operator('​file.select_all_toggle'​) ​        
 +  def invoke(self,​ context, event): 
 +   wm = context.window_manager 
 +   ​wm.fileselect_add(self) 
 +   ​return {'​RUNNING_MODAL'​} ​     
 +</​code>​
 ---- ----
 <WRAP center round important 60%> <WRAP center round important 60%>
doc_opener.1439995572.txt.gz · Last modified: 2015/08/19 14:46 by swann