[Bf-extensions-cvs] [8d24537a] master: gltf exporter: new feature: export 'Loose Points' and 'Loose Edges'

Julien Duroure noreply at git.blender.org
Thu Feb 25 19:09:45 CET 2021


Commit: 8d24537a6e9c6e39f7d18d1bf3f4d162a85edd11
Author: Julien Duroure
Date:   Thu Feb 25 19:08:53 2021 +0100
Branches: master
https://developer.blender.org/rBA8d24537a6e9c6e39f7d18d1bf3f4d162a85edd11

gltf exporter: new feature: export 'Loose Points' and 'Loose Edges'

===================================================================

M	io_scene_gltf2/__init__.py
M	io_scene_gltf2/blender/exp/gltf2_blender_extract.py
M	io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
M	io_scene_gltf2/io/exp/gltf2_io_draco_compression_extension.py

===================================================================

diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index 8d3ac965..352affa3 100755
--- a/io_scene_gltf2/__init__.py
+++ b/io_scene_gltf2/__init__.py
@@ -1,4 +1,4 @@
-# Copyright 2018-2019 The glTF-Blender-IO authors.
+# Copyright 2018-2021 The glTF-Blender-IO authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -15,7 +15,7 @@
 bl_info = {
     'name': 'glTF 2.0 format',
     'author': 'Julien Duroure, Scurest, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
-    "version": (1, 6, 4),
+    "version": (1, 6, 5),
     'blender': (2, 91, 0),
     'location': 'File > Import-Export',
     'description': 'Import-Export as glTF 2.0',
@@ -263,6 +263,22 @@ class ExportGLTF2_Base:
         default=True
     )
 
+    use_mesh_edges: BoolProperty(
+        name='Loose Edges',
+        description=(
+            'Export loose edges as lines, using the material from the first material slot'
+        ),
+        default=False,
+    )
+
+    use_mesh_vertices: BoolProperty(
+        name='Loose Points',
+        description=(
+            'Export loose points as glTF points, using the material from the first material slot'
+        ),
+        default=False,
+    )
+
     export_cameras: BoolProperty(
         name='Cameras',
         description='Export cameras',
@@ -444,10 +460,18 @@ class ExportGLTF2_Base:
         return ExportHelper.invoke(self, context, event)
 
     def save_settings(self, context):
-        # find all export_ props
+        # find all props to save
+        exceptional = [
+            # options that don't start with 'export_'
+            'use_selection',
+            'use_mesh_edges',
+            'use_mesh_vertices',
+        ]
         all_props = self.properties
-        export_props = {x: getattr(self, x) for x in dir(all_props)
-                        if (x.startswith("export_") or x == "use_selection") and all_props.get(x) is not None}
+        export_props = {
+            x: getattr(self, x) for x in dir(all_props)
+            if (x.startswith("export_") or x in exceptional) and all_props.get(x) is not None
+        }
 
         context.scene[self.scene_key] = export_props
 
@@ -479,6 +503,8 @@ class ExportGLTF2_Base:
         export_settings['gltf_texcoords'] = self.export_texcoords
         export_settings['gltf_normals'] = self.export_normals
         export_settings['gltf_tangents'] = self.export_tangents and self.export_normals
+        export_settings['gltf_loose_edges'] = self.use_mesh_edges
+        export_settings['gltf_loose_points'] = self.use_mesh_vertices
 
         if self.is_draco_available:
             export_settings['gltf_draco_mesh_compression'] = self.export_draco_mesh_compression_enable
@@ -692,6 +718,11 @@ class GLTF_PT_export_geometry(bpy.types.Panel):
         col.active = operator.export_normals
         col.prop(operator, 'export_tangents')
         layout.prop(operator, 'export_colors')
+
+        col = layout.column()
+        col.prop(operator, 'use_mesh_edges')
+        col.prop(operator, 'use_mesh_vertices')
+
         layout.prop(operator, 'export_materials')
         col = layout.column()
         col.active = operator.export_materials == "EXPORT"
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
index 5a78ab04..0492c901 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
@@ -1,4 +1,4 @@
-# Copyright 2018-2019 The glTF-Blender-IO authors.
+# Copyright 2018-2021 The glTF-Blender-IO authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -283,6 +283,90 @@ def extract_primitives(glTF, blender_mesh, library, blender_object, blender_vert
             'material': material_idx,
         })
 
