def load_component(component_id):
    # get file first
    component_name = UTILS_constants.bmfile_componentList[component_id]
    selected_file = os.path.join(os.path.dirname(__file__), 'meshes',
                                 component_name + '.bin')

    # read file. please note this sector is sync with import_bm's mesh's code. when something change, please change each other.
    fmesh = open(selected_file, 'rb')

    # create real mesh, we don't need to consider name. blender will solve duplicated name
    mesh = bpy.data.meshes.new('mesh_' + component_name)

    vList = []
    vnList = []
    faceList = []
    # in first read, store all data into list
    listCount = UTILS_file_io.read_uint32(fmesh)
    for i in range(listCount):
        cache = UTILS_file_io.read_3vector(fmesh)
        # switch yz
        vList.append((cache[0], cache[2], cache[1]))
    listCount = UTILS_file_io.read_uint32(fmesh)
    for i in range(listCount):
        cache = UTILS_file_io.read_3vector(fmesh)
        # switch yz
        vnList.append((cache[0], cache[2], cache[1]))

    listCount = UTILS_file_io.read_uint32(fmesh)
    for i in range(listCount):
        faceData = UTILS_file_io.read_component_face(fmesh)

        # we need invert triangle sort
        faceList.append((faceData[4], faceData[5], faceData[2], faceData[3],
                         faceData[0], faceData[1]))

    # then, we need add correspond count for vertices
    mesh.vertices.add(len(vList))
    mesh.loops.add(len(faceList) * 3)  # triangle face confirmed
    mesh.polygons.add(len(faceList))
    mesh.create_normals_split()

    # add vertices data
    mesh.vertices.foreach_set("co", unpack_list(vList))
    mesh.loops.foreach_set(
        "vertex_index", unpack_list(_flat_component_vertices_index(faceList)))
    mesh.loops.foreach_set(
        "normal",
        unpack_list(_flat_component_vertices_normal(faceList, vnList)))
    for i in range(len(faceList)):
        mesh.polygons[i].loop_start = i * 3
        mesh.polygons[i].loop_total = 3

        mesh.polygons[i].use_smooth = True

    mesh.validate(clean_customdata=False)
    mesh.update(calc_edges=False, calc_edges_loose=False)

    fmesh.close()

    return mesh
Example #2
0
 def invoke(self, context, event):
     me = bpy.data.meshes.new("test")
     obmade = bpy.data.objects.new("TestObject",me)
     print("Create Simple Mesh")
     bpy.data.scenes[0].objects.link(obmade)
     for i in bpy.context.scene.objects: i.select = False #deselect all objects
     obmade.select = True
     bpy.context.scene.objects.active = obmade
     
     verts = [(0,0,0),(2,0,0),(2,0,2)]
     edges = [(0,1),(1,2),(2,0)]
     faces = []
     faces.extend([(0,1,2,0)])
     #me.vertices.add(len(verts))
     #print(dir(me))
     me.vertices.add(len(verts))
     me.tessfaces.add(len(faces))
     for face in me.tessfaces:
         print(dir(face))
     
     me.vertices.foreach_set("co", unpack_list(verts))
     me.tessfaces.foreach_set("vertices_raw", unpack_list(faces))
     me.edges.add(len(edges))
     me.edges.foreach_set("vertices", unpack_list(edges))
     
     #print(len(me.tessfaces))
     me.tessface_uv_textures.new("uvtexture")
     #for uv in me.tessface_uv_textures:
         #print(len(uv.data))
         #print(dir(uv.data[0]))
         #print(dir(uv.data[0].uv1))
     return {'RUNNING_MODAL'}
Example #3
0
    def create_mesh(self, name, options):
        if options.normals_algorithm == NormalsAlgorithm.SHARP_EDGES and self.roottype == RootType.MODEL:
            self.merge_similar_vertices(options.sharp_edge_angle)

        # Create the mesh itself
        mesh = bpy.data.meshes.new(name)
        mesh.vertices.add(len(self.verts))
        mesh.vertices.foreach_set("co", unpack_list(self.verts))
        num_faces = len(self.facelist.vertices)
        mesh.loops.add(3 * num_faces)
        mesh.loops.foreach_set("vertex_index",
                               unpack_list(self.facelist.vertices))
        mesh.polygons.add(num_faces)
        mesh.polygons.foreach_set("loop_start", range(0, 3 * num_faces, 3))
        mesh.polygons.foreach_set("loop_total", (3, ) * num_faces)

        # Create materials
        for wok_mat in defines.WOK_MATERIALS:
            mat_name = wok_mat[0]
            # Walkmesh materials will be shared across multiple walkmesh objects
            if mat_name in bpy.data.materials:
                material = bpy.data.materials[mat_name]
            else:
                material = bpy.data.materials.new(mat_name)
                material.diffuse_color = [*wok_mat[1], 1.0]
                material.specular_color = (0.0, 0.0, 0.0)
                material.specular_intensity = wok_mat[2]
            mesh.materials.append(material)

        # Apply the walkmesh materials to each face
        for idx, polygon in enumerate(mesh.polygons):
            polygon.material_index = self.facelist.materials[idx]

        # Create UV map
        if len(self.uv1) > 0:
            uv = unpack_list(
                [self.uv1[i] for indices in self.facelist.uv for i in indices])
            uv_layer = mesh.uv_layers.new(name=UV_MAP_DIFFUSE, do_init=False)
            uv_layer.data.foreach_set("uv", uv)

        # Create lightmap UV map
        if len(self.uv2) > 0:
            uv = unpack_list(
                [self.uv2[i] for indices in self.facelist.uv for i in indices])
            uv_layer = mesh.uv_layers.new(name=UV_MAP_LIGHTMAP, do_init=False)
            uv_layer.data.foreach_set("uv", uv)

        mesh.update()

        if self.roottype == RootType.MODEL:
            self.post_process_mesh(mesh, options)

        return mesh
Example #4
0
    def instance_group_dupli_vert(self, name, default_material, component_stats):
        def get_orientations(v):
            orientations = defaultdict(list)
            for transform in v:
                loc, rot, scale = Matrix(transform).decompose()
                scale = (scale[0], scale[1], scale[2])
                rot = (rot[0], rot[1], rot[2], rot[3])
                orientations[(scale, rot)].append((loc[0], loc[1], loc[2]))
            for key, locs in orientations.items():
                scale , rot = key
                yield scale , rot, locs

        for scale, rot, locs in get_orientations(component_stats[(name, default_material)]):
            verts = []
            main_loc = Vector(locs[0])
            for c in locs:
                verts.append(Vector(c) - main_loc)
            dme = bpy.data.meshes.new('DUPLI_' + name)
            dme.vertices.add(len(verts))
            dme.vertices.foreach_set("co", unpack_list(verts))
            dme.update(calc_edges=True) # Update mesh with new data
            dme.validate()
            dob = bpy.data.objects.new("DUPLI_" + name, dme)
            dob.location = main_loc
            dob.dupli_type = 'VERTS'

            ob = self.instance_object_or_group(name,default_material)
            ob.scale = scale
            ob.rotation_quaternion = Quaternion((rot[0], rot[1], rot[2], rot[3]))
            ob.parent = dob

            self.context.scene.objects.link(ob)
            self.context.scene.objects.link(dob)
            sketchupLog("Complex group {} {} instanced {} times, scale -> {}".format(name, default_material, len(verts), scale))
        return
Example #5
0
 def addGeometry(cls, mesh, vertices, faces):
     from bpy_extras.io_utils import unpack_list, unpack_face_list
     mesh.vertices.add(len(vertices))
     mesh.vertices.foreach_set("co", unpack_list(vertices))
     mesh.tessfaces.add(len(faces))
     mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
     #mesh.from_pydata(vertices, [], faces)
     """
     mesh.add_geometry(len(vertices), 0, len(faces))
     # add vertex
     unpackedVertices=[]
     for v in vertices:
         unpackedVertices.extend(v)
     mesh.vertices.foreach_set("co", unpackedVertices)
     # add face
     unpackedFaces = []
     for face in faces:
         if len(face) == 4:
             if face[3] == 0:
                 # rotate indices if the 4th is 0
                 face = [face[3], face[0], face[1], face[2]]
         elif len(face) == 3:
             if face[2] == 0:
                 # rotate indices if the 3rd is 0
                 face = [face[2], face[0], face[1], 0]
             else:
                 face.append(0)
         unpackedFaces.extend(face)
     mesh.faces.foreach_set("verts_raw", unpackedFaces)
     """
     assert (len(vertices) == len(mesh.vertices))
def create_canvas_object(context, name, hooks, cleanobject, cams):
    from bpy_extras.io_utils import unpack_list

    # get all locations of the hooks in the list
    coords = get_location(hooks)

    # create the vertices of the cleanplate mesh
    me = bpy.data.meshes.new(name)
    me.vertices.add(len(coords))
    me.vertices.foreach_set("co", unpack_list(coords))

    # create the object which is using the mesh
    ob = bpy.data.objects.new(name, me)
    ob.location = (0, 0, 0)

    # link it to the scene and make it active
    bpy.context.scene.objects.link(ob)
    bpy.context.scene.objects.active = ob
    ob.layers = [True] + [False] * 19

    # go into edit mode, select all vertices and create the face
    if not context.object.mode == "EDIT":
        bpy.ops.object.mode_set(mode="EDIT")
        bpy.ops.mesh.select_all(action='SELECT')
        bpy.ops.mesh.edge_face_add()
    bpy.ops.object.mode_set(mode="OBJECT")

    cleanobject.append(ob)

    bpy.ops.object.select_all(action='DESELECT')
    camera = cams[0]
    ob.select = True
    bpy.context.scene.objects.active = camera
    bpy.ops.object.parent_set()
    camera.select = False
def create_canvas_object(context, name, hooks, cleanobject, cams):
    from bpy_extras.io_utils import unpack_list

    # get all locations of the hooks in the list
    coords=get_location(hooks)

    # create the vertices of the cleanplate mesh
    me = bpy.data.meshes.new(name)
    me.vertices.add(len(coords))
    me.vertices.foreach_set("co", unpack_list(coords))

    # create the object which is using the mesh
    ob = bpy.data.objects.new(name, me)
    ob.location = (0,0,0)

    # link it to the scene and make it active
    bpy.context.scene.objects.link(ob)
    bpy.context.scene.objects.active=ob
    ob.layers = [True] + [False] * 19

    # go into edit mode, select all vertices and create the face
    if not context.object.mode=="EDIT":
        bpy.ops.object.mode_set(mode="EDIT")
        bpy.ops.mesh.select_all(action='SELECT')
        bpy.ops.mesh.edge_face_add()
    bpy.ops.object.mode_set(mode="OBJECT")

    cleanobject.append(ob)

    bpy.ops.object.select_all(action='DESELECT')
    camera = cams[0]
    ob.select = True
    bpy.context.scene.objects.active = camera
    bpy.ops.object.parent_set()
    camera.select = False
Example #8
0
    def instance_group_dupli_vert(self, name, default_material, component_stats):
        def get_orientations(v):
            orientations = defaultdict(list)
            for transform in v:
                loc, rot, scale = Matrix(transform).decompose()
                scale = (scale[0], scale[1], scale[2])
                rot = (rot[0], rot[1], rot[2], rot[3])
                orientations[(scale, rot)].append((loc[0], loc[1], loc[2]))
            for key, locs in orientations.items():
                scale , rot = key
                yield scale , rot, locs

        for scale, rot, locs in get_orientations(component_stats[(name, default_material)]):
            verts = []
            main_loc = Vector(locs[0])
            for c in locs:
                verts.append(Vector(c) - main_loc)
            dme = bpy.data.meshes.new('DUPLI_' + name)
            dme.vertices.add(len(verts))
            dme.vertices.foreach_set("co", unpack_list(verts))
            dme.update(calc_edges=True) # Update mesh with new data
            dme.validate()
            dob = bpy.data.objects.new("DUPLI_" + name, dme)
            dob.location = main_loc
            dob.dupli_type = 'VERTS'

            ob = self.instance_object_or_group(name,default_material)
            ob.scale = scale
            ob.rotation_quaternion = Quaternion((rot[0], rot[1], rot[2], rot[3]))
            ob.parent = dob

            self.context.scene.objects.link(ob)
            self.context.scene.objects.link(dob)
            sketchupLog("Complex group {} {} instanced {} times, scale -> {}".format(name, default_material, len(verts), scale))
        return
Example #9
0
    def execute(self, context):
        from bpy_extras.io_utils import unpack_list

        sc = context.space_data
        clip = sc.clip
        tracking_object = clip.tracking.objects.active

        new_verts = []

        scene = context.scene
        camera = scene.camera
        matrix = Matrix.Identity(4)
        if camera:
            reconstruction = tracking_object.reconstruction
            framenr = scene.frame_current - clip.frame_start + 1
            reconstructed_matrix = reconstruction.cameras.matrix_from_frame(
                framenr)
            matrix = camera.matrix_world * reconstructed_matrix.inverted()

        mesh = bpy.data.meshes.new(name="Tracks")
        for track in tracking_object.tracks:
            if track.has_bundle:
                new_verts.append(track.bundle)

        if new_verts:
            mesh.vertices.add(len(new_verts))
            mesh.vertices.foreach_set("co", unpack_list(new_verts))

        ob = bpy.data.objects.new(name="Tracks", object_data=mesh)

        ob.matrix_world = matrix

        context.scene.objects.link(ob)

        return {'FINISHED'}
Example #10
0
 def addGeometry(cls, mesh, vertices, faces):
     from bpy_extras.io_utils import unpack_list, unpack_face_list
     mesh.vertices.add(len(vertices))
     mesh.vertices.foreach_set("co", unpack_list(vertices))
     mesh.tessfaces.add(len(faces))
     mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
     #mesh.from_pydata(vertices, [], faces)
     """
     mesh.add_geometry(len(vertices), 0, len(faces))
     # add vertex
     unpackedVertices=[]
     for v in vertices:
         unpackedVertices.extend(v)
     mesh.vertices.foreach_set("co", unpackedVertices)
     # add face
     unpackedFaces = []
     for face in faces:
         if len(face) == 4:
             if face[3] == 0:
                 # rotate indices if the 4th is 0
                 face = [face[3], face[0], face[1], face[2]]
         elif len(face) == 3:
             if face[2] == 0:
                 # rotate indices if the 3rd is 0
                 face = [face[2], face[0], face[1], 0]
             else:
                 face.append(0)
         unpackedFaces.extend(face)
     mesh.faces.foreach_set("verts_raw", unpackedFaces)
     """
     assert(len(vertices)==len(mesh.vertices))
Example #11
0
    def execute(self, context):
        from bpy_extras.io_utils import unpack_list

        sc = context.space_data
        clip = sc.clip
        tracking_object = clip.tracking.objects.active

        new_verts = []

        scene = context.scene
        camera = scene.camera
        matrix = Matrix.Identity(4)
        if camera:
            reconstruction = tracking_object.reconstruction
            framenr = scene.frame_current - clip.frame_start + 1
            reconstructed_matrix = reconstruction.cameras.matrix_from_frame(framenr)
            matrix = camera.matrix_world * reconstructed_matrix.inverted()

        mesh = bpy.data.meshes.new(name="Tracks")
        for track in tracking_object.tracks:
            if track.has_bundle:
                new_verts.append(track.bundle)

        if new_verts:
            mesh.vertices.add(len(new_verts))
            mesh.vertices.foreach_set("co", unpack_list(new_verts))

        ob = bpy.data.objects.new(name="Tracks", object_data=mesh)

        ob.matrix_world = matrix

        context.scene.objects.link(ob)

        return {"FINISHED"}
Example #12
0
    def execute(self, context):
        from bpy_extras.io_utils import unpack_list

        sc = context.space_data
        clip = sc.clip
        tracking_object = clip.tracking.objects.active

        new_verts = []

        scene = context.scene
        camera = scene.camera
        matrix = Matrix.Identity(4)
        if camera:
            reconstruction = tracking_object.reconstruction
            framenr = scene.frame_current - clip.frame_start + 1
            reconstructed_matrix = reconstruction.cameras.matrix_from_frame(frame=framenr)
            matrix = camera.matrix_world @ reconstructed_matrix.inverted()

        for track in tracking_object.tracks:
            if track.has_bundle and track.select:
                new_verts.append(track.bundle)

        if new_verts:
            mesh = bpy.data.meshes.new(name="Tracks")
            mesh.vertices.add(len(new_verts))
            mesh.vertices.foreach_set("co", unpack_list(new_verts))
            ob = bpy.data.objects.new(name="Tracks", object_data=mesh)
            ob.matrix_world = matrix
            context.collection.objects.link(ob)
            ob.select_set(True)
            context.view_layer.objects.active = ob
        else:
            self.report({'WARNING'}, "No usable tracks selected")

        return {'FINISHED'}
Example #13
0
def make_mesh(verteces, faces, normals, uvs, global_matrix):
    mesh = bpy.data.meshes.new('name')
    mesh.vertices.add(len(verteces))
    mesh.vertices.foreach_set("co", unpack_list(verteces))
    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))

    index = 0
    for vertex in mesh.vertices:
        vertex.normal = normals[index]
        index += 1

    uvtex = mesh.tessface_uv_textures.new()
    uvtex.name = "UV"

    for face, uv in enumerate(uvs):
        data = uvtex.data[face]
        data.uv1 = uv[0]
        data.uv2 = uv[1]
        data.uv3 = uv[2]
    mesh.update(calc_tessface=False, calc_edges=False)

    obj = bpy.data.objects.new('name', mesh)
    # apply transformation matrix
    obj.matrix_world = global_matrix
    bpy.context.scene.objects.link(obj)  # link object to scene
def make_mesh(verteces, faces, normals, uvs, global_matrix):
    mesh = bpy.data.meshes.new('name')
    mesh.vertices.add(len(verteces))
    mesh.vertices.foreach_set("co", unpack_list(verteces))
    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))

    index = 0
    for vertex in mesh.vertices:
        vertex.normal = normals[index]
        index += 1

    uvtex = mesh.tessface_uv_textures.new()
    uvtex.name = "UV"

    for face, uv in enumerate(uvs):
        data = uvtex.data[face]
        data.uv1 = uv[0]
        data.uv2 = uv[1]
        data.uv3 = uv[2]
    mesh.update(calc_tessface=False, calc_edges=False)

    obj = bpy.data.objects.new('name', mesh)
    # apply transformation matrix
    obj.matrix_world = global_matrix
    bpy.context.scene.objects.link(obj)  # link object to scene
    def instance_group_dupli_face(self, name, default_material,
                                  component_stats):
        def get_orientations(v):
            orientations = defaultdict(list)
            for transform in v:
                loc, rot, scale = Matrix(transform).decompose()
                scale = (scale[0], scale[1], scale[2])
                orientations[scale].append(transform)
            for scale, transforms in orientations.items():
                yield scale, transforms

        for scale, transforms in get_orientations(
                component_stats[(name, default_material)]):
            main_loc, _, real_scale = Matrix(transforms[0]).decompose()
            verts = []
            faces = []
            f_count = 0
            for c in transforms:
                l_loc, l_rot, l_scale = Matrix(c).decompose()
                mat = Matrix.Translation(l_loc) * l_rot.to_matrix().to_4x4()
                verts.append(
                    Vector((mat * Vector((-0.05, -0.05, 0, 1.0)))[0:3]) -
                    main_loc)
                verts.append(
                    Vector((mat * Vector((0.05, -0.05, 0, 1.0)))[0:3]) -
                    main_loc)
                verts.append(
                    Vector((mat * Vector((0.05, 0.05, 0, 1.0)))[0:3]) -
                    main_loc)
                verts.append(
                    Vector((mat * Vector((-0.05, 0.05, 0, 1.0)))[0:3]) -
                    main_loc)
                faces.append(
                    (f_count + 0, f_count + 1, f_count + 2, f_count + 3))
                f_count += 4
            dme = bpy.data.meshes.new('DUPLI_' + name)
            dme.vertices.add(len(verts))
            dme.vertices.foreach_set("co", unpack_list(verts))

            dme.tessfaces.add(f_count / 4)
            dme.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
            dme.update(calc_edges=True)  # Update mesh with new data
            dme.validate()
            dob = bpy.data.objects.new("DUPLI_" + name, dme)
            dob.dupli_type = 'FACES'
            dob.location = main_loc
            #dob.use_dupli_faces_scale = True
            #dob.dupli_faces_scale = 10

            ob = self.instance_object_or_group(name, default_material)
            ob.scale = real_scale
            ob.parent = dob
            self.context.scene.objects.link(ob)
            self.context.scene.objects.link(dob)
            sketchupLog("Complex group {} {} instanced {} times".format(
                name, default_material, f_count / 4))
        return
    def build_blender_data(self, blender_context):
        from mdl_node_volume import MDL_NODE_VOLUME
        import bpy
        from bpy_extras.io_utils import unpack_list, unpack_face_list

        super(MDL_NODE_POLYHEDRON, self).build_blender_data(blender_context)

        print(type(self).__name__ + ".build_blender_data()")

        volume_name = None

        parent_node = self.parent

        # Get parents volume name
        while True:
            # Check if we found a volume node
            if type(parent_node) == MDL_NODE_VOLUME:
                volume_name = parent_node.volume_name
                break
            # Check if we reached the root node without finding a volume node
            elif parent_node == None:
                raise Exception("No parent volume node found")
            # Otherwise get the next parent
            else:
                parent_node = parent_node.parent

        # Create a new mesh with our parents volume name
        self.blender_mesh = bpy.data.meshes.new(volume_name)

        # Load vertices data into the mesh
        self.blender_mesh.vertices.add(len(self.vol.positions))
        self.blender_mesh.vertices.foreach_set("co",
                                               unpack_list(self.vol.positions))

        # Load face data into the mesh
        self.blender_mesh.tessfaces.add(len(self.vol.indeces))
        self.blender_mesh.tessfaces.foreach_set("vertices",
                                                unpack_list(self.vol.indeces))

        # Validate mesh
        self.blender_mesh.validate()

        # Update mesh
        self.blender_mesh.update(calc_edges=True)
Example #17
0
def drawmesh():
    global DEBUGLOG, plik,vertexes,uvcoord,faceslist,num_faces,facemat,facesmooth,m
    global vertexes_ids,bonesdata,meshesdata,groups,num_materials,skala,flipyz,flipuv,mat_faceslist
    global vertices,faces
    print(faces[0])
    print("[CREATING MESH:]")
    me_ob = bpy.data.meshes.new('testmesh')
    #create mesh
    print("-Vertices count:",len(vertices))
    me_ob.vertices.add(len(vertices))
    print("-Faces count:",len(faces))
    me_ob.tessfaces.add(len(faces))
    print("-Creating vertices points...")
    me_ob.vertices.foreach_set("co", unpack_list(vertices))
    print("-Creating faces idx...")
    me_ob.tessfaces.foreach_set("vertices_raw",unpack_list( faces))
    for face in me_ob.tessfaces:
        print(dir(face))
        face.use_smooth = facesmooth[face.index]
        #face.material_index = facemat[face.index]#not yet working
    print("-Creating UV Texture...")
    me_ob.tessface_uv_textures.new('uvtexture')
    #uvtex = me_ob.tessface_uv_textures[0]
    for uv in me_ob.tessface_uv_textures:
        for face in me_ob.tessfaces:
            #uv.data[face.index].uv1.x = 
            
            #print(uv.data[face.index].uv1)
            #uv.data[face.index].uv1 = Vector(uvcoord[faces[face.index]][0],uvcoord[face.index][1])
            print(face.vertices_raw[0],face.vertices_raw[1],face.vertices_raw[2])
            uv.data[face.index].uv1 = mathutils.Vector((uvcoord[face.vertices_raw[0]][0],uvcoord[face.vertices_raw[0]][1]))
            uv.data[face.index].uv2 = mathutils.Vector((uvcoord[face.vertices_raw[1]][0],uvcoord[face.vertices_raw[1]][1]))
            uv.data[face.index].uv3 = mathutils.Vector((uvcoord[face.vertices_raw[2]][0],uvcoord[face.vertices_raw[2]][1]))

    ob = bpy.data.objects.new("TestObject",me_ob)
    #create vertex group
    for bone_id in range(len(bonesdata)):
        bonedata = bonesdata[str(bone_id)]
        namebone = bonedata[0]#.strip()[-25:]
        #print("NAME:",namebone)
        ob.vertex_groups.new(namebone)
    me_ob.update()
    bpy.context.scene.objects.link(ob) 
