Forum Sketchup Artlantis Archicad
Vous souhaitez réagir à ce message ? Créez un compte en quelques clics ou connectez-vous pour continuer.
Annonces
Bonjour Invité Bienvenue sur le forum biblio3d - le forum a été créé le Sam 19 Jan 2008 - 14:26- Nous avons enregistrés 14833 topics pour un total de : 175855 posts - le record de membres connectés simultanément :853
Galerie


twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Empty
Ton bloc notes
Derniers sujets
» [ SKETCHUP généralité ] Tête de pilastre
par JDD Aujourd'hui à 11:49

» [ CHALLENGE 2024 ] résultats du challenge
par AK40Cess Hier à 13:27

» [ FORUM ] astuce pour insérer facilement un tableau sur le forum
par tenrev Hier à 9:12

» [ SKETCHUP plugins ] une barre d’outils perso
par tenrev Lun 18 Nov 2024 - 15:05

» [ SKETCHUP généralité ] Orienter 1 Face, 1 Profil Normal (Perpendiculaire) à 1 Arête, 1 Trajectoire
par jerryvento Lun 18 Nov 2024 - 14:47

» [ SKETCHUP généralité ] Modéliser facilement 1 spirale en moins de 40 secondes
par jerryvento Lun 18 Nov 2024 - 14:47

» [ SKETCHUP généralité ] Modélise 1 Forme Hélicoïdale, en forme de spirale : main courante, rampe d'accès voitures...
par jerryvento Lun 18 Nov 2024 - 14:46

» [ SKETCHUP tutos ] Orienter 1 Face, 1 Profil Normal (Perpendiculaire) à 1 Arête, 1 Trajectoire
par jerryvento Lun 18 Nov 2024 - 14:45

» [ SKETCHUP tutos ] Modéliser facilement 1 spirale en moins de 40 secondes
par jerryvento Lun 18 Nov 2024 - 14:44

» [ SKETCHUP tutos ] Modélise 1 Forme Hélicoïdale, en forme de spirale : main courante, rampe d'accès voitures...
par jerryvento Lun 18 Nov 2024 - 14:43

» ColorMaker par Didier Bur[ SKETCHUP plugins ]
par JDD Dim 17 Nov 2024 - 20:56

» [ ARCHICAD ] Plus de format *atl dans Archicad
par Coulou Jeu 14 Nov 2024 - 8:26

» [ SKETCHUP tutos ] Créer des Bibliothèques et des livres aléatoires Facilement (2 Méthodes!)
par tenrev Mar 12 Nov 2024 - 11:31

» [ CHALLENGE 2024 ] les images finales du challenge
par tenrev Lun 11 Nov 2024 - 15:35

» [ SKETCHUP composants dynamiques ] Formule IF
par Samuel MATHIEU Jeu 7 Nov 2024 - 21:12

» [ Challenge 2024] cHallenge archjtexture exterieur ou paysagiste-vick-sketchup-enscape
par vick Jeu 7 Nov 2024 - 10:23

» [ SKETCHUP vray ]
par tenrev Mar 5 Nov 2024 - 21:19

» [ CHALLENGE 2024 ] Challenge architecture extérieure ou paysagiste- Gaspard Hauser - Sketchup - D5 render
par tenrev Mar 5 Nov 2024 - 10:22

» [ CHALLENGE 2024 ] Challenge architecture extérieure ou paysagiste - JDD - SketchUp - Enscape
par tenrev Mar 5 Nov 2024 - 10:10

» [ ARCHICAD ] Murs paramétriques
par Coulou Lun 28 Oct 2024 - 10:28

» [ SKETCHUP généralité ] Aide pour SKP 2017
par PEGASE Sam 26 Oct 2024 - 18:36

» [ ARCHICAD ] Ajouter du lambris sur un mur
par Coulou Jeu 24 Oct 2024 - 10:43

» [ SKETCHUP généralité ] 1 Citrouille à imprimer pour Halloween
par jerryvento Jeu 24 Oct 2024 - 8:13

» [ SKETCHUP tutos ] 1 Citrouille à imprimer pour Halloween
par jerryvento Jeu 24 Oct 2024 - 8:11

» [ D5_RENDER] Petit exemple "hors sujet" ... D5
par Gaspard Hauser Mar 22 Oct 2024 - 19:59

» [ MATOS INFORM. ] [WINDOWS] Miniatures de prévisualisation pour les fichiers de modèle 3D au format .OBJ, .FBX, .STL, .3DS et +
par Gaspard Hauser Mar 22 Oct 2024 - 19:49

» [ SKETCHUP Layout ] Symboles Électriques sur Layout
par JDD Jeu 17 Oct 2024 - 9:44

» [ ARCHICAD ] gardes corps et profils complexe ?
par Christophe Fortineau Lun 14 Oct 2024 - 12:10

» [ CHALLENGE 2024 ] Challenge architecture extérieure ou paysagiste - allansens - cinema 4D
par Allansens Sam 12 Oct 2024 - 13:53

» [ ARTLANTIS ] Ca donne envie !
par Gaspard Hauser Jeu 10 Oct 2024 - 10:00

» [ TWINMOTION ] Unreal Engine déménage sur Fab - DataSmith & Archicad
par Coulou Jeu 10 Oct 2024 - 9:03

» [ CHALLENGE 2024 ] Challenge architecture extérieure ou paysagiste - AK40Cess - Archicad-Twinmotion
par Coulou Mar 8 Oct 2024 - 11:53

» [ TWINMOTION ] Unreal Engine déménage sur Fab - Assets de Megascan
par JDD Lun 7 Oct 2024 - 21:52

» [ CHALLENGE ARCHITECTURE EXTERIEURE OU PAYSAGISTE ] Démarrage du challenge 2024 - les régles
par tenrev Jeu 3 Oct 2024 - 14:58

» [ ARCHICAD ] Cotation d'ouverture sans hauteur
par Titou Jeu 3 Oct 2024 - 11:21

Sondage

êtes vous intéressé et prêt à participer à un challenge ?

twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Poll_c1015%twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Poll_c10 15% [ 2 ]
twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Poll_c1031%twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Poll_c10 31% [ 4 ]
twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Poll_c1046%twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Poll_c10 46% [ 6 ]
twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Poll_c108%twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Poll_c10 8% [ 1 ]
twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Poll_c100%twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Poll_c10 0% [ 0 ]
twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Poll_c100%twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Poll_c10 0% [ 0 ]

Total des votes : 13

chaine sketchup.tv
Serveur Discord
-17%
Le deal à ne pas rater :
SSD interne Crucial SSD P3 1To NVME à 49,99€
49.99 € 59.99 €
Voir le deal

[ TWINMOTION ] Unreal Engine déménage sur Fab - Assets de Megascan

Voir le sujet précédent Voir le sujet suivant Aller en bas

JDD
JDD
V.I.P.
V.I.P.
Masculin Humeur : Cool, œil de lynx à pattes de velours
Date d'inscription : 21/05/2021
Nombre de messages : 1138
Points : 2488
Age : 75
Localisation : Nord (59)
Emploi : Director of Myself

MessageJDD Sam 21 Sep 2024 - 16:52

Bonjour,

Autres informations concernant cette réorganisation :

Les mégascans ne seront plus gratuits après 2024

Au cas où vous l'auriez manqué, Epic combine Sketchfab, Unreal Engine Marketplace,

Artstation Store et Quixel Megascans en un gigantesque magasin d'actifs appelé Fab (lancement mi-octobre).

Epic espère ainsi concurrencer directement Turbosquid, en tant que plateforme de référence

pour les ressources tierces.

Dans le cadre de cette initiative, les ressources Megascans (qui étaient auparavant gratuites pour

tous les utilisateurs d'Unreal) deviendront payantes au début de l'année 2025.

Comme on pouvait s'y attendre, les utilisateurs d'Unreal ne sont pas contents.

Mais c'est tout à fait logique si l'on considère qu'Epic veut que tous les créateurs vendent sur Fab.

Et ils ne le feront certainement pas s'ils doivent rivaliser avec 18 000 éléments gratuits.

Rendre les Megascans payants était donc le seul moyen de mettre les créateurs tiers sur un pied

d'égalité.


Dernière édition par Coulou le Lun 7 Oct 2024 - 9:51, édité 1 fois (Raison : Division de post suite à ce nouveau problème soulevé par JDD.)

tenrev, Coulou et simjoubert aiment ce message

simjoubert
simjoubert
Administrateurs
Administrateurs
Masculin Humeur : Des racines et des rêves !!!
Date d'inscription : 05/08/2012
Nombre de messages : 2916
Points : 6424
Age : 49
Localisation : Val de Marne
Emploi : Paysagiste
https://www.sketchup.simjoubert.com/

Messagesimjoubert Sam 21 Sep 2024 - 19:39

Merci Jdd

tenrev aime ce message

tenrev
tenrev
FONDATEUR DE BIBLIO3D
FONDATEUR DE BIBLIO3D
Masculin Humeur : excellente comme toujours
Date d'inscription : 19/01/2008
Nombre de messages : 19943
Points : 34784
Age : 61
Localisation : Dans la quatrieme dimension
Emploi : archi d'intérieur salarié
https://www.biblio3d.com

Messagetenrev Lun 23 Sep 2024 - 11:13

JDD a écrit:tous les utilisateurs d'Unreal) deviendront payantes au début de l'année 2025.
Comme on pouvait s'y attendre, les utilisateurs d'Unreal ne sont pas contents. .

merci  @JDD  ha oui c'est pas cool cette affaire , j'utilisais beaucoup les assets de mégascan , d'ailleurs je me suis toujours demandé pourquoi ils les avaient passés gratuits vu la qualité et qu'au départ ils étaient payants
j'espère que ceux acquis dans le luncher epic games seront toujours valides

twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Mega10

-------------------------------------------------------------------------------------------------------------------------
je ne sais pas grand chose , mais le peu que je sache , je le partage/Salut Invité merci de consulter mon profil/PC fixe Rizen 9 3950 cg RTX3080-64 go de ram DDssd 1To/1 PC portable Lenovo  16'' w11 i7 32go-CG  RTX3070 8go/1casque meta Quest 3/1 casque VR Occulus Rift /1 PC portable Dell sous Linux Ubuntu-1 pc portable HP sous chromebook/Raspberry Pi - Arduino /  Modélisation :Sketchup-Rhino-Pconplanner-Rendu:Enscape-Keyshot-Unreal Engine-Twinmotion-Autres:Photoshop-Indesign-After Effect-Première pro-Intelligence artificielle -Chatgpt+-Midjourney-Suno-Elevenlabs-Canva
twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan 575088biblio3d

JDD et simjoubert aiment ce message

Gaspard Hauser
Gaspard Hauser
Moulin à parole
Moulin à parole
Masculin Date d'inscription : 30/01/2019
Nombre de messages : 205
Points : 301
https://jskup.fr/

MessageGaspard Hauser Jeu 3 Oct 2024 - 11:29

bonjour,
je me demande, puisque j'y ai encore accès, si je ne vais pas télécharger toutes les matières Quixel avant que ça deviennen payant... et stocker en local

je vais y passer mes nuits

tenrev aime ce message

tenrev
tenrev
FONDATEUR DE BIBLIO3D
FONDATEUR DE BIBLIO3D
Masculin Humeur : excellente comme toujours
Date d'inscription : 19/01/2008
Nombre de messages : 19943
Points : 34784
Age : 61
Localisation : Dans la quatrieme dimension
Emploi : archi d'intérieur salarié
https://www.biblio3d.com

Messagetenrev Jeu 3 Oct 2024 - 15:00

Gaspard Hauser a écrit:bonjour,
je me demande, puisque j'y ai encore accès, si je ne vais pas télécharger toutes les matières Quixel avant que ça deviennen payant... et stocker en local

je vais y passer mes nuits

je l'ai fait en partie, sur unreal j'en ai récupérer un max

-------------------------------------------------------------------------------------------------------------------------
je ne sais pas grand chose , mais le peu que je sache , je le partage/Salut Invité merci de consulter mon profil/PC fixe Rizen 9 3950 cg RTX3080-64 go de ram DDssd 1To/1 PC portable Lenovo  16'' w11 i7 32go-CG  RTX3070 8go/1casque meta Quest 3/1 casque VR Occulus Rift /1 PC portable Dell sous Linux Ubuntu-1 pc portable HP sous chromebook/Raspberry Pi - Arduino /  Modélisation :Sketchup-Rhino-Pconplanner-Rendu:Enscape-Keyshot-Unreal Engine-Twinmotion-Autres:Photoshop-Indesign-After Effect-Première pro-Intelligence artificielle -Chatgpt+-Midjourney-Suno-Elevenlabs-Canva
twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan 575088biblio3d
Gaspard Hauser
Gaspard Hauser
Moulin à parole
Moulin à parole
Masculin Date d'inscription : 30/01/2019
Nombre de messages : 205
Points : 301
https://jskup.fr/

MessageGaspard Hauser Ven 4 Oct 2024 - 8:41

Salut, oui, mais il semble que ça bloque, je suppose une limitation chaque jour... et c'est fastidieux
JDD
JDD
V.I.P.
V.I.P.
Masculin Humeur : Cool, œil de lynx à pattes de velours
Date d'inscription : 21/05/2021
Nombre de messages : 1138
Points : 2488
Age : 75
Localisation : Nord (59)
Emploi : Director of Myself

MessageJDD Sam 5 Oct 2024 - 15:04

Bonjour,

Pour ceux intéressés, ci après une méthode pour récupérer tous les assets de Megascan sur votre compte Quixel ( 18871 assets)

C'est ICI

J'ai testé sur FIREFOX et EDGE, le script fonctionne correctement. Si blocage en cours, relancer le script, il complètera les assets manquants sur le compte.

EDIT 2 :

Et sur ce lien un script en python pour les télécharger sur un disque au format ZIP : ICI

Je l'ai testé ce jour, il fonctionne très bien ( une petite correction d'indentation est nécessaire en ligne 67 devant Header du script dlMegascans.py)

