[Bf-extensions-cvs] [cdd96b1] master: Quake/Doom3 Map exporter: add some basic 'guided splitting' of concave meshes, for Doom3.

Bastien Montagne noreply at git.blender.org
Sun Jul 19 18:23:42 CEST 2015


Commit: cdd96b143c363c0a92950361ef6adedafc3f5fd6
Author: Bastien Montagne
Date:   Sun Jul 19 18:20:46 2015 +0200
Branches: master
https://developer.blender.org/rBACcdd96b143c363c0a92950361ef6adedafc3f5fd6

Quake/Doom3 Map exporter: add some basic 'guided splitting' of concave meshes, for Doom3.

To summarize, you have to mark as seam the edges where you want to split your mesh.
Script will then take care of actuall splitting and adding 'fill-in' planes.

Code from motorstep, with quick review & cleanup from myself.

Note that we most likely can do much much better here, but no time for this currently.
Code works, will do for now. :)

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

M	io_scene_map/__init__.py
M	io_scene_map/export_map.py

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

diff --git a/io_scene_map/__init__.py b/io_scene_map/__init__.py
index b0019ce..f0616a1 100644
--- a/io_scene_map/__init__.py
+++ b/io_scene_map/__init__.py
@@ -20,8 +20,8 @@
 
 bl_info = {
     "name": "Quake/Doom3 MAP format",
-    "author": "Campbell Barton, scorpion81, Bastien Montagne",
-    "version": (2, 0, 0),
+    "author": "Campbell Barton, scorpion81, Bastien Montagne, motorstep",
+    "version": (2, 1, 0),
     "blender": (2, 6, 9),
     "location": "File > Export",
     "description": "Export MAP brushes, nurbs surfaces, "
@@ -69,13 +69,14 @@ class ExportMAP(bpy.types.Operator, ExportHelper):
             name="Scale",
             description="Scale everything by this value",
             min=0.01, max=1000.0,
-            default=100.0,
+            default=1.0,
             )
     grid_snap = BoolProperty(
             name="Grid Snap",
             description="Round to whole numbers",
             default=False,
             )
+
     texture_null = StringProperty(
             name="Tex Null",
             description="Texture used when none is assigned",
diff --git a/io_scene_map/export_map.py b/io_scene_map/export_map.py
index 5c868d8..d8e69e5 100644
--- a/io_scene_map/export_map.py
+++ b/io_scene_map/export_map.py
@@ -25,6 +25,10 @@ import os
 import mathutils
 from mathutils import Vector
 
+from contextlib import redirect_stdout
+import io
+stdout = io.StringIO()
+
 # TODO, make options
 PREF_SCALE = 1
 PREF_FACE_THICK = 0.1
@@ -380,6 +384,70 @@ def write_node_map(fw, ob):
     return True
 
 
+def split_objects(context, objects):
+    scene = context.scene
+    final_objects = []
+
+    bpy.ops.object.select_all(action='DESELECT')
+    for ob in objects:
+        ob.select = True
+
+    bpy.ops.object.duplicate()
+    objects = bpy.context.selected_objects
+
+    bpy.ops.object.select_all(action='DESELECT')
+
+    tot_ob = len(objects)
+    for i, ob in enumerate(objects):
+        print("Splitting object: %d/%d" % (i, tot_ob))
+        ob.select = True
+        
+        if ob.type == "MESH":
+            scene.objects.active = ob
+            bpy.ops.object.mode_set(mode='EDIT')
+            bpy.ops.mesh.select_all(action='DESELECT')
+            bpy.ops.mesh.select_mode(type='EDGE')
+            bpy.ops.object.mode_set(mode='OBJECT')
+            for edge in ob.data.edges:
+                if edge.use_seam:
+                    edge.select = True
+            bpy.ops.object.mode_set(mode='EDIT')
+            bpy.ops.mesh.edge_split()
+            bpy.ops.mesh.separate(type='LOOSE')
+            bpy.ops.object.mode_set(mode='OBJECT')
+
+            split_objects = context.selected_objects
+            for split_ob in split_objects:
+                assert(split_ob.type == "MESH")
+
+                scene.objects.active = split_ob
+                bpy.ops.object.mode_set(mode='EDIT')
+                bpy.ops.mesh.select_mode(type='EDGE')
+                bpy.ops.mesh.select_all(action="SELECT")
+                bpy.ops.mesh.region_to_loop()
+                bpy.ops.mesh.fill_holes(sides=8)
+                slot_idx = 0
+                for slot_idx, m in enumerate(split_ob.material_slots):                       
+                   if m.name == "textures/common/caulk":
+                      break
+                   #if m.name != "textures/common/caulk":
+                   #   mat = bpy.data.materials.new("textures/common/caulk")
+                   #   bpy.context.object.data.materials.append(mat)
+                split_ob.active_material_index = slot_idx  # we need to use either actual material name or custom property instead of index
+                bpy.ops.object.material_slot_assign()
+                with redirect_stdout(stdout):
+                   bpy.ops.mesh.remove_doubles()
+                bpy.ops.mesh.quads_convert_to_tris()
+                bpy.ops.mesh.tris_convert_to_quads()
+                bpy.ops.object.mode_set(mode='OBJECT')
+            final_objects += split_objects
+
+        ob.select = False
+
+    print(final_objects)
+    return final_objects
+
+
 def export_map(context, filepath):
     """
     pup_block = [\
@@ -431,6 +499,8 @@ def export_map(context, filepath):
         elif type == 'EMPTY':
             obs_empty.append(ob)
 
+    obs_mesh = split_objects(context, obs_mesh)
+
     with open(filepath, 'w') as fl:
         fw = fl.write
 
@@ -444,7 +514,11 @@ def export_map(context, filepath):
             fw('"classname" "worldspawn"\n')
 
         print("\twriting cubes from meshes")
-        for ob in obs_mesh:
+
+        tot_ob = len(obs_mesh)
+        for i, ob in enumerate(obs_mesh):
+            print("Exporting object: %d/%d" % (i, tot_ob))
+
             dummy_mesh = ob.to_mesh(scene, True, 'PREVIEW')
 
             #print len(mesh_split2connected(dummy_mesh))
@@ -581,6 +655,10 @@ def export_map(context, filepath):
             else:
                 print("\t\tignoring %s" % ob.name)
 
+    for ob in obs_mesh:
+        scene.objects.unlink(ob)
+        bpy.data.objects.remove(ob)
+
     print("Exported Map in %.4fsec" % (time.time() - t))
     print("Brushes: %d  Nodes: %d  Lamps %d\n" % (TOTBRUSH, TOTNODE, TOTLAMP))
 
@@ -588,7 +666,7 @@ def export_map(context, filepath):
 def save(operator,
          context,
          filepath=None,
-         global_scale=100.0,
+         global_scale=1.0,
          face_thickness=0.1,
          texture_null="NULL",
          texture_opts='0 0 0 1 1 0 0 0',



More information about the Bf-extensions-cvs mailing list