Example #18
0
def create_mesh(nvx2_vertices, nvx2_faces, nvx2_uvlayers):
    """TODO:Doc."""
    me = bpy.data.meshes.new('nvx2_mesh')
    # Add vertices
    me.vertices.add(len(nvx2_vertices))
    me.vertices.foreach_set('co', unpack_list(nvx2_vertices))
    # Add faces
    me.tessfaces.add(len(nvx2_faces))
    # TODO: eekadoodle fix
    me.tessfaces.foreach_set('vertices_raw', unpack_face_list(nvx2_faces))
    # Add texture coordinates
    material = create_material('nvx2_material')
    me.materials.append(material)
    uv_data = nvx2_uvlayers[0]
    if (len(uv_data) > 0):
        uv = me.tessface_uv_textures.new('nvx2_uv')
        me.tessface_uv_textures.active = uv
        for i in range(len(nvx2_faces)):
            tessface = me.tessfaces[i]
            tessface.material_index = 0
            tessfaceUV = me.tessface_uv_textures[0].data[i]
            face = nvx2_faces[i]
            # BEGIN EEEKADOODLE FIX
            # BUG: Evil eekadoodle problem where faces that have
            # vert index 0 at location 3 are shuffled.
            if face[2] == 0:
                face = [face[1], face[2], face[0]]
            # END EEEKADOODLE FIX
            tessfaceUV.uv1 = uv_data[face[0]]
            tessfaceUV.uv2 = uv_data[face[1]]
            tessfaceUV.uv3 = uv_data[face[2]]
            # Apply texture to uv face
            tessfaceUV.image = material.texture_slots[0].texture.image
        """
        me.uv_textures.new('nvx2_uv')
        uv_layer = me.uv_layers[-1].data
        vert_loops = {}
        for l in me.loops:
            vert_loops.setdefault(l.vertex_index, []).append(l.index)
        for i, coord in enumerate(uv_data):
            # For every loop of a vertex
            for li in vert_loops[i]:
                uv_layer[li].uv = coord
        """
        """
        vi_uv = {i: uv for i, uv in enumerate(uv_coords)}
        per_loop_list = [0.0] * len(me.loops)
        for loop in me.loops:
            per_loop_list[loop.index] = vi_uv.get(loop.vertex_index)
        per_loop_list = [uv for pair in per_loop_list for uv in pair]
        me.uv_textures.new('nvx2_uv')
        me.uv_layers[-1].data.foreach_set("uv", per_loop_list)
        """
    me.update()
    return me
	def build_blender_data(self, blender_context):
		from mdl_node_volume import MDL_NODE_VOLUME
		import bpy
		from bpy_extras.io_utils import unpack_list, unpack_face_list

		super(MDL_NODE_POLYHEDRON, self).build_blender_data(blender_context)

		print(type(self).__name__ + ".build_blender_data()")

		volume_name = None

		parent_node = self.parent

		# Get parents volume name
		while True:
			# Check if we found a volume node
			if type(parent_node) == MDL_NODE_VOLUME:
				volume_name = parent_node.volume_name
				break
			# Check if we reached the root node without finding a volume node
			elif parent_node == None:
				raise Exception("No parent volume node found")
			# Otherwise get the next parent
			else:
				parent_node = parent_node.parent

		# Create a new mesh with our parents volume name
		self.blender_mesh = bpy.data.meshes.new(volume_name)

		# Load vertices data into the mesh
		self.blender_mesh.vertices.add(len(self.vol.positions))
		self.blender_mesh.vertices.foreach_set("co", unpack_list(self.vol.positions))

		# Load face data into the mesh
		self.blender_mesh.tessfaces.add(len(self.vol.indeces))
		self.blender_mesh.tessfaces.foreach_set("vertices", unpack_list(self.vol.indeces))

		# Validate mesh
		self.blender_mesh.validate()

		# Update mesh
		self.blender_mesh.update(calc_edges=True)
Example #20
0
def make_mesh(verteces, faces, normals, uvs, global_matrix):

    # Create a new mesh from the vertices and faces
    mesh = bpy.data.meshes.new("Imported Mesh")
    mesh.vertices.add(len(verteces))
    mesh.vertices.foreach_set("co", unpack_list(verteces))
    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))

    # Generate normals
    index = 0
    for vertex in mesh.vertices:
        vertex.normal = normals[index]
        index += 1

    # Generate UV data
    uvtex = mesh.tessface_uv_textures.new(name="UVMap")

    for face, uv in enumerate(uvs):
        data = uvtex.data[face]
        data.uv1 = uv[0]
        data.uv2 = uv[1]
        data.uv3 = uv[2]

    # Update the mesh and link it to the scene
    mesh.update(calc_tessface=False, calc_edges=False)
    obj = bpy.data.objects.new(
        "Imported Mesh", mesh)  # Create the mesh object for the imported mesh
    obj.matrix_world = global_matrix  # Apply transformation matrix
    bpy.context.scene.objects.link(obj)  # Link object to scene

    # Prep for mesh cleaning --> https://blender.stackexchange.com/questions/174525/how-to-merge-all-vertices-by-distance-and-remove-all-inner-faces
    merge_threshold = 0.0001
    bpy.ops.object.select_all(action='DESELECT')
    obj.select = True  # Select the object we just made
    bpy.context.scene.objects.active = obj
    bpy.ops.object.mode_set(mode="EDIT")

    # Combine tri's to make a solid mesh and to remove unnecessary vertices
    bpy.ops.mesh.select_all(action="SELECT")
    bpy.ops.mesh.remove_doubles(threshold=merge_threshold)
    bpy.ops.mesh.select_all(action="DESELECT")

    # Remove interior faces that won't be seen
    bpy.ops.mesh.select_mode(type="FACE")
    bpy.ops.mesh.select_interior_faces()
    bpy.ops.mesh.delete(type="FACE")

    # Restore the scene to object mode
    if bpy.context.mode != "OBJECT":
        bpy.ops.object.mode_set(mode="OBJECT")
Example #21
0
 def create_mesh(self, name):
     verts = [
         ((self.xsize/2) / 100.0, (self.ysize/2) / 100.0, 0.0),
         ((self.xsize/2) / 100.0, (-self.ysize/2) / 100.0, 0.0),
         ((-self.xsize/2) / 100.0, (-self.ysize/2) / 100.0, 0.0),
         ((-self.xsize/2) / 100.0, (self.ysize/2) / 100.0, 0.0)
     ]
     indices = [
         (0, 1, 2),
         (0, 2, 3)
     ]
     # Create the mesh itself
     mesh = bpy.data.meshes.new(name)
     mesh.vertices.add(len(verts))
     mesh.vertices.foreach_set("co", unpack_list(verts))
     num_faces = len(indices)
     mesh.loops.add(3 * num_faces)
     mesh.loops.foreach_set("vertex_index", unpack_list(indices))
     mesh.polygons.add(num_faces)
     mesh.polygons.foreach_set("loop_start", range(0, 3 * num_faces, 3))
     mesh.polygons.foreach_set("loop_total", (3,) * num_faces)
     mesh.update()
     return mesh
Example #22
0
    def create_mesh(self, name, options):
        if options.normals_algorithm == NormalsAlgorithm.SHARP_EDGES and self.roottype == RootType.MODEL:
            self.merge_similar_vertices(options.sharp_edge_angle)

        # Create the mesh itself
        mesh = bpy.data.meshes.new(name)
        mesh.vertices.add(len(self.verts))
        mesh.vertices.foreach_set("co", unpack_list(self.verts))
        num_faces = len(self.facelist.vertices)
        mesh.loops.add(3 * num_faces)
        mesh.loops.foreach_set("vertex_index",
                               unpack_list(self.facelist.vertices))
        mesh.polygons.add(num_faces)
        mesh.polygons.foreach_set("loop_start", range(0, 3 * num_faces, 3))
        mesh.polygons.foreach_set("loop_total", (3, ) * num_faces)
        mesh.polygons.foreach_set("use_smooth", [True] * num_faces)

        # Create UV map
        if len(self.uv1) > 0:
            uv = unpack_list(
                [self.uv1[i] for indices in self.facelist.uv for i in indices])
            uv_layer = mesh.uv_layers.new(name=UV_MAP_DIFFUSE, do_init=False)
            uv_layer.data.foreach_set("uv", uv)

        # Create lightmap UV map
        if len(self.uv2) > 0:
            uv = unpack_list(
                [self.uv2[i] for indices in self.facelist.uv for i in indices])
            uv_layer = mesh.uv_layers.new(name=UV_MAP_LIGHTMAP, do_init=False)
            uv_layer.data.foreach_set("uv", uv)

        mesh.update()

        if self.roottype == RootType.MODEL:
            self.post_process_mesh(mesh, options)

        return mesh
Example #23
0
def importGMSH(file):
    result = {'FINISHED'}

    model = Header()
    model.read(file)

    for me in model.meshes:
        mesh = bpy.data.meshes.new(ntpath.basename(file.name))
        obj = bpy.data.objects.new(ntpath.basename(file.name), mesh)
        bpy.context.scene.objects.link(obj)
        bpy.context.scene.objects.active = obj

        mesh.vertices.add(me.numVertices)
        mesh.vertices.foreach_set("co", unpack_list(me.positions))

        mesh.tessfaces.add(me.numTriangles)
        mesh.tessfaces.foreach_set("vertices_raw",
                                   unpack_face_list(me.triangles))

        uvtex = mesh.tessface_uv_textures.new()
        uvtex.name = 'DefaultUV'
        if len(me.UVs) > 0:
            for v, face in enumerate(mesh.tessfaces):
                uvtex.data[v].uv1 = me.UVs[face.vertices_raw[0]]
                uvtex.data[v].uv2 = me.UVs[face.vertices_raw[1]]
                uvtex.data[v].uv3 = me.UVs[face.vertices_raw[2]]
                uvtex.data[v].uv4 = [0, 0]

        mesh.update()

        if len(me.normals) > 0:
            mesh.vertices.foreach_set("normal", unpack_list(me.normals))

    file.close()

    return result
Example #24
0
def createHiddenMeshObject(name, untransformedPositions, faces, matrix):
    mesh = bpy.data.meshes.new(name)
    meshObject = bpy.data.objects.new(name, mesh)
    meshObject.location = (0,0,0) 

    transformedPositions = []
    for v in untransformedPositions:
        transformedPositions.append(matrix * mathutils.Vector(v))

    mesh.vertices.add(len(transformedPositions))
    mesh.vertices.foreach_set("co", io_utils.unpack_list(transformedPositions))

    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set("vertices_raw", io_utils.unpack_face_list(faces))
    
    mesh.update(calc_edges=True)
    return meshObject
Example #25
0
def createGridIcoSphere():
    me = bpy.data.meshes.new("M_GridPoint")
    me.from_pydata(verts, [], faces)

    for material in materials:
        mat = bpy.data.materials.get(material)
        if (mat == None):
            mat = bpy.data.materials.new(name=material)
        me.materials.append(mat)
    me.polygons.foreach_set("material_index", material_ids)

    me.uv_layers.new(do_init=False, name="UVMap")
    me.uv_layers["UVMap"].data.foreach_set("uv", unpack_list(uvs))

    ob = bpy.data.objects.new("LightGrid", me)
    bpy.context.collection.objects.link(ob)
    return ob
Example #26
0
def mesh_from_data(name,coords,uvs,faces,face_mats,mats):
    mesh = bpy.data.meshes.new(name)
    if not mats is None:
        [mesh.materials.append(materials[ma]) for ma in mats]
    mesh.vertices.add(len(coords))
    mesh.vertices.foreach_set('co',unpack_list(coords))
    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set('vertices_raw',unpack_face_list(faces))
    mesh.tessfaces.foreach_set('material_index',face_mats)
    mesh.tessface_uv_textures.new()
    for fdx in range(len(faces)):
        fa = faces[fdx]
        mesh.tessface_uv_textures[0].data[fdx].uv1 = uvs[fa[0]].to_tuple()
        mesh.tessface_uv_textures[0].data[fdx].uv2 = uvs[fa[1]].to_tuple() 
        mesh.tessface_uv_textures[0].data[fdx].uv3 = uvs[fa[2]].to_tuple() 
    mesh.update()
    return mesh
Example #27
0
    def instance_group_dupli_face(self, name, default_material, component_stats):
        def get_orientations( v):
            orientations = defaultdict(list)
            for transform in v:
                loc, rot, scale = Matrix(transform).decompose()
                scale = (scale[0], scale[1], scale[2])
                orientations[scale].append(transform)
            for scale, transforms in orientations.items():
                yield scale, transforms


        for scale, transforms in get_orientations(component_stats[(name, default_material)]):
            main_loc, _, real_scale  = Matrix(transforms[0]).decompose()
            verts = []
            faces = []
            f_count = 0
            for c in transforms:
                l_loc, l_rot, l_scale = Matrix(c).decompose()
                mat = Matrix.Translation(l_loc) * l_rot.to_matrix().to_4x4()
                verts.append(Vector((mat * Vector((-0.05, -0.05, 0, 1.0)))[0:3]) - main_loc)
                verts.append(Vector((mat * Vector(( 0.05, -0.05, 0, 1.0)))[0:3]) - main_loc)
                verts.append(Vector((mat * Vector(( 0.05,  0.05, 0, 1.0)))[0:3]) - main_loc)
                verts.append(Vector((mat * Vector((-0.05,  0.05, 0, 1.0)))[0:3]) - main_loc)
                faces.append( (f_count + 0,  f_count + 1, f_count + 2, f_count + 3) )
                f_count += 4
            dme = bpy.data.meshes.new('DUPLI_' + name)
            dme.vertices.add(len(verts))
            dme.vertices.foreach_set("co", unpack_list(verts))

            dme.tessfaces.add(f_count /4 )
            dme.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
            dme.update(calc_edges=True) # Update mesh with new data
            dme.validate()
            dob = bpy.data.objects.new("DUPLI_" + name, dme)
            dob.dupli_type = 'FACES'
            dob.location = main_loc
            #dob.use_dupli_faces_scale = True
            #dob.dupli_faces_scale = 10

            ob = self.instance_object_or_group(name,default_material)
            ob.scale = real_scale
            ob.parent = dob
            self.context.scene.objects.link(ob)
            self.context.scene.objects.link(dob)
            sketchupLog("Complex group {} {} instanced {} times".format(name, default_material, f_count / 4))
        return
Example #28
0
def mesh_from_data(name, coords, uvs, faces, face_mats, mats):
    mesh = bpy.data.meshes.new(name)
    if not mats is None:
        [mesh.materials.append(materials[ma]) for ma in mats]
    mesh.vertices.add(len(coords))
    mesh.vertices.foreach_set('co', unpack_list(coords))
    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set('vertices_raw', unpack_face_list(faces))
    mesh.tessfaces.foreach_set('material_index', face_mats)
    mesh.tessface_uv_textures.new()
    for fdx in range(len(faces)):
        fa = faces[fdx]
        mesh.tessface_uv_textures[0].data[fdx].uv1 = uvs[fa[0]].to_tuple()
        mesh.tessface_uv_textures[0].data[fdx].uv2 = uvs[fa[1]].to_tuple()
        mesh.tessface_uv_textures[0].data[fdx].uv3 = uvs[fa[2]].to_tuple()
    mesh.update()
    return mesh
Example #29
0
    def _createMesh(scene, name, vertices, faces):
        from bpy_extras.io_utils import unpack_list, unpack_face_list

        mesh = bpy.data.meshes.new(name=name)

        mesh.vertices.add(len(vertices))
        mesh.vertices.foreach_set("co", unpack_list(vertices))

        mesh.faces.add(len(faces))
        mesh.faces.foreach_set("vertices_raw", unpack_face_list(faces))

        mesh.update(calc_edges=True)

        ob = bpy.data.objects.new(name=name, object_data=mesh)

        scene.objects.link(ob)

        return ob
Example #30
0
    def _createMesh(scene, name, vertices, faces):
        from bpy_extras.io_utils import unpack_list, unpack_face_list

        mesh = bpy.data.meshes.new(name=name)

        mesh.vertices.add(len(vertices))
        mesh.vertices.foreach_set("co", unpack_list(vertices))

        mesh.faces.add(len(faces))
        mesh.faces.foreach_set("vertices_raw", unpack_face_list(faces))

        mesh.update(calc_edges=True)

        ob = bpy.data.objects.new(name=name, object_data=mesh)

        scene.objects.link(ob)

        return ob
Example #31
0
def import_mesh(node):
    mesh = bpy.data.meshes.new(node.name)

    # join face arrays
    faces = []
    for face in node.faces:
        faces.extend(face.indices)

    # create mesh from data
    mesh.from_pydata(flip_all(node.vertices), [], flip_all(faces))

    # assign normals
    mesh.vertices.foreach_set('normal', unpack_list(node.normals))

    # create object from mesh
    ob = bpy.data.objects.new(node.name, mesh)

    # assign uv coordinates
    vert_uvs = [(0,0) if len(uv)==0 else (uv[0], 1-uv[1]) for uv in node.uvs]
    me = ob.data
    me.uv_layers.new(do_init=False)
    me.uv_layers[-1].data.foreach_set("uv", [uv for pair in [vert_uvs[l.vertex_index] for l in me.loops] for uv in pair])

    # assign materials and textures
    mat_slots = {}
    for face in node.faces:
        if face.brush_id in materials:
            mat = materials[face.brush_id]
            ob.data.materials.append(mat)
            mat_slots[face.brush_id] = len(ob.data.materials)-1
            #for uv_face in ob.data.uv_layers.active.data:
            #    if mat.active_texture:
            #        uv_face.image = mat.active_texture.image

    # link object to scene
    ctx.scene.collection.objects.link(ob)

    if len(node.faces)>1:
        assign_material_slots(ob, node, mat_slots)

    #postprocess(ob, mesh, node) # breaks weighting

    return ob
Example #32
0
def load(operator, context, filepath):
    # Parse mesh from OFF file
    # TODO: Add support for NOFF and COFF
    filepath = os.fsencode(filepath)
    file = open(filepath, 'r')
    file.readline()
    vcount, fcount, ecount = [int(x) for x in file.readline().split()]
    verts = []
    facets = []
    i=0;
    while i<vcount:
        line = file.readline()
        try:
            px, py, pz = [float(x) for x in line.split()]
        except ValueError:
            continue
        verts.append((px, py, pz))
        i=i+1

    i=0;
    while i<fcount:
        line = file.readline()
        try:
            unused, vid1, vid2, vid3 = [int(x) for x in line.split()]
        except ValueError:
            continue
        facets.append((vid1, vid2, vid3))
        i=i+1

    # Assemble mesh
    off_name = bpy.path.display_name_from_filepath(filepath)
    mesh = bpy.data.meshes.new(name=off_name)
    mesh.vertices.add(len(verts))
    mesh.vertices.foreach_set("co", unpack_list(verts))

    mesh.tessfaces.add(len(facets))
    mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(facets))

    mesh.validate()
    mesh.update()

    return mesh
Example #33
0
    def execute(self, context):
        from bpy_extras.io_utils import unpack_list

        sc = context.space_data
        clip = sc.clip

        new_verts = []

        mesh = bpy.data.meshes.new(name="Tracks")
        for track in clip.tracking.tracks:
            if track.has_bundle:
                new_verts.append(track.bundle)

        if new_verts:
            mesh.vertices.add(len(new_verts))
            mesh.vertices.foreach_set("co", unpack_list(new_verts))

        ob = bpy.data.objects.new(name="Tracks", object_data=mesh)

        context.scene.objects.link(ob)

        return {'FINISHED'}
Example #34
0
    def execute(self, context):
        from bpy_extras.io_utils import unpack_list

        sc = context.space_data
        clip = sc.clip

        new_verts = []

        mesh = bpy.data.meshes.new(name="Tracks")
        for track in clip.tracking.tracks:
            if track.has_bundle:
                new_verts.append(track.bundle)

        if new_verts:
            mesh.vertices.add(len(new_verts))
            mesh.vertices.foreach_set("co", unpack_list(new_verts))

        ob = bpy.data.objects.new(name="Tracks", object_data=mesh)

        context.scene.objects.link(ob)

        return {'FINISHED'}
Example #35
0
    def _createMesh(collection, name, vertices, faces):
        from bpy_extras.io_utils import unpack_list

        mesh = bpy.data.meshes.new(name=name)

        mesh.vertices.add(len(vertices))
        mesh.vertices.foreach_set("co", unpack_list(vertices))

        nbr_loops = len(faces)
        nbr_polys = nbr_loops // 4
        mesh.loops.add(nbr_loops)
        mesh.polygons.add(nbr_polys)

        mesh.polygons.foreach_set("loop_start", range(0, nbr_loops, 4))
        mesh.polygons.foreach_set("loop_total", (4, ) * nbr_polys)
        mesh.loops.foreach_set("vertex_index", faces)

        mesh.update()

        ob = bpy.data.objects.new(name=name, object_data=mesh)
        collection.objects.link(ob)

        return ob
Example #36
0
    def _createMesh(collection, name, vertices, faces):
        from bpy_extras.io_utils import unpack_list

        mesh = bpy.data.meshes.new(name=name)

        mesh.vertices.add(len(vertices))
        mesh.vertices.foreach_set("co", unpack_list(vertices))

        nbr_loops = len(faces)
        nbr_polys = nbr_loops // 4
        mesh.loops.add(nbr_loops)
        mesh.polygons.add(nbr_polys)

        mesh.polygons.foreach_set("loop_start", range(0, nbr_loops, 4))
        mesh.polygons.foreach_set("loop_total", (4,) * nbr_polys)
        mesh.loops.foreach_set("vertex_index", faces)

        mesh.update()

        ob = bpy.data.objects.new(name=name, object_data=mesh)
        collection.objects.link(ob)

        return ob
Example #37
0
def import_mesh(node, parent):
    global material_mapping

    mesh = bpy.data.meshes.new(node.name)

    # join face arrays
    faces = []
    for face in node.faces:
        faces.extend(face.indices)

    # create mesh from data
    mesh.from_pydata(flip_all(node.vertices), [], flip_all(faces))

    # assign normals
    mesh.vertices.foreach_set('normal', unpack_list(node.normals))

    # create object from mesh
    ob = bpy.data.objects.new(node.name, mesh)

    # assign uv coordinates
    bpymesh = ob.data
    uvs = [(0,0) if len(uv)==0 else (uv[0], 1-uv[1]) for uv in node.uvs]
    uvlist = [i for poly in bpymesh.polygons for vidx in poly.vertices for i in uvs[vidx]]
    bpymesh.uv_layers.new().data.foreach_set('uv', uvlist)

    # adding object materials (insert-ordered)
    for key, value in material_mapping.items():
        ob.data.materials.append(bpy.data.materials[value])

    # assign material_indexes
    poly = 0
    for face in node.faces:
        for _ in face.indices:
            ob.data.polygons[poly].material_index = face.brush_id
            poly += 1

    return ob
