瀏覽代碼

Added edges computation to OBJ converter.

If you want to get edges, run converter like with "-e" flag:

python convert_obj_three.py -i model.obj -o model.js -e

Output seems to match Blender exporter.
alteredq 14 年之前
父節點
當前提交
f7e3a80d70

+ 1 - 1
examples/obj/female02/Female02_bin.js

@@ -1,6 +1,6 @@
 // Converted from: ../../examples/obj/female02/female02.obj
 //  vertices: 3274
-//  faces: 6233 
+//  faces: 6233
 //  materials: 6
 //
 //  Generated with OBJ -> Three.js converter

File diff suppressed because it is too large
+ 3 - 2
examples/obj/female02/Female02_slim.js


+ 1 - 1
examples/obj/lucy/Lucy100k_bin.js

@@ -1,6 +1,6 @@
 // Converted from: ../../examples/obj/lucy/lucy100k.obj
 //  vertices: 50002
-//  faces: 100000 
+//  faces: 100000
 //  materials: 0
 //
 //  Generated with OBJ -> Three.js converter

File diff suppressed because it is too large
+ 3 - 2
examples/obj/lucy/Lucy100k_slim.js


+ 1 - 1
examples/obj/male02/Male02_bin.js

@@ -1,6 +1,6 @@
 // Converted from: ../../examples/obj/male02/male02.obj
 //  vertices: 2746
-//  faces: 5004 
+//  faces: 5004
 //  materials: 5
 //
 //  Generated with OBJ -> Three.js converter

File diff suppressed because it is too large
+ 3 - 2
examples/obj/male02/Male02_slim.js


+ 1 - 1
examples/obj/ninja/NinjaLo_bin.js

@@ -1,6 +1,6 @@
 // Converted from: ../../examples/obj/ninja/ninjaHead_Low.obj
 //  vertices: 4485
-//  faces: 4810 
+//  faces: 4810
 //  materials: 0
 //
 //  Generated with OBJ -> Three.js converter

+ 1 - 1
examples/obj/torus/Torus_bin.js

@@ -1,6 +1,6 @@
 // Converted from: ../../examples/obj/torus/Torus.obj
 //  vertices: 576
-//  faces: 576 
+//  faces: 576
 //  materials: 1
 //
 //  Generated with OBJ -> Three.js converter

File diff suppressed because it is too large
+ 3 - 2
examples/obj/torus/Torus_slim.js


+ 1 - 1
examples/obj/walt/WaltHead_bin.js

@@ -1,6 +1,6 @@
 // Converted from: ../../examples/obj/walt/WaltHead.obj
 //  vertices: 8146
-//  faces: 16160 
+//  faces: 16160
 //  materials: 1
 //
 //  Generated with OBJ -> Three.js converter

File diff suppressed because it is too large
+ 3 - 2
examples/obj/walt/WaltHead_slim.js


+ 1 - 1
src/core/Geometry.js

