forked from bartvdbraak/blender
initial x3d/vrml importer port from 2.4x.
some files import now. - no animation support yet - no rad/deg conversion changes from 2.4x - matrix multiplication still needs switching.
This commit is contained in:
parent
35e68e9785
commit
22577d98c9
27
release/scripts/modules/image_utils.py
Normal file
27
release/scripts/modules/image_utils.py
Normal file
@ -0,0 +1,27 @@
|
||||
# ##### BEGIN GPL LICENSE BLOCK #####
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or
|
||||
# modify it under the terms of the GNU General Public License
|
||||
# as published by the Free Software Foundation; either version 2
|
||||
# of the License, or (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
#
|
||||
# ##### END GPL LICENSE BLOCK #####
|
||||
|
||||
# <pep8 compliant>
|
||||
|
||||
def image_load(filepath, dirpath, place_holder=False, recursive=False, convert_callback=None):
|
||||
import bpy
|
||||
try:
|
||||
return bpy.data.images.load(filepath)
|
||||
except SystemError:
|
||||
return bpy.data.images.new("Untitled", 128, 128)
|
||||
|
@ -21,10 +21,7 @@
|
||||
DEBUG = False
|
||||
|
||||
# This should work without a blender at all
|
||||
try:
|
||||
from Blender.sys import exists
|
||||
except:
|
||||
from os.path import exists
|
||||
from os.path import exists
|
||||
|
||||
|
||||
def baseName(path):
|
||||
@ -946,13 +943,13 @@ class vrmlNode(object):
|
||||
print(url)
|
||||
urls = []
|
||||
urls.append(url)
|
||||
urls.append(BPySys.caseInsensitivePath(urls[-1]))
|
||||
urls.append(bpy.path.resolve_ncase(urls[-1]))
|
||||
|
||||
urls.append(dirName(self.getFilename()) + url)
|
||||
urls.append(BPySys.caseInsensitivePath(urls[-1]))
|
||||
urls.append(bpy.path.resolve_ncase(urls[-1]))
|
||||
|
||||
urls.append(dirName(self.getFilename()) + baseName(url))
|
||||
urls.append(BPySys.caseInsensitivePath(urls[-1]))
|
||||
urls.append(bpy.path.resolve_ncase(urls[-1]))
|
||||
|
||||
try:
|
||||
url = [url for url in urls if exists(url)][0]
|
||||
@ -1192,7 +1189,7 @@ class vrmlNode(object):
|
||||
field_list = []
|
||||
field_context = []
|
||||
|
||||
for j in xrange(len(value)):
|
||||
for j in range(len(value)):
|
||||
if iskey(value[j]):
|
||||
if field_context:
|
||||
# this IS a key but the previous value was not a key, ot it was a defined field.
|
||||
@ -1421,16 +1418,14 @@ for i, f in enumerate(files):
|
||||
# NO BLENDER CODE ABOVE THIS LINE.
|
||||
# -----------------------------------------------------------------------------------
|
||||
import bpy
|
||||
import BPyImage
|
||||
import BPySys
|
||||
reload(BPySys)
|
||||
reload(BPyImage)
|
||||
import Blender
|
||||
from Blender import Texture, Material, Mathutils, Mesh, Types, Window
|
||||
from Blender.Mathutils import TranslationMatrix
|
||||
from Blender.Mathutils import RotationMatrix
|
||||
from Blender.Mathutils import Vector
|
||||
from Blender.Mathutils import Matrix
|
||||
import image_utils
|
||||
# import BPyImage
|
||||
# import BPySys
|
||||
# reload(BPySys)
|
||||
# reload(BPyImage)
|
||||
# import Blender
|
||||
# from Blender import Texture, Material, Mathutils, Mesh, Types, Window
|
||||
from mathutils import Vector, Matrix
|
||||
|
||||
RAD_TO_DEG = 57.29578
|
||||
|
||||
@ -1439,7 +1434,7 @@ GLOBALS = {'CIRCLE_DETAIL': 16}
|
||||
|
||||
def translateRotation(rot):
|
||||
''' axis, angle '''
|
||||
return RotationMatrix(rot[3] * RAD_TO_DEG, 4, 'r', Vector(rot[:3]))
|
||||
return Matrix.Rotation(rot[3] * RAD_TO_DEG, 4, Vector(rot[:3]))
|
||||
|
||||
|
||||
def translateScale(sca):
|
||||
@ -1458,7 +1453,7 @@ def translateTransform(node, ancestry):
|
||||
tx = node.getFieldAsFloatTuple('translation', None, ancestry) # (0.0, 0.0, 0.0)
|
||||
|
||||
if cent:
|
||||
cent_mat = TranslationMatrix(Vector(cent)).resize4x4()
|
||||
cent_mat = Matrix.Translation(Vector(cent)).resize4x4()
|
||||
cent_imat = cent_mat.copy().invert()
|
||||
else:
|
||||
cent_mat = cent_imat = None
|
||||
@ -1480,7 +1475,7 @@ def translateTransform(node, ancestry):
|
||||
scaori_mat = scaori_imat = None
|
||||
|
||||
if tx:
|
||||
tx_mat = TranslationMatrix(Vector(tx)).resize4x4()
|
||||
tx_mat = Matrix.Translation(Vector(tx)).resize4x4()
|
||||
else:
|
||||
tx_mat = None
|
||||
|
||||
@ -1502,13 +1497,13 @@ def translateTexTransform(node, ancestry):
|
||||
|
||||
if cent:
|
||||
# cent is at a corner by default
|
||||
cent_mat = TranslationMatrix(Vector(cent).resize3D()).resize4x4()
|
||||
cent_mat = Matrix.Translation(Vector(cent).resize3D()).resize4x4()
|
||||
cent_imat = cent_mat.copy().invert()
|
||||
else:
|
||||
cent_mat = cent_imat = None
|
||||
|
||||
if rot:
|
||||
rot_mat = RotationMatrix(rot * RAD_TO_DEG, 4, 'z') # translateRotation(rot)
|
||||
rot_mat = Matrix.Rotation(rot * RAD_TO_DEG, 4, 'Z') # translateRotation(rot)
|
||||
else:
|
||||
rot_mat = None
|
||||
|
||||
@ -1518,7 +1513,7 @@ def translateTexTransform(node, ancestry):
|
||||
sca_mat = None
|
||||
|
||||
if tx:
|
||||
tx_mat = TranslationMatrix(Vector(tx).resize3D()).resize4x4()
|
||||
tx_mat = Matrix.Translation(Vector(tx).resize3D()).resize4x4()
|
||||
else:
|
||||
tx_mat = None
|
||||
|
||||
@ -1598,11 +1593,11 @@ def importMesh_IndexedFaceSet(geom, bpyima, ancestry):
|
||||
if vcolor:
|
||||
# float to char
|
||||
ifs_vcol = [(0, 0, 0)] # EEKADOODLE - vertex start at 1
|
||||
ifs_vcol.extend([[int(c * 256) for c in col] for col in vcolor.getFieldAsArray('color', 3, ancestry)])
|
||||
ifs_vcol.extend([col for col in vcolor.getFieldAsArray('color', 3, ancestry)])
|
||||
ifs_color_index = geom.getFieldAsArray('colorIndex', 0, ancestry)
|
||||
|
||||
if not ifs_vcol:
|
||||
vcolor_spot = [int(c * 256) for c in vcolor.getFieldAsFloatTuple('color', [], ancestry)]
|
||||
vcolor_spot = vcolor.getFieldAsFloatTuple('color', [], ancestry)
|
||||
|
||||
# Convert faces into somthing blender can use
|
||||
edges = []
|
||||
@ -1631,7 +1626,7 @@ def importMesh_IndexedFaceSet(geom, bpyima, ancestry):
|
||||
elif l == 2:
|
||||
edges.append(face)
|
||||
elif l > 4:
|
||||
for i in xrange(2, len(face)):
|
||||
for i in range(2, len(face)):
|
||||
faces.append([face[0], face[i - 1], face[i]])
|
||||
if do_uvmap:
|
||||
faces_uv.append([fuvs[0], fuvs[i - 1], fuvs[i]])
|
||||
@ -1668,21 +1663,24 @@ def importMesh_IndexedFaceSet(geom, bpyima, ancestry):
|
||||
add_face(face, fuvs, orig_index)
|
||||
del add_face # dont need this func anymore
|
||||
|
||||
bpymesh = bpy.data.meshes.new()
|
||||
bpymesh = bpy.data.meshes.new(name="XXX")
|
||||
|
||||
bpymesh.verts.extend([(0, 0, 0)]) # EEKADOODLE
|
||||
bpymesh.verts.extend(ifs_points)
|
||||
# EEKADOODLE
|
||||
bpymesh.vertices.add(1 + (len(ifs_points)))
|
||||
bpymesh.vertices.foreach_set("co", [0, 0, 0] + [a for v in ifs_points for a in v]) # XXX25 speed
|
||||
|
||||
# print(len(ifs_points), faces, edges, ngons)
|
||||
|
||||
try:
|
||||
bpymesh.faces.extend(faces, smooth=True, ignoreDups=True)
|
||||
bpymesh.faces.add(len(faces))
|
||||
bpymesh.faces.foreach_set("vertices_raw", [a for f in faces for a in (f + [0] if len(f) == 3 else f)]) # XXX25 speed
|
||||
except KeyError:
|
||||
print("one or more vert indicies out of range. corrupt file?")
|
||||
#for f in faces:
|
||||
# bpymesh.faces.extend(faces, smooth=True)
|
||||
|
||||
bpymesh.calcNormals()
|
||||
# bpymesh.calcNormals()
|
||||
bpymesh.update()
|
||||
|
||||
if len(bpymesh.faces) != len(faces):
|
||||
print('\tWarning: adding faces did not work! file is invalid, not adding UVs or vcolors')
|
||||
@ -1694,17 +1692,18 @@ def importMesh_IndexedFaceSet(geom, bpyima, ancestry):
|
||||
if coords_tex:
|
||||
#print(ifs_texpoints)
|
||||
# print(geom)
|
||||
bpymesh.faceUV = True
|
||||
for i, f in enumerate(bpymesh.faces):
|
||||
uvlay = bpymesh.uv_textures.new()
|
||||
|
||||
for i, f in enumerate(uvlay.data):
|
||||
f.image = bpyima
|
||||
fuv = faces_uv[i] # uv indicies
|
||||
for j, uv in enumerate(f.uv):
|
||||
# print(fuv, j, len(ifs_texpoints))
|
||||
try:
|
||||
uv[:] = ifs_texpoints[fuv[j]]
|
||||
f.uv[j] = ifs_texpoints[fuv[j]] # XXX25, speedup
|
||||
except:
|
||||
print('\tWarning: UV Index out of range')
|
||||
uv[:] = ifs_texpoints[0]
|
||||
f.uv[j] = ifs_texpoints[0] # XXX25, speedup
|
||||
|
||||
elif bpyima and len(bpymesh.faces):
|
||||
# Oh Bugger! - we cant really use blenders ORCO for for texture space since texspace dosnt rotate.
|
||||
@ -1768,30 +1767,37 @@ def importMesh_IndexedFaceSet(geom, bpyima, ancestry):
|
||||
# This should be safe because when 2 axies have the same length, the lower index will be used.
|
||||
axis_v += 1
|
||||
|
||||
bpymesh.faceUV = True
|
||||
uvlay = bpymesh.uv_textures.new()
|
||||
|
||||
# HACK !!! - seems to be compatible with Cosmo though.
|
||||
depth_v = depth_u = max(depth_v, depth_u)
|
||||
|
||||
for f in bpymesh.faces:
|
||||
bpymesh_vertices = bpymesh.vertices[:]
|
||||
bpymesh_faces = bpymesh.faces[:]
|
||||
|
||||
for j, f in enumerate(uvlay.data):
|
||||
f.image = bpyima
|
||||
fuv = f.uv
|
||||
f_v = bpymesh_faces[j].vertices[:] # XXX25 speed
|
||||
|
||||
for i, v in enumerate(f):
|
||||
co = v.co
|
||||
fuv[i][:] = (co[axis_u] - min_u) / depth_u, (co[axis_v] - min_v) / depth_v
|
||||
for i, v in enumerate(f_v):
|
||||
co = bpymesh_vertices[v].co
|
||||
fuv[i] = (co[axis_u] - min_u) / depth_u, (co[axis_v] - min_v) / depth_v
|
||||
|
||||
# Add vcote
|
||||
if vcolor:
|
||||
# print(ifs_vcol)
|
||||
bpymesh.vertexColors = True
|
||||
collay = bpymesh.vertex_colors.new()
|
||||
|
||||
for f in bpymesh.faces:
|
||||
fcol = f.col
|
||||
for j, f in enumerate(collay.data):
|
||||
fv = bpymesh.faces[j].vertices[:]
|
||||
if len(fv) == 3: # XXX speed
|
||||
fcol = f.color1, f.color2, f.color3
|
||||
else:
|
||||
fcol = f.color1, f.color2, f.color3, f.color4
|
||||
if ifs_colorPerVertex:
|
||||
fv = f.verts
|
||||
for i, c in enumerate(fcol):
|
||||
color_index = fv[i].index # color index is vert index
|
||||
color_index = fv[i] # color index is vert index
|
||||
if ifs_color_index:
|
||||
try:
|
||||
color_index = ifs_color_index[color_index]
|
||||
@ -1820,12 +1826,10 @@ def importMesh_IndexedFaceSet(geom, bpyima, ancestry):
|
||||
|
||||
col = ifs_vcol[color_index]
|
||||
for i, c in enumerate(fcol):
|
||||
try:
|
||||
c.r, c.g, c.b = col
|
||||
except:
|
||||
pass # incase its not between 0 and 255
|
||||
|
||||
bpymesh.verts.delete([0, ]) # EEKADOODLE
|
||||
# XXX25
|
||||
# bpymesh.vertices.delete([0, ]) # EEKADOODLE
|
||||
|
||||
return bpymesh, ccw
|
||||
|
||||
@ -1893,19 +1897,38 @@ def importMesh_PointSet(geom, ancestry):
|
||||
# vcolor = geom.getChildByName('color') # blender dosnt have per vertex color
|
||||
|
||||
bpymesh = bpy.data.meshes.new()
|
||||
bpymesh.verts.extend(points)
|
||||
bpymesh.calcNormals() # will just be dummy normals
|
||||
bpymesh.vertices.extend(points)
|
||||
# bpymesh.calcNormals() # will just be dummy normals
|
||||
bpymesh.update()
|
||||
return bpymesh
|
||||
|
||||
GLOBALS['CIRCLE_DETAIL'] = 12
|
||||
|
||||
MATRIX_Z_TO_Y = RotationMatrix(90, 4, 'x')
|
||||
MATRIX_Z_TO_Y = Matrix.Rotation(90, 4, 'X')
|
||||
|
||||
|
||||
def bpy_ops_add_object_hack(): # XXX25, evil
|
||||
scene = bpy.context.scene
|
||||
obj = scene.objects[0]
|
||||
scene.objects.unlink(obj)
|
||||
bpymesh = obj.data
|
||||
bpy.data.objects.remove(obj)
|
||||
return bpymesh
|
||||
|
||||
|
||||
def importMesh_Sphere(geom, ancestry):
|
||||
# bpymesh = bpy.data.meshes.new()
|
||||
diameter = geom.getFieldAsFloat('radius', 0.5, ancestry) * 2 # * 2 for the diameter
|
||||
bpymesh = Mesh.Primitives.UVsphere(GLOBALS['CIRCLE_DETAIL'], GLOBALS['CIRCLE_DETAIL'], diameter)
|
||||
# bpymesh = Mesh.Primitives.UVsphere(GLOBALS['CIRCLE_DETAIL'], GLOBALS['CIRCLE_DETAIL'], diameter)
|
||||
|
||||
bpy.ops.mesh.primitive_uv_sphere_add(segments=GLOBALS['CIRCLE_DETAIL'],
|
||||
ring_count=GLOBALS['CIRCLE_DETAIL'],
|
||||
size=diameter,
|
||||
view_align=False,
|
||||
enter_editmode=False,
|
||||
)
|
||||
|
||||
bpymesh = bpy_ops_add_object_hack()
|
||||
|
||||
bpymesh.transform(MATRIX_Z_TO_Y)
|
||||
return bpymesh
|
||||
|
||||
@ -1914,7 +1937,19 @@ def importMesh_Cylinder(geom, ancestry):
|
||||
# bpymesh = bpy.data.meshes.new()
|
||||
diameter = geom.getFieldAsFloat('radius', 1.0, ancestry) * 2 # * 2 for the diameter
|
||||
height = geom.getFieldAsFloat('height', 2, ancestry)
|
||||
bpymesh = Mesh.Primitives.Cylinder(GLOBALS['CIRCLE_DETAIL'], diameter, height)
|
||||
|
||||
# bpymesh = Mesh.Primitives.Cylinder(GLOBALS['CIRCLE_DETAIL'], diameter, height)
|
||||
|
||||
bpy.ops.mesh.primitive_cylinder_add(vertices=GLOBALS['CIRCLE_DETAIL'],
|
||||
radius=diameter,
|
||||
depth=height,
|
||||
cap_ends=True,
|
||||
view_align=False,
|
||||
enter_editmode=False,
|
||||
)
|
||||
|
||||
bpymesh = bpy_ops_add_object_hack()
|
||||
|
||||
bpymesh.transform(MATRIX_Z_TO_Y)
|
||||
|
||||
# Warning - Rely in the order Blender adds verts
|
||||
@ -1925,14 +1960,19 @@ def importMesh_Cylinder(geom, ancestry):
|
||||
top = geom.getFieldAsBool('top', True, ancestry)
|
||||
|
||||
if not top: # last vert is top center of tri fan.
|
||||
bpymesh.verts.delete([(GLOBALS['CIRCLE_DETAIL'] + GLOBALS['CIRCLE_DETAIL']) + 1])
|
||||
# bpymesh.vertices.delete([(GLOBALS['CIRCLE_DETAIL'] + GLOBALS['CIRCLE_DETAIL']) + 1]) # XXX25
|
||||
pass
|
||||
|
||||
if not bottom: # second last vert is bottom of triangle fan
|
||||
bpymesh.verts.delete([GLOBALS['CIRCLE_DETAIL'] + GLOBALS['CIRCLE_DETAIL']])
|
||||
# XXX25
|
||||
# bpymesh.vertices.delete([GLOBALS['CIRCLE_DETAIL'] + GLOBALS['CIRCLE_DETAIL']])
|
||||
pass
|
||||
|
||||
if not side:
|
||||
# remove all quads
|
||||
bpymesh.faces.delete(1, [f for f in bpymesh.faces if len(f) == 4])
|
||||
# XXX25
|
||||
# bpymesh.faces.delete(1, [f for f in bpymesh.faces if len(f) == 4])
|
||||
pass
|
||||
|
||||
return bpymesh
|
||||
|
||||
@ -1941,7 +1981,19 @@ def importMesh_Cone(geom, ancestry):
|
||||
# bpymesh = bpy.data.meshes.new()
|
||||
diameter = geom.getFieldAsFloat('bottomRadius', 1.0, ancestry) * 2 # * 2 for the diameter
|
||||
height = geom.getFieldAsFloat('height', 2, ancestry)
|
||||
bpymesh = Mesh.Primitives.Cone(GLOBALS['CIRCLE_DETAIL'], diameter, height)
|
||||
|
||||
# bpymesh = Mesh.Primitives.Cone(GLOBALS['CIRCLE_DETAIL'], diameter, height)
|
||||
|
||||
bpy.ops.mesh.primitive_cone_add(vertices=GLOBALS['CIRCLE_DETAIL'],
|
||||
radius=diameter,
|
||||
depth=height,
|
||||
cap_end=True,
|
||||
view_align=False,
|
||||
enter_editmode=False,
|
||||
)
|
||||
|
||||
bpymesh = bpy_ops_add_object_hack()
|
||||
|
||||
bpymesh.transform(MATRIX_Z_TO_Y)
|
||||
|
||||
# Warning - Rely in the order Blender adds verts
|
||||
@ -1951,9 +2003,11 @@ def importMesh_Cone(geom, ancestry):
|
||||
side = geom.getFieldAsBool('side', True, ancestry)
|
||||
|
||||
if not bottom: # last vert is on the bottom
|
||||
bpymesh.verts.delete([GLOBALS['CIRCLE_DETAIL'] + 1])
|
||||
# bpymesh.vertices.delete([GLOBALS['CIRCLE_DETAIL'] + 1]) # XXX25
|
||||
pass
|
||||
if not side: # second last vert is on the pointy bit of the cone
|
||||
bpymesh.verts.delete([GLOBALS['CIRCLE_DETAIL']])
|
||||
# bpymesh.vertices.delete([GLOBALS['CIRCLE_DETAIL']]) # XXX25
|
||||
pass
|
||||
|
||||
return bpymesh
|
||||
|
||||
@ -1962,10 +2016,16 @@ def importMesh_Box(geom, ancestry):
|
||||
# bpymesh = bpy.data.meshes.new()
|
||||
|
||||
size = geom.getFieldAsFloatTuple('size', (2.0, 2.0, 2.0), ancestry)
|
||||
bpymesh = Mesh.Primitives.Cube(1.0)
|
||||
|
||||
# bpymesh = Mesh.Primitives.Cube(1.0)
|
||||
bpy.ops.mesh.primitive_cube_add(view_align=False,
|
||||
enter_editmode=False,
|
||||
)
|
||||
|
||||
bpymesh = bpy_ops_add_object_hack()
|
||||
|
||||
# Scale the box to the size set
|
||||
scale_mat = Matrix([size[0], 0, 0], [0, size[1], 0], [0, 0, size[2]])
|
||||
scale_mat = Matrix(((size[0], 0, 0), (0, size[1], 0), (0, 0, size[2])))
|
||||
bpymesh.transform(scale_mat.resize4x4())
|
||||
|
||||
return bpymesh
|
||||
@ -2016,21 +2076,21 @@ def importShape(node, ancestry):
|
||||
mat = ima # This is a bit dumb, but just means we use default values for all
|
||||
|
||||
# all values between 0.0 and 1.0, defaults from VRML docs
|
||||
bpymat = bpy.data.materials.new()
|
||||
bpymat.amb = mat.getFieldAsFloat('ambientIntensity', 0.2, ancestry)
|
||||
bpymat.rgbCol = mat.getFieldAsFloatTuple('diffuseColor', [0.8, 0.8, 0.8], ancestry)
|
||||
bpymat = bpy.data.materials.new("XXX")
|
||||
bpymat.ambient = mat.getFieldAsFloat('ambientIntensity', 0.2, ancestry)
|
||||
bpymat.diffuse_color = mat.getFieldAsFloatTuple('diffuseColor', [0.8, 0.8, 0.8], ancestry)
|
||||
|
||||
# NOTE - blender dosnt support emmisive color
|
||||
# Store in mirror color and approximate with emit.
|
||||
emit = mat.getFieldAsFloatTuple('emissiveColor', [0.0, 0.0, 0.0], ancestry)
|
||||
bpymat.mirCol = emit
|
||||
bpymat.mirror_color = emit
|
||||
bpymat.emit = (emit[0] + emit[1] + emit[2]) / 3.0
|
||||
|
||||
bpymat.hard = int(1 + (510 * mat.getFieldAsFloat('shininess', 0.2, ancestry))) # 0-1 -> 1-511
|
||||
bpymat.specCol = mat.getFieldAsFloatTuple('specularColor', [0.0, 0.0, 0.0], ancestry)
|
||||
bpymat.specular_hardness = int(1 + (510 * mat.getFieldAsFloat('shininess', 0.2, ancestry))) # 0-1 -> 1-511
|
||||
bpymat.specular_color = mat.getFieldAsFloatTuple('specularColor', [0.0, 0.0, 0.0], ancestry)
|
||||
bpymat.alpha = 1.0 - mat.getFieldAsFloat('transparency', 0.0, ancestry)
|
||||
if bpymat.alpha < 0.999:
|
||||
bpymat.mode |= Material.Modes.ZTRANSP
|
||||
bpymat.use_transparency = True
|
||||
|
||||
if ima:
|
||||
ima_url = ima.getFieldAsString('url', None, ancestry)
|
||||
@ -2044,10 +2104,9 @@ def importShape(node, ancestry):
|
||||
if ima_url == None:
|
||||
print("\twarning, image with no URL, this is odd")
|
||||
else:
|
||||
bpyima = BPyImage.comprehensiveImageLoad(ima_url, dirName(node.getFilename()), PLACE_HOLDER=False, RECURSIVE=False, CONVERT_CALLBACK=imageConvertCompat)
|
||||
bpyima = image_utils.image_load(ima_url, dirName(node.getFilename()), place_holder=False, recursive=False, convert_callback=imageConvertCompat)
|
||||
if bpyima:
|
||||
texture = bpy.data.textures.new()
|
||||
texture.setType('Image')
|
||||
texture = bpy.data.textures.new("XXX", 'IMAGE')
|
||||
texture.image = bpyima
|
||||
|
||||
# Adds textures for materials (rendering)
|
||||
@ -2063,7 +2122,10 @@ def importShape(node, ancestry):
|
||||
bpymat.mode |= Material.Modes.ZTRANSP
|
||||
bpymat.alpha = 0.0
|
||||
else:
|
||||
bpymat.setTexture(0, texture, Texture.TexCo.UV, Texture.MapTo.COL)
|
||||
mtex = bpymat.texture_slots.add()
|
||||
mtex.texture = texture
|
||||
mtex.texture_coords = 'UV'
|
||||
mtex.use_map_diffuse = True
|
||||
|
||||
ima_repS = ima.getFieldAsBool('repeatS', True, ancestry)
|
||||
ima_repT = ima.getFieldAsBool('repeatT', True, ancestry)
|
||||
@ -2072,9 +2134,9 @@ def importShape(node, ancestry):
|
||||
# texture.repeat = max(1, ima_repS * 512), max(1, ima_repT * 512)
|
||||
|
||||
if not ima_repS:
|
||||
bpyima.clampX = True
|
||||
bpyima.use_clamp_x = True
|
||||
if not ima_repT:
|
||||
bpyima.clampY = True
|
||||
bpyima.use_clamp_y = True
|
||||
|
||||
bpydata = None
|
||||
geom_spec = geom.getSpec()
|
||||
@ -2102,26 +2164,27 @@ def importShape(node, ancestry):
|
||||
|
||||
bpydata.name = vrmlname
|
||||
|
||||
bpyob = node.blendObject = bpy.data.scenes.active.objects.new(bpydata)
|
||||
bpyob = node.blendObject = bpy.data.objects.new(vrmlname, bpydata)
|
||||
bpy.context.scene.objects.link(bpyob)
|
||||
|
||||
if type(bpydata) == Types.MeshType:
|
||||
if type(bpydata) == bpy.types.Mesh:
|
||||
is_solid = geom.getFieldAsBool('solid', True, ancestry)
|
||||
creaseAngle = geom.getFieldAsFloat('creaseAngle', None, ancestry)
|
||||
|
||||
if creaseAngle != None:
|
||||
bpydata.maxSmoothAngle = 1 + int(min(79, creaseAngle * RAD_TO_DEG))
|
||||
bpydata.mode |= Mesh.Modes.AUTOSMOOTH
|
||||
bpydata.auto_smooth_angle = 1 + int(min(79, creaseAngle * RAD_TO_DEG))
|
||||
bpydata.use_auto_smooth = True
|
||||
|
||||
# Only ever 1 material per shape
|
||||
if bpymat:
|
||||
bpydata.materials = [bpymat]
|
||||
bpydata.materials.append(bpymat)
|
||||
|
||||
if bpydata.faceUV:
|
||||
if bpydata.uv_textures:
|
||||
|
||||
if depth == 32: # set the faces alpha flag?
|
||||
transp = Mesh.FaceTranspModes.ALPHA
|
||||
for f in bpydata.faces:
|
||||
f.transp = transp
|
||||
for f in bpydata.uv_textures.active.data:
|
||||
f.blend_type = 'ALPHA'
|
||||
|
||||
if texmtx:
|
||||
# Apply texture transform?
|
||||
@ -2136,13 +2199,15 @@ def importShape(node, ancestry):
|
||||
|
||||
# Must be here and not in IndexedFaceSet because it needs an object for the flip func. Messy :/
|
||||
if not ccw:
|
||||
bpydata.flipNormals()
|
||||
# bpydata.flipNormals()
|
||||
# XXX25
|
||||
pass
|
||||
|
||||
# else could be a curve for example
|
||||
|
||||
# Can transform data or object, better the object so we can instance the data
|
||||
#bpymesh.transform(getFinalMatrix(node))
|
||||
bpyob.setMatrix(getFinalMatrix(node, None, ancestry))
|
||||
bpyob.matrix_world = getFinalMatrix(node, None, ancestry)
|
||||
|
||||
|
||||
def importLamp_PointLight(node, ancestry):
|
||||
@ -2158,13 +2223,12 @@ def importLamp_PointLight(node, ancestry):
|
||||
# is_on = node.getFieldAsBool('on', True, ancestry) # TODO
|
||||
radius = node.getFieldAsFloat('radius', 100.0, ancestry)
|
||||
|
||||
bpylamp = bpy.data.lamps.new()
|
||||
bpylamp.setType('Lamp')
|
||||
bpylamp = bpy.data.lamps.new("ToDo", 'POINT')
|
||||
bpylamp.energy = intensity
|
||||
bpylamp.dist = radius
|
||||
bpylamp.col = color
|
||||
bpylamp.distance = radius
|
||||
bpylamp.color = color
|
||||
|
||||
mtx = TranslationMatrix(Vector(location))
|
||||
mtx = Matrix.Translation(Vector(location))
|
||||
|
||||
return bpylamp, mtx
|
||||
|
||||
@ -2180,13 +2244,12 @@ def importLamp_DirectionalLight(node, ancestry):
|
||||
intensity = node.getFieldAsFloat('intensity', 1.0, ancestry) # max is documented to be 1.0 but some files have higher.
|
||||
# is_on = node.getFieldAsBool('on', True, ancestry) # TODO
|
||||
|
||||
bpylamp = bpy.data.lamps.new(vrmlname)
|
||||
bpylamp.setType('Sun')
|
||||
bpylamp = bpy.data.lamps.new(vrmlname, 'SUN')
|
||||
bpylamp.energy = intensity
|
||||
bpylamp.col = color
|
||||
bpylamp.color = color
|
||||
|
||||
# lamps have their direction as -z, yup
|
||||
mtx = Vector(direction).toTrackQuat('-z', 'y').toMatrix().resize4x4()
|
||||
mtx = Vector(direction).to_track_quat('-Z', 'Y').to_matrix().resize4x4()
|
||||
|
||||
return bpylamp, mtx
|
||||
|
||||
@ -2209,24 +2272,23 @@ def importLamp_SpotLight(node, ancestry):
|
||||
# is_on = node.getFieldAsBool('on', True, ancestry) # TODO
|
||||
radius = node.getFieldAsFloat('radius', 100.0, ancestry)
|
||||
|
||||
bpylamp = bpy.data.lamps.new(vrmlname)
|
||||
bpylamp.setType('Spot')
|
||||
bpylamp = bpy.data.lamps.new(vrmlname, 'SPOT')
|
||||
bpylamp.energy = intensity
|
||||
bpylamp.dist = radius
|
||||
bpylamp.col = color
|
||||
bpylamp.spotSize = cutOffAngle
|
||||
bpylamp.distance = radius
|
||||
bpylamp.color = color
|
||||
bpylamp.spot_size = cutOffAngle
|
||||
if beamWidth > cutOffAngle:
|
||||
bpylamp.spotBlend = 0.0
|
||||
bpylamp.spot_blend = 0.0
|
||||
else:
|
||||
if cutOffAngle == 0.0: # this should never happen!
|
||||
bpylamp.spotBlend = 0.5
|
||||
bpylamp.spot_blend = 0.5
|
||||
else:
|
||||
bpylamp.spotBlend = beamWidth / cutOffAngle
|
||||
bpylamp.spot_blend = beamWidth / cutOffAngle
|
||||
|
||||
# Convert
|
||||
|
||||
# lamps have their direction as -z, y==up
|
||||
mtx = Vector(direction).toTrackQuat('-z', 'y').toMatrix().resize4x4() * TranslationMatrix(Vector(location))
|
||||
mtx = Vector(direction).to_track_quat('-Z', 'Y').to_matrix().resize4x4() * Matrix.Translation(Vector(location))
|
||||
|
||||
return bpylamp, mtx
|
||||
|
||||
@ -2242,8 +2304,10 @@ def importLamp(node, spec, ancestry):
|
||||
print("Error, not a lamp")
|
||||
raise ValueError
|
||||
|
||||
bpyob = node.blendObject = bpy.data.scenes.active.objects.new(bpylamp)
|
||||
bpyob.setMatrix(getFinalMatrix(node, mtx, ancestry))
|
||||
bpyob = node.blendObject = bpy.data.objects.new("TODO", bpylamp)
|
||||
bpy.context.scene.objects.link(bpyob)
|
||||
|
||||
bpyob.matrix_world = getFinalMatrix(node, mtx, ancestry)
|
||||
|
||||
|
||||
def importViewpoint(node, ancestry):
|
||||
@ -2261,10 +2325,11 @@ def importViewpoint(node, ancestry):
|
||||
|
||||
bpycam.angle = fieldOfView
|
||||
|
||||
mtx = translateRotation(orientation) * TranslationMatrix(Vector(position))
|
||||
mtx = translateRotation(orientation) * Matrix.Translation(Vector(position))
|
||||
|
||||
bpyob = node.blendObject = bpy.data.scenes.active.objects.new(bpycam)
|
||||
bpyob.setMatrix(getFinalMatrix(node, mtx, ancestry))
|
||||
bpyob = node.blendObject = bpy.data.objects.new("TODO", bpycam)
|
||||
bpy.context.scene.objects.link(bpyob)
|
||||
bpyob.matrix_world = getFinalMatrix(node, mtx, ancestry)
|
||||
|
||||
|
||||
def importTransform(node, ancestry):
|
||||
@ -2272,12 +2337,14 @@ def importTransform(node, ancestry):
|
||||
if not name:
|
||||
name = 'Transform'
|
||||
|
||||
bpyob = node.blendObject = bpy.data.scenes.active.objects.new('Empty', name) # , name)
|
||||
bpyob.setMatrix(getFinalMatrix(node, None, ancestry))
|
||||
bpyob = node.blendObject = bpy.data.objects.new(name, None)
|
||||
bpy.context.scene.objects.link(bpyob)
|
||||
|
||||
bpyob.matrix_world = getFinalMatrix(node, None, ancestry)
|
||||
|
||||
# so they are not too annoying
|
||||
bpyob.emptyShape = Blender.Object.EmptyShapes.AXES
|
||||
bpyob.drawSize = 0.2
|
||||
bpyob.empty_draw_type = 'PLAIN_AXES'
|
||||
bpyob.empty_draw_size = 0.2
|
||||
|
||||
|
||||
#def importTimeSensor(node):
|
||||
@ -2327,7 +2394,7 @@ def translateOrientationInterpolator(node, ipo, ancestry):
|
||||
continue
|
||||
|
||||
mtx = translateRotation((x, y, z, w))
|
||||
eul = mtx.toEuler()
|
||||
eul = mtx.to_euler()
|
||||
rot_x.append((time, eul.x / 10.0))
|
||||
rot_y.append((time, eul.y / 10.0))
|
||||
rot_z.append((time, eul.z / 10.0))
|
||||
@ -2463,10 +2530,7 @@ def load_web3d(path, PREF_FLAT=False, PREF_CIRCLE_DIV=16, HELPER_FUNC=None):
|
||||
root_node, msg = vrml_parse(path)
|
||||
|
||||
if not root_node:
|
||||
if Blender.mode == 'background':
|
||||
print(msg)
|
||||
else:
|
||||
Blender.Draw.PupMenu(msg)
|
||||
return
|
||||
|
||||
# fill with tuples - (node, [parents-parent, parent])
|
||||
@ -2515,12 +2579,12 @@ def load_web3d(path, PREF_FLAT=False, PREF_CIRCLE_DIV=16, HELPER_FUNC=None):
|
||||
routeIpoDict = node.getRouteIpoDict()
|
||||
defDict = node.getDefDict()
|
||||
|
||||
for key, ipo in routeIpoDict.iteritems():
|
||||
for key, ipo in routeIpoDict.items():
|
||||
|
||||
# Assign anim curves
|
||||
node = defDict[key]
|
||||
if node.blendObject == None: # Add an object if we need one for animation
|
||||
node.blendObject = bpy.data.scenes.active.objects.new('Empty', 'AnimOb') # , name)
|
||||
node.blendObject = bpy.context.scene.objects.new('Empty', 'AnimOb') # , name)
|
||||
|
||||
node.blendObject.setIpo(ipo)
|
||||
|
||||
@ -2549,12 +2613,13 @@ def load_web3d(path, PREF_FLAT=False, PREF_CIRCLE_DIV=16, HELPER_FUNC=None):
|
||||
except:
|
||||
child_dict[blendObject] = [node.blendObject]
|
||||
|
||||
# Parent FAST
|
||||
for parent, children in child_dict.iteritems():
|
||||
parent.makeParent(children, 0, 1)
|
||||
# Parent
|
||||
for parent, children in child_dict.items():
|
||||
for c in children:
|
||||
c.parent = parent
|
||||
|
||||
# update deps
|
||||
bpy.data.scenes.active.update(1)
|
||||
bpy.context.scene.update()
|
||||
del child_dict
|
||||
|
||||
|
||||
@ -2643,7 +2708,7 @@ def test():
|
||||
f = f.strip()
|
||||
print(f, i, tot)
|
||||
sce = bpy.data.scenes.new(str(i) + '_' + f.split('/')[-1])
|
||||
bpy.data.scenes.active = sce
|
||||
bpy.context.scene = sce # XXX25
|
||||
# Window.
|
||||
load_web3d(f, PREF_FLAT=True)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user