Nécessite l'usage de Python 3 et l'installation du module "request" si pas présent. (à installer facilement via la ligne de commande suivante:

Code:
python -m pip install request

EDIT 3 :

Un script variante du précédent, avec plus de choix possibles lors du téléchargement (résolution 2K, 4K,ou 8K pour les textures), qui fonctionne également, j'ai testé.

C'est ICI

JDD


Dernière édition par JDD le Dim 6 Oct 2024 - 19:52, édité 3 fois
Gaspard Hauser
Gaspard Hauser
Moulin à parole
Moulin à parole
Masculin Date d'inscription : 30/01/2019
Nombre de messages : 205
Points : 301
https://jskup.fr/

MessageGaspard Hauser Sam 5 Oct 2024 - 15:32

merci infiniment JDD,
mais ensuite les assets son sur mon compte, mais il faut quand même tout télécharger manuellement avant la fermeture du site?
Je viens en tout cas d'ajouter les éléments à mon compte via le script et ça a marché
Gaspard Hauser
Gaspard Hauser
Moulin à parole
Moulin à parole
Masculin Date d'inscription : 30/01/2019
Nombre de messages : 205
Points : 301
https://jskup.fr/

MessageGaspard Hauser Sam 5 Oct 2024 - 15:48

c'est bon et j'ai refais tourner le script et j'ai bien tout sur mon compte.
Ensuite sur le nouveau site fab, je pourrai de nouveau télécharger sans frais.

mille mercis
twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Qxm
Gaspard Hauser
Gaspard Hauser
Moulin à parole
Moulin à parole
Masculin Date d'inscription : 30/01/2019
Nombre de messages : 205
Points : 301
https://jskup.fr/

MessageGaspard Hauser Sam 5 Oct 2024 - 15:54

par contre JDD si tu sais comment bien importer les modèles 3D au format FXB ?
Quand je prends un modèle (c'est rare) dans D5 render je me retrouve avec le modèle sans textures...
JDD
JDD
V.I.P.
V.I.P.
Masculin Humeur : Cool, œil de lynx à pattes de velours
Date d'inscription : 21/05/2021
Nombre de messages : 1138
Points : 2488
Age : 75
Localisation : Nord (59)
Emploi : Director of Myself

MessageJDD Sam 5 Oct 2024 - 16:47

@Gaspard Hauser

Tu rencontres ce problème uniquement lorsque tu importes un modèle au format FBX de Megascan dans D5 ?
Ou quelque soit la source du FBX ?

JDD


Gaspard Hauser
Gaspard Hauser
Moulin à parole
Moulin à parole
Masculin Date d'inscription : 30/01/2019
Nombre de messages : 205
Points : 301
https://jskup.fr/

MessageGaspard Hauser Sam 5 Oct 2024 - 16:50

je suis ce tuto qui installe un plugin pour convertir directement les FBX téléchargés depuis Bridge vers un format D5.
Pour l'instant je rame à cause des chemins des dossiers
Le tuto
JDD
JDD
V.I.P.
V.I.P.
Masculin Humeur : Cool, œil de lynx à pattes de velours
Date d'inscription : 21/05/2021
Nombre de messages : 1138
Points : 2488
Age : 75
Localisation : Nord (59)
Emploi : Director of Myself

MessageJDD Sam 5 Oct 2024 - 17:17


Je ne peux t'aider sur cette façon de procéder qui semble néanmoins fonctionnelle mais avec pas mal de manip nécessaires.
JDD
JDD
JDD
V.I.P.
V.I.P.
Masculin Humeur : Cool, œil de lynx à pattes de velours
Date d'inscription : 21/05/2021
Nombre de messages : 1138
Points : 2488
Age : 75
Localisation : Nord (59)
Emploi : Director of Myself

MessageJDD Sam 5 Oct 2024 - 18:37

@Gaspard Hauser

J'ai édité mon premier post avec un autre lien intéressant (que je n'ai pas testé).

Concernant les textures des assets 3D au format FBX de Megascan, j'ai le même problème avec Bridge et Blender.

Je suis obligé d'éditer dans Blender les matériaux de l'objet 3D importé via Bridge et réaffecter les textures téléchargées à partir de la librairie Megascan téléchargée sur mon disque local.

JDD
Gaspard Hauser
Gaspard Hauser
Moulin à parole
Moulin à parole
Masculin Date d'inscription : 30/01/2019
Nombre de messages : 205
Points : 301
https://jskup.fr/

MessageGaspard Hauser Sam 5 Oct 2024 - 18:42

oui, j'avais aussi choisi Blender au moment de l'instal de Bridge, puisqu'il demande le programme où installer un plugin. Mais j'ai un message d'erreur. Pas grave pour moi puisque:

j'ai réussi à paramétrer après beaucoup de galère le plugin qui permet d'importer les assets bridge (megascans) dans D5 render
JDD
JDD
V.I.P.
V.I.P.
Masculin Humeur : Cool, œil de lynx à pattes de velours
Date d'inscription : 21/05/2021
Nombre de messages : 1138
Points : 2488
Age : 75
Localisation : Nord (59)
Emploi : Director of Myself

MessageJDD Dim 6 Oct 2024 - 21:30

Bonsoir,

J'ai testé le téléchargement des assets de la librairies Megascans à l'aide des 2 scripts que j'ai indiqués dans mon premier post.
Ils fonctionnent parfaitement.  

On ne peut télécharger qu'un seul sous-dossier de la libraairie à la fois, mais néanmoins cela permet d'aller se coucher plus tôt en tentant de les télécharger un après l'autre ( il y en a quand même plus de 18000 assets au total à faire) rigole


Exemple du code python aménagé utilisé pour le script 01 (dlMegascans02.py) pour télécharger les textures Veneer dans le sous dossier Surfaces/Wood/Veneer de Megascans
Les lignes 8,9,10,11 sont aménagés une seule fois
La ligne 13 est a aménager à chaque nouveau téléchargement pour préciser le sous dossier à télécharger

dlMegascans02.py

Code:
import os
import json
import concurrent.futures
import requests
import time

# Define the token, download path, and target category
token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Imp1ZGVkb3VjaEBnbWFpbC5jb20iLCJzY29wZSI6WyJkZWZhdWx0OnVzZXIiLCJtZWdhc2NhbnM6dXNlciJdLCJlcGljQWNjb3VudElkIjoiMGZkNjM2YTVmMzBjNGY1YzgzYmUyZWJhNGQ3NDQ0YTgiLCJpc1VucmVhbEVVTEFBY2NlcHRlZCI6dHJ1ZSwiaXNFcGljQWNjb3VudCI6dHJ1ZSwicXVpeGVsQWNjb3VudElkIjoiZDNlZDRlMWItYzNjZi00MDUxLWE4NmEtODlhYWNmN2RhMmE4IiwicmVhbG0iOiJtZWdhc2NhbnMiLCJldWxhc0FjY2VwdGVkIjpbInVlIiwiZXBpY19jb250ZW50IiwidHdpbiJdLCJpYXQiOjE3MjgyMTczNTIsImV4cCI6MTcyODI0NjE1MiwiaXNzIjoicXVpeGVsLXNzby1wcm9kIiwianRpIjoiNGU5OWRiZDEtMmU5Mi00MGJhLWFiOWEtMjFmYzMxNTRhM2MxIn0.Sp7nHb3NYNdaMKBeDmyUiSRVhqs-__4b9hOswB0YscLhTauigZ827ZpQMnSGOP9I6TLAG5mc2eR2xSSoeVPmx-AyOxfcZrX9khS6Z4Eh1SUgfVvk9Pkc8HVPGdiee9YtBQqqQW-9KI_u0Zp53CAEAEduKR3FzLYCjGpMV7hr6Mea5oGzo14tgSp_QXeiHWW36VOZNej4cZ5bA-OmGSLq2hRuigYywhFaSsAYTpg2-VToiLmN1IWpi0hC8WcehxlGTVJAZni_qYLQFv7EFtN60-VgoFolR7gCpOTanfC5gyIvsdIiTym3R-i8qyFhSmw450GGfSu4W70HPKfP5Qznvw"
download_path = "Q:/Megascans/Megascans_Download"   # Update with the correct path to the directory
json_file_path = "Q:/Megascans/ms_asset_categories.json"  # Update with the correct path to the file, not the directory
cache_file_path = "Q:/Megascans/cache.txt"

target_category = "Surfaces/wood/veneer"




# Function to normalize category strings
def normalize_category(category):
    return category.strip().lower().rstrip('s')

# Function to load asset categories from JSON file
def load_asset_categories(json_file):
    with open(json_file, 'r') as f:
        return json.load(f)

# Function to convert categories to a space-separated string
def categories_to_string(categories):
    result = []
    if isinstance(categories, dict):
        for key, value in categories.items():
            if isinstance(value, dict) and value:
                subcategories = categories_to_string(value)
                if subcategories:
                    result.append(f"{key} {subcategories}")
                else:
                    result.append(key)
            elif isinstance(value, list):
                for item in value:
                    result.append(normalize_category(item))
            else:
                result.append(normalize_category(key))
    return " ".join(result)

# Load the asset categories from the JSON file
asset_categories_dict = load_asset_categories(json_file_path)

# Print what it's trying to match against
print(f"Trying to match against target category: {target_category}")

def get_asset_download_id(asset_id):
    url = "https://quixel.com/v1/downloads"
    params = {
        "asset": asset_id,
        "config": {
            "lowerlod_meshes" : True,
            "maxlod" : 100000000,
            "highpoly": False,
            "ztool": False,
            "lowerlod_normals": True,
            "albedo_lods": True,
            "meshMimeType": "application/x-fbx",
            "brushes": False,
            "lods": [29155, 13541, 6289, 2921],
        },
    }
    headers = {
        "X-Api-Key": "your_api_key_here",
        "Authorization": "Bearer " + token,
    }

    print(f"Getting download ID for asset: {asset_id}")
    download_url_response = requests.post(url, headers=headers, json=params)
    if download_url_response.status_code == 200:
        return download_url_response.json()["id"]
    else:
        print(f"Failed to get asset download url for id: {asset_id}")
        print(download_url_response.json())
        return None

def download_asset(download_id, download_directory):
    os.makedirs(download_directory, exist_ok=True)

    url = f"https://assetdownloads.quixel.com/download/{download_id}?preserveStructure=true&url=https%3A%2F%2Fquixel.com%2Fv1%2Fdownloads"

    print(f"Attempting to download from: {url}")
    
    response = requests.get(url, stream=True)
    
    if response.status_code == 400:
        print(f"Error 400: {response.text}")  # Print the response to see what's causing the issue

    attempt_count = 0
    delay = 5
    max_attempts = 5

    while attempt_count < max_attempts:
        response = requests.get(url, stream=True)
        if response.status_code == 200:
            content_disposition = response.headers.get("Content-Disposition")
            filename = content_disposition.split("filename=")[-1].strip('"') if content_disposition else download_id
            file_path = os.path.join(download_directory, filename)

            print(f"Downloading file: {file_path}")

            try:
                with open(file_path, "wb") as file:
                    for chunk in response.iter_content(chunk_size=8192):
                        file.write(chunk)
                print(f"File downloaded successfully: {file_path}")
                return True
            except requests.exceptions.ChunkedEncodingError as e:
                print(f"Error during download: {e}")
                time.sleep(delay)
                delay += 5
                attempt_count += 1
        else:
            print(f"Failed to download asset {download_id}, status code: {response.status_code}")
            print(f"Response: {response.text}")  # Print the response content for more details
            return False

    print(f"Exceeded maximum retry attempts for asset {download_id}")
    return False

# Load cached assets
cached_assets = set()
if os.path.exists(cache_file_path):
    with open(cache_file_path, "r") as cache_file:
        cached_assets = set(cache_file.read().splitlines())

# Normalize target category for matching
normalized_target_categories = [normalize_category(part) for part in target_category.split("/")]

matching_asset_ids = []
# Check matches for each asset in the loaded categories
for asset_id, categories in asset_categories_dict.items():
    # Convert the categories to a single string for matching
    categories_str = categories_to_string(categories)

    # Check if all parts of target_category exist in the categories string
    matches = all(normalize_category(part) in categories_str.lower() for part in normalized_target_categories)

    if matches and asset_id not in cached_assets:
        print(f"Asset ID: {asset_id} matches target category: {target_category}")
        matching_asset_ids.append(asset_id)

if not matching_asset_ids:
    print("No assets found for the target category.")
    exit()

# Ask the user for confirmation before downloading
print(f"{len(matching_asset_ids)} assets found.")
confirmation = input(f"Do you want to download these {len(matching_asset_ids)} assets? (y/n): ").strip().lower()
if confirmation != "y":
    print("Download canceled.")
    exit()

# Function to handle downloading for threading
def download_asset_with_id(asset_id):
    download_id = get_asset_download_id(asset_id)
    if download_id:
        return download_asset(download_id, download_path)

# Open the cache file for appending new downloads
with open(cache_file_path, "a+") as cache_file:
    # Use threading for faster downloading
    with concurrent.futures.ThreadPoolExecutor(max_workers=10) as executor:
        futures = {executor.submit(download_asset_with_id, asset_id): asset_id for asset_id in matching_asset_ids}

        for future in concurrent.futures.as_completed(futures):
            asset_id = futures[future]
            try:
                result = future.result()
                if result:
                    # Add the asset to the cache file after successful download
                    cache_file.write(f"{asset_id}\n")
                    cache_file.flush()
            except Exception as e:
                print(f"Error downloading asset {asset_id}: {e}")

Copie d'écran de la console PowerShell

twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Megasc10
twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Megasc11
twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Megasc12
twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Megasc13

Exemple du code python aménagé utilisé pour le script 02 (dlMegascans.py) pour télécharger les textures Plank dans le sous dossier Surfaces/Wood/Plank de Megascans
Les lignes 9,12,15,18 sont aménagés une seule fois
La ligne 26 est a aménager à chaque nouveau téléchargement pour préciser le sous dossier à télécharger

dlMegascans.py

Code:
import os
import json
import sys
import concurrent.futures
import requests
import time

######## INITIAL SETUP - STEP 1 ########
# Define the token, download path, and target category
token = "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJlbWFpbCI6Imp1ZGVkb3VjaEBnbWFpbC5jb20iLCJzY29wZSI6WyJkZWZhdWx0OnVzZXIiLCJtZWdhc2NhbnM6dXNlciJdLCJlcGljQWNjb3VudElkIjoiMGZkNjM2YTVmMzBjNGY1YzgzYmUyZWJhNGQ3NDQ0YTgiLCJpc1VucmVhbEVVTEFBY2NlcHRlZCI6dHJ1ZSwiaXNFcGljQWNjb3VudCI6dHJ1ZSwicXVpeGVsQWNjb3VudElkIjoiZDNlZDRlMWItYzNjZi00MDUxLWE4NmEtODlhYWNmN2RhMmE4IiwicmVhbG0iOiJtZWdhc2NhbnMiLCJldWxhc0FjY2VwdGVkIjpbInVlIiwiZXBpY19jb250ZW50IiwidHdpbiJdLCJpYXQiOjE3MjgyMTczNTIsImV4cCI6MTcyODI0NjE1MiwiaXNzIjoicXVpeGVsLXNzby1wcm9kIiwianRpIjoiNGU5OWRiZDEtMmU5Mi00MGJhLWFiOWEtMjFmYzMxNTRhM2MxIn0.Sp7nHb3NYNdaMKBeDmyUiSRVhqs-__4b9hOswB0YscLhTauigZ827ZpQMnSGOP9I6TLAG5mc2eR2xSSoeVPmx-AyOxfcZrX9khS6Z4Eh1SUgfVvk9Pkc8HVPGdiee9YtBQqqQW-9KI_u0Zp53CAEAEduKR3FzLYCjGpMV7hr6Mea5oGzo14tgSp_QXeiHWW36VOZNej4cZ5bA-OmGSLq2hRuigYywhFaSsAYTpg2-VToiLmN1IWpi0hC8WcehxlGTVJAZni_qYLQFv7EFtN60-VgoFolR7gCpOTanfC5gyIvsdIiTym3R-i8qyFhSmw450GGfSu4W70HPKfP5Qznvw"

# Update with the correct path to the directory Example: "C:/Users/MyAccount/Documents/QuixelZips"
download_path = "Q:/Megascans/Megascans_Download"  

# Update with the correct path to the ms_asset_categories.json file, not the directory. Example: :C:/Users/MyAccount/Documents/QuixelZips/ms_asset_categoies.json"
json_file_path = "Q:/Megascans/ms_asset_categories.json"  

# Pick a folder to store the download cache at (a text file). Then create the text file cache.txt there. Paste it below. IE: "C:/Users/MyAccount/Documents/Quixel/cache.txt"
cache_file_path = "Q:/Megascans/cache.txt"

######## INITIAL SETUP - FINISHED ########
#-----------------------------------------------------------------------------------------------------------------------------------#
######## DOWNLOAD SETUP - STEP 2########

## Set target download category/categories.
#working: surface, brush, displacement, imperfection, decal
target_category = "Surfaces/wood/plank"

#Use to overwrite existing cached items. (Example if you want to downlaod a different size texture. Or if they messed up and you had to adjust script to try again.)
overwrite = False

######## DOWNLOAD SETUP - FINISHED ########
#-----------------------------------------------------------------------------------------------------------------------------------#
######## VARS - DON'T TOUCH ########
headers = {
    "Authorization": "Bearer " + token,
}
downloadCount = 0
selectedSize = 0
selectedTier = 0
######## ENDVARS - DON'T TOUCH ########
#-----------------------------------------------------------------------------------------------------------------------------------#



def requestExtendedInfo(asset_id):
    url = f"https://quixel.com/v1/assets/{asset_id}/extended"
    response = requests.get(url, stream=True)
    
    if response.status_code == 400:
        print(f"Error 400: {response.text}")
    else:
        uassets = response.json()["uasset"]
        for asset in uassets:
            if (asset["tier"] == selectedTier):
                return None ## This is testing and not needed currently

# Function to normalize category strings
def normalize_category(category):
    return category.strip().lower().rstrip('s')

# Function to load asset categories from JSON file
def load_asset_categories(json_file):
    with open(json_file, 'r') as f:
        return json.load(f)

# Function to convert categories to a space-separated string
def categories_to_string(categories):
    result = []
    if isinstance(categories, dict):
        for key, value in categories.items():
            if isinstance(value, dict) and value:
                subcategories = categories_to_string(value)
                if subcategories:
                    result.append(f"{key} {subcategories}")
                else:
                    result.append(key)
            elif isinstance(value, list):
                for item in value:
                    result.append(normalize_category(item))
            else:
                result.append(normalize_category(key))
    return " ".join(result)

# Load the asset categories from the JSON file
asset_categories_dict = load_asset_categories(json_file_path)

# Print what it's trying to match against
print(f"Trying to match against target category: {target_category}")

def setSelectedSize():
    global selectedSize
    match input("What size texture do you want to download??\n"
            "2k, 4k, or 8k "):
        case "2k":
            print("File texture selected: 2k")
            selectedSize = "2k"
            return
        case "4k":
            selectedSize = "4k"
            print("File texture selection: 4k")
            return
        case "8k":
            selectedSize = "8k"
            print("File texture selection: 8k")
            return
        case _:
            print("Invalid Option. Type 2k, 4k, or 8k.\n")
            setSelectedSize()

def clickDownloadButton(asset_id):
    #Not needed publicly yet. For testing
    url = "https://quixel.com/v1/assets/xbmobcz/extended"
    
def get_asset_download_id(asset_id):
    url = "https://quixel.com/v1/downloads"
    
    params2k = {
        "asset": asset_id,
        "components": [
            {"type":"albedo","mimeType":"image/jpeg","resolution":"2048x2048"},
            {"type":"normal","mimeType":"image/jpeg","resolution":"2048x2048"},
            {"type":"displacement","mimeType":"image/jpeg","resolution":"2048x2048"},
            {"type":"ao","mimeType":"image/jpeg","resolution":"2048x2048"},
            {"type":"roughness","mimeType": "image/jpeg","resolution": "2048x2048"},
            {"type":"opacity","mimeType": "image/jpeg","resolution": "2048x2048"},
            {"type":"brush","mimeType":"image/jpeg","resolution":"2048x2048"},
        ],
        "config": {
            "highpoly": False,
            "lowerlod_meshes" : True,
            "lowerlod_normals": True,    
            "ztool": False,
            "brushes": False,
            "maxlod" : 100000000,
            "albedo_lods": True,
            "meshMimeType": "application/x-fbx",
            "lods": [29155, 13541, 6289, 2921],
        },
    }
    params4k = {
        "asset": asset_id,
        "components": [
            {"type":"albedo","mimeType":"image/jpeg","resolution":"4096x4096"},
            {"type":"normal","mimeType":"image/jpeg","resolution":"4096x4096"},
            {"type":"displacement","mimeType":"image/jpeg","resolution":"4096x4096"},
            {"type":"ao","mimeType":"image/jpeg","resolution":"4096x4096"},
            {"type":"roughness","mimeType": "image/jpeg","resolution": "4096x4096"},
            {"type":"opacity","mimeType": "image/jpeg","resolution": "4096x4096"},
            {"type":"brush","mimeType":"image/jpeg","resolution":"4096x4096"},
        ],
        "config": {
            "highpoly": False,
            "lowerlod_meshes" : True,
            "lowerlod_normals": True,    
            "ztool": False,
            "brushes": False,
            "maxlod" : 100000000,
            "albedo_lods": True,
            "meshMimeType": "application/x-fbx",
            "lods": [29155, 13541, 6289, 2921],
        },
    }
    params8k = {
        "asset": asset_id,
        "components": [
            {"type":"albedo","mimeType":"image/jpeg","resolution":"8192x8192"},
            {"type":"normal","mimeType":"image/jpeg","resolution":"8192x8192"},
            {"type":"displacement","mimeType":"image/jpeg","resolution":"8192x8192"},
            {"type":"ao","mimeType":"image/jpeg","resolution":"8192x8192"},
            {"type":"roughness","mimeType": "image/jpeg","resolution": "8192x8192"},
            {"type":"opacity","mimeType": "image/jpeg","resolution": "8192x8192"},
            {"type":"brush","mimeType":"image/jpeg","resolution":"8192x8192"},
        ],
        "config": {
            "highpoly": False,
            "lowerlod_meshes" : True,
            "lowerlod_normals": True,    
            "ztool": False,
            "brushes": False,
            "maxlod" : 100000000,
            "albedo_lods": True,
            "meshMimeType": "application/x-fbx",
            "lods": [29155, 13541, 6289, 2921],
        },
    }    
    
    #requestExtendedInfo(asset_id)
    print(f"Getting download ID for asset: {asset_id} \n")
    global selectedSize
    
    paramToPass = {}
    match selectedSize:
        case "2k":
            paramToPass = params2k
        case "4k":
            paramToPass = params4k
        case "8k":
            paramToPass = params8k
        case _:
            paramToPass = params2k

    download_url_response = requests.post(url, headers=headers, json=paramToPass)
    if download_url_response.status_code == 200:
        return download_url_response.json()["id"]
    elif download_url_response.status_code == 401:
        print("Possible expired token. Please get a new one from https://quixel.com/megascans/home/ and then update the script. \n")
        print("If you just ran the script and downloaded stuff prior to this, just re-run the script and try again.")
        input("Press any key to quit. \n")
        os._exit(0)
    else:
        print(f"Failed to get asset download url for id: {asset_id}")
        print("[DEBUG_ERROR]: " + download_url_response.json())
        return None

def download_asset(download_id, download_directory):
    os.makedirs(download_directory, exist_ok=True)

    url = f"https://assetdownloads.quixel.com/download/{download_id}?preserveStructure=True&url=https%3A%2F%2Fquixel.com%2Fv1%2Fdownloads"

    ##print(f"Attempting to download from: {url}")
    
    response = requests.get(url, stream=True)
    
    if response.status_code == 400:
        print(f"Error 400: {response.text}")  # Print the response to see what's causing the issue

    attempt_count = 0
    delay = 5
    max_attempts = 5

    while attempt_count < max_attempts:
        response = requests.get(url, stream=True)
        if response.status_code == 200:
            content_disposition = response.headers.get("Content-Disposition")
            filename = content_disposition.split("filename=")[-1].strip('"') if content_disposition else download_id
            file_path = os.path.join(download_directory, filename)

            print(f"Downloading file: {filename}")

            try: ##ctrl-q for multi line
                with open(file_path, "wb") as file:
                    for chunk in response.iter_content(chunk_size=8192):
                        file.write(chunk)
                print(f"File downloaded successfully: {file_path}")
                return True
            except requests.exceptions.ChunkedEncodingError as e:
                print(f"Error during download: {e}")
                time.sleep(delay)
                delay += 5
                attempt_count += 1
        else:
            print(f"Failed to download asset {download_id}, status code: {response.status_code}")
            print(f"Response: {response.text}")  # Print the response content for more details
            return False

    print(f"Exceeded maximum retry attempts for asset {download_id}")
    return False

match input("Do you want to redownload existing cached downloads?\n"
        "Please enter yes or no\n"):
    case "yes":
        overwrite = True
    case "no":
        overwrite = False

# print(overwrite)

# Load cached assets
cached_assets = set()
if os.path.exists(cache_file_path):
    with open(cache_file_path, "r") as cache_file:
        cached_assets = set(cache_file.read().splitlines())

# Normalize target category for matching
normalized_target_categories = [normalize_category(part) for part in target_category.split("/")]

matching_asset_ids = []
# Check matches for each asset in the loaded categorie  s
for asset_id, categories in asset_categories_dict.items():
    # Convert the categories to a single string for matching
    categories_str = categories_to_string(categories)

    # Check if all parts of target_category exist in the categories string
    matches = all(normalize_category(part) in categories_str.lower() for part in normalized_target_categories)

## matches and not in. -> add
## matches and in and overwrite -> add
    if matches and asset_id not in cached_assets:
        print(f"Asset ID: {asset_id} matches target category: {target_category}")
        matching_asset_ids.append(asset_id)
    elif matches and asset_id in cached_assets and overwrite:
        print(f"Asset ID: {asset_id} matches target category: {target_category}")
        matching_asset_ids.append(asset_id)
        
if not matching_asset_ids:
    print("No new assets found for the target category.")
    exit()

# Ask the user for confirmation before downloading
print(f"{len(matching_asset_ids)} assets found.")
downloadCount = len(matching_asset_ids)
confirmation = input(f"Do you want to download these {len(matching_asset_ids)} {target_category} assets? (yes/no): ").strip().lower()

if confirmation != "yes":
    print("Download canceled.")
    exit()

setSelectedSize()
        
# Function to handle downloading for threading
def download_asset_with_id(asset_id):
    download_id = get_asset_download_id(asset_id)
    if download_id:
        return download_asset(download_id, download_path)
    else:
        print(f"No download id found for {asset_id}.")

#Open the cache file for appending new downloads
with open(cache_file_path, "a+") as cache_file:
    # Use threading for faster downloading
    with concurrent.futures.ThreadPoolExecutor(max_workers=15) as executor:
        futures = {executor.submit(download_asset_with_id, asset_id): asset_id for asset_id in matching_asset_ids}
        for future in concurrent.futures.as_completed(futures):
            asset_id = futures[future]
            try:
                result = future.result()
                if result:
                    downloadCount-=1;
                    print(f"{downloadCount} remaining items to download.")
                    # Add the asset to the cache file after successful download
                    cache_file.write(f"{asset_id}\n")
                    cache_file.flush()
            except Exception as e:
                print(f"Error downloading asset {asset_id}: {e}")

Copie d'écran de la console PowerShell

twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Megasc16
twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Megasc14
twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Megasc17
twinmotion - [ TWINMOTION ] Unreal Engine déménage sur Fab -  Assets de Megascan Megasc15

Pour générer la valeur à indiquer pour le token en ligne 8 du premier script et la 9 pour le second script, utliser le javascript précisé dans les liens ci-avant.
Copier le code du javascript et le coller, sur la page web de Quixel contenant vos assets,  dans la console DEV de votre navigateur (Chrome, Firefox,..) qui s'ouvre par le raccourci de la touche F12, puis valider pour que le code token soit généré. On le copie et on le colle entre les guillemets dans la ligne indiqué contenant token = "  "
Attention la valeur du token peut changer au bout de quelques heures. Il faudra alors le regénérer pour poursuivre les téléchargements et le modifier dans le script en conséquence.

Code javascript  gettoken.js

Code:
function getCookie(name) {
  const value = `; ${document.cookie}`;
  const parts = value.split(`; ${name}=`);
  if (parts.length === 2) return parts.pop().split(';').shift();
}

function copyToClipboard(text) {
    var dummy = document.createElement("textarea");
    // to avoid breaking orgain page when copying more words
    // cant copy when adding below this code
    // dummy.style.display = 'none'
    document.body.appendChild(dummy);
    //Be careful if you use texarea. setAttribute('value', value), which works with "input" does not work with "textarea". – Eduard
    dummy.value = text;
    dummy.select();
    document.execCommand("copy");
    document.body.removeChild(dummy);
}

// Get the auth cookie
const authCookie = getCookie('auth');

// Parse the auth cookie (it should be a JSON string containing the token)
if (authCookie) {
  try {
    const authData = JSON.parse(decodeURIComponent(authCookie));
    const authToken = authData.token;
    console.log("Auth Token:", authToken);
   console.log("Auth token copied to clipboard.");
   copyToClipboard(authToken);
  } catch (error) {
    console.error("Error parsing auth cookie:", error);
  }
} else {
  console.error("Auth cookie not found. Please make sure you are logged in.");
}


Dernière édition par JDD le Lun 7 Oct 2024 - 14:00, édité 1 fois
JDD
JDD
V.I.P.
V.I.P.
Masculin Humeur : Cool, œil de lynx à pattes de velours
Date d'inscription : 21/05/2021
Nombre de messages : 1138
Points : 2488
Age : 75
Localisation : Nord (59)
Emploi : Director of Myself

MessageJDD Dim 6 Oct 2024 - 22:05

Re-Bonsoir,

Pour compléter :

Contenu et volume de la Librairie Megascans

Surface = 7352 assets (1.32TB)
Decals = 2235 assets (193GB)
Brush = 618 assets (5.44GB)
Imperfections = 547 assets (34GB)
Displacement = 52 assets (1.19GB)
Atlas = 3293 assets (52.2GB)
3D plant = 288 assets (317GB)

3D Assets Cat's;
3D /nature = 1878 assets (376GB)
3D /props = 743 (104GB)
3D /street = 200 assets (38.1GB)
3D /interior = 339 assets (46.3GB)
3D /industrial = 221 assets (31.9GB)
3D /historical = 240 assets (52.4GB)
3D /food = 204 assets (14.7GB)
3D /building = 346 assets (66.3GB)

total fichiers = 18556 @ 2.62TB
Gaspard Hauser
Gaspard Hauser
Moulin à parole
Moulin à parole
Masculin Date d'inscription : 30/01/2019
Nombre de messages : 205
Points : 301
https://jskup.fr/

MessageGaspard Hauser Lun 7 Oct 2024 - 8:30

Bonjour Jdd,
je n'ai pas essayé de traduire en français tous les codes que tu joins, mais si je comprends bien tu as réussi à télécharger en local les assets? Tu as consacré 2.6 TB sur tes machines aux assets de megascans?
JDD
JDD
V.I.P.
V.I.P.
Masculin Humeur : Cool, œil de lynx à pattes de velours
Date d'inscription : 21/05/2021
Nombre de messages : 1138
Points : 2488
Age : 75
Localisation : Nord (59)
Emploi : Director of Myself

MessageJDD Lun 7 Oct 2024 - 9:54

Hello  @Gaspard Hauser ,

Pourquoi veut tu traduire en français tous les codes ???

Dans le post précédent j'ai simplement voulu indiquer, pour INFORMATION et pour que l'on puisse se faire une idée du volume en cas de téléchargement, de ce que  la librairie Quixel Megascans contient , c'est à dire la totale,  avec toutes les tous formats de résolution 2K, 4K , 8K , toutes les différentes maps pour chaque matériaux, tous les formats 3d (FBX, ABC),  tous les formats images (jpg, exr, ... ) et etc..

Perso je ne suis intéressé que par les rubriques "Surface", "Imperfections" et "Displacement" en résolution 4K maxi,  mais cela nécessite déjà pas mal de place de stockage.

JDD
JDD
JDD
V.I.P.
V.I.P.
Masculin Humeur : Cool, œil de lynx à pattes de velours
Date d'inscription : 21/05/2021
Nombre de messages : 1138
Points : 2488
Age : 75
Localisation : Nord (59)
Emploi : Director of Myself

MessageJDD Lun 7 Oct 2024 - 21:52

Bonsoir,

@Gaspard Hauser , j'ai trouvé la solution pour résoudre les problèmes de non applications des textures dans Blender 4.xx lors d'un import d'un asset Quixel Megascans via Bridge.

La solution est détaillée dans cette vidéo ICI

JDD

tenrev aime ce message

Contenu sponsorisé

MessageContenu sponsorisé

Voir le sujet précédent Voir le sujet suivant Revenir en haut

Créer un compte ou se connecter pour répondre

Vous devez être membre pour répondre.

S'enregistrer

Rejoignez notre communauté ! C'est facile !


S'enregistrer

Connexion

Vous êtes déjà membre ? Aucun soucis, cliquez ici pour vous connecter.


Connexion

 
Permission de ce forum:
Vous ne pouvez pas répondre aux sujets dans ce forum