2022-12-29 23:00:24 +01:00
import bpy # Blender
import importlib
2022-12-30 02:41:32 +01:00
import sys
2022-12-29 23:00:24 +01:00
import time
###############################################################################
# twin_doc-gen.py
# @title: Script (bpy) de génération de la documentation statique de l'environnement 3D pour jumeau numérique
# @project: Blender-EduTech
# @lang: fr
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2022 Philippe Roy
# @license: GNU GPL
###############################################################################
# UPBGE scene
scene = bpy . context . scene
# scene=bpy.data.scenes["Scene"]
# Cards description
card_description = { }
# Documentation du sytème
2022-12-30 02:41:32 +01:00
path = scene . objects [ ' Doc ' ] [ ' path ' ]
name = scene . objects [ ' Doc ' ] [ ' system ' ] + ' _doc '
spec = importlib . util . spec_from_file_location ( name , path )
system = importlib . util . module_from_spec ( spec )
sys . modules [ spec . name ] = system
spec . loader . exec_module ( system )
2022-12-29 23:00:24 +01:00
# system=importlib.import_module(scene.objects['Doc']['system']+'_doc') # Système
2022-12-30 02:41:32 +01:00
system_card = system . get_system_card ( )
card_description . update ( system . get_card_description ( ) )
2022-12-29 23:00:24 +01:00
###############################################################################
# Documentation Python
###############################################################################
# "oop-card"
2022-12-30 02:41:32 +01:00
python_card = [ " function-card " , " alternative-card " , " loop-card " , " flow-card " , " text-card " , " list-card " , " dict-card " , " console-card " , " sleep-card " , " python-card " ]
#python_card=["function-card"]
# python_card=["function-card" ,"alternative-card"]
2022-12-29 23:00:24 +01:00
# Fonction
card_function_title = " Fonction "
card_function_text = " La définition d \" une fonction se fait avec \n \' def \' . La fonction peut renvoyer une \n valeur avec \' return \' . \n \n "
card_function_text = card_function_text + " def fonction_1 (arguments) : \n instruction_1 \n instruction_2 \n .... \n return valeurs_renvoyées \n \n "
card_function_text = card_function_text + " Les arguments sont des données \n transmises à la fonction. "
card_function_url = [ [ " w3schools.com : functions " , " https://www.w3schools.com/python/python_functions.asp " ] ]
card_description . update ( { " function-card " : [ card_function_title , card_function_text , card_function_url ] } )
# Alternative
card_alternative_title = " Alternative "
card_alternative_text = " L \" alternative permet d \" éxécuter des \n instructions en fonction d \" un test. \n "
card_alternative_text = card_alternative_text + " Elle se programme en suivant la suite : \n \' if \' (si) ... \' else \' (sinon) ... \n \n "
card_alternative_text = card_alternative_text + " if condition : \n "
card_alternative_text = card_alternative_text + " instruction_1 \n "
card_alternative_text = card_alternative_text + " else : \n "
card_alternative_text = card_alternative_text + " instruction_2 \n \n "
card_alternative_text = card_alternative_text + " Le \' else \' (sinon) est facultatif. "
card_alternative_url = [ [ " w3schools.com : if ... else " , " https://www.w3schools.com/python/python_conditions.asp " ] ]
card_description . update ( { " alternative-card " : [ card_alternative_title , card_alternative_text , card_alternative_url ] } )
# Boucles
card_loop_title = " Boucles "
card_loop_text = " Il y a deux types de boucle : \n - avec \' for \' pour définir un nombre de \n répétition (ici n), \n - avec \' while \' (tant que) pour prendre \n en compte une condition. \n \n "
card_loop_text = card_loop_text + " for i in range (n) : \n instruction \n \n "
card_loop_text = card_loop_text + " while condition : \n instruction "
card_loop_url = [ [ " w3schools.com : for " , " https://www.w3schools.com/python/python_for_loops.asp " ] ,
[ " w3schools.com : while " , " https://www.w3schools.com/python/python_while_loops.asp " ] ]
card_description . update ( { " loop-card " : [ card_loop_title , card_loop_text , card_loop_url ] } )
# Flux
card_flow_title = " Contrôle du flux "
card_flow_text = """ Les structures (if, while, for) peuvent \n être gérées plus finement par les \n fonctions ' break ' , ' continue ' et ' pass ' . \n
- ' break ' : termine l " itération en cours et \n arrête la boucle.
- ' continue ' : termine l " itération en cours et \n reprend la boucle.
- ' pass ' : instruction vide . """
card_flow_url = [ [ " w3schools.com : break " , " https://www.w3schools.com/python/ref_keyword_break.asp " ] ,
[ " w3schools.com : continue " , " https://www.w3schools.com/python/ref_keyword_break.asp " ] ,
[ " w3schools.com : pass " , " https://www.w3schools.com/python/ref_keyword_pass.asp " ] ]
card_description . update ( { " flow-card " : [ card_flow_title , card_flow_text , card_flow_url ] } )
# Chaîne de caractères
card_text_title = " Chaîne de caractères "
card_text_text = """ Une chaîne de caractères correspond à un \n texte (mot, phrase). Elle est délimitée \n par " ou ' : texte = ' Bonjour ! ' \n
- texte1 + texte2 : concaténe plusieurs \n chaînes .
- len ( texte ) : renvoie la longueur de texte .
- " \\ n " : caractère aller à la ligne .
- texte [ i ] : renvoie le caractère du rang i de \n texte ( commence à 0 ) .
- texte [ 2 : 5 ] : renvoie les caractères du rang \n 2 au rang 5.
- texte . replace ( " a " , " b " ) : remplace les " a " en " b " . """
card_text_url = [
[ " Doc. Python v3 Français : string " , " https://docs.python.org/fr/3/library/string.html " ] ,
[ " w3schools.com : strings " , " https://www.w3schools.com/python/python_strings.asp " ] ]
card_description . update ( { " text-card " : [ card_text_title , card_text_text , card_text_url ] } )
# Liste
card_list_title = " Liste "
card_list_text = """ Une liste est une séquence d " éléments. \n Elle est délimitée par des crochets :
liste = [ ' pomme ' , 7 , ' rouge ' , True ] \n
- liste [ i ] : renvoie l " élément du rang i de la \n liste (commence à 0).
- liste . append ( ' neige ' ) : ajoute ' neige ' à la \n fin de la liste .
- len ( liste ) : renvoie le nombre d " éléments.
- liste . sort ( ) : classe par ordre croissant la \n liste ( alphabétiquement / numériquement ) .
- liste . remove ( ' rouge ' ) : enlève la première \n occurence de la valeur . """
card_list_url = [
[ " Doc. Python v3 Français : list " , " https://docs.python.org/fr/3/library/stdtypes.html#sequence-types-list-tuple-range " ] ,
[ " w3schools.com : lists " , " https://www.w3schools.com/python/python_lists.asp " ] ]
card_description . update ( { " list-card " : [ card_list_title , card_list_text , card_list_url ] } )
# Dictionnaire
card_dict_title = " Dictionnaire "
card_dict_text = """ Une liste est une collection d " éléments. \n Elle est délimitée par des accolades, \n chaque valeur comporte une clé unique :
dico = { ' nom ' : ' Haddock ' , ' prénom ' : \n ' Archibald ' , ' année ' : 1940 } \n
- dico [ clé ] : renvoie la valeur liée à la clé .
- dico . update ( ' domicile ' : ' Moulinsart ' ) : met \n à jour les paires de clé / valeur .
- len ( dico ) : renvoie le nombre d " éléments.
- list ( dico ) : renvoie la liste des clés .
- dico . pop ( " année " ) : enlève la valeur associée \n à la clé . """
card_dict_url = [
[ " Doc. Python v3 Français : dict " , " https://docs.python.org/fr/3/library/stdtypes.html#mapping-types-dict " ] ,
[ " w3schools.com : dictionaries " , " https://www.w3schools.com/python/python_dictionaries.asp " ] ]
card_description . update ( { " dict-card " : [ card_dict_title , card_dict_text , card_dict_url ] } )
# Objet (POO)
card_oop_title = " Programmation \n orientée objet (POO) "
card_oop_text = " \n FIXME "
card_oop_url = [ [ " w3schools.com : classes & objects " , " https://www.w3schools.com/python/python_classes.asp " ] ]
card_description . update ( { " oop-card " : [ card_oop_title , card_oop_text , card_oop_url ] } )
# Console
card_console_title = " Console "
card_console_text = " Si vous avez executé Ropy dans un \n terminal (avec l \" option \' -con \' ), vous \n pouvez utiliser le terminal comme \n console de debuggage. \n \n "
card_console_text = card_console_text + " print( \' Bonjour ! \' ) \n -> Affiche le texte dans la console. \n \n "
card_console_text = card_console_text + " variable = input () \n -> Permet la saisie, par exemple : \n "
card_console_text = card_console_text + " entree = \' \' \n while entree == \' \' : \n entree = input () "
card_console_url = [ [ " w3schools.com : print " , " https://www.w3schools.com/python/ref_func_print.asp " ] ,
[ " w3schools.com : input " , " https://www.w3schools.com/python/ref_func_input.asp " ] ]
card_description . update ( { " console-card " : [ card_console_title , card_console_text , card_console_url ] } )
# Temps
card_sleep_title = " Gestion du temps "
card_sleep_text = " Vous pouvez créer des temporisations \n dans le déroulement du script. \n \n "
card_sleep_text = card_sleep_text + " time.sleep(x) \n -> Marque d \" un temps d \" arrêt de \n x secondes. \n \n "
card_sleep_text = card_sleep_text + " Il faudra préalablement importer la \n bibliothèque \' time \' avec \' import time \' . "
card_sleep_url = [ [ " Doc. Python v3 Fr : sleep " , " https://docs.python.org/fr/3/library/time.html#time.sleep " ] ]
card_description . update ( { " sleep-card " : [ card_sleep_title , card_sleep_text , card_sleep_url ] } )
# Python
card_python_title = " Langage Python "
card_python_text = """ Le Python est un langage de programmation \n interprété open source. Python vise à être \n visuellement épuré avec une syntaxe \n clairement séparée des mécanismes de \n bas niveau. \n
Python possède beaucoup de bibliothèques \n spécialisées . Multiplateformes et \n multiparadigme , il est utilisé dans de \n nombreux contextes : scriptage , calcul \n numérique , prototypage , enseignement , \n ou encore comme langage de commande \n pour de nombreux logiciels . """
card_python_url = [ [ " python.org " , " https://python.org " ] , [ " AFPy " , " https://www.afpy.org " ] ]
card_description . update ( { " python-card " : [ card_python_title , card_python_text , card_python_url ] } )
###############################################################################
# Génération statique des pages (fichiers *_doc-fr.blend)
###############################################################################
# Sortir de la génération
def text_gene_end ( ) :
print ( " Génération des pages effectuée. " )
# print ("Génération des pages effectuée.")
# for item in scene.objects:
# print (item.name)
# Génération des pages
def text_gene ( obj ) :
print ( " Génération des pages de la documentation pour le chapitre : " + obj . name + " ... " )
if obj . name == " Doc_chap-system " :
chap_card = system_card
2022-12-30 02:41:32 +01:00
rep_chap = bpy . data . objects [ " Doc_chap-system " ]
2022-12-29 23:00:24 +01:00
if obj . name == " Doc_chap-python " :
chap_card = python_card
2022-12-30 02:41:32 +01:00
rep_chap = bpy . data . objects [ " Doc_chap-python " ]
2022-12-29 23:00:24 +01:00
# Création des objets 3D
2022-12-30 02:41:32 +01:00
# bpy.ops.collection.create(name='Collection')
2022-12-29 23:00:24 +01:00
i = 1
for card in chap_card :
print ( " Génération de la page : " + card )
# Repère page
rep_ref = bpy . data . objects [ " Doc_chap-ref " ]
2022-12-30 02:41:32 +01:00
rep_page = duplicateObject ( scene , " Doc_page- " + str ( card ) , " Doc_chap-ref " , rep_chap . location . x + i * 100 , rep_chap . location . y , rep_chap . location . z )
# collection = bpy.data.collections["Test"]
# collection.objects.link(rep_page)
2022-12-29 23:00:24 +01:00
i + = 1
2022-12-30 02:41:32 +01:00
# Titre
titre_name = " Doc_title- " + str ( card )
titre_ref = bpy . data . objects [ " Doc_title-ref " ]
titre = addText ( scene , titre_name , " Doc_title-ref " , card_description [ card ] [ 0 ] ,
titre_ref . location . x - rep_ref . location . x ,
titre_ref . location . y - rep_ref . location . y ,
titre_ref . location . z - rep_ref . location . z )
titre . parent = rep_page
# Texte de la page en une seule fois
ligne_name = " Doc_text- " + str ( card )
ligne_ref = bpy . data . objects [ " Doc_text-l1-ref " ]
ligne_text = addText ( scene , ligne_name , " Doc_text-l1-ref " , card_description [ card ] [ 1 ] ,
ligne_ref . location . x - rep_ref . location . x ,
ligne_ref . location . y - rep_ref . location . y ,
ligne_ref . location . z - rep_ref . location . z )
# bpy.data.collections["Doc generation"].objects.link(ligne_text)
ligne_text . parent = rep_page
# Texte de la page découpé
# lines = card_description[card][1].split("\n")
# for j in range (13):
# ligne_name = "Doc_text-l"+str(j+1)+"-"+str(card)
# ligne_ref=bpy.data.objects["Doc_text-l"+str(j+1)+"-ref"]
# # ligne_ref.data.body="A"
# if j >= len(lines):
# pass
# else:
# if len(lines[j]) ==0:
# pass
# else:
# ligne_text = addText(scene, ligne_name, "Doc_text-l"+str(j+1)+"-ref", lines[j],
# ligne_ref.location.x-rep_ref.location.x,
# ligne_ref.location.y-rep_ref.location.y,
# ligne_ref.location.z-rep_ref.location.z)
# bpy.data.collections["Doc generation"].objects.link(ligne_text)
# ligne_text.parent = rep_page
# # for obj_selected in bpy.context.selected_objects:
# # obj_selected.select_set(False)
# # bpy.ops.object.join()
2022-12-29 23:00:24 +01:00
# Fin
print ( " Génération des pages de la documentation pour le chapitre : " + obj . name + " Ok " )
###############################################################################
# Bas niveau duplication d'objet
###############################################################################
2022-12-30 02:41:32 +01:00
# Copier un object
2022-12-29 23:00:24 +01:00
def duplicateObject ( scene , name , src , x , y , z ) :
2022-12-30 02:41:32 +01:00
for obj in bpy . context . selected_objects :
obj . select_set ( False )
bpy . data . objects [ src ] . select_set ( True )
bpy . ops . object . duplicate ( )
for obj in bpy . context . selected_objects :
break
2022-12-29 23:00:24 +01:00
obj . name = name
obj . scale = bpy . data . objects [ src ] . scale
obj . location = ( x , y , z )
return obj
2022-12-30 02:41:32 +01:00
# Créer un texte
def addText ( scene , name , src , body , x , y , z ) :
curve = duplicateObject ( scene , name , src , x , y , z )
curve . data . body = body
return curve
# Créer un maillage texte
def addTextMesh ( scene , name , src , body , x , y , z ) :
curve = duplicateObject ( scene , name , src , x , y , z )
curve . data . body = body
mesh = bpy . data . meshes . new_from_object ( curve )
obj = bpy . data . objects . new ( name , mesh )
obj . matrix_world = curve . matrix_world
for obj_selected in bpy . context . selected_objects :
obj_selected . select_set ( False )
curve . select_set ( True )
bpy . ops . object . delete ( )
obj . name = name
return obj
2022-12-29 23:00:24 +01:00
###############################################################################
# Main
###############################################################################
2022-12-30 02:41:32 +01:00
text_gene ( scene . objects [ " Doc_chap-system " ] )
2022-12-29 23:00:24 +01:00
text_gene ( bpy . data . objects [ " Doc_chap-python " ] )
text_gene_end ( )