mirror of
https://github.com/wahyd4/three.js.git
synced 2026-08-09 04:56:01 +10:00
Fixed Blender importer to work with Blender 2.58.
This commit is contained in:
@@ -27,7 +27,7 @@ import json
|
||||
import bpy
|
||||
import mathutils
|
||||
from mathutils.geometry import tesselate_polygon
|
||||
from io_utils import load_image, unpack_list, unpack_face_list
|
||||
from bpy_extras.image_utils import load_image
|
||||
|
||||
# #####################################################
|
||||
# Generators
|
||||
@@ -40,43 +40,43 @@ def setColor(c, t):
|
||||
def create_texture(filename, modelpath):
|
||||
name = filename
|
||||
texture = bpy.data.textures.new(name, type='IMAGE')
|
||||
|
||||
|
||||
image = load_image(filename, modelpath)
|
||||
has_data = False
|
||||
|
||||
if image:
|
||||
texture.image = image
|
||||
has_data = image.has_data
|
||||
|
||||
|
||||
return texture
|
||||
|
||||
|
||||
def create_materials(data, modelpath):
|
||||
materials = []
|
||||
materials_data = data.get("materials", [])
|
||||
|
||||
|
||||
for i, m in enumerate(materials_data):
|
||||
|
||||
name = m.get("DbgName", "material_%d" % i)
|
||||
|
||||
|
||||
colorAmbient = m.get("colorAmbient", None)
|
||||
colorDiffuse = m.get("colorDiffuse", None)
|
||||
colorSpecular = m.get("colorSpecular", None)
|
||||
alpha = m.get("transparency", 1.0)
|
||||
specular_hardness = m.get("specularCoef", 0)
|
||||
|
||||
|
||||
mapDiffuse = m.get("mapDiffuse", None)
|
||||
mapLightmap = m.get("mapLightmap", None)
|
||||
|
||||
|
||||
vertexColorsType = m.get("vertexColors", False)
|
||||
|
||||
|
||||
useVertexColors = False
|
||||
if vertexColorsType:
|
||||
useVertexColors = True
|
||||
|
||||
|
||||
material = bpy.data.materials.new(name)
|
||||
|
||||
|
||||
material.THREE_useVertexColors = useVertexColors
|
||||
|
||||
|
||||
if colorDiffuse:
|
||||
setColor(material.diffuse_color, colorDiffuse)
|
||||
material.diffuse_intensity = 1.0
|
||||
@@ -84,14 +84,14 @@ def create_materials(data, modelpath):
|
||||
if colorSpecular:
|
||||
setColor(material.specular_color, colorSpecular)
|
||||
material.specular_intensity = 1.0
|
||||
|
||||
|
||||
if alpha < 1.0:
|
||||
material.alpha = alpha
|
||||
material.use_transparency = True
|
||||
|
||||
|
||||
if specular_hardness:
|
||||
material.specular_hardness = specular_hardness
|
||||
|
||||
|
||||
if mapDiffuse:
|
||||
texture = create_texture(mapDiffuse, modelpath)
|
||||
mtex = material.texture_slots.add()
|
||||
@@ -99,13 +99,13 @@ def create_materials(data, modelpath):
|
||||
mtex.texture_coords = 'UV'
|
||||
mtex.use = True
|
||||
mtex.use_map_color_diffuse = True
|
||||
|
||||
|
||||
material.active_texture = texture
|
||||
|
||||
materials.append(material)
|
||||
|
||||
|
||||
return materials
|
||||
|
||||
|
||||
def create_mesh_object(name, vertices, materials, face_data, flipYZ, recalculate_normals):
|
||||
|
||||
faces = face_data["faces"]
|
||||
@@ -114,23 +114,23 @@ def create_mesh_object(name, vertices, materials, face_data, flipYZ, recalculate
|
||||
vertexUVs = face_data["vertexUVs"]
|
||||
faceMaterials = face_data["materials"]
|
||||
faceColors = face_data["faceColors"]
|
||||
|
||||
|
||||
edges = []
|
||||
|
||||
|
||||
# Create a new mesh
|
||||
|
||||
|
||||
me = bpy.data.meshes.new(name)
|
||||
me.from_pydata(vertices, edges, faces)
|
||||
|
||||
|
||||
# Handle normals
|
||||
|
||||
|
||||
if not recalculate_normals:
|
||||
me.update(calc_edges = True)
|
||||
|
||||
|
||||
if face_data["hasVertexNormals"]:
|
||||
|
||||
|
||||
print("setting vertex normals")
|
||||
|
||||
|
||||
for fi in range(len(faces)):
|
||||
|
||||
if vertexNormals[fi]:
|
||||
@@ -139,24 +139,24 @@ def create_mesh_object(name, vertices, materials, face_data, flipYZ, recalculate
|
||||
|
||||
# if me.update() is called after setting vertex normals
|
||||
# setting face.use_smooth overrides these normals
|
||||
# - this fixes weird shading artefacts (seems to come from sharing
|
||||
# - this fixes weird shading artefacts (seems to come from sharing
|
||||
# of vertices between faces, didn't find a way how to set vertex normals
|
||||
# per face use of vertex as opposed to per vertex),
|
||||
# per face use of vertex as opposed to per vertex),
|
||||
# - probably this just overrides all custom vertex normals
|
||||
# - to preserve vertex normals from the original data
|
||||
# call me.update() before setting them
|
||||
|
||||
|
||||
me.faces[fi].use_smooth = True
|
||||
|
||||
|
||||
if not recalculate_normals:
|
||||
for j in range(len(vertexNormals[fi])):
|
||||
|
||||
|
||||
vertexNormal = vertexNormals[fi][j]
|
||||
|
||||
|
||||
x = vertexNormal[0]
|
||||
y = vertexNormal[1]
|
||||
z = vertexNormal[2]
|
||||
|
||||
|
||||
if flipYZ:
|
||||
tmp = y
|
||||
y = -z
|
||||
@@ -169,45 +169,45 @@ def create_mesh_object(name, vertices, materials, face_data, flipYZ, recalculate
|
||||
#z = -z
|
||||
|
||||
vi = me.faces[fi].vertices[j]
|
||||
|
||||
|
||||
me.vertices[vi].normal.x = x
|
||||
me.vertices[vi].normal.y = y
|
||||
me.vertices[vi].normal.z = z
|
||||
|
||||
|
||||
if recalculate_normals:
|
||||
me.update(calc_edges = True)
|
||||
|
||||
# Handle colors
|
||||
|
||||
|
||||
if face_data["hasVertexColors"]:
|
||||
|
||||
print("setting vertex colors")
|
||||
|
||||
me.vertex_colors.new("vertex_color_layer_0")
|
||||
|
||||
|
||||
for fi in range(len(faces)):
|
||||
|
||||
if vertexColors[fi]:
|
||||
|
||||
|
||||
face_colors = me.vertex_colors[0].data[fi]
|
||||
face_colors = face_colors.color1, face_colors.color2, face_colors.color3, face_colors.color4
|
||||
|
||||
|
||||
for vi in range(len(vertexColors[fi])):
|
||||
|
||||
|
||||
r = vertexColors[fi][vi][0]
|
||||
g = vertexColors[fi][vi][1]
|
||||
b = vertexColors[fi][vi][2]
|
||||
|
||||
|
||||
face_colors[vi].r = r
|
||||
face_colors[vi].g = g
|
||||
face_colors[vi].b = b
|
||||
|
||||
|
||||
elif face_data["hasFaceColors"]:
|
||||
|
||||
print("setting vertex colors from face colors")
|
||||
|
||||
me.vertex_colors.new("vertex_color_layer_0")
|
||||
|
||||
|
||||
for fi in range(len(faces)):
|
||||
|
||||
if faceColors[fi]:
|
||||
@@ -218,19 +218,19 @@ def create_mesh_object(name, vertices, materials, face_data, flipYZ, recalculate
|
||||
|
||||
face_colors = me.vertex_colors[0].data[fi]
|
||||
face_colors = face_colors.color1, face_colors.color2, face_colors.color3, face_colors.color4
|
||||
|
||||
|
||||
for vi in range(len(faces[fi])):
|
||||
|
||||
|
||||
face_colors[vi].r = r
|
||||
face_colors[vi].g = g
|
||||
face_colors[vi].b = b
|
||||
|
||||
# Handle uvs
|
||||
|
||||
|
||||
if face_data["hasVertexUVs"]:
|
||||
|
||||
print("setting vertex uvs")
|
||||
|
||||
|
||||
for li, layer in enumerate(vertexUVs):
|
||||
|
||||
me.uv_textures.new("uv_layer_%d" % li)
|
||||
@@ -238,47 +238,47 @@ def create_mesh_object(name, vertices, materials, face_data, flipYZ, recalculate
|
||||
for fi in range(len(faces)):
|
||||
|
||||
if layer[fi]:
|
||||
|
||||
|
||||
uv_face = me.uv_textures[li].data[fi]
|
||||
face_uvs = uv_face.uv1, uv_face.uv2, uv_face.uv3, uv_face.uv4
|
||||
|
||||
|
||||
for vi in range(len(layer[fi])):
|
||||
|
||||
|
||||
u = layer[fi][vi][0]
|
||||
v = layer[fi][vi][1]
|
||||
|
||||
|
||||
face_uvs[vi].x = u
|
||||
face_uvs[vi].y = 1.0 - v
|
||||
|
||||
|
||||
active_texture = materials[faceMaterials[fi]].active_texture
|
||||
|
||||
|
||||
if active_texture:
|
||||
uv_face.use_image = True
|
||||
uv_face.image = active_texture.image
|
||||
|
||||
|
||||
# Handle materials # 1
|
||||
|
||||
|
||||
if face_data["hasMaterials"]:
|
||||
|
||||
|
||||
|
||||
print("setting materials (mesh)")
|
||||
|
||||
|
||||
for m in materials:
|
||||
|
||||
|
||||
me.materials.append(m)
|
||||
|
||||
print("setting materials (faces)")
|
||||
print("setting materials (faces)")
|
||||
|
||||
for fi in range(len(faces)):
|
||||
|
||||
|
||||
if faceMaterials[fi] >= 0:
|
||||
|
||||
|
||||
me.faces[fi].material_index = faceMaterials[fi]
|
||||
|
||||
# Create a new object
|
||||
|
||||
ob = bpy.data.objects.new(name, me)
|
||||
|
||||
ob = bpy.data.objects.new(name, me)
|
||||
ob.data = me # link the mesh data to the object
|
||||
|
||||
|
||||
@@ -286,14 +286,14 @@ def create_mesh_object(name, vertices, materials, face_data, flipYZ, recalculate
|
||||
scene.objects.link(ob) # link the object into the scene
|
||||
|
||||
ob.location = scene.cursor_location # position object at 3d-cursor
|
||||
|
||||
|
||||
|
||||
|
||||
# #####################################################
|
||||
# Faces
|
||||
# #####################################################
|
||||
|
||||
def extract_faces(data):
|
||||
|
||||
|
||||
result = {
|
||||
"faces" : [],
|
||||
"materials" : [],
|
||||
@@ -303,14 +303,14 @@ def extract_faces(data):
|
||||
"vertexNormals" : [],
|
||||
"faceColors" : [],
|
||||
"vertexColors" : [],
|
||||
|
||||
|
||||
"hasVertexNormals" : False,
|
||||
"hasVertexUVs" : False,
|
||||
"hasVertexColors" : False,
|
||||
"hasFaceColors" : False,
|
||||
"hasMaterials" : False
|
||||
}
|
||||
|
||||
|
||||
faces = data.get("faces", [])
|
||||
normals = data.get("normals", [])
|
||||
colors = data.get("colors", [])
|
||||
@@ -351,23 +351,23 @@ def extract_faces(data):
|
||||
result["hasVertexColors"] = result["hasVertexColors"] or hasFaceVertexColor
|
||||
result["hasFaceColors"] = result["hasFaceColors"] or hasFaceColor
|
||||
result["hasMaterials"] = result["hasMaterials"] or hasMaterial
|
||||
|
||||
|
||||
# vertices
|
||||
|
||||
|
||||
if isQuad:
|
||||
|
||||
a = faces[ offset ]
|
||||
offset += 1
|
||||
|
||||
|
||||
b = faces[ offset ]
|
||||
offset += 1
|
||||
|
||||
|
||||
c = faces[ offset ]
|
||||
offset += 1
|
||||
|
||||
|
||||
d = faces[ offset ]
|
||||
offset += 1
|
||||
|
||||
|
||||
face = [a, b, c, d]
|
||||
|
||||
nVertices = 4
|
||||
@@ -376,26 +376,26 @@ def extract_faces(data):
|
||||
|
||||
a = faces[ offset ]
|
||||
offset += 1
|
||||
|
||||
|
||||
b = faces[ offset ]
|
||||
offset += 1
|
||||
|
||||
|
||||
c = faces[ offset ]
|
||||
offset += 1
|
||||
|
||||
face = [a, b, c]
|
||||
|
||||
|
||||
nVertices = 3
|
||||
|
||||
result["faces"].append(face)
|
||||
|
||||
# material
|
||||
|
||||
|
||||
if hasMaterial:
|
||||
|
||||
materialIndex = faces[ offset ]
|
||||
offset += 1
|
||||
|
||||
|
||||
else:
|
||||
|
||||
materialIndex = -1
|
||||
@@ -407,9 +407,9 @@ def extract_faces(data):
|
||||
for i in range(nUvLayers):
|
||||
|
||||
faceUv = None
|
||||
|
||||
|
||||
if hasFaceUv:
|
||||
|
||||
|
||||
uvLayer = data["uvs"][ i ]
|
||||
|
||||
uvIndex = faces[ offset ]
|
||||
@@ -419,7 +419,7 @@ def extract_faces(data):
|
||||
v = uvLayer[ uvIndex * 2 + 1 ]
|
||||
|
||||
faceUv = [u, v]
|
||||
|
||||
|
||||
result["faceUVs"][i].append(faceUv)
|
||||
|
||||
|
||||
@@ -452,18 +452,18 @@ def extract_faces(data):
|
||||
z = normals[ normalIndex + 2 ]
|
||||
|
||||
faceNormal = [x, y, z]
|
||||
|
||||
|
||||
else:
|
||||
|
||||
faceNormal = None
|
||||
|
||||
|
||||
result["faceNormals"].append(faceNormal)
|
||||
|
||||
|
||||
if hasFaceVertexNormal:
|
||||
|
||||
vertexNormals = []
|
||||
|
||||
|
||||
for j in range(nVertices):
|
||||
|
||||
normalIndex = faces[ offset ] * 3
|
||||
@@ -472,14 +472,14 @@ def extract_faces(data):
|
||||
x = normals[ normalIndex ]
|
||||
y = normals[ normalIndex + 1 ]
|
||||
z = normals[ normalIndex + 2 ]
|
||||
|
||||
|
||||
vertexNormals.append( [x, y, z] )
|
||||
|
||||
|
||||
else:
|
||||
|
||||
vertexNormals = None
|
||||
|
||||
|
||||
result["vertexNormals"].append(vertexNormals)
|
||||
|
||||
|
||||
@@ -487,11 +487,11 @@ def extract_faces(data):
|
||||
|
||||
colorIndex = faces[ offset ]
|
||||
offset += 1
|
||||
|
||||
|
||||
faceColor = hexToTuple( colors[ colorIndex ] )
|
||||
|
||||
else:
|
||||
|
||||
|
||||
faceColor = None
|
||||
|
||||
result["faceColors"].append(faceColor)
|
||||
@@ -510,14 +510,14 @@ def extract_faces(data):
|
||||
vertexColors.append( color )
|
||||
|
||||
else:
|
||||
|
||||
|
||||
vertexColors = None
|
||||
|
||||
|
||||
result["vertexColors"].append(vertexColors)
|
||||
|
||||
|
||||
return result
|
||||
|
||||
|
||||
# #####################################################
|
||||
# Utils
|
||||
# #####################################################
|
||||
@@ -527,10 +527,10 @@ def hexToTuple( hexColor ):
|
||||
g = (( hexColor >> 8 ) & 0xff) / 255.0
|
||||
b = ( hexColor & 0xff) / 255.0
|
||||
return (r, g, b)
|
||||
|
||||
|
||||
def isBitSet(value, position):
|
||||
return value & ( 1 << position )
|
||||
|
||||
|
||||
def splitArray(data, chunkSize):
|
||||
result = []
|
||||
chunk = []
|
||||
@@ -546,7 +546,7 @@ def splitArray(data, chunkSize):
|
||||
def extract_json_string(text):
|
||||
marker_begin = "var model ="
|
||||
marker_end = "postMessage"
|
||||
|
||||
|
||||
start = text.find(marker_begin) + len(marker_begin)
|
||||
end = text.find(marker_end)
|
||||
end = text.rfind("}", start, end)
|
||||
@@ -563,13 +563,13 @@ def get_path(filepath):
|
||||
# #####################################################
|
||||
|
||||
def load(operator, context, filepath, option_flip_yz = True, recalculate_normals = True):
|
||||
|
||||
|
||||
print('\nimporting %r' % filepath)
|
||||
|
||||
time_main = time.time()
|
||||
|
||||
print("\tparsing JSON file...")
|
||||
|
||||
|
||||
time_sub = time.time()
|
||||
|
||||
file = open(filepath, 'rU')
|
||||
@@ -578,24 +578,24 @@ def load(operator, context, filepath, option_flip_yz = True, recalculate_normals
|
||||
|
||||
json_string = extract_json_string(rawcontent)
|
||||
data = json.loads( json_string )
|
||||
|
||||
|
||||
time_new = time.time()
|
||||
|
||||
print('parsing %.4f sec' % (time_new - time_sub))
|
||||
|
||||
|
||||
time_sub = time_new
|
||||
|
||||
# flip YZ
|
||||
|
||||
|
||||
vertices = splitArray(data["vertices"], 3)
|
||||
|
||||
|
||||
if option_flip_yz:
|
||||
vertices[:] = [(v[0], -v[2], v[1]) for v in vertices]
|
||||
vertices[:] = [(v[0], -v[2], v[1]) for v in vertices]
|
||||
|
||||
# extract faces
|
||||
|
||||
|
||||
face_data = extract_faces(data)
|
||||
|
||||
|
||||
# deselect all
|
||||
|
||||
bpy.ops.object.select_all(action='DESELECT')
|
||||
@@ -606,19 +606,19 @@ def load(operator, context, filepath, option_flip_yz = True, recalculate_normals
|
||||
ncolors = len(data.get("colors", [])) / 3
|
||||
nuvs = len(data.get("uvs", [])) / 2
|
||||
nmaterials = len(data.get("materials", []))
|
||||
|
||||
print('\tbuilding geometry...\n\tfaces:%i, vertices:%i, vertex normals: %i, vertex uvs: %i, vertex colors: %i, materials: %i ...' % (
|
||||
|
||||
print('\tbuilding geometry...\n\tfaces:%i, vertices:%i, vertex normals: %i, vertex uvs: %i, vertex colors: %i, materials: %i ...' % (
|
||||
nfaces, nvertices, nnormals, nuvs, ncolors, nmaterials ))
|
||||
|
||||
# Create materials
|
||||
|
||||
|
||||
materials = create_materials(data, get_path(filepath))
|
||||
|
||||
|
||||
# Create new obj
|
||||
|
||||
|
||||
create_mesh_object(get_name(filepath), vertices, materials, face_data, option_flip_yz, recalculate_normals)
|
||||
|
||||
scene = bpy.context.scene
|
||||
scene = bpy.context.scene
|
||||
scene.update()
|
||||
|
||||
time_new = time.time()
|
||||
|
||||
Reference in New Issue
Block a user