def my_handler(scene): 

    frame = scene.frame_current
    activationFlag = bpy.context.scene.lineGenActivate
    randomConnections = bpy.context.scene.randomConnections
    handle_random_mul = bpy.context.scene.randomizeInfluence
    coordinate_noise = bpy.context.scene.coordinate_noise
    coordinate_noise_influence = bpy.context.scene.coordinate_noise_influence
    coordinate_noise_scale = bpy.context.scene.coordinate_noise_scale
    coordinate_offset_dx = bpy.context.scene.coordinate_offset_dx
    coordinate_offset_dy = bpy.context.scene.coordinate_offset_dy
    coordinate_offset_dz = bpy.context.scene.coordinate_offset_dz
    curveOutward= bpy.context.scene.curveOutward
    pointLerp = bpy.context.scene.pointLerp
    pointIdentity = bpy.context.scene.pointIdentity 
    randomNum=[]
    ANIM_DIST=bpy.context.scene.animDist
    print(str(activationFlag) + " " +str(ANIM_DIST))
    if activationFlag == True:
        
        #go through each object in the group (set up index boundaries)
        xLength = len(pointList) #-1 
        indexA=0
        bpy.ops.object.select_all(action='DESELECT')
        curvedata.splines.clear()
        for x in pointList:
            indexA= indexA+1
            if indexA <= xLength:
                for indexY in range(indexA,xLength):
                    y= pointList[indexY]
                    locX=x.location
                    locY=pointList[indexY].location
                    distance = math.sqrt( (locX[0] - locY[0])**2 + (locX[1] - locY[1])**2 + (locX[2] - locY[2])**2)
                    if (randomConnections):
                        randomNum = random.random()*100
                        if randomNum <= bpy.context.scene.randomConnections_threshold:
                            if distance >= ANIM_DIST:
                                distance = ANIM_DIST*0.9
                        if randomNum >= bpy.context.scene.randomConnections_threshold:
                            distance = ANIM_DIST*3
                    if distance <= ANIM_DIST:
                        minimumRadius = bpy.context.scene.radius_minimum
                        radius_multiplier = bpy.context.scene.radius_multiplier
                        pointRadius = (1 - (distance / ANIM_DIST))*radius_multiplier + minimumRadius
                        coordinate_Pairs = []
                        coordinate_Pairs.append(locX)
                        coordinate_Pairs.append(locY)

                        spline = curvedata.splines.new('BEZIER')
                        spline.bezier_points.add(1)
                        spline.bezier_points.foreach_set("co", unpack_list(coordinate_Pairs))
                        maxindex=2
                        if (pointIdentity):
                            maxindex=1
                        for i in range(0,maxindex):
                            left_dx = bpy.context.scene.left_dx
                            left_dy = bpy.context.scene.left_dy
                            left_dz = bpy.context.scene.left_dz
                            
                            right_dx = bpy.context.scene.right_dx
                            right_dy = bpy.context.scene.right_dy
                            right_dz = bpy.context.scene.right_dz


                            spline.bezier_points[i].handle_left[0]  += coordinate_Pairs[i][0]+left_dx
                            spline.bezier_points[i].handle_left[1]  += coordinate_Pairs[i][1]+left_dy
                            spline.bezier_points[i].handle_left[2]  += coordinate_Pairs[i][2]+left_dz

                            spline.bezier_points[i].handle_right[0] += coordinate_Pairs[i][0]+right_dx
                            spline.bezier_points[i].handle_right[1] += coordinate_Pairs[i][1]+right_dy
                            spline.bezier_points[i].handle_right[2] += coordinate_Pairs[i][2]+right_dz
                            if(curveOutward):
                                #spline.bezier_points[i].handle_right.xyz  = spline.bezier_points[i].co
                                #v=mathutils.Vector((0.01,0.01,0.01))
                                #spline.bezier_points[i].handle_left.xyz = spline.bezier_points[i].co+v
                                #spline.bezier_points[i].handle_right_type='FREE'
                                #spline.bezier_points[i].handle_left_type='FREE'

                                #spline.bezier_points[i].handle_right_type='ALIGNED'
                                #spline.bezier_points[i].handle_left_type='ALIGNED'
                                #spline.bezier_points[i].handle_right_type='VECTOR'
                                #spline.bezier_points[i].handle_left_type='VECTOR'

                                spline.bezier_points[i].handle_left.xyz  += spline.bezier_points[i].handle_left.lerp(spline.bezier_points[i].co,pointLerp)
                                spline.bezier_points[i].handle_right.xyz += spline.bezier_points[i].handle_right.lerp(spline.bezier_points[i].co,pointLerp)



                            if(bpy.context.scene.randomHandles):
                                spline.bezier_points[i].handle_left[0]  +=(0.5-random.random())*handle_random_mul 
                                spline.bezier_points[i].handle_left[1]  +=(0.5-random.random())*handle_random_mul 
                                spline.bezier_points[i].handle_left[2]  +=(0.5-random.random())*handle_random_mul 
                                spline.bezier_points[i].handle_right[0] +=(0.5-random.random())*handle_random_mul 
                                spline.bezier_points[i].handle_right[1] +=(0.5-random.random())*handle_random_mul 
                                spline.bezier_points[i].handle_right[2] +=(0.5-random.random())*handle_random_mul
                            if(coordinate_noise):
                                spline.bezier_points[i].handle_left[0]  +=math.sin(spline.bezier_points[i].handle_left[0]*coordinate_noise_scale+coordinate_offset_dx)*coordinate_noise_influence
                                spline.bezier_points[i].handle_left[1]  +=math.cos(spline.bezier_points[i].handle_left[1]*coordinate_noise_scale+coordinate_offset_dy)*coordinate_noise_influence
                                spline.bezier_points[i].handle_left[2]  +=math.sin(spline.bezier_points[i].handle_left[2]*coordinate_noise_scale+coordinate_offset_dz)*coordinate_noise_influence
                                spline.bezier_points[i].handle_right[0] +=math.sin(spline.bezier_points[i].handle_left[0]*coordinate_noise_scale+coordinate_offset_dx)*coordinate_noise_influence
                                spline.bezier_points[i].handle_right[1] +=math.cos(spline.bezier_points[i].handle_left[1]*coordinate_noise_scale+coordinate_offset_dy)*coordinate_noise_influence
                                spline.bezier_points[i].handle_right[2] +=math.sin(spline.bezier_points[i].handle_left[2]*coordinate_noise_scale+coordinate_offset_dz)*coordinate_noise_influence
                            spline.bezier_points[i].radius = pointRadius
Example #39
0
def make_mesh(model, name, meshes, amtobj):
	print("importing mesh", name, "with", len(meshes), "parts")

	mesh = bpy.data.meshes.new(name)
	obj = bpy.data.objects.new(name, mesh)
	bpy.context.scene.objects.link(obj)
	bpy.context.scene.objects.active = obj

	# Set the mesh to single-sided to spot normal errors
	mesh.show_double_sided = False

	# Flip winding
	for m in meshes:
		m.faces = [x[::-1] for x in m.faces]

	# Positions, normals, blends and vertex groups go to vertices.
	# Material, texture coords and vertex colors go to faces.

	weld = {}
	out_vp, out_vn, out_vb = [], [], []
	out_f, out_f_mat, out_f_img, out_ft, out_fc = [], [], [], [], []

	for m in meshes:
		material, image = make_material(m.material)
		if material.name not in mesh.materials:
			mesh.materials.append(material)
		material_index = mesh.materials.find(material.name)

		out_from_in = []

		for i, p in enumerate(m.positions):
			n = m.normals[i] if len(m.normals) > i else (0,0,1)
			b = m.blends[i] if len(m.blends) > i else None
			# TODO: vertex groups custom data
			key = p, n, b
			if not key in weld:
				weld[key] = len(out_vp)
				out_vp.append(p)
				out_vn.append(n)
				out_vb.append(b)
			out_from_in.append(weld[key])

		vt, vt_names = gather_vt(model.vertexarrays, m)
		vc, vc_names = gather_vc(model.vertexarrays, m)

		print(vc_names)
		print(vc)

		for face in m.faces:
			f = [out_from_in[v] for v in face]
			ft = [[t[v] for t in vt] for v in face]
			fc = [[c[v] for c in vc] for v in face]
			f, ft, fc = reorder(f, ft, fc)
			if isdegenerate(f):
				print("degenerate face", f)
				continue

			out_f.append(f)
			out_ft.append(ft)
			out_fc.append(fc)
			out_f_mat.append(material_index)
			out_f_img.append(image)

	print("\tcollected %d vertices and %d faces" % (len(out_vp), len(out_f)))

	# Create mesh vertex and face data

	mesh.vertices.add(len(out_vp))
	mesh.vertices.foreach_set("co", unpack_list(out_vp))

	mesh.tessfaces.add(len(out_f))
	mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(out_f))

	for i, face in enumerate(mesh.tessfaces):
		face.use_smooth = True
		face.material_index = out_f_mat[i]

	for k, name in enumerate(vt_names):
		layer = mesh.tessface_uv_textures.new(name)
		for i, face in enumerate(mesh.tessfaces):
			data = layer.data[i]
			ft = out_ft[i]
			data.image = out_f_img[i]
			data.uv1 = (ft[0][k][0], 1-ft[0][k][1])
			data.uv2 = (ft[1][k][0], 1-ft[1][k][1])
			data.uv3 = (ft[2][k][0], 1-ft[2][k][1])
			if len(ft) > 3:
				data.uv4 = (ft[3][k][0], 1-ft[3][k][1])

	for k, name in enumerate(vc_names):
		layer = mesh.tessface_vertex_colors.new(name)
		for i, face in enumerate(mesh.tessfaces):
			data = layer.data[i]
			data.color1 = tuple(out_fc[i][0][k][:3])
			data.color2 = tuple(out_fc[i][1][k][:3])
			data.color3 = tuple(out_fc[i][2][k][:3])
			if len(out_fc[i]) > 3:
				data.color4 = tuple(out_fc[i][3][k][:3])

	# Vertex groups and armature modifier for skinning

	if amtobj:
		for iqbone in iqmodel.bones:
			obj.vertex_groups.new(iqbone[0])

		for vgroup in obj.vertex_groups:
			for i, b in enumerate(out_vb):
				idx, wgt = b
				if idx == vgroup.index:
					vgroup.add([i], idx, 'REPLACE')

		mod = obj.modifiers.new("Armature", 'ARMATURE')
		mod.object = amtobj
		mod.use_vertex_groups = True

	# Update mesh polygons from tessfaces

	mesh.update()

	# Must set normals after mesh.update() or they will be recalculated.
	mesh.vertices.foreach_set("normal", unpack_list(out_vn))

	return obj
Example #40
0
def import_mesh(filename):
	print("importing", filename)

	name = filename.split("/")[-1].split("\\")[-1].split(".")[0]
	file = open(filename)
	line = file.readline()
	if not line.startswith("# Inter-Quake Export"):
		raise Exception("Not an IQE file!")

	has_vc = has_vt = False

	faces = []
	mat, img = None, None
	for line in file.readlines():
		if "#" in line or "\"" in line:
			line = shlex.split(line, "#")
		else:
			line = line.split()
		if len(line) == 0: pass
		elif line[0] == "mesh": in_vp, in_vn, in_vt, in_vc = [], [], [], []
		elif line[0] == "material": mat, img = import_material(line[1])
		elif line[0] == "vp": in_vp.append((float(line[1]), float(line[2]), float(line[3])))
		elif line[0] == "vn": in_vn.append((float(line[1]), float(line[2]), float(line[3])))
		elif line[0] == "vt": has_vt = True; in_vt.append((float(line[1]), 1.0 - float(line[2])))
		elif line[0] == "vc": has_vc = True; in_vc.append((float(line[1]), float(line[2]), float(line[3])))
		elif line[0] == "fm":
			verts = []
			for f in [int(x) for x in line[1:]]:
				p, n = in_vp[f], in_vn[f]
				t = in_vt[f] if f < len(in_vt) else (0,0)
				c = in_vc[f] if f < len(in_vc) else (1,1,1)
				verts.insert(0, (p, n, t, c))
			faces.append((verts, mat, img))

	vertex_map = {}
	out_vp, out_vn, out_f, out_ft, out_fc, out_fm = [], [], [], [], [], []
	for verts, mat, img in faces:
		f, ft, fc = [], [], []
		for p, n, t, c in verts:
			if not (p,n) in vertex_map:
				vertex_map[(p,n)] = len(out_vp)
				out_vp.append(p)
				out_vn.append(n)
			f.append(vertex_map[p,n])
			ft.append(t)
			fc.append(c)
		f, ft, fc = reorder(f, ft, fc)
		if isdegenerate(f):
			print("degenerate face", f)
			continue
		out_f.append(f)
		out_ft.append(ft)
		out_fc.append(fc)
		out_fm.append((mat, img))

	mesh = bpy.data.meshes.new(name)
	obj = bpy.data.objects.new(name, mesh)
	grp = bpy.data.groups.new(name)
	grp.objects.link(obj)

	mesh.show_double_sided = False

	mesh.vertices.add(len(out_vp))
	mesh.vertices.foreach_set("co", unpack_list(out_vp))
	mesh.tessfaces.add(len(out_f))
	mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(out_f))

	if has_vt: uvlayer = mesh.tessface_uv_textures.new()
	if has_vc: vclayer = mesh.tessface_vertex_colors.new()
	for i, face in enumerate(mesh.tessfaces):
		mat, img = out_fm[i]
		if mat.name not in mesh.materials:
			mesh.materials.append(mat)
		face.material_index = mesh.materials.find(mat.name)
		face.use_smooth = True
		if has_vt:
			uvlayer.data[i].image = img
			uvlayer.data[i].uv1 = out_ft[i][0]
			uvlayer.data[i].uv2 = out_ft[i][1]
			uvlayer.data[i].uv3 = out_ft[i][2]
			uvlayer.data[i].uv4 = out_ft[i][3] if len(out_ft[i]) == 4 else (0,0)
		if has_vc:
			vclayer.data[i].color1 = out_fc[i][0]
			vclayer.data[i].color2 = out_fc[i][1]
			vclayer.data[i].color3 = out_fc[i][2]
			vclayer.data[i].color4 = out_fc[i][3] if len(out_fc[i]) == 4 else (1,1,1)

	for mat in mesh.materials:
		mat.use_vertex_color_paint = has_vc

	mesh.update()

	# Must set normals after mesh.update() or they will be recalculated
	mesh.vertices.foreach_set("normal", unpack_list(out_vn))

	bpy.context.scene.objects.link(obj)
	bpy.context.scene.objects.active = obj
Example #41
0
def make_mesh_data(iqmodel, name, meshes, amtobj, dir):
	print("importing mesh", name, "with", len(meshes), "parts")

	mesh = bpy.data.meshes.new(name)
	obj = bpy.data.objects.new(name, mesh)
	bpy.context.scene.objects.link(obj)
	bpy.context.scene.objects.active = obj

	# Set the mesh to single-sided to spot normal errors
	mesh.show_double_sided = False

	has_vn = len(iqmodel.meshes[0].vn) > 0
	has_vt = len(iqmodel.meshes[0].vt) > 0
	has_vc = len(iqmodel.meshes[0].vc) > 0
	has_vb = len(iqmodel.meshes[0].vbi) > 0 and len(iqmodel.meshes[0].vbw) == len(iqmodel.meshes[0].vbi)
	has_v0 = len(iqmodel.meshes[0].v0) > 0
	has_v1 = len(iqmodel.meshes[0].v1) > 0
	has_v2 = len(iqmodel.meshes[0].v2) > 0
	has_v3 = len(iqmodel.meshes[0].v3) > 0
	has_v4 = len(iqmodel.meshes[0].v4) > 0
	has_v5 = len(iqmodel.meshes[0].v5) > 0
	has_v6 = len(iqmodel.meshes[0].v6) > 0
	has_v7 = len(iqmodel.meshes[0].v7) > 0
	has_v8 = len(iqmodel.meshes[0].v8) > 0
	has_v9 = len(iqmodel.meshes[0].v9) > 0

	# Flip winding and UV coords.

	for iqmesh in meshes:
		iqmesh.faces = [x[::-1] for x in iqmesh.faces]
		iqmesh.vt = [(u,1-v) for (u,v) in iqmesh.vt]

	# Blender has texcoords and colors on faces rather than vertices.
	# Create material slots for all materials used.
	# Create new vertices from unique vp/vn/vb sets (vertex data).
	# Create new faces which index these new vertices, and has associated face data.

	vertex_map = {}

	new_f = []
	new_ft = []
	new_fc = []
	new_fm_m = []
	new_fm_i = []

	new_vp = []
	new_vn = []
	new_vbi = []
	new_vbw = []
	new_v0 = []
	new_v1 = []
	new_v2 = []
	new_v3 = []
	new_v4 = []
	new_v5 = []
	new_v6 = []
	new_v7 = []
	new_v8 = []
	new_v9 = []

	for iqmesh in meshes:
		material, image = make_material(iqmesh.material, dir)
		if material.name not in mesh.materials:
			mesh.materials.append(material)
		material_index = mesh.materials.find(material.name)

		for iqface in iqmesh.faces:
			f = []
			ft = []
			fc = []
			for iqvert in iqface:
				vp = iqmesh.vp[iqvert]
				vn = iqmesh.vn[iqvert] if has_vn else None
				vbi = iqmesh.vbi[iqvert] if has_vb else None
				vbw = iqmesh.vbw[iqvert] if has_vb else None
				v0 = iqmesh.v0[iqvert] if has_v0 else None
				v1 = iqmesh.v1[iqvert] if has_v1 else None
				v2 = iqmesh.v2[iqvert] if has_v2 else None
				v3 = iqmesh.v3[iqvert] if has_v3 else None
				v4 = iqmesh.v4[iqvert] if has_v4 else None
				v5 = iqmesh.v5[iqvert] if has_v5 else None
				v6 = iqmesh.v6[iqvert] if has_v6 else None
				v7 = iqmesh.v7[iqvert] if has_v7 else None
				v8 = iqmesh.v8[iqvert] if has_v8 else None
				v9 = iqmesh.v9[iqvert] if has_v9 else None
				vertex = (vp, vn, vbi, vbw, v0, v1, v2, v3, v4, v5, v6, v7, v8, v9)
				if not vertex in vertex_map:
					vertex_map[vertex] = len(new_vp)
					new_vp.append(vp)
					new_vn.append(vn)
					new_vbi.append(vbi)
					new_vbw.append(vbw)
					new_v0.append(v0)
					new_v1.append(v1)
					new_v2.append(v2)
					new_v3.append(v3)
					new_v4.append(v4)
					new_v5.append(v5)
					new_v6.append(v6)
					new_v7.append(v7)
					new_v8.append(v8)
					new_v9.append(v9)
				f.append(vertex_map[vertex])
				ft.append(iqmesh.vt[iqvert] if has_vt else None)
				fc.append(iqmesh.vc[iqvert] if has_vc else None)
			f, ft, fc = reorder(f, ft, fc)
			if isdegenerate(f):
				print("degenerate face", iqface, f)
				continue
			new_f.append(f)
			new_ft.append(ft)
			new_fc.append(fc)
			new_fm_m.append(material_index)
			new_fm_i.append(image)

	print("\tcollected %d vertices and %d faces" % (len(new_vp), len(new_f)))

	# Create mesh vertex and face data

	mesh.vertices.add(len(new_vp))
	mesh.vertices.foreach_set("co", unpack_list(new_vp))

	mesh.tessfaces.add(len(new_f))
	mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list(new_f))

	# Set up UV and Color layers

	uvlayer = mesh.tessface_uv_textures.new() if has_vt else None
	clayer = mesh.tessface_vertex_colors.new() if has_vc else None

	for i, face in enumerate(mesh.tessfaces):
		face.use_smooth = True
		face.material_index = new_fm_m[i]
		if uvlayer:
			uvlayer.data[i].uv1 = new_ft[i][0]
			uvlayer.data[i].uv2 = new_ft[i][1]
			uvlayer.data[i].uv3 = new_ft[i][2]
			uvlayer.data[i].uv4 = new_ft[i][3] if len(new_ft[i]) == 4 else (0,0)
			uvlayer.data[i].image = new_fm_i[i]
		if clayer:
			clayer.data[i].color1 = new_fc[0]
			clayer.data[i].color2 = new_fc[1]
			clayer.data[i].color3 = new_fc[2]
			clayer.data[i].color4 = new_fc[3] if len(new_fc[i]) == 4 else (1,1,1)

	# Vertex groups and armature modifier for skinning

	if has_vb and amtobj:
		for iqbone in iqmodel.bones:
			obj.vertex_groups.new(iqbone.name)

		for vgroup in obj.vertex_groups:
			for v, vbi in enumerate(new_vbi):
				for i, bi in enumerate(vbi):
					bw = new_vbw[v][i]
					if bi == vgroup.index:
						vgroup.add([v], bw, 'REPLACE')

		mod = obj.modifiers.new("Armature", 'ARMATURE')
		mod.object = amtobj
		mod.use_vertex_groups = True

	# Vertex groups for custom attributes

	def make_custom_vgroup(obj, name, size, vdata):
		print("importing custom attribute as vertex group", name)
		if size == 1:
			xg = obj.vertex_groups.new(name)
			for i, v in enumerate(vdata):
				xg.add([i], v[0], 'REPLACE')
		if size == 2:
			xg = obj.vertex_groups.new(name + ".x")
			yg = obj.vertex_groups.new(name + ".y")
			for i, v in enumerate(vdata):
				xg.add([i], v[0], 'REPLACE')
				yg.add([i], v[1], 'REPLACE')
		if size == 3:
			xg = obj.vertex_groups.new(name + ".x")
			yg = obj.vertex_groups.new(name + ".y")
			zg = obj.vertex_groups.new(name + ".z")
			for i, v in enumerate(vdata):
				xg.add([i], v[0], 'REPLACE')
				yg.add([i], v[1], 'REPLACE')
				zg.add([i], v[2], 'REPLACE')
		if size == 4:
			xg = obj.vertex_groups.new(name + ".x")
			yg = obj.vertex_groups.new(name + ".y")
			zg = obj.vertex_groups.new(name + ".z")
			wg = obj.vertex_groups.new(name + ".z")
			for i, v in enumerate(vdata):
				xg.add([i], v[0], 'REPLACE')
				yg.add([i], v[1], 'REPLACE')
				zg.add([i], v[2], 'REPLACE')
				wg.add([i], v[3], 'REPLACE')

	if has_v0: make_custom_vgroup(obj, iqmodel.custom_name[0], iqmodel.custom_size[0], new_v0)
	if has_v1: make_custom_vgroup(obj, iqmodel.custom_name[1], iqmodel.custom_size[1], new_v1)
	if has_v2: make_custom_vgroup(obj, iqmodel.custom_name[2], iqmodel.custom_size[2], new_v2)
	if has_v3: make_custom_vgroup(obj, iqmodel.custom_name[3], iqmodel.custom_size[3], new_v3)
	if has_v4: make_custom_vgroup(obj, iqmodel.custom_name[4], iqmodel.custom_size[4], new_v4)
	if has_v5: make_custom_vgroup(obj, iqmodel.custom_name[5], iqmodel.custom_size[5], new_v5)
	if has_v6: make_custom_vgroup(obj, iqmodel.custom_name[6], iqmodel.custom_size[6], new_v6)
	if has_v7: make_custom_vgroup(obj, iqmodel.custom_name[7], iqmodel.custom_size[7], new_v7)
	if has_v8: make_custom_vgroup(obj, iqmodel.custom_name[8], iqmodel.custom_size[8], new_v8)
	if has_v9: make_custom_vgroup(obj, iqmodel.custom_name[9], iqmodel.custom_size[9], new_v9)

	# Update mesh polygons from tessfaces

	mesh.update()

	# Must set normals after mesh.update() or they will be recalculated.
	mesh.vertices.foreach_set("normal", unpack_list(new_vn))

	return obj
    def write_mesh_data(self,
                        entities=None,
                        name="",
                        default_material='Material'):
        mesh_key = (name, default_material)
        if mesh_key in self.component_meshes:
            return self.component_meshes[mesh_key]
        verts = []
        faces = []
        mat_index = []
        mats = keep_offset()
        seen = keep_offset()
        uv_list = []
        alpha = False  # We assume object does not need alpha flag
        uvs_used = False  # We assume no uvs need to be added

        for f in entities.faces:

            if f.material:
                mat_number = mats[f.material.name]
            else:
                mat_number = mats[default_material]
                if default_material != 'Material':
                    f.st_scale = self.materials_scales[default_material]

            vs, tri, uvs = f.tessfaces

            mapping = {}
            for i, (v, uv) in enumerate(zip(vs, uvs)):
                l = len(seen)
                mapping[i] = seen[v]
                if len(seen) > l:
                    verts.append(v)
                uvs.append(uv)

            for face in tri:
                f0, f1, f2 = face[0], face[1], face[2]
                if mapping[f2] == 0:  ## eeekadoodle dance
                    faces.append((mapping[f2], mapping[f0], mapping[f1]))
                    uv_list.append((uvs[f2][0], uvs[f2][1], uvs[f0][0],
                                    uvs[f0][1], uvs[f1][0], uvs[f1][1], 0, 0))
                else:
                    faces.append((mapping[f0], mapping[f1], mapping[f2]))
                    uv_list.append((uvs[f0][0], uvs[f0][1], uvs[f1][0],
                                    uvs[f1][1], uvs[f2][0], uvs[f2][1], 0, 0))
                mat_index.append(mat_number)

        # verts, faces, uv_list, mat_index, mats = entities.get__triangles_lists(default_material)

        if len(verts) == 0:
            return None, False

        me = bpy.data.meshes.new(name)

        me.vertices.add(len(verts))
        me.tessfaces.add(len(faces))

        if len(mats) >= 1:
            mats_sorted = OrderedDict(sorted(mats.items(), key=lambda x: x[1]))
            for k in mats_sorted.keys():
                bmat = self.materials[k]
                me.materials.append(bmat)
                if bmat.alpha < 1.0:
                    alpha = True
                try:
                    if 'Image Texture' in bmat.node_tree.nodes.keys():
                        uvs_used = True
                except AttributeError as e:
                    uvs_used = False
        else:
            sketchupLog("WARNING OBJECT {} HAS NO MATERIAL".format(name))

        me.vertices.foreach_set("co", unpack_list(verts))
        me.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
        me.tessfaces.foreach_set("material_index", mat_index)

        if uvs_used:
            me.tessface_uv_textures.new()
            for i in range(len(faces)):
                me.tessface_uv_textures[0].data[i].uv_raw = uv_list[i]

        me.update(calc_edges=True)
        me.validate()
        self.component_meshes[mesh_key] = me, alpha
        return me, alpha
