Différences

Ci-dessous, les différences entre deux révisions de la page.

Lien vers cette vue comparative

Les deux révisions précédentes Révision précédente
Prochaine révision
Révision précédente
recherche:residence_polygones:mesh2svg2paper [2025/11/09 15:49]
emoc [obj2svg]
recherche:residence_polygones:mesh2svg2paper [2025/11/09 20:44] (Version actuelle)
emoc [Conversion de formats 3D en ligne de commande]
Ligne 26: Ligne 26:
   * Geomview object file format (.off),   * Geomview object file format (.off),
   * VRML 2.0 - export only (.wrl).   * VRML 2.0 - export only (.wrl).
 +Exemple :
 +  ctmconv parasect.obj parasect.stl
 +
 +===== Infos sur un objet 3D en ligne de commande =====
 +
 +Nombre de points, de faces, etc.
 +
 +Avec **assimp-utils**
 +  sudo apt install assimp-utils
 +  assimp info teapot.obj
 +  ​
 +Assimp pour Open Asset Import Library
 +  * https://​github.com/​assimp/​assimp
 +  * https://​the-asset-importer-lib-documentation.readthedocs.io/​en/​latest/​
 +===== Affichage d'​objets STL =====
 +
 +Avec GMSH : https://​gmsh.info/​ qui est aussi capable d'une multitude d'​autres choses (en GUI ou CLI)
 +
 +{{:​recherche:​residence_polygones:​gmsh.png?​direct&​600|}}
 +
  
 ===== Installation de Go ===== ===== Installation de Go =====
Ligne 66: Ligne 86:
 ===== Utilisation de Simplify ===== ===== Utilisation de Simplify =====
  
-Simplify est un logiciel en ligne de commande de Michael Fogleman qui permet de réduire le nombre de faces d'un objet 3D. Simplify est programmé en Go+Simplify est un logiciel en ligne de commande de Michael Fogleman qui permet de réduire le nombre de faces d'un objet 3D **au format .STL**. Simplify est programmé en Go
  
 https://​github.com/​fogleman/​simplify https://​github.com/​fogleman/​simplify
