jumeaux-numeriques/twin_doc.py

645 lines
34 KiB
Python
Raw Normal View History

import bge # Bibliothèque Blender Game Engine (UPBGE)
import bpy # Blender
import os
import importlib
import webbrowser
import time
###############################################################################
2022-12-11 10:28:41 +01:00
# twin_doc.py
2022-12-13 02:42:31 +01:00
# @title: Documentation de l'environnement 3D pour jumeau numérique
# @project: Blender-EduTech
# @lang: fr
# @authors: Philippe Roy <philippe.roy@ac-grenoble.fr>
# @copyright: Copyright (C) 2020-2023 Philippe Roy
# @license: GNU GPL
###############################################################################
# UPBGE scene
scene = bge.logic.getCurrentScene()
# Colors
color_doc_chap = (0.198, 0.109, 0.8, 1) # Violet
color_doc_fct = (0.198, 0.109, 0.8, 1) # Violet
color_doc_hl = (0.8, 0.005, 0.315, 1) # Magenta
# color_doc_activate = (0.936, 0.033, 1, 1) # Activé : Rose
color_doc_activate = (0.051, 0.270, 0.279,1) # Turquoise
# color_doc_activate = (0.936, 0.033, 1, 1) # Activé : Rose
# UPBGE constants
JUST_ACTIVATED = bge.logic.KX_INPUT_JUST_ACTIVATED
JUST_RELEASED = bge.logic.KX_INPUT_JUST_RELEASED
ACTIVATE = bge.logic.KX_INPUT_ACTIVE
# JUST_DEACTIVATED = bge.logic.KX_SENSOR_JUST_DEACTIVATED
# Cards description
card_description ={}
# Documentation du sytème
system=importlib.import_module(scene.objects['System']['system']+'_doc') # Système
system_card = system.get_system_card()
card_description.update(system.get_system_card_description())
###############################################################################
# Documentation Python
###############################################################################
# "oop-card"
python_card=["function-card", "alternative-card", "loop-card", "flow-card", "text-card", "list-card", "dict-card", "console-card", "sleep-card", "python-card"]
# Fonction
2022-12-16 18:39:00 +01:00
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"
2022-12-16 18:39:00 +01:00
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
2022-12-16 18:39:00 +01:00
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"
2022-12-16 18:39:00 +01:00
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."
2022-12-16 18:39:00 +01:00
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
2022-12-16 18:39:00 +01:00
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"
2022-12-16 18:39:00 +01:00
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"]]
2022-12-16 18:39:00 +01:00
card_description.update({"loop-card" : [card_loop_title, card_loop_text, card_loop_url]})
# Flux
2022-12-16 18:39:00 +01:00
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 \n et reprend la boucle.
- pass : instruction vide."""
2022-12-16 18:39:00 +01:00
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"]]
2022-12-16 18:39:00 +01:00
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.
- texte[2:5] : renvoie les caractères du rang \n 2 au rang 5.
- texte.replace("a","b") : remplace les "a" \n par des "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"]]
2022-12-16 18:39:00 +01:00
card_description.update({"text-card" : [card_text_title, card_text_text, card_text_url]})
# Liste
2022-12-16 18:39:00 +01:00
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).
2023-01-01 14:48:27 +01:00
- liste.remove("rouge") : enlève la première \n occurence de la valeur "rouge"."""
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"]]
2022-12-16 18:39:00 +01:00
card_description.update({"list-card" : [card_list_title, card_list_text, card_list_url]})
# Dictionnaire
2022-12-16 18:39:00 +01:00
card_dict_title="Dictionnaire"
card_dict_text=""" Un dictionnaire est une collection \n d'éléments. Il est délimité par des \n accolades, chaque valeur est associée à
2023-01-01 14:48:27 +01:00
une clé unique : dct = {"nom": "Haddock",\n "prénom": "Archibald", "année": 1940} \n
- dct[clé] : renvoie la valeur liée à la clé.
- dct.update("domicile" : "Moulinsart") : \n met à jour les paires de clé/valeur.
- len(dct) : renvoie le nombre d'éléments.
- list(dct) : renvoie la liste des clés.
- dct.pop("année") : enlève la valeur \n associée à la clé (ici 1940)."""
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"]]
2022-12-16 18:39:00 +01:00
card_description.update({"dict-card" : [card_dict_title, card_dict_text, card_dict_url]})
# Objet (POO)
# card_oop_title="Programmation\norientée objet (POO)"
# card_oop_text="\nFIXME"
# 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
2022-12-16 18:39:00 +01:00
card_console_title="Console"
2023-01-01 14:48:27 +01:00
card_console_text=" Si vous avez executé le simulateur dans \n un 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"
2022-12-16 18:39:00 +01:00
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 ()"
2022-12-16 18:39:00 +01:00
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"]]
2022-12-16 18:39:00 +01:00
card_description.update({"console-card" : [card_console_title, card_console_text, card_console_url]})
# Temps
2022-12-16 18:39:00 +01:00
card_sleep_title="Gestion du temps"
card_sleep_text=""" tempo(x) \n -> Marque un temps d'arrêt de x secondes.
Vous pouvez alors créer des temporisations \n dans le déroulement du script.\n
get_t() \n -> Retourne le temps écoulé en seconde \n depuis le démarrage du cycle. \n
set_t(x) -> Définir la valeur du temps avec x. \n
reset_t() -> Réinitialiser la valeur du temps."""
card_sleep_url=[["Doc. Python v3 Fr : sleep","https://docs.python.org/fr/3/library/time.html#time.sleep"]]
2022-12-16 18:39:00 +01:00
card_description.update({"sleep-card" : [card_sleep_title, card_sleep_text, card_sleep_url]})
# Python
card_python_title="Langage Python"
2023-01-01 14:48:27 +01:00
card_python_text=""" Python est un langage de programmation \n interprété open source. Python vise à être
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
multiparadigme, il est utilisé dans de \n nombreux contextes : scriptage, calcul
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]})
###############################################################################
# Interface
###############################################################################
##
# Initialisation de la documentation
##
def init():
# UI : information
scene.objects['Cmd-text']['Text']= "Chargement de la documentation ..."
scene.objects['Cmd-text'].setVisible(True,False)
# Mettre les couleurs sur les icones (chapitres et cartes)
chap=("general", "system", "python")
for page in chap:
scene.objects["Doc-"+page].color = color_doc_chap
scene.objects["Doc-"+page+"-text"].color = color_doc_chap
for i in range(len(system_card)):
scene.objects[system_card[i]].color = color_doc_fct
scene.objects[system_card[i]+"-icon"].color = color_doc_fct
scene.objects[system_card[i]+"-text"].color = color_doc_fct
for i in range(len(python_card)):
scene.objects[python_card[i]].color = color_doc_fct
scene.objects[python_card[i]+"-icon"].color = color_doc_fct
scene.objects[python_card[i]+"-text"].color = color_doc_fct
# Cacher et mettre les couleurs sur les liens (URL)
scene.objects['Doc_chap-system-url_title'].setVisible(False,True)
scene.objects['Doc_chap-system-url_title'].color = color_doc_activate
scene.objects['Doc_chap-python-url_title'].setVisible(False,True)
scene.objects['Doc_chap-python-url_title'].color = color_doc_activate
for i in range(3):
scene.objects['Doc_chap-python-url'+str(i)].setVisible(False,True)
scene.objects['Doc_chap-python-url'+str(i)+'-colbox'].suspendPhysics()
scene.objects['Doc_chap-python-url'+str(i)].color = color_doc_chap
scene.objects['Doc_chap-system-url'+str(i)].setVisible(False,True)
scene.objects['Doc_chap-system-url'+str(i)+'-colbox'].suspendPhysics()
scene.objects['Doc_chap-system-url'+str(i)].color = color_doc_chap
# Chargement du texte
if scene.objects['Doc']['static']: # en statique
text_static_load()
else:
text_dynamic_load() # en dynamique
# Mémorisation de la position des pages
for page in chap:
scene.objects["Doc_chap-"+page]['init_lx']=scene.objects["Doc_chap-"+page].worldPosition.x
scene.objects["Doc_chap-"+page]['init_ly']=scene.objects["Doc_chap-"+page].worldPosition.y
scene.objects["Doc_chap-"+page]['init_lz']=scene.objects["Doc_chap-"+page].worldPosition.z
# Page par défaut
scene.objects['Doc']['page_chap'] = "general"
# UI : information
# scene.objects['Cmd-text']['Text']= ""
# scene.objects['Cmd-text'].setVisible(False,False)
##
# Ouvrir la documentation
##
def open():
# Chargement de la documentation
if scene.objects['Doc']['page_chap']=="":
init()
# Placer la tablette
scene.objects['System']['manip_mode']=8 # Fenêtre modale Documentation
scene.objects['Doc-cmd-Hl'].setVisible(False,False)
scene.objects['Doc-cmd'].setVisible(True,False)
scene.objects['Cmd-text'].setVisible(False,False)
scene.objects['Twins-icon'].setVisible(False,True)
scene.objects['Twins-text'].setVisible(False,True)
scene.objects['Script-icon'].setVisible(False,True)
scene.objects['Script-text'].setVisible(False,True)
bpy.context.view_layer.update() # Bug de mise à jour
scene.active_camera = scene.objects["Camera-Doc"]
2022-12-21 05:43:56 +01:00
# scene.removeOverlayCollection(bpy.data.collections['Hud']) # Crash de UPBGE sur la supression de l'Overlay
# scene.objects['Twins-icon'].setVisible(False,True) # Crash de UPBGE sur la supression de l'Overlay
# scene.objects['Twins-text'].setVisible(False,True) # Crash de UPBGE sur la supression de l'Overlay
scene.objects['Doc_close'].color= color_doc_fct
scene.objects['Doc'].setVisible(True,True)
if scene.objects['Doc']['static']:
scene.objects['Doc_title'].setVisible(False,True)
for i in range (13):
scene.objects['Doc_text-l'+str(i+1)+'-ref'].setVisible(False, False)
else:
text_dynamic_hide()
# Placer le nouveau chapitre
name_chap = scene.objects['Doc']['page_chap']
scene.objects['Doc-'+name_chap].color = color_doc_activate
scene.objects['Doc-'+name_chap+'-text'].color = color_doc_activate
scene.objects['Doc_chap-'+name_chap].worldPosition = scene.objects['Doc'].worldPosition
scene.objects['Doc_chap-'+name_chap].setVisible(True,True)
# URL
if name_chap == "system" or name_chap == "python":
name_fct = scene.objects['Doc_chap-'+name_chap]['page_fct']
scene.objects['Doc_chap-'+name_chap+'-url_title'].setVisible(False,True)
for i in range(3):
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)].setVisible(False,True)
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox'].suspendPhysics()
if name_fct !="":
if len(card_description[name_fct][2])>0:
scene.objects['Doc_chap-'+name_chap+'-url_title'].setVisible(True,True)
for i in range(len(card_description[name_fct][2])):
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)]['Text'] = card_description[name_fct][2][i][0]
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)].setVisible(True,True)
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox'].restorePhysics()
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox']['Url'] = card_description[name_fct][2][i][1]
# Afficher le texte de la carte active
if scene.objects['Doc']['static'] :
pass
else:
if name_chap != "general" and scene.objects['Doc_chap-'+name_chap]['page_fct'] !="":
name_fct = scene.objects['Doc_chap-'+name_chap]['page_fct']
# scene.objects['Doc_title']['Text'] = card_description[name_fct][0]
scene.objects['Doc_title'].blenderObject.data.body=card_description[name_fct][0] # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
scene.objects['Doc_title'].setVisible(True, False)
text_dynamic_show(name_fct)
else:
# scene.objects['Doc_title']['Text'] = " "
scene.objects['Doc_title'].blenderObject.data.body=" " # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
scene.objects['Doc_title'].setVisible(False,True)
text_dynamic_hide()
##
# Fermer la documentation
##
def close(cont):
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
scene.objects['System']['manip_mode']=0 # Enlever la fenêtre modale
scene.active_camera = scene.objects["Camera"]
2022-12-21 05:43:56 +01:00
# scene.addOverlayCollection(scene.cameras['Camera-Hud'], bpy.data.collections['Hud']) # Crash de UPBGE sur la supression de l'Overlay
scene.objects['Twins-icon'].setVisible(True,True) # Crash de UPBGE sur la supression de l'Overlay
scene.objects['Twins-text'].setVisible(True,True) # Crash de UPBGE sur la supression de l'Overlay
scene.objects['Script-icon'].setVisible(True,True) # Crash de UPBGE sur la supression de l'Overlay
scene.objects['Script-text'].setVisible(True,True) # Crash de UPBGE sur la supression de l'Overlay
bpy.context.view_layer.update() # Bug de mise à jour
chap=("general", "system", "python")
for page in chap:
scene.objects["Doc_chap-"+page].setVisible(False,True)
scene.objects["Doc_chap-"+page].worldPosition.x = scene.objects["Doc_chap-"+page]['init_lx']
scene.objects["Doc_chap-"+page].worldPosition.y = scene.objects["Doc_chap-"+page]['init_ly']
scene.objects["Doc_chap-"+page].worldPosition.z = scene.objects["Doc_chap-"+page]['init_lz']
scene.objects['Doc'].setVisible(False,True)
if scene.objects['Doc']['static'] :
for card in card_description:
scene.objects["Doc_page-"+card].setVisible(False,True)
scene.objects["Doc_title-"+card].setVisible(False,True)
scene.objects["Doc_text-"+card].setVisible(False,True)
else:
text_dynamic_hide()
##
# Highlight
##
def hl (cont):
# Activation
if cont.sensors['MO'].status == JUST_ACTIVATED :
obj = cont.owner
name=obj.name[:-7]
name_text=name+"-text"
name_icon=name+"-icon"
# Close ou lien
if name == "Doc_close" :
scene.objects[name].color = color_doc_hl
elif name == "Doc_chap-python-url0" or name == "Doc_chap-python-url1" or name == "Doc_chap-python-url2":
scene.objects[name].color = color_doc_hl
elif name == "Doc_chap-system-url0" or name == "Doc_chap-system-url1" or name == "Doc_chap-system-url2":
scene.objects[name].color = color_doc_hl
else:
if "Doc-" in name : # Chapitre
if name[4:] == scene.objects['Doc']['page_chap']:
scene.objects[name].color = color_doc_activate
scene.objects[name_text].color = color_doc_activate
else:
scene.objects[name].color = color_doc_hl
scene.objects[name_text].color = color_doc_hl
else: # Carte
name_chap = scene.objects['Doc']['page_chap']
if name == scene.objects['Doc_chap-'+name_chap]['page_fct'] :
scene.objects[name].color = color_doc_activate
scene.objects[name_text].color = color_doc_activate
scene.objects[name_icon].color = color_doc_activate
else:
scene.objects[name].color = color_doc_hl
scene.objects[name_text].color = color_doc_hl
scene.objects[name_icon].color = color_doc_hl
# Désactivation
if cont.sensors['MO'].status == JUST_RELEASED :
obj = cont.owner
name=obj.name[:-7]
name_text=obj.name[:-7]+"-text"
name_icon=obj.name[:-7]+"-icon"
# Close ou lien
if name == "Doc_close" :
scene.objects[name].color = color_doc_fct
elif name == "Doc_chap-python-url0" or name == "Doc_chap-python-url1" or name == "Doc_chap-python-url2":
scene.objects[name].color = color_doc_fct
elif name == "Doc_chap-system-url0" or name == "Doc_chap-system-url1" or name == "Doc_chap-system-url2":
scene.objects[name].color = color_doc_fct
else:
if "Doc-" in name : # Chapitre
if name[4:] == scene.objects['Doc']['page_chap']:
scene.objects[name].color = color_doc_activate
scene.objects[name_text].color = color_doc_activate
else:
scene.objects[name].color = color_doc_fct
scene.objects[name_text].color = color_doc_fct
else: # Carte
name_chap = scene.objects['Doc']['page_chap']
if name == scene.objects['Doc_chap-'+name_chap]['page_fct'] :
scene.objects[name].color = color_doc_activate
scene.objects[name_text].color = color_doc_activate
scene.objects[name_icon].color = color_doc_activate
else:
scene.objects[name].color = color_doc_fct
scene.objects[name_text].color = color_doc_fct
scene.objects[name_icon].color = color_doc_fct
##
# Afficher le chapitre
##
def chapter(cont):
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive and cont.sensors['Click'].positive:
obj = cont.owner
# scene.objects['Doc_title']['Text'] = " "
scene.objects['Doc_title'].blenderObject.data.body=" " # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
# Enlever l'ancien chapitre
name_chap = scene.objects['Doc']['page_chap']
scene.objects['Doc-'+scene.objects['Doc']['page_chap']].color = color_doc_chap
scene.objects['Doc-'+scene.objects['Doc']['page_chap']+'-text'].color = color_doc_chap
scene.objects["Doc_chap-"+name_chap].worldPosition.x = scene.objects["Doc_chap-"+name_chap]['init_lx']
scene.objects["Doc_chap-"+name_chap].worldPosition.y = scene.objects["Doc_chap-"+name_chap]['init_ly']
scene.objects["Doc_chap-"+name_chap].worldPosition.z = scene.objects["Doc_chap-"+name_chap]['init_lz']
if scene.objects['Doc']['page_chap'] != "general" and scene.objects["Doc_chap-"+name_chap]['page_fct'] !="":
if scene.objects['Doc']['static'] :
name_chap = scene.objects['Doc']['page_chap']
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].worldPosition.x = scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']]['init_lx']
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].worldPosition.y = scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']]['init_ly']
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].worldPosition.z = scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']]['init_lz']
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].setVisible(False,True)
else:
text_dynamic_hide(scene.objects["Doc_chap-"+scene.objects['Doc']['page_chap']]['page_fct'])
# Placer le nouveau chapitre
name_chap= obj.name[4:-7]
scene.objects['Doc-'+name_chap].color = color_doc_activate
scene.objects['Doc-'+name_chap+'-text'].color = color_doc_activate
scene.objects['Doc']['page_chap'] = name_chap
scene.objects['Doc_chap-'+name_chap].worldPosition = scene.objects['Doc'].worldPosition
scene.objects['Doc_chap-'+name_chap].setVisible(True,True)
# URL
if name_chap == "system" or name_chap == "python":
name_fct = scene.objects['Doc_chap-'+name_chap]['page_fct']
scene.objects['Doc_chap-'+name_chap+'-url_title'].setVisible(False,True)
for i in range(3):
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)].setVisible(False,True)
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox'].suspendPhysics()
if name_fct !="":
if len(card_description[name_fct][2])>0:
scene.objects['Doc_chap-'+name_chap+'-url_title'].setVisible(True,True)
for i in range(len(card_description[name_fct][2])):
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)]['Text'] = card_description[name_fct][2][i][0]
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)].setVisible(True,True)
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox'].restorePhysics()
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox']['Url'] = card_description[name_fct][2][i][1]
# Afficher le texte de la carte active
if name_chap != "general" and scene.objects['Doc_chap-'+name_chap]['page_fct'] !="":
if scene.objects['Doc']['static'] :
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']]['init_lx']=scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].worldPosition.x
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']]['init_ly']=scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].worldPosition.y
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']]['init_lz']=scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].worldPosition.z
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].worldPosition = scene.objects['Doc'].worldPosition
scene.objects["Doc_page-"+scene.objects['Doc_chap-'+name_chap]['page_fct']].setVisible(True,True)
else:
name_fct = scene.objects['Doc_chap-'+name_chap]['page_fct']
# scene.objects['Doc_title']['Text'] = card_description[name_fct][0]
scene.objects['Doc_title'].blenderObject.data.body=card_description[name_fct][0] # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
scene.objects['Doc_title'].setVisible(True, False)
text_dynamic_show(name_fct)
else:
if scene.objects['Doc']['static'] :
pass
else:
# scene.objects['Doc_title']['Text'] = " "
scene.objects['Doc_title'].blenderObject.data.body=" " # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
scene.objects['Doc_title'].setVisible(False,True)
text_dynamic_hide()
##
# Afficher les details de la fonction à partir d'une carte
##
def card (cont):
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
obj = cont.owner
name_chap = scene.objects['Doc']['page_chap']
name_fct= obj.name[:-7]
name_old_fct= scene.objects['Doc_chap-'+name_chap]['page_fct']
# scene.objects['Doc_title']['Text'] = " "
scene.objects['Doc_title'].blenderObject.data.body=" " # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
# Enlever l'ancienne carte
if name_old_fct !="":
if scene.objects['Doc']['static'] :
scene.objects["Doc_page-"+name_old_fct].worldPosition.x = scene.objects["Doc_page-"+name_old_fct]['init_lx']
scene.objects["Doc_page-"+name_old_fct].worldPosition.y = scene.objects["Doc_page-"+name_old_fct]['init_ly']
scene.objects["Doc_page-"+name_old_fct].worldPosition.z = scene.objects["Doc_page-"+name_old_fct]['init_lz']
scene.objects["Doc_page-"+name_old_fct].setVisible(False,True)
else:
text_dynamic_hide(name_old_fct)
scene.objects[name_old_fct].color = color_doc_fct
scene.objects[name_old_fct+'-text'].color = color_doc_fct
scene.objects[name_old_fct+'-icon'].color = color_doc_fct
# Afficher le texte de la carte
scene.objects['Doc_chap-'+name_chap]['page_fct'] = name_fct
scene.objects[name_fct].color = color_doc_activate
scene.objects[name_fct+'-icon'].color = color_doc_activate
scene.objects[name_fct+'-text'].color = color_doc_activate
if scene.objects['Doc']['static'] :
scene.objects["Doc_page-"+name_fct].worldPosition = scene.objects['Doc'].worldPosition
scene.objects["Doc_page-"+name_fct].setVisible(True,True)
else:
# scene.objects['Doc_title']['Text'] = card_description[name_fct][0]
scene.objects['Doc_title'].blenderObject.data.body=card_description[name_fct][0] # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
scene.objects['Doc_title'].setVisible(True, False)
text_dynamic_show(name_fct)
# URL
if name_chap == "system" or name_chap == "python":
name_fct = scene.objects['Doc_chap-'+name_chap]['page_fct']
scene.objects['Doc_chap-'+name_chap+'-url_title'].setVisible(False,True)
for i in range(3):
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)].setVisible(False,True)
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox'].suspendPhysics()
if name_fct !="":
if len(card_description[name_fct][2])>0:
scene.objects['Doc_chap-'+name_chap+'-url_title'].setVisible(True,True)
for i in range(len(card_description[name_fct][2])):
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)]['Text'] = card_description[name_fct][2][i][0]
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)].setVisible(True,True)
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox'].restorePhysics()
scene.objects['Doc_chap-'+name_chap+'-url'+str(i)+'-colbox']['Url'] = card_description[name_fct][2][i][1]
##
# Aller à la page internet
##
def link (cont):
if cont.sensors['Click'].status == JUST_ACTIVATED and cont.sensors['MO'].positive :
webbrowser.open(cont.owner['Url'])
###############################################################################
# Génération dynamique des pages
###############################################################################
##
# Cacher le texte
##
def text_dynamic_hide(card=None):
if card is None:
for card in card_description:
for i in range (13):
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)].setVisible(False, False)
else:
for i in range (13):
scene.objects['Doc_text-l'+str(i+1)+'-'+card].setVisible(False, False)
##
# Afficher le texte
##
def text_dynamic_show(card=None):
if card is None:
for card in card_description:
for i in range (13):
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)].setVisible(True, False)
else:
for i in range (13):
scene.objects['Doc_text-l'+str(i+1)+'-'+card].setVisible(True, False)
##
# Préchargement des textes
##
def text_dynamic_load():
for i in range (13):
scene.objects['Doc_text-l'+str(i+1)+'-ref']['Text'] = ""
# Création des objets 3D
for card in card_description:
lines = card_description[card][1].split("\n")
for i in range (13):
doc_text= scene.addObject('Doc_text-l'+str(i+1), None, 0.00, True)
doc_text.setParent(scene.objects['Doc'])
doc_text.name = 'Doc_text-l'+str(i+1)+'-'+str(card)
doc_text.worldPosition.x = scene.objects['Doc_text-l'+str(i+1)+'-ref'].worldPosition.x
doc_text.worldPosition.y = scene.objects['Doc_text-l'+str(i+1)+'-ref'].worldPosition.y
doc_text.worldPosition.z = scene.objects['Doc_text-l'+str(i+1)+'-ref'].worldPosition.z
doc_text.setVisible(False, False)
if i >= len(lines):
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)]['Text']=""
else:
if len(lines[i]) ==0:
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)]['Text']=""
else:
# scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)]['Text']=lines[i]
scene.objects['Doc_text-l'+str(i+1)+'-'+str(card)].blenderObject.data.body=lines[i] # Bug de la propriétés 'Text' (UPBGE) -> passage par 'body' de bpy (Blender)
###############################################################################
# Chargement des pages statiques
###############################################################################
def text_static_load():
# Charger la collection
file_path = "asset/doc/porcou_doc-fr.blend"
inner_path = "Collection"
object_name ="Doc generation"
bpy.ops.wm.append(
filepath=os.path.join(file_path, inner_path, object_name),
directory=os.path.join(file_path, inner_path),
filename=object_name)
scene.convertBlenderCollection(bpy.data.collections[object_name], True)
# Lier et configurer les objects
for card in card_description:
# Repère
page_name ="Doc_page-"+card
scene.objects[page_name]['init_lx']=scene.objects[page_name].worldPosition.x
scene.objects[page_name]['init_ly']=scene.objects[page_name].worldPosition.y
scene.objects[page_name]['init_lz']=scene.objects[page_name].worldPosition.z
# Titre
title_name ="Doc_title-"+card
scene.objects[title_name]. setParent(scene.objects[page_name], True, False)
bpy.data.objects[title_name].data.font=bpy.data.fonts['Espresso Dolce Regular']
scene.objects[title_name].worldPosition.x += scene.objects[page_name].worldPosition.x
scene.objects[title_name].worldPosition.y += scene.objects[page_name].worldPosition.y
scene.objects[title_name].worldPosition.z += scene.objects[page_name].worldPosition.z
# Texte
text_name ="Doc_text-"+card
scene.objects[text_name]. setParent(scene.objects[page_name], True, False)
# text_object=scene.objects[text_name].blenderObject.data
# text_object.font=bpy.data.fonts['Espresso Dolce Regular'] # Trop lourd
bpy.data.objects[text_name].data.font=bpy.data.fonts['Bfont Regular'] # Bien plus léger
scene.objects[text_name].worldPosition.x += scene.objects[page_name].worldPosition.x
scene.objects[text_name].worldPosition.y += scene.objects[page_name].worldPosition.y
scene.objects[text_name].worldPosition.z += scene.objects[page_name].worldPosition.z
scene.objects[page_name].setVisible(False,True)
scene.objects[title_name].setVisible(False,True)
scene.objects[text_name].setVisible(False,True)