+    if export_settings['gltf_loose_edges']:
+        # Find loose edges
+        loose_edges = [e for e in blender_mesh.edges if e.is_loose]
+        blender_idxs = [vi for e in loose_edges for vi in e.vertices]
+
+        if blender_idxs:
+            # Export one glTF vert per unique Blender vert in a loose edge
+            blender_idxs = np.array(blender_idxs, dtype=np.uint32)
+            blender_idxs, indices = np.unique(blender_idxs, return_inverse=True)
+
+            attributes = {}
+
+            attributes['POSITION'] = locs[blender_idxs]
+
+            for morph_i, vs in enumerate(morph_locs):
+                attributes['MORPH_POSITION_%d' % morph_i] = vs[blender_idxs]
+
+            if skin:
+                joints = [[] for _ in range(num_joint_sets)]
+                weights = [[] for _ in range(num_joint_sets)]
+
+                for vi in blender_idxs:
+                    bones = vert_bones[vi]
+                    for j in range(0, 4 * num_joint_sets):
+                        if j < len(bones):
+                            joint, weight = bones[j]
+                        else:
+                            joint, weight = 0, 0.0
+                        joints[j//4].append(joint)
+                        weights[j//4].append(weight)
+
+                for i, (js, ws) in enumerate(zip(joints, weights)):
+                    attributes['JOINTS_%d' % i] = js
+                    attributes['WEIGHTS_%d' % i] = ws
+
+            primitives.append({
+                'attributes': attributes,
+                'indices': indices,
+                'mode': 1,  # LINES
+                'material': 0,
+            })
+
+    if export_settings['gltf_loose_points']:
+        # Find loose points
+        verts_in_edge = set(vi for e in blender_mesh.edges for vi in e.vertices)
+        blender_idxs = [
+            vi for vi, _ in enumerate(blender_mesh.vertices)
+            if vi not in verts_in_edge
+        ]
+
+        if blender_idxs:
+            blender_idxs = np.array(blender_idxs, dtype=np.uint32)
+
+            attributes = {}
+
+            attributes['POSITION'] = locs[blender_idxs]
+
+            for morph_i, vs in enumerate(morph_locs):
+                attributes['MORPH_POSITION_%d' % morph_i] = vs[blender_idxs]
+
+            if skin:
+                joints = [[] for _ in range(num_joint_sets)]
+                weights = [[] for _ in range(num_joint_sets)]
+
+                for vi in blender_idxs:
+                    bones = vert_bones[vi]
+                    for j in range(0, 4 * num_joint_sets):
+                        if j < len(bones):
+                            joint, weight = bones[j]
+                        else:
+                            joint, weight = 0, 0.0
+                        joints[j//4].append(joint)
+                        weights[j//4].append(weight)
+
+                for i, (js, ws) in enumerate(zip(joints, weights)):
+                    attributes['JOINTS_%d' % i] = js
+                    attributes['WEIGHTS_%d' % i] = ws
+
+            primitives.append({
+                'attributes': attributes,
+                'mode': 0,  # POINTS
+                'material': 0,
+            })
+
     print_console('INFO', 'Primitives created: %d' % len(primitives))
 
     return primitives
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
index 8678db83..9f9b949a 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
@@ -1,4 +1,4 @@
-# Copyright 2018-2019 The glTF-Blender-IO authors.
+# Copyright 2018-2021 The glTF-Blender-IO authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you may not use this file except in compliance with the License.
@@ -54,7 +54,7 @@ def gather_primitives(
         material_idx = internal_primitive['material']
         material = None
 
-        if export_settings['gltf_materials'] == "EXPORT":
+        if export_settings['gltf_materials'] == "EXPORT" and material_idx is not None:
             blender_material = None
             if material_names:
                 i = material_idx if material_idx < len(material_names) else -1
@@ -73,7 +73,7 @@ def gather_primitives(
             extras=None,
             indices=internal_primitive['indices'],
             material=material,
-            mode=None,
+            mode=internal_primitive['mode'],
             targets=internal_primitive['targets']
         )
         primitives.append(primitive)
@@ -101,7 +101,8 @@ def __gather_cache_primitives(
         primitive = {
             "attributes": __gather_attributes(internal_primitive, blender_mesh, modifiers, export_settings),
             "indices": __gather_indices(internal_primitive, blender_mesh, modifiers, export_settings),
-            "material": internal_primitive['material'],
+            "mode": internal_primitive.get('mode'),
+            "material": internal_primitive.get('material'),
             "targets": __gather_targets(internal_primitive, blender_mesh, modifiers, export_settings)
         }
         primitives.append(primitive)
@@ -109,7 +110,9 @@ def __gather_cache_primitives(
     return primitives
 
 def __gather_indices(blender_primitive, blender_mesh, modifiers, export_settings):
-    indices = blender_primitive['indices']
+    indices = blender_primitive.get('indices')
+    if indices is None:
+        return None
 
     # NOTE: Values used by some graphics APIs as "primitive restart" values are disallowed.
     # Specifically, the values 65535 (in UINT16) and 4294967295 (in UINT32) cannot be used as indices.
diff --git a/io_scene_gltf2/io/exp/gltf2_io_draco_compression_extension.py b/io_scene_gltf2/io/exp/gltf2_io_draco_compression_extension.py
index 0c6bfaf4..74dbfa03 100644
--- a/io_scene_gltf2/io/exp/gltf2_io_draco_compression_extension.py
+++ b/io_scene_gltf2/io/exp/gltf2_io_draco_compression_extension.py
@@ -1,4 +1,4 @@
-# Copyright 2018-2019 The glTF-Blender-IO authors.
+# Copyright 2018-2021 The glTF-Blender-IO authors.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
 # you m

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list