Ligne 221: Ligne 241:
 **TODO : permettre la rotation de la vue** **TODO : permettre la rotation de la vue**
  
 +===== rendu wireframe avec blender CLI + gif =====
  
 +{{:​recherche:​residence_polygones:​teapot_wire.gif?​direct|}}
 +
 +Script python blender à utiliser en ligne de commande avec 
 +  blender --background --python blender_teapot_wireframe_views.py
 +
 +<​accordion>​
 +<panel title="​blender_teapot_wireframe_views.py (cliquer pour afficher le code)">​
 +<code python blender_teapot_wireframe_views.py>​
 +# Blender 3.4.1 
 +# Debian 12 @ tenko
 +#​ 20251109,​ résidence polygones @ Fablab des portes logiques
 +
 +import bpy
 +import math
 +
 +# -------------------------------
 +# Rendu wireframe "​propre"​ 600x600
 +# -------------------------------
 +
 +# Supprimer tous les objets existants
 +bpy.ops.wm.read_factory_settings(use_empty=True)
 +
 +# Importer le STL
 +bpy.ops.import_mesh.stl(filepath="​teapot.stl"​)
 +obj = bpy.context.selected_objects[0]
 +
 +# Supprimer tous les matériaux existants
 +obj.data.materials.clear()
 +
 +# Ajouter un modifier wireframe
 +mod = obj.modifiers.new(name="​WireframeMod",​ type='​WIREFRAME'​)
 +mod.thickness = 0.02  # épaisseur des lignes
 +
 +# Créer un matériau noir shadeless pour le wireframe
 +mat = bpy.data.materials.new(name="​WireMat"​)
 +mat.diffuse_color = (0, 0, 0, 1)
 +mat.use_nodes = True
 +bsdf = mat.node_tree.nodes.get("​Principled BSDF")
 +bsdf.inputs['​Base Color'​].default_value = (0, 0, 0, 1)
 +bsdf.inputs['​Specular'​].default_value = 0
 +bsdf.inputs['​Roughness'​].default_value = 1
 +obj.data.materials.append(mat)
 +
 +# Ajouter une caméra
 +cam_data = bpy.data.cameras.new(name="​Camera"​)
 +cam_object = bpy.data.objects.new("​Camera",​ cam_data)
 +bpy.context.collection.objects.link(cam_object)
 +bpy.context.scene.camera = cam_object
 +
 +# Paramètres de rendu
 +scene = bpy.context.scene
 +scene.render.image_settings.file_format = '​PNG'​
 +scene.render.resolution_x = 600
 +scene.render.resolution_y = 600
 +scene.render.film_transparent = False  # fond blanc
 +# scene.render.film_transparent_glass = False
 +
 +# Désactiver l’anti-aliasing
 +# scene.render.use_antialiasing = False
 +scene.render.engine = '​BLENDER_EEVEE' ​ # moteur Eevee plus simple
 +# Eevee anti-aliasing quasi désactivé
 +scene.eevee.taa_render_samples = 1
 +
 +# Récupérer la scène
 +scene = bpy.context.scene
 +
 +# Créer un monde si nécessaire
 +if scene.world is None:
 +    world = bpy.data.worlds.new("​World"​)
 +    scene.world = world
 +
 +# Couleur de fond blanc
 +scene.world.use_nodes = True
 +bg = scene.world.node_tree.nodes['​Background'​]
 +bg.inputs['​Color'​].default_value = (1, 1, 1, 1)  # blanc
 +
 +# Centrer la caméra autour de l'​objet
 +center = obj.location
 +
 +# Paramètres rotation
 +n_views = 30
 +radius = 10   # distance caméra
 +elevation = 5
 +
 +for i in range(n_views):​
 +    angle = 2 * math.pi * i / n_views
 +    cam_object.location.x = center.x + radius * math.cos(angle)
 +    cam_object.location.y = center.y + radius * math.sin(angle)
 +    cam_object.location.z = center.z + elevation
 +    ​
 +    # Orienter la caméra vers le centre
 +    direction = center - cam_object.location
 +    rot_quat = direction.to_track_quat('​-Z',​ '​Y'​)
 +    cam_object.rotation_euler = rot_quat.to_euler()
 +    ​
 +    # Nom du fichier
 +    scene.render.filepath = f"​teapot_wire_{i:​02d}.png"​
 +    ​
 +    # Rendu
 +    bpy.ops.render.render(write_still=True)
 +</​code>​
 +</​panel>​
 +</​accordion>​
 +
 +Ensuite on peut assembler les images avec 
 +  convert teapot_wire_*.png -threshold 50% -colors 2 -resize 600x600 teapot_wire.gif
 +
 +{{:​recherche:​residence_polygones:​teapot_facewire.gif?​direct|}}
 +  ​
 +Version alternative qui affiche également les faces (et masque les faces cachées)
 +  blender --background --python blender_teapot_facewire.py ​                                      # calculer les rendus d'​image
 +  convert teapot_facewire_*.png -threshold 50% -colors 2 -resize 300x300 teapot_facewire.gif ​    # préparer l'​animation
 +
 +<​accordion>​
 +<panel title="​blender_teapot_facewire.py (cliquer pour afficher le code)">​
 +<code python blender_teapot_facewire.py>​
 +# Blender 3.4.1 
 +# Debian 12 @ tenko
 +#​ 20251109,​ résidence polygones @ Fablab des portes logiques
 +
 +import bpy
 +import math
 +
 +# -------------------------------
 +# Configuration de la scène
 +# -------------------------------
 +
 +# Supprimer tous les objets existants
 +bpy.ops.wm.read_factory_settings(use_empty=True)
 +
 +# Importer le STL
 +bpy.ops.import_mesh.stl(filepath="​teapot.stl"​)
 +obj = bpy.context.selected_objects[0]
 +
 +# Supprimer tous les matériaux existants
 +obj.data.materials.clear()
 +
 +# -------------------------------
 +# Matériau blanc pour les faces
 +# -------------------------------
 +mat = bpy.data.materials.new("​FaceWhite"​)
 +mat.use_nodes = True
 +bsdf = mat.node_tree.nodes["​Principled BSDF"]
 +bsdf.inputs['​Base Color'​].default_value = (1, 1, 1, 1)  # blanc
 +bsdf.inputs['​Specular'​].default_value = 0
 +obj.data.materials.append(mat)
 +
 +# -------------------------------
 +# Matériau Wireframe noir
 +# -------------------------------
 +# Ajouter un modifier wireframe
 +mod = obj.modifiers.new(name="​WireframeMod",​ type='​WIREFRAME'​)
 +mod.thickness = 0.02
 +mod.use_replace = False  # conserve faces originales
 +
 +# Création d’un second matériau pour le wireframe
 +wire_mat = bpy.data.materials.new("​WireBlack"​)
 +wire_mat.use_nodes = True
 +nodes = wire_mat.node_tree.nodes
 +bsdf_wire = nodes.get("​Principled BSDF")
 +bsdf_wire.inputs['​Base Color'​].default_value = (0, 0, 0, 1)  # noir
 +bsdf_wire.inputs['​Specular'​].default_value = 0
 +obj.data.materials.append(wire_mat)
 +
 +# Associer le modifier wireframe au matériau noir
 +mod.material_offset = 1  # utilise le second matériau
 +
 +# -------------------------------
 +# Caméra
 +# -------------------------------
 +cam_data = bpy.data.cameras.new(name="​Camera"​)
 +cam_object = bpy.data.objects.new("​Camera",​ cam_data)
 +bpy.context.collection.objects.link(cam_object)
 +bpy.context.scene.camera = cam_object
 +
 +# Paramètres de rendu
 +scene = bpy.context.scene
 +scene.render.image_settings.file_format = '​PNG'​
 +scene.render.resolution_x = 600
 +scene.render.resolution_y = 600
 +scene.render.film_transparent = False  # fond blanc
 +scene.render.engine = '​BLENDER_EEVEE'​
 +scene.eevee.taa_render_samples = 1  # anti-aliasing minimal
 +
 +# Fond blanc
 +if scene.world is None:
 +    world = bpy.data.worlds.new("​World"​)
 +    scene.world = world
 +scene.world.use_nodes = True
 +bg = scene.world.node_tree.nodes['​Background'​]
 +bg.inputs['​Color'​].default_value = (1, 1, 1, 1)  # blanc
 +
 +# -------------------------------
 +# Paramètres rotation
 +# -------------------------------
 +center = obj.location
 +n_views = 30
 +radius = 10
 +elevation = 5
 +
 +# -------------------------------
 +# Générer les images
 +# -------------------------------
 +for i in range(n_views):​
 +    angle = 2 * math.pi * i / n_views
 +    cam_object.location.x = center.x + radius * math.cos(angle)
 +    cam_object.location.y = center.y + radius * math.sin(angle)
 +    cam_object.location.z = center.z + elevation
 +    ​
 +    # Orienter la caméra vers le centre de l'​objet
 +    direction = center - cam_object.location
 +    rot_quat = direction.to_track_quat('​-Z',​ '​Y'​)
 +    cam_object.rotation_euler = rot_quat.to_euler()
 +    ​
 +    # Nom du fichier
 +    scene.render.filepath = f"​teapot_facewire_{i:​02d}.png"​
 +    ​
 +    # Rendu
 +    bpy.ops.render.render(write_still=True)
 +</​code>​
 +</​panel>​
 +</​accordion>​
 ===== Autres trucs intéressants à essayer ===== ===== Autres trucs intéressants à essayer =====
  
  • recherche/residence_polygones/mesh2svg2paper.1762699755.txt.gz
  • Dernière modification: 2025/11/09 15:49
  • par emoc