@@ -404,7 +404,7 @@ THREE.Geometry.prototype = {
 
 		function edge_hash( a, b ) {
 
-			 return Math.min( a, b ) + "_" + Math.max( a, b );
+			return Math.min( a, b ) + "_" + Math.max( a, b );
 
 		};
 

+ 118 - 13
utils/exporters/convert_obj_three.py

@@ -4,15 +4,28 @@
 How to use this converter
 -------------------------
 
-python convert_obj_three.py -i infile.obj -o outfile.js [-m morphfiles*.obj] [-c morphcolors*.obj] [-a center|centerxz|top|bottom|none] [-s smooth|flat] [-t ascii|binary] [-d invert|normal] [-b]
+python convert_obj_three.py -i infile.obj -o outfile.js [-m "morphfiles*.obj"] [-c "morphcolors*.obj"] [-a center|centerxz|top|bottom|none] [-s smooth|flat] [-t ascii|binary] [-d invert|normal] [-b] [-e]
 
 Notes: 
+    - flags
+        -i infile.obj			input OBJ file
+        -o outfile.js			output JS file
+        -m "morphfiles*.obj"	morph OBJ files (can use wildcards, enclosed in quotes multiple patterns separate by space)
+        -c "morphcolors*.obj"	morph colors OBJ files (can use wildcards, enclosed in quotes multiple patterns separate by space)
+        -a center|centerxz|top|bottom|none model alignment
+        -s smooth|flat			smooth = export vertex normals, flat = no normals (face normals computed in loader)
+        -t ascii|binary			export ascii or binary format (ascii has more features, binary just supports vertices, faces, normals, uvs and materials)
+        -d invert|normal		invert transparency
+        -b						bake material colors into face colors
+        -e						export edges
 
     - by default:
         converted model will be centered (middle of bounding box goes to 0,0,0)
         use smooth shading (if there were vertex normals in the original model)
         will be in ASCII format
         original model is assumed to use non-inverted transparency / dissolve (0.0 fully transparent, 1.0 fully opaque)
+        no face colors baking
+        no edges export
  
     - binary conversion will create two files: 
         outfile.js  (materials)
@@ -62,10 +75,7 @@ Current limitations
     - for the moment, only diffuse color and texture are used 
       (will need to extend shaders / renderers / materials in Three)
      
-    - models can have more than 65,536 vertices,
-      but in most cases it will not work well with browsers,
-      which currently seem to have troubles with handling
-      large JS files
+    - models can have more than 65,536 vertices
        
     - texture coordinates can be wrong in canvas renderer
       (there is crude normalization, but it doesn't
@@ -138,6 +148,7 @@ TYPE = "ascii"          # ascii binary
 TRANSPARENCY = "normal" # normal invert
 
 BAKE_COLORS = False
+EXPORT_EDGES = False
 
 # default colors for debugging (each material gets one distinct color): 
 # white, red, green, blue, yellow, cyan, magenta
@@ -149,11 +160,12 @@ COLORS = [0xeeeeee, 0xee0000, 0x00ee00, 0x0000ee, 0xeeee00, 0x00eeee, 0xee00ee]
 TEMPLATE_FILE_ASCII = u"""\
 // Converted from: %(fname)s
 //  vertices: %(nvertex)d
-//  faces: %(nface)d 
+//  faces: %(nface)d
 //  normals: %(nnormal)d
 //  colors: %(ncolor)d
-//  uvs: %(nuv)d 
+//  uvs: %(nuv)d
 //  materials: %(nmaterial)d
+//  edges: %(nedge)d
 //
 //  Generated with OBJ -> Three.js converter
 //  http://github.com/alteredq/three.js/blob/master/utils/exporters/convert_obj_three.py
@@ -177,7 +189,9 @@ var model = {
 
     "uvs": [[%(uvs)s]],
 
-    "faces": [%(faces)s]
+    "faces": [%(faces)s],
+
+    "edges" : [%(edges)s]
 
 };
 
@@ -187,7 +201,7 @@ postMessage( model );
 TEMPLATE_FILE_BIN = u"""\
 // Converted from: %(fname)s
 //  vertices: %(nvertex)d
-//  faces: %(nface)d 
+//  faces: %(nface)d
 //  materials: %(nmaterial)d
 //
 //  Generated with OBJ -> Three.js converter
@@ -213,6 +227,7 @@ TEMPLATE_N = "%f,%f,%f"
 TEMPLATE_UV = "%f,%f"
 TEMPLATE_COLOR = "%.3f,%.3f,%.3f"
 TEMPLATE_COLOR_DEC = "%d"
+TEMPLATE_EDGE = "%d,%d"
 
 TEMPLATE_MORPH_VERTICES = '\t{ "name": "%s", "vertices": [%s] }'
 TEMPLATE_MORPH_COLORS   = '\t{ "name": "%s", "colors": [%s] }'
@@ -339,6 +354,9 @@ def normalize(v):
         v[1] /= l
         v[2] /= l
 
+def veckey3(v):
+    return round(v[0], 6), round(v[1], 6), round(v[2], 6)
+
 # #####################################################
 # MTL parser
 # #####################################################
@@ -675,6 +693,9 @@ def generate_color_rgb(c):
 def generate_color_decimal(c):
     return TEMPLATE_COLOR_DEC % hexcolor(c)
     
+def generate_edge(e):
+    return TEMPLATE_EDGE % (e[0], e[1])
+    
 # #####################################################
 # Morphs
 # #####################################################
@@ -812,6 +833,74 @@ def generate_morph_colors(colorfiles, n_vertices, n_faces):
     
     return morphColors, colorFaces, materialColors
 
+# #####################################################
+# Edges
+# #####################################################
+def edge_hash(a, b):
+    return "%d_%d" % (min(a, b), max(a, b))
+    
+def add_unique_edge(a, b, edge_set, edges):
+    h = edge_hash(a[0], b[0])
+    if h not in edge_set:
+        x = min(a[1], b[1])
+        y = max(a[1], b[1])
+        edges.append([x, y])
+        edge_set.add(h)
+    
+def compute_edges(faces, vertices):
+    edges = []
+    
+    # compute unique vertices
+
+    unique_vertices = {}
+    vertex_count = 0
+    
+    for i, v in enumerate(vertices):
+        key = veckey3(v)
+        if key not in unique_vertices:
+            unique_vertices[key] = [vertex_count, i]
+            vertex_count += 1
+
+    # find edges between unique vertices
+    
+    edge_set = set()    
+
+    for f in faces:
+        vertex_indices = f["vertex"]
+        unique_indices = []
+
+        for vi in vertex_indices:
+            v = vertices[vi - 1]
+            key = veckey3(v)
+            unique_indices.append(unique_vertices[key])
+        
+        if len(unique_indices) == 3:
+            a = unique_indices[0]
+            b = unique_indices[1]
+            c = unique_indices[2]
+            
+            add_unique_edge(a, b, edge_set, edges)
+            add_unique_edge(b, c, edge_set, edges)
+            add_unique_edge(a, c, edge_set, edges)
+
+        elif len(unique_indices) == 4:
+            a = unique_indices[0]
+            b = unique_indices[1]
+            c = unique_indices[2]
+            d = unique_indices[3]
+            
+            # this should be inside edge of quad, should it go in?
+            # add_unique_edge(b, d, edge_set, edges) 
+            
+            add_unique_edge(a, b, edge_set, edges)
+            add_unique_edge(a, d, edge_set, edges)
+            add_unique_edge(b, c, edge_set, edges)
+            add_unique_edge(c, d, edge_set, edges)
+
+    edges.sort()
+    
+    return edges
+
 # #####################################################
 # Materials
 # #####################################################
@@ -1034,10 +1123,10 @@ def convert_ascii(infile, morphfiles, colorfiles, outfile):
     morphColors, colorFaces, materialColors = generate_morph_colors(colorfiles, n_vertices, n_faces)    
 
     # generate colors string
-    
+
     ncolor = 0
     colors_string = ""
-    
+
     if len(colorFaces) < len(faces):
         colorFaces = faces
         materialColors = extract_material_colors(materials, mtllib, infile)
@@ -1046,6 +1135,16 @@ def convert_ascii(infile, morphfiles, colorfiles, outfile):
         colors_string = ",".join(generate_color_decimal(c) for c in materialColors)
         ncolor = len(materialColors)
         
+    # generate edges string
+    
+    nedge = 0
+    edges_string = ""
+    
+    if EXPORT_EDGES:
+        edges = compute_edges(faces, vertices)
+        nedge = len(edges) 
+        edges_string  = ",".join(generate_edge(e) for e in edges)
+        
     # generate ascii model string
 
     text = TEMPLATE_FILE_ASCII % {
@@ -1057,6 +1156,7 @@ def convert_ascii(infile, morphfiles, colorfiles, outfile):
     "nnormal"   : nnormal,
     "ncolor"    : ncolor,
     "nmaterial" : len(materials),
+    "nedge"     : nedge,
 
     "materials" : generate_materials_string(materials, mtllib, infile),
 
@@ -1068,7 +1168,9 @@ def convert_ascii(infile, morphfiles, colorfiles, outfile):
     "morphTargets"  : morphTargets,
     "morphColors"   : morphColors,
     
-    "faces"     : ",".join(generate_face(f, fc) for f, fc in zip(faces, colorFaces))
+    "faces"     : ",".join(generate_face(f, fc) for f, fc in zip(faces, colorFaces)),
+        
+    "edges"    : edges_string
     }
     
     out = open(outfile, "w")
@@ -1403,7 +1505,7 @@ if __name__ == "__main__":
     
     # get parameters from the command line
     try:
-        opts, args = getopt.getopt(sys.argv[1:], "hbi:m:c:b:o:a:s:t:d:", ["help", "bakecolors", "input=", "morphs=", "colors=", "output=", "align=", "shading=", "type=", "dissolve="])
+        opts, args = getopt.getopt(sys.argv[1:], "hbei:m:c:b:o:a:s:t:d:", ["help", "bakecolors", "edges", "input=", "morphs=", "colors=", "output=", "align=", "shading=", "type=", "dissolve="])
     
     except getopt.GetoptError:
         usage()
@@ -1449,6 +1551,9 @@ if __name__ == "__main__":
         elif o in ("-b", "--bakecolors"):
             BAKE_COLORS = True
 
+        elif o in ("-e", "--edges"):
+            EXPORT_EDGES = True
+
     if infile == "" or outfile == "":
         usage()
         sys.exit(2)

Some files were not shown because too many files changed in this diff