[Bf-extensions-cvs] [9733e52] temp-x3d_import-T44758: Merge branch 'master' into temp-x3d_import-T44758

Bastien Montagne noreply at git.blender.org
Sat Sep 19 16:14:06 CEST 2015


Commit: 9733e526cf6c325e8b0e687825817841b50a9246
Author: Bastien Montagne
Date:   Sat Sep 19 16:12:32 2015 +0200
Branches: temp-x3d_import-T44758
https://developer.blender.org/rBA9733e526cf6c325e8b0e687825817841b50a9246

Merge branch 'master' into temp-x3d_import-T44758

Note that conflict was rather large here, I think merge is OK (few quick tests
seems to show instanciation is still working), but...

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



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

diff --cc io_scene_x3d/import_x3d.py
index 217036b,aec4f89..31125e1
--- a/io_scene_x3d/import_x3d.py
+++ b/io_scene_x3d/import_x3d.py
@@@ -345,8 -381,8 +389,9 @@@ class vrmlNode(object)
          self.node_type = node_type
          self.parent = parent
          self.blendObject = None
+         self.blendData = None
          self.x3dNode = None  # for x3d import only
 +        self.parsed = None  # We try to reuse objects in a smart way
          if parent:
              parent.children.append(self)
  
@@@ -2549,526 -1939,312 +2558,535 @@@ def importMesh_Cylinder(geom, ancestry
      return bpymesh
  
  
 -def importMesh_Cylinder(geom, ancestry):
 -    # bpymesh = bpy.data.meshes.new()
 -    diameter = geom.getFieldAsFloat('radius', 1.0, ancestry)
 +def importMesh_Cone(geom, ancestry, bpyima):
 +    # Solid ignored
 +    # Extra parameter subdivision="n" - how many faces to use
 +    n = geom.getFieldAsInt('subdivision', GLOBALS['CIRCLE_DETAIL'], ancestry)
 +    radius = geom.getFieldAsFloat('bottomRadius', 1.0, ancestry)
      height = geom.getFieldAsFloat('height', 2, ancestry)
 +    bottom = geom.getFieldAsBool('bottom', True, ancestry)
 +    side = geom.getFieldAsBool('side', True, ancestry)
  
 -    # bpymesh = Mesh.Primitives.Cylinder(GLOBALS['CIRCLE_DETAIL'], diameter, height)
 +    d = height / 2
 +    angle = 2 * pi / n
  
 -    bpy.ops.mesh.primitive_cylinder_add(vertices=GLOBALS['CIRCLE_DETAIL'],
 -                                        radius=diameter,
 -                                        depth=height,
 -                                        end_fill_type='NGON',
 -                                        view_align=False,
 -                                        enter_editmode=False,
 -                                        )
 +    verts = [(0, d, 0)]
 +    verts += [(-radius * sin(angle * i),
 +               -d,
 +               -radius * cos(angle * i)) for i in range(n)]
 +    faces = []
  
 -    bpymesh = bpy_ops_add_object_hack()
 +    # Side face vertices go: up down right
 +    if side:
 +        faces += [(1 + (i + 1) % n, 0, 1 + i) for i in range(n)]
 +    if bottom:
 +        faces += [[i for i in range(n, 0, -1)]]
 +
 +    bpymesh = bpy.data.meshes.new(name="Cone")
 +    bpymesh.from_pydata(verts, [], faces)
 +
 +    bpymesh.validate(False)
 +    if bpyima:
 +        loops = []
 +        if side:
 +            loops += [co for i in range(n)
 +                      for co in ((i + 1) / n, 0, (i + 0.5) / n, 1, i / n, 0)]
 +        if bottom:
 +            loops += [0.5 - co / 2 for i in range(n - 1, -1, -1)
 +                      for co in (sin(angle * i), cos(angle * i))]
 +        importMesh_ApplyTextureToLoops(bpymesh, bpyima, loops)
  
 -    bpymesh.transform(MATRIX_Z_TO_Y)
 +    bpymesh.update()
 +    return bpymesh
  
 -    # Warning - Rely in the order Blender adds verts
 -    # not nice design but wont change soon.
  
 -    bottom = geom.getFieldAsBool('bottom', True, ancestry)
 -    side = geom.getFieldAsBool('side', True, ancestry)
 -    top = geom.getFieldAsBool('top', True, ancestry)
 +def importMesh_Box(geom, ancestry, bpyima):
 +    # Solid is ignored
 +    # No ccw in this element
 +    (dx, dy, dz) = geom.getFieldAsFloatTuple('size', (2.0, 2.0, 2.0), ancestry)
 +    dx /= 2
 +    dy /= 2
 +    dz /= 2
 +
 +    bpymesh = bpy.data.meshes.new(name="Box")
 +    bpymesh.vertices.add(8)
 +
 +    # xz plane at +y, ccw
 +    co = (dx, dy, dz, -dx, dy, dz, -dx, dy, -dz, dx, dy, -dz,
 +          # xz plane at -y
 +          dx, -dy, dz, -dx, -dy, dz, -dx, -dy, -dz, dx, -dy, -dz)
 +    bpymesh.vertices.foreach_set('co', co)
 +
 +    bpymesh.tessfaces.add(6)
 +    bpymesh.tessfaces.foreach_set('vertices_raw', (
 +        0, 1, 2, 3,   # +y
 +        4, 0, 3, 7,   # +x
 +        7, 3, 2, 6,   # -z
 +        6, 2, 1, 5,   # -x
 +        5, 1, 0, 4,   # +z
 +        7, 6, 5, 4))  # -y
 +
 +    bpymesh.validate(False)
 +    if bpyima:
 +        d = bpymesh.tessface_uv_textures.new().data
 +        for face in d:  # No foreach_set for nonscalars
 +            face.image = bpyima
 +        d.foreach_set('uv_raw', (
 +            1, 0, 0, 0, 0, 1, 1, 1,
 +            0, 0, 0, 1, 1, 1, 1, 0,
 +            0, 0, 0, 1, 1, 1, 1, 0,
 +            0, 0, 0, 1, 1, 1, 1, 0,
 +            0, 0, 0, 1, 1, 1, 1, 0,
 +            1, 0, 0, 0, 0, 1, 1, 1))
  
 -    if not top:  # last vert is top center of tri fan.
 -        # bpymesh.vertices.delete([(GLOBALS['CIRCLE_DETAIL'] + GLOBALS['CIRCLE_DETAIL']) + 1])  # XXX25
 -        pass
 +    bpymesh.update()
 +    return bpymesh
  
 -    if not bottom:  # second last vert is bottom of triangle fan
 -        # XXX25
 -        # bpymesh.vertices.delete([GLOBALS['CIRCLE_DETAIL'] + GLOBALS['CIRCLE_DETAIL']])
 -        pass
 +# -----------------------------------------------------------------------------------
 +# Utilities for importShape
 +
 +
 +# Textures are processed elsewhere.
 +def appearance_CreateMaterial(vrmlname, mat, ancestry, is_vcol):
 +    # Given an X3D material, creates a Blender material.
 +    # texture is applied later, in appearance_Create().
 +    # All values between 0.0 and 1.0, defaults from VRML docs.
 +    bpymat = bpy.data.materials.new(vrmlname)
 +    bpymat.ambient = mat.getFieldAsFloat('ambientIntensity', 0.2, ancestry)
 +    diff_color = mat.getFieldAsFloatTuple('diffuseColor',
 +                                          [0.8, 0.8, 0.8],
 +                                          ancestry)
 +    bpymat.diffuse_color = diff_color
 +
 +    # 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.mirror_color = emit
 +    bpymat.emit = (emit[0] + emit[1] + emit[2]) / 3.0
 +
 +    shininess = mat.getFieldAsFloat('shininess', 0.2, ancestry)
 +    bpymat.specular_hardness = int(1 + (510 * shininess))
 +    # 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.use_transparency = True
 +    if is_vcol:
 +        bpymat.use_vertex_color_paint = True
 +    return bpymat
 +
 +
 +def appearance_CreateDefaultMaterial():
 +    # Just applies the X3D defaults. Used for shapes
 +    # without explicit material definition
 +    # (but possibly with a texture).
 +
 +    bpymat = bpy.data.materials.new("Material")
 +    bpymat.ambient = 0.2
 +    bpymat.diffuse_color = [0.8, 0.8, 0.8]
 +    bpymat.mirror_color = (0, 0, 0)
 +    bpymat.emit = 0
 +
 +    bpymat.specular_hardness = 103
 +    # 0-1 -> 1-511
 +    bpymat.specular_color = (0, 0, 0)
 +    bpymat.alpha = 1
 +    return bpymat
 +
 +
 +def appearance_LoadImageTextureFile(ima_urls, node):
 +    bpyima = None
 +    for f in ima_urls:
 +        dirname = os.path.dirname(node.getFilename())
 +        bpyima = image_utils.load_image(f, dirname,
 +                                        place_holder=False,
 +                                        recursive=False,
 +                                        convert_callback=imageConvertCompat)
 +        if bpyima:
 +            break
  
 -    if not side:
 -        # remove all quads
 -        # XXX25
 -        # bpymesh.tessfaces.delete(1, [f for f in bpymesh.tessfaces if len(f) == 4])
 -        pass
 +    return bpyima
  
 -    return bpymesh
  
 +def appearance_LoadImageTexture(imageTexture, ancestry, node):
 +    # TODO: cache loaded textures...
 +    ima_urls = imageTexture.getFieldAsString('url', None, ancestry)
  
 -def importMesh_Cone(geom, ancestry):
 -    # bpymesh = bpy.data.meshes.new()
 -    diameter = geom.getFieldAsFloat('bottomRadius', 1.0, ancestry)
 -    height = geom.getFieldAsFloat('height', 2, ancestry)
 +    if ima_urls is None:
 +        try:
 +            ima_urls = imageTexture.getFieldAsStringArray('url', ancestry)
 +            # in some cases we get a list of images.
 +        except:
 +            ima_urls = None
 +    else:
 +        if '" "' in ima_urls:
 +            # '"foo" "bar"' --> ['foo', 'bar']
 +            ima_urls = [w.strip('"') for w in ima_urls.split('" "')]
 +        else:
 +            ima_urls = [ima_urls]
 +    # ima_urls is a list or None
 +
 +    if ima_urls is None:
 +        print("\twarning, image with no URL, this is odd")
 +        return None
 +    else:
 +        bpyima = appearance_LoadImageTextureFile(ima_urls, node)
  
 -    # bpymesh = Mesh.Primitives.Cone(GLOBALS['CIRCLE_DETAIL'], diameter, height)
 +        if not bpyima:
 +            print("ImportX3D warning: unable to load texture", ima_urls)
 +        else:
 +            # KNOWN BUG; PNGs with a transparent color are not perceived
 +            # as transparent. Need alpha channel.
 +
 +            bpyima.use_alpha = bpyima.depth in {32, 128}
 +        return bpyima
 +
 +
 +def appearance_LoadTexture(tex_node, ancestry, node):
 +    # Both USE-based caching and desc-based caching
 +    # Works for bother ImageTextures and PixelTextures
 +
 +    # USE-based caching
 +    if tex_node.reference:
 +        return tex_node.getRealNode().parsed
 +
 +    # Desc-based caching. It might misfire on multifile models, where the
 +    # same desc means different things in different files.
 +    # TODO: move caches to file level.
 +    desc = tex_node.desc()
 +    if desc and desc in texture_cache:
 +        bpyima = texture_cache[desc]
 +        if tex_node.canHaveReferences():
 +            tex_node.parsed = bpyima
 +        return bpyima
 +
 +    # No cached texture, load it.
 +    if tex_node.getSpec() == 'ImageTexture':
 +        bpyima = appearance_LoadImageTexture(tex_node, ancestry, node)
 +    else:  # PixelTexture
 +        bpyima = appearance_LoadPixelTexture(tex_node, ancestry)
 +
 +    if bpyima:  # Loading can still fail
 +        repeat_s = tex_node.getFieldAsBool('repeatS', True, ancestry)
 +        bpyima.use_clamp_x = not repeat_s
 +        repeat_t = tex_node.getFieldAsBool('repeatT', True, ancestry)
 +        bpyima.use_clamp_y = not repeat_t
 +
 +        # Update the desc-b

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list