def pskimport(infile, importmesh, importbone, bDebugLogPSK,
              importmultiuvtextures):
    global DEBUGLOG
    DEBUGLOG = bDebugLogPSK
    print("--------------------------------------------------")
    print("---------SCRIPT EXECUTING PYTHON IMPORTER---------")
    print("--------------------------------------------------")
    print(" DEBUG Log:", bDebugLogPSK)
    print("Importing file: ", infile)

    pskfile = open(infile, 'rb')
    if (DEBUGLOG):
        logpath = infile.replace(".psk", ".txt")
        print("logpath:", logpath)
        logf = open(logpath, 'w')

    def printlog(strdata):
        if (DEBUGLOG):
            logf.write(strdata)

    objName = infile.split('\\')[-1].split('.')[0]

    me_ob = bpy.data.meshes.new(objName)
    print("objName:", objName)
    printlog(("New Mesh = " + me_ob.name + "\n"))
    #read general header
    indata = unpack('20s3i', pskfile.read(32))
    #not using the general header at this time
    #==================================================================================================
    # vertex point
    #==================================================================================================
    #read the PNTS0000 header
    indata = unpack('20s3i', pskfile.read(32))
    recCount = indata[3]
    printlog(("Nbr of PNTS0000 records: " + str(recCount) + "\n"))
    counter = 0
    verts = []
    verts2 = []
    while counter < recCount:
        counter = counter + 1
        indata = unpack('3f', pskfile.read(12))
        #print(indata[0], indata[1], indata[2])
        verts.extend([(indata[0], indata[1], indata[2])])
        verts2.extend([(indata[0], indata[1], indata[2])])
        #print([(indata[0], indata[1], indata[2])])
        printlog(
            str(indata[0]) + "|" + str(indata[1]) + "|" + str(indata[2]) +
            "\n")
        #Tmsh.vertices.append(NMesh.Vert(indata[0], indata[1], indata[2]))

    #==================================================================================================
    # UV
    #==================================================================================================
    #read the VTXW0000 header
    indata = unpack('20s3i', pskfile.read(32))
    recCount = indata[3]
    printlog("Nbr of VTXW0000 records: " + str(recCount) + "\n")
    counter = 0
    UVCoords = []
    #UVCoords record format = [index to PNTS, U coord, v coord]
    printlog("[index to PNTS, U coord, v coord]\n")
    while counter < recCount:
        counter = counter + 1
        indata = unpack('hhffhh', pskfile.read(16))
        UVCoords.append([indata[0], indata[2], indata[3]])
        printlog(
            str(indata[0]) + "|" + str(indata[2]) + "|" + str(indata[3]) +
            "\n")
        #print('mat index %i', indata(4))
        #print([indata[0], indata[2], indata[3]])
        #print([indata[1], indata[2], indata[3]])

    #==================================================================================================
    # Face
    #==================================================================================================
    #read the FACE0000 header
    indata = unpack('20s3i', pskfile.read(32))
    recCount = indata[3]
    printlog("Nbr of FACE0000 records: " + str(recCount) + "\n")
    #PSK FACE0000 fields: WdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp
    #associate MatIdx to an image, associate SmthGrp to a material
    SGlist = []
    counter = 0
    faces = []
    faceuv = []
    facesmooth = []
    #the psk values are: nWdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp
    printlog("nWdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp \n")
    while counter < recCount:
        counter = counter + 1
        indata = unpack('hhhbbi', pskfile.read(12))
        printlog(
            str(indata[0]) + "|" + str(indata[1]) + "|" + str(indata[2]) +
            "|" + str(indata[3]) + "|" + str(indata[4]) + "|" +
            str(indata[5]) + "\n")
        #indata[0] = index of UVCoords
        #UVCoords[indata[0]]=[index to PNTS, U coord, v coord]
        #UVCoords[indata[0]][0] = index to PNTS
        PNTSA = UVCoords[indata[2]][0]
        PNTSB = UVCoords[indata[1]][0]
        PNTSC = UVCoords[indata[0]][0]
        #print(PNTSA, PNTSB, PNTSC) #face id vertex
        #faces.extend([0, 1, 2, 0])
        faces.extend([(PNTSA, PNTSB, PNTSC, 0)])
        uv = []
        u0 = UVCoords[indata[2]][1]
        v0 = UVCoords[indata[2]][2]
        uv.append([u0, 1.0 - v0])
        u1 = UVCoords[indata[1]][1]
        v1 = UVCoords[indata[1]][2]
        uv.append([u1, 1.0 - v1])
        u2 = UVCoords[indata[0]][1]
        v2 = UVCoords[indata[0]][2]
        uv.append([u2, 1.0 - v2])
        faceuv.append([uv, indata[3], indata[4], indata[5]])

        #print("material:", indata[3])
        #print("UV: ", u0, v0)
        #update the uv var of the last item in the Tmsh.faces list
        # which is the face just added above
        ##Tmsh.faces[-1].uv = [(u0, v0), (u1, v1), (u2, v2)]
        #print("smooth:",indata[5])
        #collect a list of the smoothing groups
        facesmooth.append(indata[5])
        #print(indata[5])
        if SGlist.count(indata[5]) == 0:
            SGlist.append(indata[5])
            print("smooth:", indata[5])
        #assign a material index to the face
        #Tmsh.faces[-1].materialIndex = SGlist.index(indata[5])
    printlog("Using Materials to represent PSK Smoothing Groups...\n")
    #==========
    # skip something...
    #==========

    #==================================================================================================
    # Material
    #==================================================================================================
    ##
    #read the MATT0000 header
    indata = unpack('20s3i', pskfile.read(32))
    recCount = indata[3]
    printlog("Nbr of MATT0000 records: " + str(recCount) + "\n")
    printlog(
        " - Not importing any material data now. PSKs are texture wrapped! \n")
    counter = 0
    materialcount = 0
    while counter < recCount:
        counter = counter + 1
        indata = unpack('64s6i', pskfile.read(88))
        materialcount += 1
        print("Material", counter)
        print("Mat name %s", indata[0])

    ##
    #==================================================================================================
    # Bones (Armature)
    #==================================================================================================
    #read the REFSKEL0 header
    indata = unpack('20s3i', pskfile.read(32))
    recCount = indata[3]
    printlog("Nbr of REFSKEL0 records: " + str(recCount) + "\n")
    #REFSKEL0 fields - Name|Flgs|NumChld|PrntIdx|Qw|Qx|Qy|Qz|LocX|LocY|LocZ|Lngth|XSize|YSize|ZSize

    Bns = []
    bone = []

    md5_bones = []
    bni_dict = {}
    #==================================================================================================
    # Bone Data
    #==================================================================================================
    counter = 0
    print("---PRASE--BONES---")
    printlog(
        "Name|Flgs|NumChld|PrntIdx|Qx|Qy|Qz|Qw|LocX|LocY|LocZ|Lngth|XSize|YSize|ZSize\n"
    )
    while counter < recCount:
        indata = unpack('64s3i11f', pskfile.read(120))
        #print( "DATA",str(indata))

        bone.append(indata)

        createbone = md5_bone()
        #temp_name = indata[0][:30]
        temp_name = indata[0]
        temp_name = bytes.decode(temp_name)
        temp_name = temp_name.lstrip(" ")
        temp_name = temp_name.rstrip(" ")
        temp_name = temp_name.strip()
        temp_name = temp_name.strip(bytes.decode(b'\x00'))
        printlog(temp_name + "|" + str(indata[1]) + "|" + str(indata[2]) +
                 "|" + str(indata[3]) + "|" + str(indata[4]) + "|" +
                 str(indata[5]) + "|" + str(indata[6]) + "|" + str(indata[7]) +
                 "|" + str(indata[8]) + "|" + str(indata[9]) + "|" +
                 str(indata[10]) + "|" + str(indata[11]) + "|" +
                 str(indata[12]) + "|" + str(indata[13]) + "|" +
                 str(indata[14]) + "\n")
        createbone.name = temp_name
        createbone.bone_index = counter
        createbone.parent_index = indata[3]
        createbone.bindpos[0] = indata[8]
        createbone.bindpos[1] = indata[9]
        createbone.bindpos[2] = indata[10]
        createbone.scale[0] = indata[12]
        createbone.scale[1] = indata[13]
        createbone.scale[2] = indata[14]

        bni_dict[createbone.name] = createbone.bone_index

        #w,x,y,z
        if (counter == 0):  #main parent
            createbone.bindmat = mathutils.Quaternion(
                (indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()
            createbone.origmat = mathutils.Quaternion(
                (indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()
        else:
            createbone.bindmat = mathutils.Quaternion(
                (indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()
            createbone.origmat = mathutils.Quaternion(
                (indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()

        createbone.bindmat = mathutils.Matrix.Translation(mathutils.Vector((indata[8], indata[9], indata[10]))) * \
                             createbone.bindmat.to_4x4()

        md5_bones.append(createbone)
        counter = counter + 1
        bnstr = (str(indata[0]))
        Bns.append(bnstr)

    for pbone in md5_bones:
        pbone.parent = md5_bones[pbone.parent_index]

    for pbone in md5_bones:
        if pbone.name != pbone.parent.name:
            pbone.bindmat = pbone.parent.bindmat * pbone.bindmat
            #print(pbone.name)
            #print(pbone.bindmat)
            #print("end")
        else:
            pbone.bindmat = pbone.bindmat

    for pbone in md5_bones:
        pbone.head = getheadpos(pbone, md5_bones)

    for pbone in md5_bones:
        pbone.tail = gettailpos(pbone, md5_bones)

    for pbone in md5_bones:
        pbone.parent = md5_bones[pbone.parent_index].name

    bonecount = 0
    for armbone in bone:
        temp_name = armbone[0][:30]
        #print ("BONE NAME: ", len(temp_name))
        temp_name = str((temp_name))
        #temp_name = temp_name[1]
        #print ("BONE NAME: ", temp_name)
        bonecount += 1
    print("-------------------------")
    print("----Creating--Armature---")
    print("-------------------------")

    #================================================================================================
    #Check armature if exist if so create or update or remove all and addnew bone
    #================================================================================================
    #bpy.ops.object.mode_set(mode='OBJECT')
    meshname = "ArmObject"
    objectname = "armaturedata"
    # arm = None  # UNUSED
    if importbone:
        obj = bpy.data.objects.get(meshname)
        # arm = obj  # UNUSED

        if not obj:
            armdata = bpy.data.armatures.new(objectname)
            ob_new = bpy.data.objects.new(meshname, armdata)
            #ob_new = bpy.data.objects.new(meshname, 'ARMATURE')
            #ob_new.data = armdata
            bpy.context.collection.objects.link(ob_new)
            #bpy.ops.object.mode_set(mode='OBJECT')
            for i in bpy.context.scene.objects:
                i.select_set(False)  #deselect all objects
            ob_new.select_set(True)
            #set current armature to edit the bone
            bpy.context.view_layer.objects.active = ob_new
            #set mode to able to edit the bone
            if bpy.ops.object.mode_set.poll():
                bpy.ops.object.mode_set(mode='EDIT')

            #newbone = ob_new.data.edit_bones.new('test')
            #newbone.tail.y = 1
            print("creating bone(s)")
            bpy.ops.object.mode_set(mode='OBJECT')
            for bone in md5_bones:
                #print(dir(bone))
                bpy.ops.object.mode_set(
                    mode='EDIT')  #Go to edit mode for the bones
                newbone = ob_new.data.edit_bones.new(bone.name)
                #parent the bone
                #print("DRI:", dir(newbone))
                parentbone = None
                #note bone location is set in the real space or global not local
                bonesize = bpy.types.Scene.unrealbonesize
                if bone.name != bone.parent:
                    pos_x = bone.bindpos[0]
                    pos_y = bone.bindpos[1]
                    pos_z = bone.bindpos[2]
                    #print("LINKING:" , bone.parent ,"j")
                    parentbone = ob_new.data.edit_bones[bone.parent]
                    newbone.parent = parentbone
                    rotmatrix = bone.bindmat
                    newbone.head.x = bone.head[0]
                    newbone.head.y = bone.head[1]
                    newbone.head.z = bone.head[2]
                    newbone.tail.x = bone.tail[0]
                    newbone.tail.y = bone.tail[1]
                    newbone.tail.z = bone.tail[2]

                    vecp = parentbone.tail - parentbone.head
                    vecc = newbone.tail - newbone.head
                    vecc.normalize()
                    vecp.normalize()
                    if vecp.dot(vecc) > -0.8:
                        newbone.roll = parentbone.roll
                    else:
                        newbone.roll = -parentbone.roll
                else:
                    rotmatrix = bone.bindmat
                    newbone.head.x = bone.head[0]
                    newbone.head.y = bone.head[1]
                    newbone.head.z = bone.head[2]
                    newbone.tail.x = bone.tail[0]
                    newbone.tail.y = bone.tail[1]
                    newbone.tail.z = bone.tail[2]
                    newbone.roll = math.radians(90.0)
                """
                vec = newbone.tail - newbone.head
                if vec.z > 0.0:
                    newbone.roll = math.radians(90.0)
                else:
                    newbone.roll = math.radians(-90.0)
                """
    bpy.context.view_layer.update()

    #==================================================================================================
    #END BONE DATA BUILD
    #==================================================================================================
    VtxCol = []
    for x in range(len(Bns)):
        #change the overall darkness of each material in a range between 0.1 and 0.9
        tmpVal = ((float(x) + 1.0) / (len(Bns)) * 0.7) + 0.1
        tmpVal = int(tmpVal * 256)
        tmpCol = [tmpVal, tmpVal, tmpVal, 0]
        #Change the color of each material slightly
        if x % 3 == 0:
            if tmpCol[0] < 128:
                tmpCol[0] += 60
            else:
                tmpCol[0] -= 60
        if x % 3 == 1:
            if tmpCol[1] < 128:
                tmpCol[1] += 60
            else:
                tmpCol[1] -= 60
        if x % 3 == 2:
            if tmpCol[2] < 128:
                tmpCol[2] += 60
            else:
                tmpCol[2] -= 60
        #Add the material to the mesh
        VtxCol.append(tmpCol)

    #==================================================================================================
    # Bone Weight
    #==================================================================================================
    #read the RAWW0000 header
    indata = unpack('20s3i', pskfile.read(32))
    recCount = indata[3]
    printlog("Nbr of RAWW0000 records: " + str(recCount) + "\n")
    #RAWW0000 fields: Weight|PntIdx|BoneIdx
    RWghts = []
    counter = 0
    while counter < recCount:
        counter = counter + 1
        indata = unpack('fii', pskfile.read(12))
        RWghts.append([indata[1], indata[2], indata[0]])
        #print("weight:", [indata[1], indata[2], indata[0]])
    #RWghts fields = PntIdx|BoneIdx|Weight
    RWghts.sort()
    printlog("Vertex point and groups count =" + str(len(RWghts)) + "\n")
    printlog("PntIdx|BoneIdx|Weight")
    for vg in RWghts:
        printlog(str(vg[0]) + "|" + str(vg[1]) + "|" + str(vg[2]) + "\n")

    #Tmsh.update_tag()

    #set the Vertex Colors of the faces
    #face.v[n] = RWghts[0]
    #RWghts[1] = index of VtxCol
    """
    for x in range(len(Tmsh.faces)):
        for y in range(len(Tmsh.faces[x].v)):
            #find v in RWghts[n][0]
            findVal = Tmsh.faces[x].v[y].index
            n = 0
            while findVal != RWghts[n][0]:
                n = n + 1
            TmpCol = VtxCol[RWghts[n][1]]
            #check if a vertex has more than one influence
            if n != len(RWghts) - 1:
                if RWghts[n][0] == RWghts[n + 1][0]:
                    #if there is more than one influence, use the one with the greater influence
                    #for simplicity only 2 influences are checked, 2nd and 3rd influences are usually very small
                    if RWghts[n][2] < RWghts[n + 1][2]:
                        TmpCol = VtxCol[RWghts[n + 1][1]]
        Tmsh.faces[x].col.append(NMesh.Col(TmpCol[0], TmpCol[1], TmpCol[2], 0))
    """
    if (DEBUGLOG):
        logf.close()
    #==================================================================================================
    #Building Mesh
    #==================================================================================================
    print("vertex:", len(verts), "faces:", len(faces))
    print("vertex2:", len(verts2))
    me_ob.vertices.add(len(verts2))
    me_ob.tessfaces.add(len(faces))
    me_ob.vertices.foreach_set("co", unpack_list(verts2))
    me_ob.tessfaces.foreach_set("vertices_raw", unpack_list(faces))

    for face in me_ob.tessfaces:
        face.use_smooth = facesmooth[face.index]
    """
    Material setup coding.
    First the mesh has to be create first to get the uv texture setup working.
    -Create material(s) list in the psk pack data from the list.(to do list)
    -Append the material to the from create the mesh object.
    -Create Texture(s)
    -face loop for uv assign and assign material index
    """
    bpy.ops.object.mode_set(mode='OBJECT')
    #===================================================================================================
    #Material Setup
    #===================================================================================================
    print("-------------------------")
    print("----Creating--Materials--")
    print("-------------------------")
    materialname = "pskmat"
    materials = []

    for matcount in range(materialcount):
        #if texturedata is not None:
        matdata = bpy.data.materials.new(materialname + str(matcount))
        #mtex = matdata.texture_slots.new()
        #mtex.texture = texture[matcount].data
        #print(type(texture[matcount].data))
        #print(dir(mtex))
        #print(dir(matdata))
        #for texno in range(len( bpy.data.textures)):
        #print((bpy.data.textures[texno].name))
        #print(dir(bpy.data.textures[texno]))
        #matdata.active_texture = bpy.data.textures[matcount - 1]
        #matdata.texture_coords = 'UV'
        #matdata.active_texture = texturedata
        materials.append(matdata)

    for material in materials:
        #add material to the mesh list of materials
        me_ob.materials.append(material)
    #===================================================================================================
    #UV Setup
    #===================================================================================================
    print("-------------------------")
    print("-- Creating UV Texture --")
    print("-------------------------")
    texture = []
    # texturename = "text1"  # UNUSED
    countm = 0
    for countm in range(materialcount):
        psktexname = "psk" + str(countm)
        me_ob.uv_textures.new(name=psktexname)
        countm += 1
    print("INIT UV TEXTURE...")
    _matcount = 0
    #for mattexcount in materials:
    #print("MATERIAL ID:", _matcount)
    _textcount = 0
    for uv in me_ob.tessface_uv_textures:  # uv texture
        print("UV TEXTURE ID:", _textcount)
        print(dir(uv))
        for face in me_ob.tessfaces:  # face, uv
            #print(dir(face))
            if faceuv[face.index][
                    1] == _textcount:  #if face index and texture index matches assign it
                mfaceuv = faceuv[face.index]  #face index
                _uv1 = mfaceuv[0][0]  #(0,0)
                uv.data[face.index].uv1 = mathutils.Vector(
                    (_uv1[0], _uv1[1]))  #set them
                _uv2 = mfaceuv[0][1]  #(0,0)
                uv.data[face.index].uv2 = mathutils.Vector(
                    (_uv2[0], _uv2[1]))  #set them
                _uv3 = mfaceuv[0][2]  #(0,0)
                uv.data[face.index].uv3 = mathutils.Vector(
                    (_uv3[0], _uv3[1]))  #set them
            else:  #if not match zero them
                uv.data[face.index].uv1 = mathutils.Vector((0, 0))  #zero them
                uv.data[face.index].uv2 = mathutils.Vector((0, 0))  #zero them
                uv.data[face.index].uv3 = mathutils.Vector((0, 0))  #zero them
        _textcount += 1
        #_matcount += 1
        #print(matcount)
    print("END UV TEXTURE...")

    print("UV TEXTURE LEN:", len(texture))
    #for tex in me_ob.uv_textures:
    #print("mesh tex:", dir(tex))
    #print((tex.name))

    #for face in me_ob.faces:
    #print(dir(face))

    #===================================================================================================
    #
    #===================================================================================================
    obmesh = bpy.data.objects.new(objName, me_ob)
    #===================================================================================================
    #Mesh Vertex Group bone weight
    #===================================================================================================
    print("---- building bone weight mesh ----")
    #print(dir(ob_new.data.bones))
    #create bone vertex group #deal with bone id for index number
    for bone in ob_new.data.bones:
        #print("names:", bone.name, ":", dir(bone))
        #print("names:", bone.name)
        group = obmesh.vertex_groups.new(name=bone.name)

    for vgroup in obmesh.vertex_groups:
        #print(vgroup.name, ":", vgroup.index)
        for vgp in RWghts:
            #bone index
            if vgp[1] == bni_dict[vgroup.name]:
                #print(vgp)
                #[vertex id],weight
                vgroup.add([vgp[0]], vgp[2], 'ADD')

    #check if there is a material to set to
    if len(materials) > 0:
        obmesh.active_material = materials[0]  #material setup tmp
    print("---- adding mesh to the scene ----")

    bpy.ops.object.mode_set(mode='OBJECT')
    #bpy.ops.object.select_pattern(extend=True, pattern=obmesh.name, case_sensitive=True)
    #bpy.ops.object.select_pattern(extend=True, pattern=ob_new.name, case_sensitive=True)

    #bpy.ops.object.select_name(name=str(obmesh.name))
    #bpy.ops.object.select_name(name=str(ob_new.name))
    #bpy.context.scene.objects.active = ob_new
    me_ob.update()
    bpy.context.collection.objects.link(obmesh)
    bpy.context.view_layer.update()
    obmesh.select_set(False)
    ob_new.select_set(False)
    obmesh.select_set(True)
    ob_new.select_set(True)
    bpy.ops.object.parent_set(type="ARMATURE")

    print("PSK2Blender completed")
Example #44
0
def create_mesh(sobj, use_smooth_groups, fore_is_y, import_textures):
    """Takes a submodel and adds a Blender mesh."""
    m = sobj.get_mesh()
    
    if fore_is_y:
        m.flip_yz()

    me = bpy.data.meshes.new("{}-mesh".format(sobj.name.decode()))

    vert_list = m.verts
    face_list = m.faces
    me.vertices.add(len(vert_list))
    me.vertices.foreach_set('co', unpack_list(vert_list))
    me.tessfaces.add(len(face_list))
    me.tessfaces.foreach_set('vertices_raw', unpack_face_list(face_list))

    invisible_faces = 0

    if import_textures:
        m.flip_v()
        uvtex = me.tessface_uv_textures.new()
        uvtex.name = me.name
        for n, tf in enumerate(m.uv):
            uv_data = uvtex.data[n]
            uv_data.uv1 = tf[0]
            uv_data.uv2 = tf[1]
            uv_data.uv3 = tf[2]
            if len(tf) == 4:
                uv_data.uv4 = tf[3]
            if m.tex_ids[n] is not None:
                tex_slot = import_textures[m.tex_ids[n]].texture_slots[0]
            else:
                tex_slot = None
            if tex_slot is not None:
                uv_data.image = tex_slot.texture.image
            else:
                invisible_faces += 1
        for mat in import_textures:
            me.materials.append(mat)
        for i, f in enumerate(me.tessfaces):
            if m.tex_ids[n] is not None:
                f.material_index = m.tex_ids[i]
        uvtex.active = True
        uvtex.active_render = True

    # index edges in a dict by a frozenset of the vert coords
    # that way we don't have to worry about messed up indicies when
    # adding the seams for smoothgroups (an edge might be [v1, v2] or [v2, v1])
    me.update(calc_edges=True)
    if use_smooth_groups:
        m.calc_sharp()
        for e in me.edges:
            v1 = tuple(me.vertices[e.vertices[0]].co)
            v2 = tuple(me.vertices[e.vertices[1]].co)
            this_edge = (v1, v2)
            this_edge = frozenset(this_edge)
            e.use_edge_sharp = m.edges[this_edge]
        for f in me.polygons:
            f.use_smooth = True

    bobj = bpy.data.objects.new("Mesh", me)
    bobj['POF model id'] = sobj.model_id
    bobj.name = sobj.name.decode()
    if use_smooth_groups:
        bobj.modifiers.new("POF smoothing", "EDGE_SPLIT")
    if invisible_faces > 2 * (len(me.polygons) / 3):
        bobj.draw_type = 'WIRE'
        
    return bobj
Example #45
0
def build_model2(mod,**kwargs):

    default_materials()

    oname = mod.filename.replace('.mesh','.000')
    mname = oname+'.'+'mesh'

    ps = mod.pset.ps
    us = mod.uset.ps

    mats = ['generic','concrete1','grass2']
    fs_lookup = {}
    for fmx in range(len(mats)):
        fs_lookup[mats[fmx]] = fmx

    for gfx in mod.gfxmeshes:
        faces = [f for f in gfx.faces if not f is None]
        face_mats = [fs_lookup[gfx.fs_mats[f][1]] for f in faces]
        oloc = (0,0,0)

        #mesh = mesh_from_data(mname,ps,us,faces,face_mats,mats)
        #def mesh_from_data(name,ps,us,faces,face_mats,mats):

        mesh = bpy.data.meshes.new(mname)
        if not mats is None:
            [mesh.materials.append(materials[ma]) for ma in mats]
        mesh.vertices.add(len(ps))
        mesh.vertices.foreach_set('co',unpack_list(ps))
        mesh.tessfaces.add(len(faces))
        mesh.tessfaces.foreach_set('vertices_raw',unpack_face_list(faces))
        mesh.tessfaces.foreach_set('material_index',face_mats)
        mesh.tessface_uv_textures.new()
        for fdx in range(len(faces)):
            fa = faces[fdx]
            mesh.tessface_uv_textures[0].data[fdx].uv1 = tuple(us[fa[0]])[:-1]
            mesh.tessface_uv_textures[0].data[fdx].uv2 = tuple(us[fa[1]])[:-1]
            mesh.tessface_uv_textures[0].data[fdx].uv3 = tuple(us[fa[2]])[:-1]
        mesh.update()




    '''#
    faces = mod.gfxmeshes[0].faces
    face_mats = [fs_lookup[mod.gfxmeshes[0].fs_mats[f]] for f in faces]
    #face_mats = [0]*len(faces)
    #mats = ['generic']
    oloc = (0,0,0)

    #mesh = mesh_from_data(mname,ps,us,faces,face_mats,mats)
    #def mesh_from_data(name,ps,us,faces,face_mats,mats):

    mesh = bpy.data.meshes.new(mname)
    if not mats is None:
        [mesh.materials.append(materials[ma]) for ma in mats]
    mesh.vertices.add(len(ps))
    mesh.vertices.foreach_set('co',unpack_list(ps))
    mesh.tessfaces.add(len(faces))
    mesh.tessfaces.foreach_set('vertices_raw',unpack_face_list(faces))
    mesh.tessfaces.foreach_set('material_index',face_mats)
    mesh.tessface_uv_textures.new()
    for fdx in range(len(faces)):
        fa = faces[fdx]
        mesh.tessface_uv_textures[0].data[fdx].uv1 = tuple(us[fa[0]])[:-1]
        mesh.tessface_uv_textures[0].data[fdx].uv2 = tuple(us[fa[1]])[:-1]
        mesh.tessface_uv_textures[0].data[fdx].uv3 = tuple(us[fa[2]])[:-1]
    mesh.update()
    '''#



    obj = object_from_mesh(oname,mesh,oloc,mats)
    object_to_scene(obj)
    return obj
Example #46
0
def load(operator, context, filepath,
         global_clamp_size=0.0,
         use_verbose=False,
         dump_first_only=False,
         use_uv_map=True,
         use_diffuse_texture=True,
         use_normal_texture=True,
         use_specular_texture=True,         
         use_computed_normals=False,
         use_shadeless=True,
         viz_normals=True,
         viz_blendweights=False,
         use_specular=True,
         global_matrix=None,
         use_debug_bones=False
         ):
    '''
    Called by the user interface or another script.
    load_obj(path) - should give acceptable results.
    This function passes the file and sends the data off
        to be split into objects and then converted into mesh objects
    '''
    print('\nimporting crf %r' % filepath)

    filepath = os.fsencode(filepath)

    if global_matrix is None:
        global_matrix = mathutils.Matrix()

    new_objects = []  # put new objects here
    
    time_main = time.time()
    print("\tparsing crf file...")
    time_sub = time.time()

    file = open(filepath, "rb")
    CRF = CRF_object()    
    CRF.parse_bin(file)
    meshfile = CRF.meshfile

    bad_vertex_list = []
    
    # start importing meshes
    for i in range(0, meshfile.num_meshes):
        verts_loc = []
        verts_tex0 = []
        verts_tex1 = []
        faces = []  # tuples of the faces
        face_tex = [] # tuples of uv coordinates for faces
        vertex_normals = []
        vertex_specular = []
        vertex_blendweights1 = []        
        
        mesh = meshfile.meshes[i]
        faces = mesh.face_list
        
        #convert from DirectX to Blender face vertex ordering
        bad_mesh_vertex_list = []
        for i in range(0, len(faces)):
            v1,v2,v3 = faces[i]
            # if there are duplicated vertices in triangle, delete that face by making all vertices the same
            if v1 == v2 or v1 == v3 or v2 == v3:
                print("Found a bad face %i, eliminating %i,%i,%i" % (i,v1,v2,v3))
                faces[i] = (v3,v3,v3)
                bad_mesh_vertex_list.append(v1)
                bad_mesh_vertex_list.append(v2)
                bad_mesh_vertex_list.append(v3)
            else:
                faces[i] = (v3,v2,v1)
        bad_vertex_list.append(bad_mesh_vertex_list)
        
        for vertex in mesh.vertices0:
            verts_loc.append( (vertex.x_blend, vertex.y_blend, vertex.z_blend) )            
            verts_tex0.append( (vertex.u0_blend, vertex.v0_blend) )        

            vertex_normals.append( (vertex.normal_x_blend, vertex.normal_y_blend, vertex.normal_z_blend, vertex.normal_w_blend) )
            vertex_specular.append( (vertex.specular_red_blend, vertex.specular_green_blend, vertex.specular_blue_blend, vertex.specular_alpha_blend) )
            vertex_blendweights1.append( (vertex.blendweights1_x_blend, vertex.blendweights1_y_blend, vertex.blendweights1_z_blend, vertex.blendweights1_w_blend) )
        
        # deselect all
        if bpy.ops.object.select_all.poll():
            bpy.ops.object.select_all(action='DESELECT')

        # create blender mesh
        me = bpy.data.meshes.new("Dumped_Mesh")   # create a new mesh
        object_name = os.path.splitext(os.path.basename(filepath))[0]
        ob = bpy.data.objects.new(os.fsdecode(object_name) + "_%i" % mesh.mesh_number, me)
        # Fill the mesh with verts, edges, faces
        me.vertices.add(len(verts_loc))
        me.vertices.foreach_set("co", unpack_list(verts_loc))
        me.tessfaces.add(len(faces))
        me.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
        
        
        # use computed normals
        if use_computed_normals:
            for vertex, vertex_normal in zip(me.vertices, vertex_normals):
                print("vertex index", vertex.index, vertex_normal)
                vertex.normal = vertex_normal[0:3]
                
        # fill face uv texture array
        for face in ob.data.tessfaces:
            verts_in_face = face.vertices[:]
            if use_verbose:
                print("face index", face.index)  
                print("normal", face.normal)  
                for vert in verts_in_face:  
                    print("vert", vert, " vert co", ob.data.vertices[vert].co)
                    print("Normal X:%s Y:%s Z:%s " % (vertex_normals[vert][0], vertex_normals[vert][1], vertex_normals[vert][2]))
                    print("specular R:%s G:%s B:%s " % (vertex_specular[vert][0], vertex_specular[vert][1], vertex_specular[vert][2]))
                    print("UV0: ", verts_tex0[vert])
                    print()
            i = face.index
            v1 = verts_in_face[0]
            v2 = verts_in_face[1]
            v3 = verts_in_face[2]
            face_tex.append([ verts_tex0[v1], verts_tex0[v2], verts_tex0[v3] ]) 
        
        # start all optional tasks        
        # add uv map
        if use_uv_map:
            uvMain = createTextureLayer("UV_Main", me, face_tex)

        # add texture
        if use_diffuse_texture or use_normal_texture or use_specular_texture:
            # create a material to which textures can be added
            mat = createMaterial('TexMat', use_shadeless, viz_normals)
            if use_diffuse_texture:
                diffuse_texture = mesh.materials.diffuse_texture            
                diffuse_texture_filepath = findTextureFile(os.fsdecode(filepath),  diffuse_texture.decode(sys.stdout.encoding))
                print("Adding diffuse texture ", diffuse_texture_filepath)        
                if diffuse_texture_filepath != None and diffuse_texture_filepath != "":
                    addDiffuseTexture(diffuse_texture_filepath, mat)
                    mat.use_transparency = True
                    mat.alpha = 0 #TODO check model data for this param
            if use_normal_texture:
                normal_texture = mesh.materials.normal_texture            
                normal_texture_filepath = findTextureFile(os.fsdecode(filepath),  normal_texture.decode(sys.stdout.encoding))
                print("Adding normals texture ", normal_texture_filepath)        
                if normal_texture_filepath != None and normal_texture_filepath != "":
                    addNormalTexture(normal_texture_filepath, mat)
            if use_specular_texture:
                specular_texture = mesh.materials.specular_texture            
                specular_texture_filepath = findTextureFile(os.fsdecode(filepath),  specular_texture.decode(sys.stdout.encoding))
                print("Adding normals texture ", specular_texture_filepath)        
                if specular_texture_filepath != None and specular_texture_filepath != "":
                    addSpecularTexture(specular_texture_filepath, mat)                            
            ob.data.materials.append(mat)

        # viz normals
                
        # add specular constant
        if use_specular:
            vertex_specular = []
            for vertex in mesh.vertices0:
                vertex_specular.append((vertex.specular_red_blend, vertex.specular_green_blend, vertex.specular_blue_blend, vertex.specular_alpha_blend))
                
            setVertexSpecularColors(me, ob.data.tessfaces, vertex_specular)
            # if no materials exist, create one+
            if len(ob.data.materials) == 0:
                mat = createMaterial('Specular', use_shadeless, viz_normals)
                mat.specular_color = mesh.materials.specular_constant
                ob.data.materials.append(mat)
            else:
                if mesh.materials.specular_constant != None:
                    ob.data.materials[0].specular_color = mesh.materials.specular_constant
                else:
                    ob.data.materials[0].specular_color = (1, 0, 0)
                    print("Failed to find specular constnat! FIXME")
                print(ob.data.materials[0].specular_color)
                      
        # viz blendweights
        
        # end all optional tasks
        
        me.update(calc_tessface=True, calc_edges=True)
        new_objects.append(ob)
    # end loop for importing meshes
    
    # import bones, create armature    
    if CRF.footer.get_jointmap() != None:                
        amt = bpy.data.armatures.new("Armature")
        amt_ob = bpy.data.objects.new("Armature", amt)
        scn = bpy.context.scene
        scn.objects.link(amt_ob)
        scn.objects.active = amt_ob
        amt_ob.select = True
        
        bpy.ops.object.mode_set(mode='EDIT')        
        make_skel(amt, CRF.jointmap, 0)

        if use_debug_bones:
            for key,value in CRF.jointmap.bone_dict.items():
                crf_joint = CRF.jointmap.joint_list[key]
                m = bone_transform(crf_joint.matrix)
                print("Bone %i\n" % key, m, "parent", crf_joint.parent_id)            
                bpy.ops.mesh.primitive_uv_sphere_add(size=0.1, location=(0,0,0))
                bpy.context.object.matrix_world = m
                bpy.context.object.name = "joint_%s_%s" % (key, CRF.jointmap.bone_dict[key].bone_name)
               
        bpy.ops.object.mode_set(mode='OBJECT')
        amt_ob.select = False
        
            
    time_new = time.time()
    print("%.4f sec" % (time_new - time_sub))
    time_sub = time_new

    print('\tloading materials and images...')


    time_new = time.time()
    print("%.4f sec" % (time_new - time_sub))
    time_sub = time_new
    
    # Create new obj
    scene = context.scene    
    for ob,bad_vertices in zip(new_objects,bad_vertex_list):
        base = scene.objects.link(ob)
        base.select = True

        # we could apply this anywhere before scaling.
        ob.matrix_world = global_matrix
        
        #delete bad vertices
        bpy.context.scene.objects.active = ob 
        ob.select = True
        bpy.ops.object.mode_set(mode='EDIT')
        bpy.ops.mesh.select_all(action='DESELECT')
        bpy.ops.object.mode_set(mode='OBJECT')
        for v in bad_vertices:
            print("Deleting vertex %i in %s" % (v, ob.name))
            ob.data.vertices[v].select = True        
        bpy.ops.object.mode_set(mode='EDIT')        
        bpy.ops.mesh.delete(type='VERT')
        bpy.ops.object.mode_set(mode='OBJECT')

    if CRF.footer.get_jointmap() != None:
        #select objects, select armature as active, parent objects to armature      
        bpy.ops.object.select_all(action='DESELECT') #deselect all object        
        for ob in new_objects:
            print("in loop ", ob)
            ob.select = True
        bpy.context.scene.objects.active = amt_ob    #the active object will be the parent of all selected object
        bpy.ops.object.parent_set(type='ARMATURE_NAME')

        # print all vertex groups for each object
        #for ob in new_objects:
        #    print(ob.vertex_groups.keys())
        #for ob in new_objects:
        #    for v in ob.data.vertices:
        #        print("number of groups", len(v.groups))

        obj_id = 0
        for ob in new_objects:
            if len(CRF.meshfile.meshes[obj_id].vertices1) != 0:
                for v in ob.data.vertices:                
                    CRF.meshfile.meshes[obj_id].vertices1[v.index].raw2blend() # convert 
                    blendindices = CRF.meshfile.meshes[obj_id].vertices1[v.index].blendindices
                    blendweights = CRF.meshfile.meshes[obj_id].vertices1[v.index].blendweights_blend
                    """
                    try:
                        pos  = blendindices.index(CRF.jointmap.bone_name_id_dict[b"Bone01_L_Forearm"])
                        blendindices = [blendindices[pos]+1]
                        blendweights = [1.0]
                    except ValueError:
                        blendindices = []
                        blendindices = []
                    """
                    
                    #print(blendindices, blendweights)
                    for bi,bw in zip(blendindices, blendweights):
                        #print("Assign vertex %s group %s with weight %s" % (v.index, bi, bw))
                        new_objects[obj_id].vertex_groups[bi].add([v.index], bw, 'ADD')
            obj_id+=1                    
 
    scene.update()

    axis_min = [1000000000] * 3
    axis_max = [-1000000000] * 3

    if global_clamp_size:
        # Get all object bounds
        for ob in new_objects:
            for v in ob.bound_box:
                for axis, value in enumerate(v):
                    if axis_min[axis] > value:
                        axis_min[axis] = value
                    if axis_max[axis] < value:
                        axis_max[axis] = value

        # Scale objects
        max_axis = max(axis_max[0] - axis_min[0], axis_max[1] - axis_min[1], axis_max[2] - axis_min[2])
        scale = 1.0

        while global_clamp_size < max_axis * scale:
            scale = scale / 10.0

        for obj in new_objects:
            obj.scale = scale, scale, scale

    time_new = time.time()    
    print("finished importing: %r in %.4f sec." % (filepath, (time_new - time_main)))
    return {'FINISHED'}
def pskimport(infile,importmesh,importbone,bDebugLogPSK,importmultiuvtextures):
    global DEBUGLOG
    DEBUGLOG = bDebugLogPSK
    print ("--------------------------------------------------")
    print ("---------SCRIPT EXECUTING PYTHON IMPORTER---------")
    print ("--------------------------------------------------")
    print (" DEBUG Log:",bDebugLogPSK)
    print ("Importing file: ", infile)

    pskfile = open(infile,'rb')
    if (DEBUGLOG):
        logpath = infile.replace(".psk", ".txt")
        print("logpath:",logpath)
        logf = open(logpath,'w')

    def printlog(strdata):
        if (DEBUGLOG):
            logf.write(strdata)

    objName = infile.split('\\')[-1].split('.')[0]

    me_ob = bpy.data.meshes.new(objName)
    print("objName:",objName)
    printlog(("New Mesh = " + me_ob.name + "\n"))
    #read general header
    indata = unpack('20s3i', pskfile.read(32))
    #not using the general header at this time
    #==================================================================================================
    # vertex point
    #==================================================================================================
    #read the PNTS0000 header
    indata = unpack('20s3i', pskfile.read(32))
    recCount = indata[3]
    printlog(("Nbr of PNTS0000 records: " + str(recCount) + "\n"))
    counter = 0
    verts = []
    verts2 = []
    while counter < recCount:
        counter = counter + 1
        indata = unpack('3f', pskfile.read(12))
        #print(indata[0], indata[1], indata[2])
        verts.extend([(indata[0], indata[1], indata[2])])
        verts2.extend([(indata[0], indata[1], indata[2])])
        #print([(indata[0], indata[1], indata[2])])
        printlog(str(indata[0]) + "|" + str(indata[1]) + "|" + str(indata[2]) + "\n")
        #Tmsh.vertices.append(NMesh.Vert(indata[0], indata[1], indata[2]))

    #==================================================================================================
    # UV
    #==================================================================================================
    #read the VTXW0000 header
    indata = unpack('20s3i', pskfile.read(32))
    recCount = indata[3]
    printlog("Nbr of VTXW0000 records: " + str(recCount)+ "\n")
    counter = 0
    UVCoords = []
    #UVCoords record format = [index to PNTS, U coord, v coord]
    printlog("[index to PNTS, U coord, v coord]\n");
    while counter < recCount:
        counter = counter + 1
        indata = unpack('hhffhh', pskfile.read(16))
        UVCoords.append([indata[0], indata[2], indata[3]])
        printlog(str(indata[0]) + "|" + str(indata[2]) + "|" + str(indata[3]) + "\n")
        #print('mat index %i', indata(4))
        #print([indata[0], indata[2], indata[3]])
        #print([indata[1], indata[2], indata[3]])

    #==================================================================================================
    # Face
    #==================================================================================================
    #read the FACE0000 header
    indata = unpack('20s3i', pskfile.read(32))
    recCount = indata[3]
    printlog("Nbr of FACE0000 records: " + str(recCount) + "\n")
    #PSK FACE0000 fields: WdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp
    #associate MatIdx to an image, associate SmthGrp to a material
    SGlist = []
    counter = 0
    faces = []
    faceuv = []
    facesmooth = []
    #the psk values are: nWdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp
    printlog("nWdgIdx1|WdgIdx2|WdgIdx3|MatIdx|AuxMatIdx|SmthGrp \n")
    while counter < recCount:
        counter = counter + 1
        indata = unpack('hhhbbi', pskfile.read(12))
        printlog(str(indata[0]) + "|" + str(indata[1]) + "|" + str(indata[2]) + "|" + str(indata[3]) + "|" +
                 str(indata[4]) + "|" + str(indata[5]) + "\n")
        #indata[0] = index of UVCoords
        #UVCoords[indata[0]]=[index to PNTS, U coord, v coord]
        #UVCoords[indata[0]][0] = index to PNTS
        PNTSA = UVCoords[indata[2]][0]
        PNTSB = UVCoords[indata[1]][0]
        PNTSC = UVCoords[indata[0]][0]
        #print(PNTSA, PNTSB, PNTSC) #face id vertex
        #faces.extend([0, 1, 2, 0])
        faces.extend([(PNTSA, PNTSB, PNTSC, 0)])
        uv = []
        u0 = UVCoords[indata[2]][1]
        v0 = UVCoords[indata[2]][2]
        uv.append([u0, 1.0 - v0])
        u1 = UVCoords[indata[1]][1]
        v1 = UVCoords[indata[1]][2]
        uv.append([u1, 1.0 - v1])
        u2 = UVCoords[indata[0]][1]
        v2 = UVCoords[indata[0]][2]
        uv.append([u2, 1.0 - v2])
        faceuv.append([uv, indata[3], indata[4], indata[5]])

        #print("material:", indata[3])
        #print("UV: ", u0, v0)
        #update the uv var of the last item in the Tmsh.faces list
        # which is the face just added above
        ##Tmsh.faces[-1].uv = [(u0, v0), (u1, v1), (u2, v2)]
        #print("smooth:",indata[5])
        #collect a list of the smoothing groups
        facesmooth.append(indata[5])
        #print(indata[5])
        if SGlist.count(indata[5]) == 0:
            SGlist.append(indata[5])
            print("smooth:", indata[5])
        #assign a material index to the face
        #Tmsh.faces[-1].materialIndex = SGlist.index(indata[5])
    printlog("Using Materials to represent PSK Smoothing Groups...\n")
    #==========
    # skip something...
    #==========

    #==================================================================================================
    # Material
    #==================================================================================================
    ##
    #read the MATT0000 header
    indata = unpack('20s3i', pskfile.read(32))
    recCount = indata[3]
    printlog("Nbr of MATT0000 records: " +  str(recCount) + "\n" )
    printlog(" - Not importing any material data now. PSKs are texture wrapped! \n")
    counter = 0
    materialcount = 0
    while counter < recCount:
        counter = counter + 1
        indata = unpack('64s6i', pskfile.read(88))
        materialcount += 1
        print("Material", counter)
        print("Mat name %s", indata[0])

    ##
    #==================================================================================================
    # Bones (Armature)
    #==================================================================================================
    #read the REFSKEL0 header
    indata = unpack('20s3i', pskfile.read(32))
    recCount = indata[3]
    printlog( "Nbr of REFSKEL0 records: " + str(recCount) + "\n")
    #REFSKEL0 fields - Name|Flgs|NumChld|PrntIdx|Qw|Qx|Qy|Qz|LocX|LocY|LocZ|Lngth|XSize|YSize|ZSize

    Bns = []
    bone = []

    md5_bones = []
    bni_dict = {}
    #==================================================================================================
    # Bone Data
    #==================================================================================================
    counter = 0
    print ("---PRASE--BONES---")
    printlog("Name|Flgs|NumChld|PrntIdx|Qx|Qy|Qz|Qw|LocX|LocY|LocZ|Lngth|XSize|YSize|ZSize\n")
    while counter < recCount:
        indata = unpack('64s3i11f', pskfile.read(120))
        #print( "DATA",str(indata))

        bone.append(indata)

        createbone = md5_bone()
        #temp_name = indata[0][:30]
        temp_name = indata[0]
        temp_name = bytes.decode(temp_name)
        temp_name = temp_name.lstrip(" ")
        temp_name = temp_name.rstrip(" ")
        temp_name = temp_name.strip()
        temp_name = temp_name.strip( bytes.decode(b'\x00'))
        printlog(temp_name + "|" + str(indata[1]) + "|" + str(indata[2]) + "|" + str(indata[3]) + "|" +
                 str(indata[4]) + "|" + str(indata[5]) + "|" + str(indata[6]) + "|" + str(indata[7]) + "|" +
                 str(indata[8]) + "|" + str(indata[9]) + "|" + str(indata[10]) + "|" + str(indata[11]) + "|" +
                 str(indata[12]) + "|" + str(indata[13]) + "|" + str(indata[14]) + "\n")
        createbone.name = temp_name
        createbone.bone_index = counter
        createbone.parent_index = indata[3]
        createbone.bindpos[0] = indata[8]
        createbone.bindpos[1] = indata[9]
        createbone.bindpos[2] = indata[10]
        createbone.scale[0] = indata[12]
        createbone.scale[1] = indata[13]
        createbone.scale[2] = indata[14]

        bni_dict[createbone.name] = createbone.bone_index

        #w,x,y,z
        if (counter == 0):#main parent
             createbone.bindmat = mathutils.Quaternion((indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()
             createbone.origmat = mathutils.Quaternion((indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()
        else:
             createbone.bindmat = mathutils.Quaternion((indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()
             createbone.origmat = mathutils.Quaternion((indata[7], -indata[4], -indata[5], -indata[6])).to_matrix()

        createbone.bindmat = mathutils.Matrix.Translation(mathutils.Vector((indata[8], indata[9], indata[10]))) * \
                             createbone.bindmat.to_4x4()

        md5_bones.append(createbone)
        counter = counter + 1
        bnstr = (str(indata[0]))
        Bns.append(bnstr)

    for pbone in md5_bones:
        pbone.parent = md5_bones[pbone.parent_index]

    for pbone in md5_bones:
        if pbone.name != pbone.parent.name:
            pbone.bindmat = pbone.parent.bindmat * pbone.bindmat
            #print(pbone.name)
            #print(pbone.bindmat)
            #print("end")
        else:
            pbone.bindmat = pbone.bindmat

    for pbone in md5_bones:
        pbone.head = getheadpos(pbone, md5_bones)

    for pbone in md5_bones:
        pbone.tail = gettailpos(pbone, md5_bones)

    for pbone in md5_bones:
        pbone.parent =  md5_bones[pbone.parent_index].name

    bonecount = 0
    for armbone in bone:
        temp_name = armbone[0][:30]
        #print ("BONE NAME: ", len(temp_name))
        temp_name=str((temp_name))
        #temp_name = temp_name[1]
        #print ("BONE NAME: ", temp_name)
        bonecount += 1
    print ("-------------------------")
    print ("----Creating--Armature---")
    print ("-------------------------")

    #================================================================================================
    #Check armature if exist if so create or update or remove all and addnew bone
    #================================================================================================
    #bpy.ops.object.mode_set(mode='OBJECT')
    meshname ="ArmObject"
    objectname = "armaturedata"
    # arm = None  # UNUSED
    if importbone:
        obj = bpy.data.objects.get(meshname)
        # arm = obj  # UNUSED

        if not obj:
            armdata = bpy.data.armatures.new(objectname)
            ob_new = bpy.data.objects.new(meshname, armdata)
            #ob_new = bpy.data.objects.new(meshname, 'ARMATURE')
            #ob_new.data = armdata
            bpy.context.scene.objects.link(ob_new)
            #bpy.ops.object.mode_set(mode='OBJECT')
            for i in bpy.context.scene.objects:
                i.select = False #deselect all objects
            ob_new.select = True
            #set current armature to edit the bone
            bpy.context.scene.objects.active = ob_new
            #set mode to able to edit the bone
            if bpy.ops.object.mode_set.poll():
                bpy.ops.object.mode_set(mode='EDIT')

            #newbone = ob_new.data.edit_bones.new('test')
            #newbone.tail.y = 1
            print("creating bone(s)")
            bpy.ops.object.mode_set(mode='OBJECT')
            for bone in md5_bones:
                #print(dir(bone))
                bpy.ops.object.mode_set(mode='EDIT')#Go to edit mode for the bones
                newbone = ob_new.data.edit_bones.new(bone.name)
                #parent the bone
                #print("DRI:", dir(newbone))
                parentbone = None
                #note bone location is set in the real space or global not local
                bonesize = bpy.types.Scene.unrealbonesize
                if bone.name != bone.parent:
                    pos_x = bone.bindpos[0]
                    pos_y = bone.bindpos[1]
                    pos_z = bone.bindpos[2]
                    #print("LINKING:" , bone.parent ,"j")
                    parentbone = ob_new.data.edit_bones[bone.parent]
                    newbone.parent = parentbone
                    rotmatrix = bone.bindmat
                    newbone.head.x = bone.head[0]
                    newbone.head.y = bone.head[1]
                    newbone.head.z = bone.head[2]
                    newbone.tail.x = bone.tail[0]
                    newbone.tail.y = bone.tail[1]
                    newbone.tail.z = bone.tail[2]

                    vecp = parentbone.tail - parentbone.head
                    vecc = newbone.tail - newbone.head
                    vecc.normalize()
                    vecp.normalize()
                    if vecp.dot(vecc) > -0.8:
                        newbone.roll = parentbone.roll
                    else:
                        newbone.roll = - parentbone.roll
                else:
                    rotmatrix = bone.bindmat
                    newbone.head.x = bone.head[0]
                    newbone.head.y = bone.head[1]
                    newbone.head.z = bone.head[2]
                    newbone.tail.x = bone.tail[0]
                    newbone.tail.y = bone.tail[1]
                    newbone.tail.z = bone.tail[2]
                    newbone.roll = math.radians(90.0)
                """
                vec = newbone.tail - newbone.head
                if vec.z > 0.0:
                    newbone.roll = math.radians(90.0)
                else:
                    newbone.roll = math.radians(-90.0)
                """
    bpy.context.scene.update()

    #==================================================================================================
    #END BONE DATA BUILD
    #==================================================================================================
    VtxCol = []
    for x in range(len(Bns)):
        #change the overall darkness of each material in a range between 0.1 and 0.9
        tmpVal = ((float(x) + 1.0) / (len(Bns)) * 0.7) + 0.1
        tmpVal = int(tmpVal * 256)
        tmpCol = [tmpVal, tmpVal, tmpVal, 0]
        #Change the color of each material slightly
        if x % 3 == 0:
            if tmpCol[0] < 128:
                tmpCol[0] += 60
            else:
                tmpCol[0] -= 60
        if x % 3 == 1:
            if tmpCol[1] < 128:
                tmpCol[1] += 60
            else:
                tmpCol[1] -= 60
        if x % 3 == 2:
            if tmpCol[2] < 128:
                tmpCol[2] += 60
            else:
                tmpCol[2] -= 60
        #Add the material to the mesh
        VtxCol.append(tmpCol)

    #==================================================================================================
    # Bone Weight
    #==================================================================================================
    #read the RAWW0000 header
    indata = unpack('20s3i', pskfile.read(32))
    recCount = indata[3]
    printlog("Nbr of RAWW0000 records: " + str(recCount) +"\n")
    #RAWW0000 fields: Weight|PntIdx|BoneIdx
    RWghts = []
    counter = 0
    while counter < recCount:
        counter = counter + 1
        indata = unpack('fii', pskfile.read(12))
        RWghts.append([indata[1], indata[2], indata[0]])
        #print("weight:", [indata[1], indata[2], indata[0]])
    #RWghts fields = PntIdx|BoneIdx|Weight
    RWghts.sort()
    printlog("Vertex point and groups count =" + str(len(RWghts)) + "\n")
    printlog("PntIdx|BoneIdx|Weight")
    for vg in RWghts:
        printlog(str(vg[0]) + "|" + str(vg[1]) + "|" + str(vg[2]) + "\n")

    #Tmsh.update_tag()

    #set the Vertex Colors of the faces
    #face.v[n] = RWghts[0]
    #RWghts[1] = index of VtxCol
    """
    for x in range(len(Tmsh.faces)):
        for y in range(len(Tmsh.faces[x].v)):
            #find v in RWghts[n][0]
            findVal = Tmsh.faces[x].v[y].index
            n = 0
            while findVal != RWghts[n][0]:
                n = n + 1
            TmpCol = VtxCol[RWghts[n][1]]
            #check if a vertex has more than one influence
            if n != len(RWghts) - 1:
                if RWghts[n][0] == RWghts[n + 1][0]:
                    #if there is more than one influence, use the one with the greater influence
                    #for simplicity only 2 influences are checked, 2nd and 3rd influences are usually very small
                    if RWghts[n][2] < RWghts[n + 1][2]:
                        TmpCol = VtxCol[RWghts[n + 1][1]]
        Tmsh.faces[x].col.append(NMesh.Col(TmpCol[0], TmpCol[1], TmpCol[2], 0))
    """
    if (DEBUGLOG):
        logf.close()
    #==================================================================================================
    #Building Mesh
    #==================================================================================================
    print("vertex:", len(verts), "faces:", len(faces))
    print("vertex2:", len(verts2))
    me_ob.vertices.add(len(verts2))
    me_ob.tessfaces.add(len(faces))
    me_ob.vertices.foreach_set("co", unpack_list(verts2))
    me_ob.tessfaces.foreach_set("vertices_raw", unpack_list( faces))

    for face in me_ob.tessfaces:
        face.use_smooth = facesmooth[face.index]

    """
    Material setup coding.
    First the mesh has to be create first to get the uv texture setup working.
    -Create material(s) list in the psk pack data from the list.(to do list)
    -Append the material to the from create the mesh object.
    -Create Texture(s)
    -face loop for uv assign and assign material index
    """
    bpy.ops.object.mode_set(mode='OBJECT')
    #===================================================================================================
    #Material Setup
    #===================================================================================================
    print ("-------------------------")
    print ("----Creating--Materials--")
    print ("-------------------------")
    materialname = "pskmat"
    materials = []

    for matcount in range(materialcount):
        #if texturedata is not None:
        matdata = bpy.data.materials.new(materialname + str(matcount))
        #mtex = matdata.texture_slots.new()
        #mtex.texture = texture[matcount].data
        #print(type(texture[matcount].data))
        #print(dir(mtex))
        #print(dir(matdata))
        #for texno in range(len( bpy.data.textures)):
            #print((bpy.data.textures[texno].name))
            #print(dir(bpy.data.textures[texno]))
        #matdata.active_texture = bpy.data.textures[matcount - 1]
        #matdata.texture_coords = 'UV'
        #matdata.active_texture = texturedata
        materials.append(matdata)

    for material in materials:
        #add material to the mesh list of materials
        me_ob.materials.append(material)
    #===================================================================================================
    #UV Setup
    #===================================================================================================
    print ("-------------------------")
    print ("-- Creating UV Texture --")
    print ("-------------------------")
    texture = []
    # texturename = "text1"  # UNUSED
    countm = 0
    for countm in range(materialcount):
        psktexname = "psk" + str(countm)
        me_ob.uv_textures.new(name=psktexname)
        countm += 1
    print("INIT UV TEXTURE...")
    _matcount = 0
    #for mattexcount in materials:
        #print("MATERAIL ID:", _matcount)
    _textcount = 0
    for uv in me_ob.tessface_uv_textures: # uv texture
        print("UV TEXTURE ID:",_textcount)
        print(dir(uv))
        for face in me_ob.tessfaces:# face, uv
            #print(dir(face))
            if faceuv[face.index][1] == _textcount: #if face index and texture index matches assign it
                mfaceuv = faceuv[face.index] #face index
                _uv1 = mfaceuv[0][0] #(0,0)
                uv.data[face.index].uv1 = mathutils.Vector((_uv1[0], _uv1[1])) #set them
                _uv2 = mfaceuv[0][1] #(0,0)
                uv.data[face.index].uv2 = mathutils.Vector((_uv2[0], _uv2[1])) #set them
                _uv3 = mfaceuv[0][2] #(0,0)
                uv.data[face.index].uv3 = mathutils.Vector((_uv3[0], _uv3[1])) #set them
            else: #if not match zero them
                uv.data[face.index].uv1 = mathutils.Vector((0, 0)) #zero them
                uv.data[face.index].uv2 = mathutils.Vector((0, 0)) #zero them
                uv.data[face.index].uv3 = mathutils.Vector((0, 0)) #zero them
        _textcount += 1
        #_matcount += 1
        #print(matcount)
    print("END UV TEXTURE...")

    print("UV TEXTURE LEN:", len(texture))
        #for tex in me_ob.uv_textures:
            #print("mesh tex:", dir(tex))
            #print((tex.name))

    #for face in me_ob.faces:
        #print(dir(face))

    #===================================================================================================
    #
    #===================================================================================================
    obmesh = bpy.data.objects.new(objName,me_ob)
    #===================================================================================================
    #Mesh Vertex Group bone weight
    #===================================================================================================
    print("---- building bone weight mesh ----")
    #print(dir(ob_new.data.bones))
    #create bone vertex group #deal with bone id for index number
    for bone in ob_new.data.bones:
        #print("names:", bone.name, ":", dir(bone))
        #print("names:", bone.name)
        group = obmesh.vertex_groups.new(bone.name)

    for vgroup in obmesh.vertex_groups:
        #print(vgroup.name, ":", vgroup.index)
        for vgp in RWghts:
            #bone index
            if vgp[1] == bni_dict[vgroup.name]:
                #print(vgp)
                #[vertex id],weight
                vgroup.add([vgp[0]], vgp[2], 'ADD')

    #check if there is a material to set to
    if len(materials) > 0:
        obmesh.active_material = materials[0] #material setup tmp
    print("---- adding mesh to the scene ----")

    bpy.ops.object.mode_set(mode='OBJECT')
    #bpy.ops.object.select_pattern(extend=True, pattern=obmesh.name, case_sensitive=True)
    #bpy.ops.object.select_pattern(extend=True, pattern=ob_new.name, case_sensitive=True)

    #bpy.ops.object.select_name(name=str(obmesh.name))
    #bpy.ops.object.select_name(name=str(ob_new.name))
    #bpy.context.scene.objects.active = ob_new
    me_ob.update()
    bpy.context.scene.objects.link(obmesh)
    bpy.context.scene.update()
    obmesh.select = False
    ob_new.select = False
    obmesh.select = True
    ob_new.select = True
    bpy.ops.object.parent_set(type="ARMATURE")

    print ("PSK2Blender completed")
	def build_blender_data(self, blender_context):
		from mdl_node_bone import MDL_NODE_BONE
		import bpy
		from bpy_extras.io_utils import unpack_list, unpack_face_list
		from bpy_extras.image_utils import load_image

		super(MDL_NODE_VOLUMEVIEW, self).build_blender_data(blender_context)

		if self.ply:
			print(type(self).__name__ + ".build_blender_data()")

			bone_name = None
			naterial_node = None
			diffuse_node = None

			parent_node = self.parent

			# Get parents bone name
			while True:
				# Check if we found a bone node
				if type(parent_node) == MDL_NODE_BONE:
					bone_name = parent_node.bone_name
					break
				# Check if we reached the root node without finding a bone node
				elif parent_node == None:
					raise Exception("No parent bone node found")
				# Otherwise get the next parent
				else:
					parent_node = parent_node.parent

			# Create a new mesh with our parents bone name
			self.blender_mesh = bpy.data.meshes.new(bone_name)

			# Load vertices data into the mesh
			self.blender_mesh.vertices.add(len(self.ply.positions))
			self.blender_mesh.vertices.foreach_set("co", unpack_list(self.ply.positions))

			# Load face data into the mesh
			self.blender_mesh.tessfaces.add(len(self.ply.indices))
			self.blender_mesh.tessfaces.foreach_set("vertices", unpack_list(self.ply.indices))

			# Validate mesh
			self.blender_mesh.validate()

			# Update mesh
			self.blender_mesh.update(calc_edges=True)

			# Create a new UV layer
			self.blender_mesh.uv_textures.new()

			# Get the mesh UV layer
			uv_layer = self.blender_mesh.uv_layers.active

			# Process all faces of the mesh
			for face in self.blender_mesh.polygons:
				# Process all loops of the mesh
				for loop_index in face.loop_indices:
					# Use loop_index to get to the actual loop and then get the vertex index from it
					vertex_index = self.blender_mesh.loops[loop_index].vertex_index
					# With the vertex index, append the UV data from that vertex to the UV array
					uv_layer.data[loop_index].uv = self.ply.UVs[vertex_index]

			# Create blender object
			ob = bpy.data.objects.new(name=bone_name, object_data=self.blender_mesh)
			parent_node.blender_object_name = ob.name

			# Create the vertex groups
			for mesh in self.ply.meshes:
				vg = ob.vertex_groups.new(name=bone_name+'#'+mesh.material_file)
				vg.add(mesh.indices, 1.0, 'ADD')

			# Find material child nodes
			for material in self.nodes:
				if type(material) == MDL_NODE_MATERIAL:
					# Find texture child nodes
					for texture in material.nodes:
						if type(texture) == MDL_NODE_DIFFUSE:
							# Create a material
							mat = bpy.data.materials.new(name=bone_name+'#'+material.material_file)
							# Add the material to the object
							ob.data.materials.append(mat)
							# Create a texture
							tex = bpy.data.textures.new(name=bone_name+'#'+texture.texturename, type="IMAGE")
							# Apply image to the texture
							tex.image = texture.blender_images[texture.texturename]
							# Create a new texture slot inside the material
							tex_slot = mat.texture_slots.add()
							# Add the texture to the newly created slot
							tex_slot.texture = tex
Example #49
0
	def makeObject(self):
		print("Creating mesh", end='')
		# Create the mesh
		mesh = bpy.data.meshes.new(self.name)

		# Prepare vertices and faces
		mesh.vertices.add(self.numVerts)
		mesh.tessfaces.add(self.numTris)
		print('.', end='')

		# Verts
		mesh.vertices.foreach_set("co", unpack_list(self.frames[0]))
		mesh.transform(Matrix.Rotation(-pi / 2, 4, 'Z'))
		print('.', end='')

		# Tris
		mesh.tessfaces.foreach_set("vertices_raw", unpack_face_list([face[0] for face in self.tris]))
		print('.', end='')

		# Skins
		mesh.tessface_uv_textures.new()
		if self.numSkins > 0:
			material = bpy.data.materials.new(self.name)
			for skin in self.skins:
				skinImg = Util.loadImage(skin, self.filePath)
				if skinImg == None:
					skinImg = bpy.data.images.new(os.path.join(self.filePath, skin), self.skinWidth, self.skinHeight)
				skinImg.mapping = 'UV'
				skinImg.name = skin
				skinTex = bpy.data.textures.new(self.name + skin, type='IMAGE')
				skinTex.image = skinImg
				matTex = material.texture_slots.add()
				matTex.texture = skinTex
				matTex.texture_coords = 'UV'
				matTex.use_map_color_diffuse = True
				matTex.use_map_alpha = True
				matTex.uv_layer = mesh.tessface_uv_textures[0].name
			mesh.materials.append(material)
		print('.', end='')

		# UV
		mesh.tessface_uv_textures[0].data.foreach_set("uv_raw", unpack_list([self.uvs[i] for i in unpack_face_list([face[1] for face in self.tris])]))
		if self.numSkins > 0:
			image = mesh.materials[0].texture_slots[0].texture.image
			if image != None:
				for uv in mesh.tessface_uv_textures[0].data:
					uv.image = image
		print('.', end='')

		mesh.validate()
		mesh.update()
		obj = bpy.data.objects.new(mesh.name, mesh)
		base = bpy.context.scene.objects.link(obj)
		bpy.context.scene.objects.active = obj
		base.select = True
		print("Done")

		# Animate
		if self.options.fImportAnimation and self.numFrames > 1:
			for i, frame in enumerate(self.frames):
				progressStatus = i / self.numFrames * 100
				#bpy.context.scene.frame_set(i + 1)
				obj.shape_key_add(from_mix=False)
				mesh.vertices.foreach_set("co", unpack_list(frame))
				mesh.transform(Matrix.Rotation(-pi / 2, 4, 'Z'))
				mesh.shape_keys.key_blocks[i].value = 1.0
				mesh.shape_keys.key_blocks[i].keyframe_insert("value", frame=i + 1)
				if i < len(self.frames) - 1:
					mesh.shape_keys.key_blocks[i].value = 0.0
					mesh.shape_keys.key_blocks[i].keyframe_insert("value", frame=i + 2)
				if i > 0:
					mesh.shape_keys.key_blocks[i].value = 0.0
					mesh.shape_keys.key_blocks[i].keyframe_insert("value", frame=i)
				print("Animating - progress: %3i%%\r" % int(progressStatus), end='')
			print("Animating - progress: 100%.")

		bpy.context.scene.update()
		print("Model imported")
def create_mesh(new_objects,
                has_ngons,
                use_ngons,
                use_edges,
                verts_loc,
                verts_tex,
                faces,
                unique_materials,
                unique_material_images,
                unique_smooth_groups,
                vertex_groups,
                dataname,
                ):
    """
    Takes all the data gathered and generates a mesh, adding the new object to new_objects
    deals with ngons, sharp edges and assigning materials
    """
    from bpy_extras.mesh_utils import ngon_tessellate

    if not has_ngons:
        use_ngons = False

    if unique_smooth_groups:
        sharp_edges = {}
        smooth_group_users = {context_smooth_group: {} for context_smooth_group in list(unique_smooth_groups.keys())}
        context_smooth_group_old = -1

    # Split ngons into tri's
    fgon_edges = set()  # Used for storing fgon keys
    if use_edges:
        edges = []

    context_object = None

    # reverse loop through face indices
    for f_idx in range(len(faces) - 1, -1, -1):

        (face_vert_loc_indices,
         face_vert_tex_indices,
         context_material,
         context_smooth_group,
         context_object,
         ) = faces[f_idx]

        len_face_vert_loc_indices = len(face_vert_loc_indices)

        if len_face_vert_loc_indices == 1:
            faces.pop(f_idx)  # cant add single vert faces

        elif not face_vert_tex_indices or len_face_vert_loc_indices == 2:  # faces that have no texture coords are lines
            if use_edges:
                # generators are better in python 2.4+ but can't be used in 2.3
                # edges.extend( (face_vert_loc_indices[i], face_vert_loc_indices[i+1]) for i in xrange(len_face_vert_loc_indices-1) )
                edges.extend([(face_vert_loc_indices[i], face_vert_loc_indices[i + 1]) for i in range(len_face_vert_loc_indices - 1)])

            faces.pop(f_idx)
        else:

            # Smooth Group
            if unique_smooth_groups and context_smooth_group:
                # Is a part of of a smooth group and is a face
                if context_smooth_group_old is not context_smooth_group:
                    edge_dict = smooth_group_users[context_smooth_group]
                    context_smooth_group_old = context_smooth_group

                for i in range(len_face_vert_loc_indices):
                    i1 = face_vert_loc_indices[i]
                    i2 = face_vert_loc_indices[i - 1]
                    if i1 > i2:
                        i1, i2 = i2, i1

                    try:
                        edge_dict[i1, i2] += 1
                    except KeyError:
                        edge_dict[i1, i2] = 1

            # NGons into triangles
            if has_ngons and len_face_vert_loc_indices > 4:

                ngon_face_indices = ngon_tessellate(verts_loc, face_vert_loc_indices)
                faces.extend([([face_vert_loc_indices[ngon[0]],
                                face_vert_loc_indices[ngon[1]],
                                face_vert_loc_indices[ngon[2]],
                                ],
                               [face_vert_tex_indices[ngon[0]],
                                face_vert_tex_indices[ngon[1]],
                                face_vert_tex_indices[ngon[2]],
                                ],
                               context_material,
                               context_smooth_group,
                               context_object,
                              )
                             for ngon in ngon_face_indices]
                            )

                # edges to make ngons
                if use_ngons:
                    edge_users = {}
                    for ngon in ngon_face_indices:
                        for i in (0, 1, 2):
                            i1 = face_vert_loc_indices[ngon[i]]
                            i2 = face_vert_loc_indices[ngon[i - 1]]
                            if i1 > i2:
                                i1, i2 = i2, i1

                            try:
                                edge_users[i1, i2] += 1
                            except KeyError:
                                edge_users[i1, i2] = 1

                    for key, users in edge_users.items():
                        if users > 1:
                            fgon_edges.add(key)

                # remove all after 3, means we dont have to pop this one.
                faces.pop(f_idx)

    # Build sharp edges
    if unique_smooth_groups:
        for edge_dict in list(smooth_group_users.values()):
            for key, users in list(edge_dict.items()):
                if users == 1:  # This edge is on the boundry of a group
                    sharp_edges[key] = None

    # map the material names to an index
    material_mapping = {name: i for i, name in enumerate(unique_materials)}  # enumerate over unique_materials keys()

    materials = [None] * len(unique_materials)

    for name, index in list(material_mapping.items()):
        materials[index] = unique_materials[name]

    me = bpy.data.meshes.new(dataname.decode('utf-8', "replace"))

    # make sure the list isnt too big
    for material in materials:
        me.materials.append(material)

    me.vertices.add(len(verts_loc))
    me.tessfaces.add(len(faces))

    # verts_loc is a list of (x, y, z) tuples
    me.vertices.foreach_set("co", unpack_list(verts_loc))

    # faces is a list of (vert_indices, texco_indices, ...) tuples
    # XXX faces should contain either 3 or 4 verts
    # XXX no check for valid face indices
    me.tessfaces.foreach_set("vertices_raw", unpack_face_list([f[0] for f in faces]))

    if verts_tex and me.tessfaces:
        me.tessface_uv_textures.new()

    context_material_old = -1  # avoid a dict lookup
    mat = 0  # rare case it may be un-initialized.
    me_faces = me.tessfaces

    for i, face in enumerate(faces):
        if len(face[0]) < 2:
            pass  # raise "bad face"
        elif len(face[0]) == 2:
            if use_edges:
                edges.append(face[0])
        else:

            blender_face = me.tessfaces[i]

            (face_vert_loc_indices,
             face_vert_tex_indices,
             context_material,
             context_smooth_group,
             context_object,
             ) = face

            if context_smooth_group:
                blender_face.use_smooth = True

            if context_material:
                if context_material_old is not context_material:
                    mat = material_mapping[context_material]
                    context_material_old = context_material

                blender_face.material_index = mat
#                blender_face.mat= mat

            if verts_tex:

                blender_tface = me.tessface_uv_textures[0].data[i]

                if context_material:
                    image = unique_material_images[context_material]
                    if image:  # Can be none if the material dosnt have an image.
                        blender_tface.image = image

                # BUG - Evil eekadoodle problem where faces that have vert index 0 location at 3 or 4 are shuffled.
                if len(face_vert_loc_indices) == 4:
                    if face_vert_loc_indices[2] == 0 or face_vert_loc_indices[3] == 0:
                        face_vert_tex_indices = face_vert_tex_indices[2], face_vert_tex_indices[3], face_vert_tex_indices[0], face_vert_tex_indices[1]
                else:  # length of 3
                    if face_vert_loc_indices[2] == 0:
                        face_vert_tex_indices = face_vert_tex_indices[1], face_vert_tex_indices[2], face_vert_tex_indices[0]
                # END EEEKADOODLE FIX

                # assign material, uv's and image
                blender_tface.uv1 = verts_tex[face_vert_tex_indices[0]]
                blender_tface.uv2 = verts_tex[face_vert_tex_indices[1]]
                blender_tface.uv3 = verts_tex[face_vert_tex_indices[2]]

                if len(face_vert_loc_indices) == 4:
                    blender_tface.uv4 = verts_tex[face_vert_tex_indices[3]]

#                for ii, uv in enumerate(blender_face.uv):
#                    uv.x, uv.y=  verts_tex[face_vert_tex_indices[ii]]
    del me_faces
#     del ALPHA

    if use_edges and not edges:
        use_edges = False

    if use_edges:
        me.edges.add(len(edges))

        # edges should be a list of (a, b) tuples
        me.edges.foreach_set("vertices", unpack_list(edges))
#         me_edges.extend( edges )

#     del me_edges

    # Add edge faces.
#     me_edges= me.edges

    def edges_match(e1, e2):
        return (e1[0] == e2[0] and e1[1] == e2[1]) or (e1[0] == e2[1] and e1[1] == e2[0])

    me.validate()
    me.update(calc_edges=use_edges)

    if unique_smooth_groups and sharp_edges:
        import bmesh
        bm = bmesh.new()
        bm.from_mesh(me)
        # to avoid slow iterator lookups later / indexing verts is slow in bmesh
        bm_verts = bm.verts[:]

        for sharp_edge in sharp_edges.keys():
            vert1 = bm_verts[sharp_edge[0]]
            vert2 = bm_verts[sharp_edge[1]]
            if vert1 != vert2:
                edge = bm.edges.get((vert1, vert2))
                if edge is not None:
                    me.edges[edge.index].use_edge_sharp = True

        bm.free()
        del bm

    mesh_untessellate(me, fgon_edges)

    # XXX slow
#     if unique_smooth_groups and sharp_edges:
#         for sharp_edge in sharp_edges.keys():
#             for ed in me.edges:
#                 if edges_match(sharp_edge, ed.vertices):
#                     ed.use_edge_sharp = True

#     if unique_smooth_groups and sharp_edges:
#         SHARP= Mesh.EdgeFlags.SHARP
#         for ed in me.findEdges( sharp_edges.keys() ):
#             if ed is not None:
#                 me_edges[ed].flag |= SHARP
#         del SHARP

    ob = bpy.data.objects.new(me.name, me)
    new_objects.append(ob)

    # Create the vertex groups. No need to have the flag passed here since we test for the
    # content of the vertex_groups. If the user selects to NOT have vertex groups saved then
    # the following test will never run
    for group_name, group_indices in vertex_groups.items():
        group = ob.vertex_groups.new(group_name.decode('utf-8', "replace"))
        group.add(group_indices, 1.0, 'REPLACE')
Example #51
0
def create_mesh(new_objects,
                use_edges,
                verts_loc,
                verts_nor,
                verts_tex,
                faces,
                unique_materials,
                unique_material_images,
                unique_smooth_groups,
                vertex_groups,
                dataname,
                ):
    """
    Takes all the data gathered and generates a mesh, adding the new object to new_objects
    deals with ngons, sharp edges and assigning materials
    """

    if unique_smooth_groups:
        sharp_edges = set()
        smooth_group_users = {context_smooth_group: {} for context_smooth_group in unique_smooth_groups.keys()}
        context_smooth_group_old = -1

    fgon_edges = set()  # Used for storing fgon keys when we need to tesselate/untesselate them (ngons with hole).
    edges = []
    tot_loops = 0

    context_object = None

    # reverse loop through face indices
    for f_idx in range(len(faces) - 1, -1, -1):
        (face_vert_loc_indices,
         face_vert_nor_indices,
         face_vert_tex_indices,
         context_material,
         context_smooth_group,
         context_object,
         face_invalid_blenpoly,
         ) = faces[f_idx]

        len_face_vert_loc_indices = len(face_vert_loc_indices)

        if len_face_vert_loc_indices == 1:
            faces.pop(f_idx)  # cant add single vert faces

        # Face with a single item in face_vert_nor_indices is actually a polyline!
        elif len(face_vert_nor_indices) == 1 or len_face_vert_loc_indices == 2:
            if use_edges:
                edges.extend((face_vert_loc_indices[i], face_vert_loc_indices[i + 1])
                             for i in range(len_face_vert_loc_indices - 1))
            faces.pop(f_idx)

        else:
            # Smooth Group
            if unique_smooth_groups and context_smooth_group:
                # Is a part of of a smooth group and is a face
                if context_smooth_group_old is not context_smooth_group:
                    edge_dict = smooth_group_users[context_smooth_group]
                    context_smooth_group_old = context_smooth_group

                prev_vidx = face_vert_loc_indices[-1]
                for vidx in face_vert_loc_indices:
                    edge_key = (prev_vidx, vidx) if (prev_vidx < vidx) else (vidx, prev_vidx)
                    prev_vidx = vidx
                    edge_dict[edge_key] = edge_dict.get(edge_key, 0) + 1

            # NGons into triangles
            if face_invalid_blenpoly:
                from bpy_extras.mesh_utils import ngon_tessellate
                ngon_face_indices = ngon_tessellate(verts_loc, face_vert_loc_indices)
                faces.extend([([face_vert_loc_indices[ngon[0]],
                                face_vert_loc_indices[ngon[1]],
                                face_vert_loc_indices[ngon[2]],
                                ],
                               [face_vert_nor_indices[ngon[0]],
                                face_vert_nor_indices[ngon[1]],
                                face_vert_nor_indices[ngon[2]],
                                ] if face_vert_nor_indices else [],
                               [face_vert_tex_indices[ngon[0]],
                                face_vert_tex_indices[ngon[1]],
                                face_vert_tex_indices[ngon[2]],
                                ] if face_vert_tex_indices else [],
                               context_material,
                               context_smooth_group,
                               context_object,
                               [],
                               )
                             for ngon in ngon_face_indices]
                             )
                tot_loops += 3 * len(ngon_face_indices)

                # edges to make ngons
                edge_users = set()
                for ngon in ngon_face_indices:
                    prev_vidx = face_vert_loc_indices[ngon[-1]]
                    for ngidx in ngon:
                        vidx = face_vert_loc_indices[ngidx]
                        if vidx == prev_vidx:
                            continue  # broken OBJ... Just skip.
                        edge_key = (prev_vidx, vidx) if (prev_vidx < vidx) else (vidx, prev_vidx)
                        prev_vidx = vidx
                        if edge_key in edge_users:
                            fgon_edges.add(edge_key)
                        else:
                            edge_users.add(edge_key)

                faces.pop(f_idx)
            else:
                tot_loops += len_face_vert_loc_indices

    # Build sharp edges
    if unique_smooth_groups:
        for edge_dict in smooth_group_users.values():
            for key, users in edge_dict.items():
                if users == 1:  # This edge is on the boundry of a group
                    sharp_edges.add(key)

    # map the material names to an index
    material_mapping = {name: i for i, name in enumerate(unique_materials)}  # enumerate over unique_materials keys()

    materials = [None] * len(unique_materials)

    for name, index in material_mapping.items():
        materials[index] = unique_materials[name]

    me = bpy.data.meshes.new(dataname)

    # make sure the list isnt too big
    for material in materials:
        me.materials.append(material)

    me.vertices.add(len(verts_loc))
    me.loops.add(tot_loops)
    me.polygons.add(len(faces))

    # verts_loc is a list of (x, y, z) tuples
    me.vertices.foreach_set("co", unpack_list(verts_loc))

    loops_vert_idx = []
    faces_loop_start = []
    faces_loop_total = []
    lidx = 0
    for f in faces:
        vidx = f[0]
        nbr_vidx = len(vidx)
        loops_vert_idx.extend(vidx)
        faces_loop_start.append(lidx)
        faces_loop_total.append(nbr_vidx)
        lidx += nbr_vidx

    me.loops.foreach_set("vertex_index", loops_vert_idx)
    me.polygons.foreach_set("loop_start", faces_loop_start)
    me.polygons.foreach_set("loop_total", faces_loop_total)

    if verts_nor and me.loops:
        # Note: we store 'temp' normals in loops, since validate() may alter final mesh,
        #       we can only set custom lnors *after* calling it.
        me.create_normals_split()

    if verts_tex and me.polygons:
        me.uv_textures.new()

    context_material_old = -1  # avoid a dict lookup
    mat = 0  # rare case it may be un-initialized.

    for i, (face, blen_poly) in enumerate(zip(faces, me.polygons)):
        if len(face[0]) < 3:
            raise Exception("bad face")  # Shall not happen, we got rid of those earlier!

        (face_vert_loc_indices,
         face_vert_nor_indices,
         face_vert_tex_indices,
         context_material,
         context_smooth_group,
         context_object,
         face_invalid_blenpoly,
         ) = face

        if context_smooth_group:
            blen_poly.use_smooth = True

        if context_material:
            if context_material_old is not context_material:
                mat = material_mapping[context_material]
                context_material_old = context_material
            blen_poly.material_index = mat

        if verts_nor and face_vert_nor_indices:
            for face_noidx, lidx in zip(face_vert_nor_indices, blen_poly.loop_indices):
                me.loops[lidx].normal[:] = verts_nor[0 if (face_noidx is ...) else face_noidx]

        if verts_tex and face_vert_tex_indices:
            if context_material:
                image = unique_material_images[context_material]
                if image:  # Can be none if the material dosnt have an image.
                    me.uv_textures[0].data[i].image = image

            blen_uvs = me.uv_layers[0]
            for face_uvidx, lidx in zip(face_vert_tex_indices, blen_poly.loop_indices):
                blen_uvs.data[lidx].uv = verts_tex[0 if (face_uvidx is ...) else face_uvidx]

    use_edges = use_edges and bool(edges)
    if use_edges:
        me.edges.add(len(edges))
        # edges should be a list of (a, b) tuples
        me.edges.foreach_set("vertices", unpack_list(edges))

    me.validate(clean_customdata=False)  # *Very* important to not remove lnors here!
    me.update(calc_edges=use_edges)

    # Un-tessellate as much as possible, in case we had to triangulate some ngons...
    if fgon_edges:
        import bmesh
        bm = bmesh.new()
        bm.from_mesh(me)
        verts = bm.verts[:]
        get = bm.edges.get
        edges = [get((verts[vidx1], verts[vidx2])) for vidx1, vidx2 in fgon_edges]
        try:
            bmesh.ops.dissolve_edges(bm, edges=edges, use_verts=False)
        except:
            # Possible dissolve fails for some edges, but don't fail silently in case this is a real bug.
            import traceback
            traceback.print_exc()

        bm.to_mesh(me)
        bm.free()

    # XXX If validate changes the geometry, this is likely to be broken...
    if unique_smooth_groups and sharp_edges:
        for e in me.edges:
            if e.key in sharp_edges:
                e.use_edge_sharp = True
        me.show_edge_sharp = True

    if verts_nor:
        clnors = array.array('f', [0.0] * (len(me.loops) * 3))
        me.loops.foreach_get("normal", clnors)

        if not unique_smooth_groups:
            me.polygons.foreach_set("use_smooth", [True] * len(me.polygons))

        me.normals_split_custom_set(tuple(zip(*(iter(clnors),) * 3)))
        me.use_auto_smooth = True
        me.show_edge_sharp = True

    ob = bpy.data.objects.new(me.name, me)
    new_objects.append(ob)

    # Create the vertex groups. No need to have the flag passed here since we test for the
    # content of the vertex_groups. If the user selects to NOT have vertex groups saved then
    # the following test will never run
    for group_name, group_indices in vertex_groups.items():
        group = ob.vertex_groups.new(group_name.decode('utf-8', "replace"))
        group.add(group_indices, 1.0, 'REPLACE')
def read_scm():
    global xy_to_xz_transform
    global scm_filepath  # [0] both [1] path [2] name
    global sca_filepath  # [0] both [1] path [2] name

    print("=== LOADING Sup Com Model ===")
    print("")

    #global counter
    #
    #if (counter < 10):
    #
    #    bpy.utils.unregister_class(SimpleOperator)
    #    SimpleOperator.bl_label = "toto"+str(counter)
    #    bpy.utils.register_class(SimpleOperator)
    #
    #    bpy.ops.object.simple_operator('INVOKE_DEFAULT')
    #
    #    return
    #

    #xy_to_xz_transform.resize_4x4()
    #bpy.ops.object.mode_set(mode='OBJECT')
    #scene = Blender.Scene.GetCurrent()
    scene = bpy.context.scene
    mesh = scm_mesh()

    if (mesh.load(scm_filepath[0]) == None):
        print('Failed to load %s' % scm_filepath[2])
        my_popup('Failed to load %s' % scm_filepath[2])
        return

    #ProgBarLSCM = ProgressBar( "Imp: load SCM", (2*len(mesh.vertices) + len(mesh.faces)))

    armature_name = scm_filepath[2].rstrip(".scm")
    print("armature ", armature_name)

    ###        CREATE ARMATURE
    armData = bpy.data.armatures.new(armature_name)
    armData.show_axes = True

    armObj = bpy.data.objects.new(armature_name, armData)

    scene.objects.link(armObj)
    scene.objects.active = armObj
    armObj.select = True
    armObj.show_x_ray = True

    bpy.ops.object.mode_set(mode='EDIT')

    for index in range(len(mesh.bones)):
        #print('boneIndex',index)
        bone = mesh.bones[index]
        #print('boneName',bone.name)

        blender_bone = armData.edit_bones.new(bone.name)

        #not nice parent may not exist,  but usualy should exist (depends on storing in scm)
        if (bone.parent != 0):
            blender_bone.parent = armData.edit_bones[bone.parent.name]

        t_matrix = bone.rel_mat * xy_to_xz_transform
        loc, rot, sca = t_matrix.transposed().decompose()
        blender_bone.head = loc
        blender_bone.tail = (rot.to_matrix() * Vector(
            (0, 1, 0))) + blender_bone.head
        blender_bone.matrix = t_matrix.transposed()

    bpy.ops.object.mode_set(mode='OBJECT')

    meshData = bpy.data.meshes.new('Mesh')

    #add verts
    vertlist = []
    for vert in mesh.vertices:
        #ProgBarLSCM.do()
        vertlist.append(Vector(vert.position) * xy_to_xz_transform)

    meshData.vertices.add(len(vertlist))
    meshData.tessfaces.add(len(mesh.faces))
    meshData.vertices.foreach_set("co", unpack_list(vertlist))
    meshData.tessfaces.foreach_set("vertices_raw", unpack_list(mesh.faces))

    print(len(meshData.tessfaces))

    meshData.uv_textures.new(name='UVMap')

    for uv in meshData.tessface_uv_textures:  # uv texture
        print(uv)
        for face in meshData.tessfaces:  # face, uv
            uv1 = mesh.vertices[mesh.faces[face.index][0]].uv1
            uv.data[face.index].uv1 = Vector((uv1[0], 1.0 - uv1[1]))
            uv1 = mesh.vertices[mesh.faces[face.index][1]].uv1
            uv.data[face.index].uv2 = Vector((uv1[0], 1.0 - uv1[1]))
            uv1 = mesh.vertices[mesh.faces[face.index][2]].uv1
            uv.data[face.index].uv3 = Vector((uv1[0], 1.0 - uv1[1]))

    mesh_obj = bpy.data.objects.new('Mesh', meshData)
    scene.objects.link(mesh_obj)
    scene.objects.active = mesh_obj
    mesh_obj.select = True

    meshData.update()

    #assigns vertex groups #mesh must be in object
    for bone in mesh.bones:
        mesh_obj.vertex_groups.new(bone.name)

    for vgroup in mesh_obj.vertex_groups:
        #print(vgroup.name, ":", vgroup.index)
        for vertex_index in range(len(mesh.vertices)):
            #bone index
            vertex = mesh.vertices[vertex_index]
            bone_index = vertex.bone_index[0]
            boneName = mesh.bones[bone_index].name
            if boneName == vgroup.name:
                vgroup.add([vertex_index], 1.0, 'ADD')

    meshData.update()

    bpy.context.scene.update()

    bpy.ops.object.select_all(action='DESELECT')

    mesh_obj.select = False
    armObj.select = False

    #armObj.select = True
    mesh_obj.select = True
    armObj.select = True
    scene.objects.active = armObj
    bpy.ops.object.parent_set(type="ARMATURE")

    if len(mesh.info):
        print("=== INFO ===")
        for info in mesh.info:
            print("", info)

    print("=== COMPLETE ===")

    global globMesh
    globMesh = mesh
Example #53
0
def CriaBezierUnidoTeethDef(self, context):

    context = bpy.context
    obj = context.active_object
    scn = context.scene

    Pontos = [
        obj for obj in bpy.context.scene.objects
        if fnmatch.fnmatchcase(obj.name, "PT_Linh*")
    ]

    coords = []

    for i in Pontos:
        VetorAtual = i.location
        VetX = i.location[0]
        VetY = i.location[1]
        VetZ = i.location[2]
        coords.append((VetX, VetY, VetZ))


#    edges = []

#    for i in range(len(vertices)):
#        edges.append([i,i+1])

#    del(edges[-1]) # Apaga o Ășltimo elemento da cena

# create the Curve Datablock
    curveData = bpy.data.curves.new('myCurve', type='CURVE')
    curveData.dimensions = '3D'
    #    curveData.resolution_u = 6
    curveData.resolution_u = 36

    # map coords to spline
    polyline = curveData.splines.new('BEZIER')
    polyline.bezier_points.add(len(coords) - 1)
    #    for i, coord in enumerate(coords):
    #        x,y,z = coord
    #        polyline.points[i].co = (x, y, z, 1)

    from bpy_extras.io_utils import unpack_list
    polyline.bezier_points.foreach_set("co", unpack_list(coords))

    # Apaga pontos
    bpy.ops.object.select_all(action='DESELECT')

    for i in Pontos:
        i.select_set(True)

    bpy.ops.object.delete(use_global=False)

    # Cria Linha
    curveOB = bpy.data.objects.new('myCurve', curveData)

    # attach to scene and validate context
    scn = bpy.context.scene
    #   scn.objects.link(curveOB)
    scn.collection.objects.link(curveOB)
    bpy.ops.object.select_all(action='DESELECT')
    bpy.context.view_layer.objects.active = curveOB
    curveOB.select_set(True)

    bpy.ops.object.editmode_toggle()
    bpy.ops.curve.select_all(action='SELECT')
    bpy.ops.curve.handle_type_set(type='AUTOMATIC')

    bpy.ops.curve.make_segment()

    bpy.ops.object.editmode_toggle()

    bpy.ops.object.modifier_add(type='SHRINKWRAP')
    bpy.context.object.modifiers["Shrinkwrap"].target = obj
    bpy.context.object.modifiers["Shrinkwrap"].offset = 0.01  # ORIGINAL 0.01
    bpy.context.object.modifiers["Shrinkwrap"].wrap_mode = 'ABOVE_SURFACE'
    bpy.ops.object.modifier_apply(apply_as='DATA', modifier="Shrinkwrap")

    #    bpy.ops.object.modifier_add(type='SMOOTH')
    #    bpy.context.object.modifiers["Smooth"].factor = 2
    #    bpy.context.object.modifiers["Smooth"].iterations = 3

    bpy.context.object.data.bevel_depth = 0.2

    ListaMateriais = []
    MateriaisCena = bpy.data.materials

    for i in MateriaisCena:
        ListaMateriais.append(i.name)

    if 'MatModalPoints' in ListaMateriais:
        activeObject = bpy.context.active_object  #Set active object to variable
        mat = bpy.data.materials[
            "MatModalPointsTeeth"]  #set new material to variable
        activeObject.data.materials.append(
            mat)  #add the material to the object
        bpy.context.object.active_material.diffuse_color = (0.2, 0.2, 0.9, 1)
    else:
        activeObject = bpy.context.active_object  #Set active object to variable
        mat = bpy.data.materials.new(
            name="MatModalPointsTeeth")  #set new material to variable
        activeObject.data.materials.append(
            mat)  #add the material to the object
        bpy.context.object.active_material.diffuse_color = (0.2, 0.2, 0.9, 1)

    bpy.ops.object.select_all(action='DESELECT')
    obj.select_set(True)
    bpy.context.view_layer.objects.active = obj
Example #54
0
def CriaBezierUnidoDef(self, context):

    context = bpy.context
    obj = context.active_object
    scn = context.scene

    Pontos = [
        obj for obj in bpy.context.scene.objects
        if fnmatch.fnmatchcase(obj.name, "PT_Linh*")
    ]

    coords = []

    for i in Pontos:
        VetorAtual = i.location
        VetX = i.location[0]
        VetY = i.location[1]
        VetZ = i.location[2]
        coords.append((VetX, VetY, VetZ))


#    edges = []

#    for i in range(len(vertices)):
#        edges.append([i,i+1])

#    del(edges[-1]) # Apaga o Ășltimo elemento da cena

# create the Curve Datablock
    curveData = bpy.data.curves.new('myCurve', type='CURVE')
    curveData.dimensions = '3D'
    #    curveData.resolution_u = 6
    curveData.resolution_u = 36

    # map coords to spline
    polyline = curveData.splines.new('BEZIER')
    polyline.bezier_points.add(len(coords) - 1)
    #    for i, coord in enumerate(coords):
    #        x,y,z = coord
    #        polyline.points[i].co = (x, y, z, 1)

    from bpy_extras.io_utils import unpack_list
    polyline.bezier_points.foreach_set("co", unpack_list(coords))

    # Apaga pontos
    bpy.ops.object.select_all(action='DESELECT')

    for i in Pontos:
        i.select_set(True)

    bpy.ops.object.delete(use_global=False)

    # Cria Linha
    curveOB = bpy.data.objects.new('myCurve', curveData)

    # attach to scene and validate context
    scn = bpy.context.scene
    #   scn.objects.link(curveOB)
    scn.collection.objects.link(curveOB)
    bpy.ops.object.select_all(action='DESELECT')
    bpy.context.view_layer.objects.active = curveOB
    curveOB.select_set(True)

    bpy.ops.object.editmode_toggle()
    bpy.ops.curve.select_all(action='SELECT')
    bpy.ops.curve.handle_type_set(type='AUTOMATIC')

    bpy.ops.curve.make_segment()

    bpy.ops.object.editmode_toggle()

    bpy.ops.object.modifier_add(type='SHRINKWRAP')
    bpy.context.object.modifiers["Shrinkwrap"].target = obj
    bpy.context.object.modifiers["Shrinkwrap"].offset = 0.01
    bpy.context.object.modifiers["Shrinkwrap"].wrap_mode = 'ABOVE_SURFACE'

    bpy.ops.object.select_all(action='DESELECT')
    obj.select_set(True)
    bpy.context.view_layer.objects.active = obj
Example #55
0
    def write_mesh_data(self, entities, name, default_material='Material'):
        verts = []
        faces = []
        mat_index = []
        mats = keep_offset()
        seen = keep_offset()
        uv_list = []
        alpha = False # We assume object does not need alpha flag
        uvs_used = False # We assume no uvs need to be added


        for f in entities.faces:
            vs, tri, uvs = f.tessfaces

            if f.material:
                mat_number = mats[f.material.name]
            else:
                mat_number = mats[default_material]


            mapping = {}
            for i, (v, uv) in enumerate(zip(vs, uvs)):
                l = len(seen)
                mapping[i] = seen[v]
                if len(seen) > l:
                    verts.append(v)
                uvs.append(uv)


            for face in tri:
                f0, f1, f2 = face[0], face[1], face[2]
                if f2 == 0: ## eeekadoodle dance
                    faces.append( ( mapping[f1], mapping[f2], mapping[f0] ) )
                    uv_list.append(( uvs[f2][0], uvs[f2][1],
                                     uvs[f1][0], uvs[f1][1],
                                     uvs[f0][0], uvs[f0][1],
                                     0, 0 ) )
                else:
                    faces.append( ( mapping[f0], mapping[f1], mapping[f2] ) )
                    uv_list.append(( uvs[f0][0], uvs[f0][1],
                                     uvs[f1][0], uvs[f1][1],
                                     uvs[f2][0], uvs[f2][1],
                                     0, 0 ) )
                mat_index.append(mat_number)

        # verts, faces, uv_list, mat_index, mats = entities.get__triangles_lists(default_material)

        if len(verts) == 0:
            return None, False

        me = bpy.data.meshes.new(name)

        me.vertices.add(len(verts))
        me.tessfaces.add(len(faces))

        if len(mats) >= 1:
            mats_sorted = OrderedDict(sorted(mats.items(), key=lambda x: x[1]))
            for k in mats_sorted.keys():
                bmat = self.materials[k]
                me.materials.append(bmat)
                if bmat.alpha < 1.0:
                    alpha = True
                try:
                    if 'Image Texture' in bmat.node_tree.nodes.keys():
                        uvs_used = True
                except AttributeError as e:
                    uvs_used = False
        else:
            sketchupLog("WARNING OBJECT {} HAS NO MATERIAL".format(name))

        me.vertices.foreach_set("co", unpack_list(verts))
        me.tessfaces.foreach_set("vertices_raw", unpack_face_list(faces))
        me.tessfaces.foreach_set("material_index", mat_index)

        if uvs_used:
            me.tessface_uv_textures.new()
            for i in range(len(faces)):
                me.tessface_uv_textures[0].data[i].uv_raw = uv_list[i]

        me.update(calc_edges=True)
        me.validate()
        return me, alpha
Example #56
0
def load(context, filepath):
	with open(filepath, "rb") as fd:
		ter = read_ter(fd)

	name = root_name(filepath)
	me = bpy.data.meshes.new(name)

	for orig_path in ter.materialNames:
		if not orig_path:
			continue

		mat_name = root_name(orig_path)
		mat_file = resolve_texture(filepath, mat_name)

		mat = bpy.data.materials.new(mat_name)
		me.materials.append(mat)

		if mat_file:
			try:
				image = bpy.data.images.load(mat_file)
			except:
				print("Cannot load image", mat_file)
				continue

			slot = mat.texture_slots.add()
			slot.texture = bpy.data.textures.new(mat_name, "IMAGE")
			slot.texture.image = image
			slot.texture_coords = "ORCO"
			slot.scale = 32, 32, 32

	# This is a bit of a mess.
	# Feel free to clean it up :)

	# me.vertices.add(BlockSize2)
	#
	# for i, vert in enumerate(me.vertices):
	# 	vert.co = (
	# 		(i // BlockSize) * 8 / 32,
	# 		(i %  BlockSize) * 8 / -32,
	# 		ter.heightMap[i] / 32 / 32
	# 	)

	verts = []

	for x in range(BlockSize + 1):
		for y in range(BlockSize + 1):
			i = (y % BlockSize) * BlockSize + (x % BlockSize)

			verts.append((
				x * 8 - 1024,
				y * 8 - 1024,
				ter.heightMap[i] / 32
			))

	faces = []

	for x in range(BlockSize):
		for y in range(BlockSize):
			vert0 = y * 257 + x
			vert1 = y * 257 + x + 1
			vert2 = y * 257 + x + 257
			vert3 = y * 257 + x + 258

			if x % 2 == y % 2:
				faces.append(((vert0, vert2, vert3), (x, y)))
				faces.append(((vert3, vert1, vert0), (x, y)))
			else:
				faces.append(((vert0, vert2, vert1), (x, y)))
				faces.append(((vert3, vert1, vert2), (x, y)))

	me.vertices.add(len(verts))
	me.vertices.foreach_set("co", unpack_list(verts))

	me.polygons.add(len(faces))
	me.loops.add(len(faces) * 3)

	# me.uv_textures.new()
	# uvs = me.uv_layers[0]

	for i, ((verts, (gx, gy)), poly) in enumerate(zip(faces, me.polygons)):
		poly.use_smooth = True
		poly.loop_total = 3
		poly.loop_start = i * 3

		# For now, just solidly fill in the material with the highest alpha
		best_mat_index = None
		best_mat_alpha = None
		grid_idx = gx * BlockSize + gy # ... this is the wrong way around?

		for mat_index in range(MaterialGroups):
			if ter.materialAlpha[mat_index]:
				alpha = ter.materialAlpha[mat_index][grid_idx]

				if best_mat_index == None or alpha > best_mat_alpha:
					best_mat_index = mat_index
					best_mat_alpha = alpha

		if best_mat_index is not None:
			poly.material_index = best_mat_index

		for j, index in zip(poly.loop_indices, verts):
			me.loops[j].vertex_index = index
			# uvs.data[j].uv = ()

	me.validate()
	me.update()

	ob = bpy.data.objects.new(name, me)
	context.scene.objects.link(ob)

	return {"FINISHED"}
Example #57
0
def do_import(path, DELETE_TOP_BONE=True):
	# limits
	MAX_NUMMESHES = 1000
	MAX_NUMVERTS = 100000
	MAX_NUMNORMALS = 100000
	MAX_NUMTRIS = 100000
	MAX_NUMMATS = 16
	MAX_NUMBONES = 1000
	MAX_NUMPOSKEYS = 1000
	MAX_NUMROTKEYS = 1000

	# get scene
	scn = bpy.context.scene
	if scn==None:
		return "No scene to import to!"

	# open the file
	try:
		file = open(path, 'r')
	except IOError:
		return "Failed to open the file!"
	
	try:
		if not path.endswith(".nb2"):
			raise IOError
	except IOError:
		return "Must be an nb2 file!"
		
	# Read frame info
	try:
		lines = getNextLine(file).split()
		if len(lines) != 2 or lines[0] != "Frames:":
			raise ValueError
		lines = getNextLine(file).split()
		if len(lines) != 2 or lines[0] != "Frame:":
			raise ValueError
	except ValueError:
		return "Frame information is invalid!"

	# Create the mesh
	meshName = "Mesh Object"
	
	# Before adding any meshes or armatures go into Object mode.
	if bpy.ops.object.mode_set.poll():
		bpy.ops.object.mode_set(mode='OBJECT')

	# read the number of meshes
	try:
		lines = getNextLine(file).split()
		if len(lines)!=2 or lines[0]!="Meshes:":
			raise ValueError
		numMeshes = int(lines[1])
		if numMeshes < 0 or numMeshes > MAX_NUMMESHES:
			raise ValueError
	except ValueError:
		return "Number of meshes is invalid!"

	# read meshes
	boneIds = [[],[],[],[]]
	boneWeights = [[],[],[],[]]
	meshVertexGroups = {}
	vCount = 0
	
	meshes = []
	meshObjects = []
	
	for i in range(numMeshes):
		# read name, flags and material
		try:
			lines = re.findall(r'\".*\"|[^ ]+', getNextLine(file))
			if len(lines)!=3:
				raise ValueError
			meshName = lines[0]
			meshName = meshName[1:-1]
			print ("processing mesh name:%s..." % meshName)
			material = int(lines[2])
		except ValueError:
			return "Name, flags or material in mesh " + str(i+1) + " are invalid!"
		
		meshes.append(bpy.data.meshes.new(meshName))
		meshObjects.append(bpy.data.objects.new(meshName + "Ob", meshes[i]))
		scn.objects.link(meshObjects[i])
		
		# read the number of vertices
		try:
			numVerts = int(getNextLine(file))
			if numVerts < 0 or numVerts > MAX_NUMVERTS:
				raise ValueError
		except ValueError:
			return "Number of vertices in mesh " + str(i+1) + " is invalid!"
			
		print ("Number of vertices in mesh:%d" % numVerts)
		
		# read vertices
		coords = []
		uvs = []
		for j in range(numVerts):
			try:
				lines = getNextLine(file).split()
				if len(lines)!=14:
					raise ValueError
				coords.append([float(lines[1]), float(lines[2]), float(lines[3])])
				uvs.append([float(lines[4]), 1-float(lines[5])])
				boneIds[0].append(int(lines[6]))
				boneWeights[0].append(float(lines[7]))
				boneIds[1].append(int(lines[8]))
				boneWeights[1].append(float(lines[9]))
				boneIds[2].append(int(lines[10]))
				boneWeights[2].append(float(lines[11]))
				boneIds[3].append(int(lines[12]))
				boneWeights[3].append(float(lines[13]))
				meshVertexGroups[vCount] = meshName     # uses the long mesh name - may be > 21 chars
				vCount += 1
			except ValueError:
				return "Vertex " + str(j+1) + " in mesh " + str(i+1) + " is invalid!"
		
		meshes[i].vertices.add(len(coords))
		meshes[i].vertices.foreach_set("co", unpack_list(coords))
		
		# read number of normals
		try:
			numNormals = int(getNextLine(file))
			if numNormals < 0 or numNormals > MAX_NUMNORMALS:
				raise ValueError
		except ValueError:
			return "Number of normals in mesh " + str(i+1) + " is invalid!"

		print ("Number of normals in mesh:%d" % numNormals)
			
		# read normals
		normals = []
		for j in range(numNormals):
			try:
				lines = getNextLine(file).split()
				if len(lines)!=3:
					raise ValueError
				normals.append([float(lines[0]), float(lines[1]), float(lines[2])])
			except ValueError:
				return "Normal " + str(j+1) + " in mesh " + str(i+1) + " is invalid!"

		# read the number of triangles
		try:
			numTris = int(getNextLine(file))
			if numTris < 0 or numTris > MAX_NUMTRIS:
				raise ValueError
		except ValueError:
			return "Number of triangles in mesh " + str(i+1) + " is invalid!"

		print ("Number of triangles in mesh:%d" % numTris)
			
		# read triangles
		faces = []
		for j in range(numTris):
			# read the triangle
			try:
				lines = getNextLine(file).split()
				if len(lines) != 8:
					raise ValueError
				v1 = int(lines[1])
				v2 = int(lines[2])
				v3 = int(lines[3])
				
				faces.append([v1,v2,v3,0])
			except ValueError:
				return "Triangle " + str(j+1) + " in mesh " + str(i+1) + " is invalid!"
		
		meshes[i].tessfaces.add(len(faces))
		for fi, fpol in enumerate(faces):
			vlen = len(fpol)
			if vlen == 3 or vlen == 4:
				for v in range(vlen):
					meshes[i].tessfaces[fi].vertices_raw[v]= fpol[v]
		
		# set texture coordinates and material
		meshes[i].tessface_uv_textures.new()
		for j, face in enumerate(meshes[i].tessfaces):
			face_uv = meshes[i].tessface_uv_textures[0].data[j]
			
			face_uv.uv1 = Vector(uvs[face.vertices[0]]);
			face_uv.uv2 = Vector(uvs[face.vertices[1]]);
			face_uv.uv3 = Vector(uvs[face.vertices[2]]);
			
			if material >= 0:
				face.material_index = material
				
	for mesh in meshes:
		mesh.update()
	
	# read the number of materials
	try:
		lines = getNextLine(file).split()
		if len(lines)!=2 or lines[0]!="Materials:":
			raise ValueError
		numMats = int(lines[1])
		if numMats < 0 or numMats > MAX_NUMMATS:
			raise ValueError
	except ValueError:
		return "Number of materials is invalid!"

	# read the materials
	for i in range(numMats):
			# read name
			name = getNextLine(file)[1:-1]

			# create the material
			#mat = Blender.Material.New(name)
			#mesh.materials += [mat]

			# read ambient color
			try:
				lines = getNextLine(file).split()
				if len(lines)!=4:
					raise ValueError
			except ValueError:
				return "Ambient color in material " + str(i+1) + " is invalid!"

			# read diffuse color
			try:
				lines = getNextLine(file).split()
				if len(lines)!=4:
					raise ValueError
			except ValueError:
				return "Diffuse color in material " + str(i+1) + " is invalid!"

			# read specular color
			try:
				lines = getNextLine(file).split()
				if len(lines)!=4:
					raise ValueError
			except ValueError:
				return "Specular color in material " + str(i+1) + " is invalid!"

			# read emissive color
			try:
				lines = getNextLine(file).split()
				if len(lines)!=4:
					raise ValueError
			except ValueError:
				return "Emissive color in material " + str(i+1) + " is invalid!"

			# read shininess
			try:
				shi = float(getNextLine(file))
			except ValueError:
				return "Shininess in material " + str(i+1) + " is invalid!"

			# read transparency
			try:
				alpha = float(getNextLine(file))
			except ValueError:
				return "Transparency in material " + str(i+1) + " is invalid!"

			# read texturemap
			texturemap = getNextLine(file)[1:-1]
			alphamap = getNextLine(file)[1:-1]

	# read the number of bones
	try:
		lines = getNextLine(file).split()
		if len(lines)!=2 or lines[0]!="Bones:":
			raise ValueError
		numBones = int(lines[1])
		if numBones < 0 or numBones > MAX_NUMBONES:
			raise ValueError
	except:
		return "Number of bones is invalid!"

	# create the armature
	armature = None
	armOb = None
	
	print ("numBones:")
	
	numBones
	if numBones > 0:
		armature = bpy.data.armatures.new("Armature")
		armOb = bpy.data.objects.new("ArmatureObject", armature)
		armature.draw_type = 'STICK'
		scn.objects.link(armOb)
		scn.objects.active = armOb
		
	# read bones
	posKeys = {}
	rotKeys = {}
	boneNames = []
	bpy.ops.object.editmode_toggle()
	bpy.types.EditBone.rot_matrix = bpy.props.FloatVectorProperty(name="Rot Matrix", size=9)

	for i in range(numBones):
		# read name
		fullName = getNextLine(file)[1:-1]
		boneNames.append(fullName)
		bone = armature.edit_bones.new(fullName)
		
		# read parent
		parentBoneName = getNextLine(file)[1:-1]
		if len(parentBoneName) > 0:
			bone.parent = armature.bones.data.edit_bones[parentBoneName]

		# read position and rotation
		try:
			line = getNextLine(file)
			lines = line.split()
			if not (len(lines) == 8 or len(lines) == 24):
				raise ValueError
			pos = [float(lines[1]), float(lines[2]), float(lines[3])]
			quat = [float(lines[4]), float(lines[5]), float(lines[6]), float(lines[7])]
			#print 'Read bone: %s' % line
		except ValueError:
			return "Invalid position or orientation in a bone!"
		
		# # Granny Rotation Quaternions are stored X,Y,Z,W but Blender uses W,X,Y,Z
		quaternion = Quaternion((quat[3], quat[0], quat[1], quat[2])) 
		rotMatrix = quaternion.to_matrix() 
		rotMatrix.transpose() # Need to transpose to get same behaviour as 2.49 script
		
		print ("Bone Data")
		print (fullName)
		print (pos)
		print (rotMatrix)
		
		boneLength = 3
		# set position and orientation
		if bone.parent:
			bone_parent_matrix = Matrix([[bone.parent.rot_matrix[0], bone.parent.rot_matrix[1], bone.parent.rot_matrix[2]],
										[bone.parent.rot_matrix[3], bone.parent.rot_matrix[4], bone.parent.rot_matrix[5]],
										[bone.parent.rot_matrix[6], bone.parent.rot_matrix[7], bone.parent.rot_matrix[8]]])
			bone.head =  Vector(pos) * bone_parent_matrix + bone.parent.head
			bone.tail = bone.head + Vector([boneLength,0,0]) 
			tempM = rotMatrix * bone_parent_matrix
			bone.rot_matrix = [tempM[0][0], tempM[0][1], tempM[0][2], 
								tempM[1][0], tempM[1][1], tempM[1][2],
								tempM[2][0], tempM[2][1], tempM[2][2]]
			bone.matrix = Matrix([[-bone.rot_matrix[3], bone.rot_matrix[0], bone.rot_matrix[6], bone.head[0]],
								 [-bone.rot_matrix[4], bone.rot_matrix[1], bone.rot_matrix[7], bone.head[1]], 
								 [-bone.rot_matrix[5], bone.rot_matrix[2], bone.rot_matrix[8], bone.head[2]], 
								 [0, 0, 0, 1]])
		else:
			bone.head = Vector(pos)
			bone.tail = bone.head + Vector([boneLength,0,0])
			bone.rot_matrix = [rotMatrix[0][0], rotMatrix[0][1], rotMatrix[0][2], 
								rotMatrix[1][0], rotMatrix[1][1], rotMatrix[1][2],
								rotMatrix[2][0], rotMatrix[2][1], rotMatrix[2][2]]
			bone.matrix = Matrix([[-bone.rot_matrix[3], bone.rot_matrix[0], bone.rot_matrix[6], bone.head[0]],
								 [-bone.rot_matrix[4], bone.rot_matrix[1], bone.rot_matrix[7], bone.head[1]], 
								 [-bone.rot_matrix[5], bone.rot_matrix[2], bone.rot_matrix[8], bone.head[2]], 
								 [0, 0, 0, 1]])
			
		print (bone.rot_matrix[0], bone.rot_matrix[1], bone.rot_matrix[2])
		print (bone.rot_matrix[3], bone.rot_matrix[4], bone.rot_matrix[5])
		print (bone.rot_matrix[6], bone.rot_matrix[7], bone.rot_matrix[8])
		print (bone.head)
		print (bone.tail)
		print ("bone roll")
		print (bone.roll)

		# read the number of position key frames
		try:
			numPosKeys = int(getNextLine(file))
			if numPosKeys < 0 or numPosKeys > MAX_NUMPOSKEYS:
				raise ValueError
		except ValueError:
			return "Invalid number of position key frames!"

		# read position key frames
		posKeys[name] = []
		for j in range(numPosKeys):
			# read time and position
			try:
				lines = getNextLine(file).split()
				if len(lines) != 4:
					raise ValueError
			except ValueError:
				return "Invalid position key frame!"
			
		# read the number of rotation key frames
		try:
			numRotKeys = int(getNextLine(file))
			if numRotKeys < 0 or numRotKeys > MAX_NUMROTKEYS:
				raise ValueError
		except ValueError:
			return "Invalid number of rotation key frames!"

		# read rotation key frames
		rotKeys[name] = []
		for j in range(numRotKeys):
			# read time and rotation
			try:
				lines = getNextLine(file).split()
				if len(lines) != 4:
					raise ValueError
			except ValueError:
				return "Invalid rotation key frame!"

	# Roll Fix
	#for bone in armature.edit_bones:
	#	if bone.parent:
	#		roll = bone.roll
	#		bone.roll = roll - math.radians(90.0)
	
	# Create Vertex Groups
	vi = 0
	for meshOb in meshObjects:
		mesh = meshOb.data
		for mvi, vertex in enumerate(mesh.vertices):
			for bi in range(numBones):
				for j in range(4):
					if bi==boneIds[j][vi]:
						name = boneNames[bi] 
						if not meshOb.vertex_groups.get(name):
							meshOb.vertex_groups.new(name)
						grp = meshOb.vertex_groups.get(name)
						grp.add([mvi], boneWeights[j][vi], 'ADD')
			vi = vi + 1
		
		# Give mesh object an armature modifier, using vertex groups but
		# not envelopes
		mod = meshOb.modifiers.new('mod_' + mesh.name, 'ARMATURE')
		mod.object = armOb
		mod.use_bone_envelopes = False
		mod.use_vertex_groups = True

	if DELETE_TOP_BONE:
		# Adjust object names, remove top bone for Civ V - Deliverator
		#armature.makeEditable()
		
		bone = armature.bones.data.edit_bones[boneNames[0]]
		while not bone.parent is None:
			bone = bone.parent
		
		print ('Found World Bone: %s' % bone.name)
		
		name = bone.name
		armOb.name = name
		
		# Delete top bone unless that would leave zero bones
		if (len(armature.bones.data.edit_bones) > 1):
			bpy.ops.object.select_pattern(pattern=name)
			bpy.ops.armature.delete()
			#del armature.bones.data.edit_bones[name]
			
		# armature.update()
		
	bpy.ops.object.editmode_toggle()
	bpy.ops.object.editmode_toggle()
	bpy.ops.object.editmode_toggle()
	
	# The import was a success!
	return ""