コード例 #1
0
    def add_asset(self, obj):
        model_configuration = None
        base_matrix = obj.matrix_basis.inverted()
        free, derived_objects = create_derived_objects(self._scene, obj)

        if derived_objects is None:
            return None, None

        asset = Asset(id_=tools.safe_query_selector_id(obj.data.name))

        if len(derived_objects) == 1:
            (derived_object, matrix) = derived_objects[0]
            asset.matrix = base_matrix * matrix
            model_configuration = self.add_asset_data(asset, derived_object)
        else:
            for derived_object, matrix in derived_objects:
                model_configuration = ModelConfiguration()
                if derived_object.type not in {
                        'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'
                }:
                    continue
                submodel_configuration = self.add_subasset(
                    asset, derived_object, base_matrix * matrix)
                model_configuration.children.append(submodel_configuration)

        if free:
            free_derived_objects(obj)

        self.assets.append(asset)
        return asset.id, model_configuration
コード例 #2
0
    def add_asset(self, obj):
        model_configuration = None
        base_matrix = obj.matrix_basis.inverted()
        free, derived_objects = create_derived_objects(self._scene, obj)

        if derived_objects is None:
            return None, None

        asset = Asset(id_=tools.safe_query_selector_id(obj.data.name))

        if len(derived_objects) == 1:
            (derived_object, matrix) = derived_objects[0]
            asset.matrix = base_matrix * matrix
            model_configuration = self.add_asset_data(asset, derived_object)
        else:
            for derived_object, matrix in derived_objects:
                model_configuration = ModelConfiguration()
                if derived_object.type not in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}:
                    continue
                submodel_configuration = self.add_subasset(asset, derived_object, base_matrix * matrix)
                model_configuration.children.append(submodel_configuration)

        if free:
            free_derived_objects(obj)

        self.assets.append(asset)
        return asset.id, model_configuration
コード例 #3
0
ファイル: tamy_scene.py プロジェクト: dabroz/Tamy
	def build_entities( self ):
		
		from bpy_extras.io_utils import create_derived_objects, free_derived_objects
			
		for ob in self.objects:	
						
			# The object represents a mesh
			if ob.type == 'MESH':
			
				# get derived objects
				free, derived = create_derived_objects( self.scene, ob )

				if derived is None:
					continue
					
				# create a binding entity
				parentEntityIdx = -1
				parentArmatureObject = ob.find_armature()
				if parentArmatureObject is not None:						
					parentEntityIdx = self.add_armature_entity( parentArmatureObject )
				else:
					parentEntityIdx = self.add_node_entity( ob )
				
				# create meshes
				for obDerived, objectMtx in derived:
					try:
						derivedBlenderMesh = obDerived.to_mesh( self.scene, False, 'PREVIEW' )
					except:
						derivedBlenderMesh = None
					
					if derivedBlenderMesh:
						self.map_materials( derivedBlenderMesh )
					
					meshes = []
					meshName = "%s" % ob.name
					tamy_mesh.create_tamy_meshes( meshName, obDerived, derivedBlenderMesh, self.materialsDict, meshes )
					
					self.add_geometry_component( obDerived, meshes, parentEntityIdx )
					
					# cleanup
					if free:
						free_derived_objects( derivedBlenderMesh )
			
			# The object represents a light				
			elif ob.type == 'LAMP':
				self.add_light_entity( ob )
				
			elif ob.type == 'ARMATURE':
				self.add_armature_entity( ob)
コード例 #4
0
ファイル: export_from_blender.py プロジェクト: mastrost/Coiil
def exportMeshes(scene, file):
    if bpy.ops.object.mode_set.poll():
        bpy.ops.object.mode_set(mode='OBJECT')

    mesh_objects = []

    for obj in scene.objects:
        free, derived = create_derived_objects(scene, obj)

        if derived is None:
            continue

        for ob_derived, matrix in derived:
            if obj.type == 'EMPTY':
                pass
            elif obj.type == 'LIGHT':
                light = obj.data
                # file.write("light: \"%s\"\n" % str(light.name))
                # file.write("%s " % str(round(obj.location.x, 6)))
                # file.write("%s " % str(round(obj.location.y, 6)))
                # file.write("%s\n" % str(round(obj.location.z, 6)))
                # file.write("%s " % str(round(light.color.r, 2)))
                # file.write("%s " % str(round(light.color.g, 2)))
                # file.write("%s\n" % str(round(light.color.b, 2)))
                # file.write("\n")
            elif obj.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}:
                theMesh = ob_derived.to_mesh()

                if theMesh is None:
                    continue

                theMesh.transform(matrix)
                try:
                    dumpMesh(theMesh, file, ob_derived)
                except Exception as e:
                    if hasattr(e, 'message'):
                        errorMsg = e.message
                    else:
                        errorMsg = str(e)
                    sys.stderr.write(
                        f"Skipping mesh: '{theMesh.name}' ({errorMsg})\n")

                file.write("\n")
            else:
                sys.stderr.write("Skipping unknown type: '%s'\n" %
                                 str(obj.type))

        if free:
            free_derived_objects(obj)
コード例 #5
0
ファイル: tamy_scene.py プロジェクト: chenwenbin928/tamy
def build_entities_and_materials( scene, objects, outMaterials, outEntities, outMaterialsDict, outTexturesDict, outEntitiesDict ):
	
	from bpy_extras.io_utils import create_derived_objects, free_derived_objects
		
	for ob in objects:	
	
		# get derived objects
		free, derived = create_derived_objects(scene, ob)

		if derived is None:
			continue

		for obDerived, objectMtx in derived:

			tamyEntity = None
			tamyEntityType = ''
			
			# The object represents a mesh
			if ob.type in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}:
				try:
					derivedBlenderMesh = obDerived.to_mesh( scene, True, 'PREVIEW' )
				except:
					derivedBlenderMesh = None
					
				if derivedBlenderMesh:
					build_materials( derivedBlenderMesh, outMaterials, outMaterialsDict, outTexturesDict )
					
					meshes = []
					meshName = "%s" % ob.name
					tamy_mesh.create_tamy_meshes( meshName, derivedBlenderMesh, outMaterialsDict, meshes )
					tamyEntity = tamy_entities.TamyGeometry( meshes, ob.name )
					tamyEntityType = 'MESH'
					
					# cleanup
					if free:
						free_derived_objects( derivedBlenderMesh )
			
			# The object represents a light				
			elif ob.type == 'LAMP':
				tamyEntityType = 'LIGHT'
				tamyEntity = tamy_entities.TamyLight( ob.name, ob.data )
				
			
			# add new entity to our list
			if tamyEntity is not None:
				entityIdx = len( outEntities )
				outEntitiesDict[ob] = entityIdx					
				outEntities.append( ( tamyEntityType, obDerived, objectMtx, tamyEntity ) )
コード例 #6
0
def save(
    operator,
    context,
    filepath="",
    use_selection=True,
    global_matrix=None,
):

    import bpy
    import mathutils

    import time
    from bpy_extras.io_utils import create_derived_objects, free_derived_objects
    """Save the Blender scene to a 3ds file."""

    # Time the export
    time1 = time.clock()
    #Blender.Window.WaitCursor(1)

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

    if bpy.ops.object.mode_set.poll():
        bpy.ops.object.mode_set(mode='OBJECT')

    # Initialize the main chunk (primary):
    primary = _3ds_chunk(PRIMARY)
    # Add version chunk:
    version_chunk = _3ds_chunk(VERSION)
    version_chunk.add_variable("version", _3ds_uint(3))
    primary.add_subchunk(version_chunk)

    # init main object info chunk:
    object_info = _3ds_chunk(OBJECTINFO)
    ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX
    # init main key frame data chunk:
    kfdata = make_kfdata()
    '''

    # Make a list of all materials used in the selected meshes (use a dictionary,
    # each material is added once):
    materialDict = {}
    mesh_objects = []

    scene = context.scene
    depsgraph = context.evaluated_depsgraph_get()

    if use_selection:
        objects = (ob for ob in scene.objects
                   if ob.is_visible(scene) and ob.select)
    else:
        objects = (ob for ob in scene.objects if ob.is_visible(scene))

    for ob in objects:
        # get derived objects
        free, derived = create_derived_objects(scene, ob)

        if derived is None:
            continue

        for ob_derived, mat in derived:
            if ob.type not in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}:
                continue

            ob_derived_eval = ob_derived.evaluated_get(depsgraph)
            try:
                data = ob_derived_eval.to_mesh()
            except:
                data = None

            if data:
                matrix = global_matrix * mat
                data.transform(matrix)
                mesh_objects.append((ob_derived, data, matrix))
                mat_ls = data.materials
                mat_ls_len = len(mat_ls)

                # get material/image tuples.
                if data.tessface_uv_textures:
                    if not mat_ls:
                        mat = mat_name = None

                    for f, uf in zip(data.tessfaces,
                                     data.tessface_uv_textures.active.data):
                        if mat_ls:
                            mat_index = f.material_index
                            if mat_index >= mat_ls_len:
                                mat_index = f.mat = 0
                            mat = mat_ls[mat_index]
                            mat_name = None if mat is None else mat.name
                        # else there already set to none

                        img = uf.image
                        img_name = None if img is None else img.name

                        materialDict.setdefault((mat_name, img_name),
                                                (mat, img))

                else:
                    for mat in mat_ls:
                        if mat:  # material may be None so check its not.
                            materialDict.setdefault((mat.name, None),
                                                    (mat, None))

                    # Why 0 Why!
                    for f in data.tessfaces:
                        if f.material_index >= mat_ls_len:
                            f.material_index = 0

                ob_derived_eval.to_mesh_clear()

        if free:
            free_derived_objects(ob)

    # Make material chunks for all materials used in the meshes:
    for mat_and_image in materialDict.values():
        object_info.add_subchunk(
            make_material_chunk(mat_and_image[0], mat_and_image[1]))

    # Give all objects a unique ID and build a dictionary from object name to object id:
    """
    name_to_id = {}
    for ob, data in mesh_objects:
        name_to_id[ob.name]= len(name_to_id)
    #for ob in empty_objects:
    #    name_to_id[ob.name]= len(name_to_id)
    """

    # Create object chunks for all meshes:
    i = 0
    for ob, blender_mesh, matrix in mesh_objects:
        # create a new object chunk
        object_chunk = _3ds_chunk(OBJECT)

        # set the object name
        object_chunk.add_variable("name", _3ds_string(sane_name(ob.name)))

        # make a mesh chunk out of the mesh:
        object_chunk.add_subchunk(
            make_mesh_chunk(blender_mesh, matrix, materialDict))

        # ensure the mesh has no over sized arrays
        # skip ones that do!, otherwise we cant write since the array size wont
        # fit into USHORT.
        if object_chunk.validate():
            object_info.add_subchunk(object_chunk)
        else:
            operator.report({'WARNING'},
                            "Object %r can't be written into a 3DS file")
        ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX
        # make a kf object node for the object:
        kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id))
        '''

        if not blender_mesh.users:
            bpy.data.meshes.remove(blender_mesh)
        #blender_mesh.vertices = None

        i += i

    # Create chunks for all empties:
    ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX
    for ob in empty_objects:
        # Empties only require a kf object node:
        kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id))
        pass
    '''

    # Add main object info chunk to primary chunk:
    primary.add_subchunk(object_info)
    ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX
    # Add main keyframe data chunk to primary chunk:
    primary.add_subchunk(kfdata)
    '''

    # At this point, the chunk hierarchy is completely built.

    # Check the size:
    primary.get_size()
    # Open the file for writing:
    file = open(filepath, 'wb')

    # Recursively write the chunks to file:
    primary.write(file)

    # Close the file:
    file.close()

    # Clear name mapping vars, could make locals too
    del name_unique[:]
    name_mapping.clear()

    # Debugging only: report the exporting time:
    #Blender.Window.WaitCursor(0)
    print("3ds export time: %.2f" % (time.clock() - time1))

    # Debugging only: dump the chunk hierarchy:
    #primary.dump()

    return {'FINISHED'}
コード例 #7
0
ファイル: export_3ds.py プロジェクト: Badcreature/sagcg
def save(operator,
         context, filepath="",
         use_selection=True,
         global_matrix=None,
         ):

    import bpy
    import mathutils

    import time
    from bpy_extras.io_utils import create_derived_objects, free_derived_objects

    '''Save the Blender scene to a 3ds file.'''

    # Time the export
    time1 = time.clock()
#	Blender.Window.WaitCursor(1)

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

    if bpy.ops.object.mode_set.poll():
        bpy.ops.object.mode_set(mode='OBJECT')

    # Initialize the main chunk (primary):
    primary = _3ds_chunk(PRIMARY)
    # Add version chunk:
    version_chunk = _3ds_chunk(VERSION)
    version_chunk.add_variable("version", _3ds_uint(3))
    primary.add_subchunk(version_chunk)

    # init main object info chunk:
    object_info = _3ds_chunk(OBJECTINFO)

    ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX
    # init main key frame data chunk:
    kfdata = make_kfdata()
    '''

    # Make a list of all materials used in the selected meshes (use a dictionary,
    # each material is added once):
    materialDict = {}
    mesh_objects = []

    scene = context.scene

    if use_selection:
        objects = (ob for ob in scene.objects if ob.is_visible(scene) and ob.select)
    else:
        objects = (ob for ob in scene.objects if ob.is_visible(scene))

    for ob in objects:
        # get derived objects
        free, derived = create_derived_objects(scene, ob)

        if derived is None:
            continue

        for ob_derived, mat in derived:
            if ob.type not in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}:
                continue

            try:
                data = ob_derived.to_mesh(scene, True, 'PREVIEW')
            except:
                data = None

            if data:
                matrix = global_matrix * mat
                data.transform(matrix)
                mesh_objects.append((ob_derived, data, matrix))
                mat_ls = data.materials
                mat_ls_len = len(mat_ls)

                # get material/image tuples.
                if data.tessface_uv_textures:
                    if not mat_ls:
                        mat = mat_name = None

                    for f, uf in zip(data.tessfaces, data.tessface_uv_textures.active.data):
                        if mat_ls:
                            mat_index = f.material_index
                            if mat_index >= mat_ls_len:
                                mat_index = f.mat = 0
                            mat = mat_ls[mat_index]
                            mat_name = None if mat is None else mat.name
                        # else there already set to none

                        img = uf.image
                        img_name = None if img is None else img.name

                        materialDict.setdefault((mat_name, img_name), (mat, img))

                else:
                    for mat in mat_ls:
                        if mat:  # material may be None so check its not.
                            materialDict.setdefault((mat.name, None), (mat, None))

                    # Why 0 Why!
                    for f in data.tessfaces:
                        if f.material_index >= mat_ls_len:
                            f.material_index = 0

        if free:
            free_derived_objects(ob)

    # Make material chunks for all materials used in the meshes:
    for mat_and_image in materialDict.values():
        object_info.add_subchunk(make_material_chunk(mat_and_image[0], mat_and_image[1]))

    # Give all objects a unique ID and build a dictionary from object name to object id:
    """
    name_to_id = {}
    for ob, data in mesh_objects:
        name_to_id[ob.name]= len(name_to_id)
    #for ob in empty_objects:
    #	name_to_id[ob.name]= len(name_to_id)
    """

    # Create object chunks for all meshes:
    i = 0
    for ob, blender_mesh, matrix in mesh_objects:
        # create a new object chunk
        object_chunk = _3ds_chunk(OBJECT)

        # set the object name
        object_chunk.add_variable("name", _3ds_string(sane_name(ob.name)))

        # make a mesh chunk out of the mesh:
        object_chunk.add_subchunk(make_mesh_chunk(blender_mesh, matrix, materialDict))

        # ensure the mesh has no over sized arrays
        # skip ones that do!, otherwise we cant write since the array size wont
        # fit into USHORT.
        if object_chunk.validate():
            object_info.add_subchunk(object_chunk)
        else:
            operator.report({'WARNING'}, "Object %r can't be written into a 3DS file")

        ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX
        # make a kf object node for the object:
        kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id))
        '''
        if not blender_mesh.users:
            bpy.data.meshes.remove(blender_mesh)
# 		blender_mesh.vertices = None

        i += i

    # Create chunks for all empties:
    ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX
    for ob in empty_objects:
        # Empties only require a kf object node:
        kfdata.add_subchunk(make_kf_obj_node(ob, name_to_id))
        pass
    '''

    # Add main object info chunk to primary chunk:
    primary.add_subchunk(object_info)

    ''' # COMMENTED OUT FOR 2.42 RELEASE!! CRASHES 3DS MAX
    # Add main keyframe data chunk to primary chunk:
    primary.add_subchunk(kfdata)
    '''

    # At this point, the chunk hierarchy is completely built.

    # Check the size:
    primary.get_size()
    # Open the file for writing:
    file = open(filepath, 'wb')

    # Recursively write the chunks to file:
    primary.write(file)

    # Close the file:
    file.close()

    # Clear name mapping vars, could make locals too
    name_unique[:] = []
    name_mapping.clear()

    # Debugging only: report the exporting time:
# 	Blender.Window.WaitCursor(0)
    print("3ds export time: %.2f" % (time.clock() - time1))

    # Debugging only: dump the chunk hierarchy:
    #primary.dump()

    return {'FINISHED'}
コード例 #8
0
    def export_object(obj_main_parent, obj_main, obj_children):
        """Export Object Hierarchy (recursively called)."""
        matrix_fallback = mathutils.Matrix()
        world = scene.world
        free, derived = create_derived_objects(scene, obj_main)

        obj_main_matrix_world = obj_main.matrix_world
        if obj_main_parent:
            obj_main_matrix = obj_main_parent.matrix_world.inverted(matrix_fallback) * obj_main_matrix_world
        else:
            obj_main_matrix = obj_main_matrix_world
        obj_main_matrix_world_invert = obj_main_matrix_world.inverted(matrix_fallback)

        obj_main_id = unique_name(obj_main, obj_main.name, uuid_cache_object, clean_func=slugify, sep='_')

        (skipUselessTransform, supplementaryCurvyBracket) = write_transform_begin(obj_main, obj_main_matrix if obj_main_parent else global_matrix * obj_main_matrix, obj_main_id)

        for obj, obj_matrix in (() if derived is None else derived):
            obj_type = obj.type
            obj_matrix = obj_main_matrix_world_invert * obj_matrix  # Make transform node relative.

            if obj_type in {'MESH', 'CURVE', 'SURFACE', 'FONT'}:
                if (obj_type != 'MESH') or (use_mesh_modifiers and obj.is_modified(scene, 'PREVIEW')):
                    me = obj.to_mesh(scene, use_mesh_modifiers, 'PREVIEW')
                    do_remove = True
                else:
                    me = obj.data
                    do_remove = False

                if me is not None:
                    # ensure unique name, we could also do this by
                    # postponing mesh removal, but clearing data - TODO
                    if do_remove:
                        me.name = obj.name.rstrip('1234567890').rstrip('.')
                        me_name_new = me_name_org = me.name
                        count = 0
                        while me_name_new in mesh_name_set:
                            me.name = '%.17s.%03d' % (me_name_org, count)
                            me_name_new = me.name
                            count += 1
                        mesh_name_set.add(me_name_new)
                        del me_name_new, me_name_org, count

                    write_indexed_face_set(obj, me, obj_matrix, world)

                    # Rree mesh created with create_mesh()
                    if do_remove:
                        bpy.data.meshes.remove(me)

            else:
                # print('Info: Ignoring [%s], object type [%s] not handle yet' % (object.name,object.getType))
                pass

        if free:
            free_derived_objects(obj_main)

        # Write out children recursively
        for obj_child, obj_child_children in obj_children:
            export_object(obj_main, obj_child, obj_child_children)

        if not skipUselessTransform:
            write_transform_end(supplementaryCurvyBracket)
コード例 #9
0
def save(
    operator,
    context,
    filepath="",
    use_selection=True,
    enable_corona=False,
    enable_flares=True,
    enable_environment=True,
    center_objects_to_origin=False,
):

    import bpy
    import mathutils

    import time
    from bpy_extras.io_utils import create_derived_objects, free_derived_objects

    #get the folder where file will be saved and add a log in that folder
    workingpath = '\\'.join(filepath.split('\\')[0:-1])
    log_file = open(workingpath + "//export-log.txt", 'a')
    # Time the export
    time1 = time.clock()
    date = datetime.datetime.now()

    log_file.write("Started exporting on " +
                   date.strftime("%d-%m-%Y %H:%M:%S") + "\n" + "File path: " +
                   filepath + "\n")

    global_matrix = mathutils.Matrix()

    if bpy.ops.object.mode_set.poll():
        bpy.ops.object.mode_set(mode='OBJECT')

    # Make a list of all materials used in the selected meshes
    materials_list = ["colwhite"]
    mesh_objects = []
    lamp_objects = []

    collfound = False
    shadfound = False

    meshes_list = ""

    scene = context.scene

    if use_selection:
        objects = (ob for ob in scene.objects
                   if ob.is_visible(scene) and ob.select)
    else:
        objects = (ob for ob in scene.objects if ob.is_visible(scene))

    for ob in objects:
        free, derived = create_derived_objects(scene, ob)

        if derived is None:
            continue

        for ob_derived, mat in derived:
            if ob.type == 'MESH':
                try:
                    data = ob_derived.to_mesh(scene, True, 'PREVIEW')
                except:
                    data = None

                if "mainshad" in ob.name: shadfound = True
                elif "maincoll" in ob.name: collfound = True

                meshes_list += ob.name + " "

                if data:
                    matrix = global_matrix * mat
                    data.transform(matrix)
                    mesh_objects.append((ob_derived, data, matrix))
                    mat_ls = data.materials
                    mat_ls_len = len(mat_ls)

                    # get material/image tuples.
                    if data.tessface_uv_textures:
                        if not mat_ls:
                            mat = mat_name = None

                        for f, uf in zip(
                                data.tessfaces,
                                data.tessface_uv_textures.active.data):
                            if mat_ls:
                                mat_index = f.material_index
                                if mat_index >= mat_ls_len:
                                    mat_index = f.mat = 0
                                mat = mat_ls[mat_index]
                                mat_name = None if mat is None else mat.name
                            # else there already set to none

                            if mat_name not in materials_list:
                                materials_list.append(mat_name)

                    else:
                        log_file.write("No UVs found on mesh" + str(ob.name) +
                                       ". Using default UVs.\n")
                        for mat in mat_ls:
                            if mat:  # material may be None so check its not.
                                if mat.name not in materials_list:
                                    materials_list.append(mat.name)

                        # Why 0 Why!
                        for f in data.tessfaces:
                            if f.material_index >= mat_ls_len:
                                f.material_index = 0

            if ob.type == 'LAMP':
                lamp_objects.append(ob)

        if free:
            free_derived_objects(ob)

    #write all the meshes list into the log, so we can use it when setting up the carinfo.cca
    log_file.write("Meshes: " + meshes_list + "\n")

    # Initialize the main chunk (primary):
    primary = _3ds_chunk(sane_name("P3D"), write_size=False)

    tex = _3ds_chunk(sane_name("TEX"))
    tex_array = _3ds_bytearray()
    for m in materials_list:
        tex_array.add(_3ds_string(sane_name(m + ".tga")))
    tex.add_variable("textures", tex_array)

    lights = _3ds_chunk(sane_name("LIGHTS"))
    lights_array = _3ds_array()

    for l in lamp_objects:
        lamp = _3ds_unnamed_chunk()
        lamp.add_variable("name", _3ds_string(sane_name(l.name)))
        pos = l.matrix_world.to_translation()
        lamp.add_variable("pos", _3ds_point_3d((pos[0], pos[2], pos[1])))
        lamp.add_variable("range", _3ds_float(l.data.energy))
        lamp.add_variable(
            "color",
            _3ds_uint(
                int(
                    '%02x%02x%02x' %
                    (int(l.data.color[0] * 255), int(l.data.color[1] * 255),
                     int(l.data.color[2] * 255)), 16)))

        lamp.add_variable("corona", _3ds_byte(int(enable_corona)))
        lamp.add_variable("flares", _3ds_byte(int(enable_flares)))
        lamp.add_variable("environment", _3ds_byte(int(enable_environment)))
        lights_array.add(lamp)

    lights.add_variable("lights", lights_array)

    meshes = _3ds_chunk(sane_name("MESHES"))
    meshes_array = _3ds_array()

    length = 0.0
    height = 0.0
    depth = 0.0

    objcenterx = 0.0
    objcentery = 0.0
    objcenterz = 0.0

    #we have to get the main meshes dimensions before
    #we save all the other meshes, so we could properly center them if needed
    for ob, blender_mesh, matrix in mesh_objects:
        if ob.name == "main":
            v = blender_mesh.vertices[0].co
            lowx = v[0]
            highx = v[0]
            lowy = v[1]
            highy = v[1]
            lowz = v[2]
            highz = v[2]

            for vert in blender_mesh.vertices:
                pos = vert.co
                if pos[0] < lowx: lowx = pos[0]
                elif pos[0] > highx: highx = pos[0]

                if pos[1] < lowy: lowy = pos[1]
                elif pos[1] > highy: highy = pos[1]

                if pos[2] < lowz: lowz = pos[2]
                elif pos[2] > highz: highz = pos[2]

            length = highx - lowx
            height = highz - lowz
            depth = highy - lowy

            objcenterx = (highx + lowx) / 2
            objcentery = (highy + lowy) / 2
            objcenterz = (highz + lowz) / 2

    for ob, blender_mesh, matrix in mesh_objects:
        submesh = _3ds_chunk(sane_name("SUBMESH"))

        # Extract the triangles from the mesh:
        tri_list = extract_triangles(blender_mesh, materials_list)

        material_size = []

        for i in range(len(materials_list)):
            material_size.append(0)

        polys = _3ds_array()
        for tri in tri_list:
            poly = _3ds_unnamed_chunk()

            n = materials_list.index(blender_mesh.materials[tri.mat].name)
            material_size[n] += 1

            poly.add_variable("p1", _3ds_short(tri.vertex_index[0]))
            poly.add_variable("uv1", _3ds_point_uv(tri.faceuvs[0]))

            poly.add_variable("p2", _3ds_short(tri.vertex_index[2]))
            poly.add_variable("uv2", _3ds_point_uv(tri.faceuvs[2]))

            poly.add_variable("p3", _3ds_short(tri.vertex_index[1]))
            poly.add_variable("uv3", _3ds_point_uv(tri.faceuvs[1]))

            polys.add(poly)

        flags = 0

        #if "coll" not in ob.name and "shad" not in ob.name: flags = flags | 2
        if "shad" in ob.name: flags = flags | 4
        elif "coll" in ob.name: flags = flags | 8
        elif "main" in ob.name:
            flags = flags | 3
            if shadfound == False:
                flags = flags | 4
                log_file.write(
                    "! shadow mesh was not found, using main mesh for shadow.\n"
                )
            if collfound == False:
                flags = flags | 8
                log_file.write(
                    "! collision mesh was not found, using main mesh for collisions.\n"
                )
        else:
            flags = flags | 2

        #for some reason these are not used?
        """if "det_" in ob.name: flags = flags | 16
        if "gls_" in ob.name: flags = flags | 32
        if "plas_" in ob.name: flags = flags | 64
        if "wood_" in ob.name: flags = flags | 128
        if "metl_" in ob.name: flags = flags | 256
        if "expl_" in ob.name: flags = flags | 256 #????

        if "headl_" in ob.name: flags = flags | 1024
        if "brakel_" in ob.name: flags = flags | 2048"""

        submesh.add_variable("name", _3ds_string(sane_name(ob.name)))
        submesh.add_variable("flags", _3ds_uint(flags))

        v = blender_mesh.vertices[0].co
        lowx = v[0]
        highx = v[0]
        lowy = v[1]
        highy = v[1]
        lowz = v[2]
        highz = v[2]

        vertices = _3ds_array()
        #find dimensions of every mesh
        for vert in blender_mesh.vertices:
            pos = vert.co
            if pos[0] < lowx: lowx = pos[0]
            elif pos[0] > highx: highx = pos[0]

            if pos[1] < lowy: lowy = pos[1]
            elif pos[1] > highy: highy = pos[1]

            if pos[2] < lowz: lowz = pos[2]
            elif pos[2] > highz: highz = pos[2]

        #construct vertices array
        for vert in blender_mesh.vertices:
            pos = vert.co
            if (center_objects_to_origin == True):
                vertices.add(
                    _3ds_point_3d((pos[0] - (highx + lowx) / 2,
                                   pos[2] - (highz + lowz) / 2,
                                   pos[1] - (highy + lowy) / 2)))
            else:
                vertices.add(_3ds_point_3d((pos[0], pos[2], pos[1])))

        #construct mesh positions array
        pos = ob.matrix_world.to_translation()
        if (center_objects_to_origin == True):
            submesh.add_variable(
                "pos",
                _3ds_point_3d(((highx + lowx) / 2 - objcenterx,
                               (highz + lowz) / 2 - objcenterz,
                               (highy + lowy) / 2 - objcentery)))
        else:
            submesh.add_variable("pos", _3ds_point_3d(
                (pos[0], pos[2], pos[1])))

        #save mesh dimensions
        submesh.add_variable("Length", _3ds_float(highx - lowx))
        submesh.add_variable("Height", _3ds_float(highz - lowz))
        submesh.add_variable("Depth", _3ds_float(highy - lowy))

        s = 0
        for i in range(len(materials_list)):
            submesh.add_variable("texstart", _3ds_short(s))
            submesh.add_variable("numflat", _3ds_short(0))
            submesh.add_variable("numflatmetal", _3ds_short(0))
            submesh.add_variable("gourad", _3ds_short(material_size[i]))
            submesh.add_variable("gouradmetal", _3ds_short(0))
            submesh.add_variable("gouradmetalenv", _3ds_short(0))
            submesh.add_variable("shining", _3ds_short(0))
            s += material_size[i]

        submesh.add_variable("vertices", vertices)
        submesh.add_variable("polygons", polys)

        if submesh.validate():
            meshes_array.add(submesh)
        else:
            operator.report({'WARNING'},
                            "Object %r can't be written into a 3DS file")

        if not blender_mesh.users:
            bpy.data.meshes.remove(blender_mesh)

    meshes.add_variable("meshes", meshes_array)

    user = _3ds_chunk(sane_name("USER"))
    user.add_variable("userdatasize", _3ds_uint(0))
    user.add_variable("userdata", _3ds_stringtag(sane_name("")))

    primary.add_variable("version", _3ds_byte(2))

    primary.add_variable("Length", _3ds_float(length))
    primary.add_variable("Height", _3ds_float(height))
    primary.add_variable("Depth", _3ds_float(depth))

    primary.add_subchunk(tex)
    primary.add_subchunk(lights)
    primary.add_subchunk(meshes)
    primary.add_subchunk(user)

    #calculate all the sizes
    primary.get_size()
    # Open the file for writing:
    file = open(filepath, 'wb')

    # Recursively write the chunks to file:
    primary.write(file)

    # Close the file:
    file.close()

    # Clear name mapping vars, could make locals too
    del name_unique[:]
    name_mapping.clear()

    print("p3d export time: %.2f" % (time.clock() - time1))
    log_file.write("Finished p3d export. Time taken: %.2f \n\n\n" %
                   (time.clock() - time1))
    log_file.close()

    return {'FINISHED'}
コード例 #10
0
def save(
    context,
    filepath,
    *,
    use_selection=True,
    global_matrix=None,
):
    ##
    import bpy
    import mathutils
    import struct
    import bmesh
    from bpy_extras.io_utils import create_derived_objects, free_derived_objects

    ##
    file = open(filepath, 'wb')
    ##
    depsgraph = context.evaluated_depsgraph_get()
    scene = context.scene
    #exit edit mode
    if bpy.ops.object.mode_set.poll():
        bpy.ops.object.mode_set(mode='OBJECT')

    frame = scene.frame_current
    if use_selection:
        objects = context.selected_objects
    else:
        objects = scene.objects
    if global_matrix is None:
        global_matrix = mathutils.Matrix()

    mesh_objects = []
    print(f"Processing {len(objects)} objects...")
    for ob in objects:
        print(f"Object type: {ob.type}")
        if ob.type not in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}:
            continue

        # get derived ojects
        free, derived = create_derived_objects(scene, ob)
        if derived is None:
            continue

        print(f"Processing {len(derived)} derived objects...")
        for ob_derived, mat in derived:
            try:
                data = ob_derived.evaluated_get(depsgraph).to_mesh()
            except:
                data = None

            if data:
                print("Got data...")
                matrix = global_matrix @ mat
                data.transform(matrix)
                mesh_objects.append((ob_derived, data, matrix))

        if free:
            free_derived_objects(ob)

    faces = []
    vertices = []
    submeshes = []

    print(f"Processing {len(mesh_objects)} mesh objects...")
    for ob, blender_mesh, matrix in mesh_objects:

        submeshOffset = len(faces) * 3
        submeshCount = 0

        # explicitly triangulate the mesh
        bm = bmesh.new()
        bm.from_mesh(blender_mesh)
        bmesh.ops.triangulate(bm, faces=bm.faces[:])
        bm.to_mesh(blender_mesh)
        bm.free()

        blender_mesh.calc_loop_triangles()
        blender_mesh.calc_tangents()
        for i, face in enumerate(blender_mesh.loop_triangles):
            faceVertices = []
            for vertIdx, loopIdx in zip(face.vertices, face.loops):
                position = (-blender_mesh.vertices[vertIdx].co.x,
                            blender_mesh.vertices[vertIdx].co.y,
                            blender_mesh.vertices[vertIdx].co.z)
                normal = (-blender_mesh.vertices[vertIdx].normal.x,
                          blender_mesh.vertices[vertIdx].normal.y,
                          blender_mesh.vertices[vertIdx].normal.z)
                tangent = (blender_mesh.loops[loopIdx].tangent.x,
                           blender_mesh.loops[loopIdx].tangent.y,
                           blender_mesh.loops[loopIdx].tangent.z)
                uvLayer0 = blender_mesh.uv_layers.active.data
                uvs = (uvLayer0[loopIdx].uv[0], uvLayer0[loopIdx].uv[1])
                faceVertices.append(
                    Vertex(vertIdx, position, normal, tangent, uvs))
                submeshCount = submeshCount + 1
            faces.append(Face(faceVertices))
        submeshes.append(Submesh(submeshOffset, submeshCount))
        print(
            f"Added submesh with offset = {submeshOffset}, count = {submeshCount}"
        )
    ##
    indices = []
    indexMap = {}
    for f in faces:
        ind = []
        for v in f.vertices:
            vTuple = v.get_tuple()
            if vTuple in indexMap:
                ind.append(indexMap[vTuple])
            else:
                ind.append(len(vertices))
                indexMap[vTuple] = len(vertices)
                vertices.append(v)
        indices.append(ind[0])
        indices.append(ind[2])
        indices.append(ind[1])

    # write header
    numIndices = len(indices)
    formatSpecifier = None
    if numIndices <= 256:
        formatSpecifier = '<B'
        indexFormat = IndexFormat.UINT8
    else:
        if numIndices > 0xffff:
            formatSpecifier = '<I'
            indexFormat = IndexFormat.UINT32
        else:
            formatSpecifier = '<H'
            indexFormat = IndexFormat.UINT16

    file.write(
        struct.pack('<B', int(VertexFormat.POSITION_NORMAL_TANGENT_TEXCOORD0)))
    file.write(struct.pack(
        '<B', int(indexFormat)))  # @NOTE assumption of 2 byte indices
    file.write(struct.pack('<Q', len(vertices)))
    file.write(struct.pack('<Q', numIndices))
    file.write(struct.pack('<I', len(submeshes)))

    # write bounding box

    bbox = AABB(
        Vec3(vertices[0].position[0], vertices[0].position[1],
             vertices[0].position[2]),
        Vec3(vertices[0].position[0], vertices[0].position[1],
             vertices[0].position[2]))
    for v in vertices:
        if v.position[0] < bbox.min.x:
            bbox.min.x = v.position[0]
        if v.position[1] < bbox.min.y:
            bbox.min.y = v.position[1]
        if v.position[2] < bbox.min.z:
            bbox.min.z = v.position[2]

        if v.position[0] > bbox.max.x:
            bbox.max.x = v.position[0]
        if v.position[1] > bbox.max.y:
            bbox.max.y = v.position[1]
        if v.position[2] > bbox.max.z:
            bbox.max.z = v.position[2]

    file.write(struct.pack('<f', bbox.max.x))
    file.write(struct.pack('<f', bbox.max.y))
    file.write(struct.pack('<f', bbox.max.z))
    file.write(struct.pack('<f', bbox.min.x))
    file.write(struct.pack('<f', bbox.min.y))
    file.write(struct.pack('<f', bbox.min.z))

    print(
        f"Writing mesh with {len(vertices)} vertices, {len(indices)} indices, {len(submeshes)} submeshes."
    )

    # write vertices
    for i, v in enumerate(vertices):
        # position
        file.write(struct.pack('<f', v.position[0]))
        file.write(struct.pack('<f', v.position[1]))
        file.write(struct.pack('<f', v.position[2]))
        # normal
        file.write(struct.pack('<f', v.normal[0]))
        file.write(struct.pack('<f', v.normal[1]))
        file.write(struct.pack('<f', v.normal[2]))
        # tangent
        file.write(struct.pack('<f', v.tangent[0]))
        file.write(struct.pack('<f', v.tangent[1]))
        file.write(struct.pack('<f', v.tangent[2]))
        file.write(struct.pack('<f', 0))
        # uvs
        file.write(struct.pack('<f', v.uvs[0]))
        file.write(struct.pack('<f', v.uvs[1]))

    # write indices
    for i in indices:
        file.write(struct.pack(formatSpecifier, i))

    # write submeshes
    for submesh in submeshes:
        print(
            f"Write submesh with offset = {submesh.offset}, count = {submesh.count}"
        )
        file.write(struct.pack('<Q', submesh.offset))
        file.write(struct.pack('<Q', submesh.count))

    file.close()
    return {'FINISHED'}
コード例 #11
0
ファイル: import_blender.py プロジェクト: Ace17/abrasive
def exportMesh(scene, filepath=""):
    if bpy.ops.object.mode_set.poll():
        bpy.ops.object.mode_set(mode='OBJECT')

    # Make a list of all materials used in the selected meshes (use a dictionary,
    # each material is added once):
    materialDict = {}
    mesh_objects = []

    objects = (ob for ob in scene.objects if ob.is_visible(scene))

    for ob in objects:
        # get derived objects
        free, derived = create_derived_objects(scene, ob)

        if derived is None:
            continue

        for ob_derived, mat in derived:
            if ob.type not in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}:
                continue

            try:
                data = ob_derived.to_mesh(scene, True, 'PREVIEW')
            except:
                data = None

            if data:
                matrix = mat
                data.transform(matrix)
                mesh_objects.append((ob_derived, data, matrix))
                mat_ls = data.materials
                mat_ls_len = len(mat_ls)

                # get material/image tuples.
                if data.tessface_uv_textures:
                    if not mat_ls:
                        mat = mat_name = None

                    for f, uf in zip(data.tessfaces,
                                     data.tessface_uv_textures.active.data):
                        if mat_ls:
                            mat_index = f.material_index
                            if mat_index >= mat_ls_len:
                                mat_index = f.mat = 0
                            mat = mat_ls[mat_index]
                            mat_name = None if mat is None else mat.name
                        # else there already set to none

                        img = uf.image
                        img_name = None if img is None else img.name

                        materialDict.setdefault((mat_name, img_name),
                                                (mat, img))

                else:
                    for mat in mat_ls:
                        if mat:  # material may be None so check its not.
                            materialDict.setdefault((mat.name, None),
                                                    (mat, None))

                    # Why 0 Why!
                    for f in data.tessfaces:
                        if f.material_index >= mat_ls_len:
                            f.material_index = 0

        if free:
            free_derived_objects(ob)

    assert (len(mesh_objects) == 1)

    # Create object chunks for all meshes:
    (ob, blender_mesh, matrix) = mesh_objects[0]

    # make a mesh chunk out of the mesh:
    dumpMesh(blender_mesh, filepath)
コード例 #12
0
def save(operator, context, filepath="", use_selection=True, global_matrix=None):
    
    file = open(filepath, 'wb')
    
    import bpy
    import mathutils
    import struct
    import bmesh
    from bpy_extras.io_utils import create_derived_objects, free_derived_objects

    if global_matrix is None:
        global_matrix = mathutils.Matrix()
    
    mesh_objects = [] 

    scene = context.scene
    if use_selection:
        objects = (ob for ob in scene.objects if ob.is_visible(scene) and ob.select)
    else:
        objects = (ob for ob in scene.objects if ob.is_visible(scene))

    for ob in objects:
        # get derived objects
        free, derived = create_derived_objects(scene, ob)

        if derived is None:
            continue

        for ob_derived, mat in derived:
            if ob.type not in {'MESH', 'CURVE', 'SURFACE', 'FONT', 'META'}:
                continue

            try:
                data = ob_derived.to_mesh(scene, True, 'PREVIEW')
            except:
                data = None
            
            if data:
                matrix = global_matrix * mat
                data.transform(matrix)
                mesh_objects.append((ob_derived, data, matrix))

        if free:
            free_derived_objects(ob)

    # write number of meshes
    file.write(struct.pack('<I', len(mesh_objects)))

    id = 0
    for ob, blender_mesh, matrix in mesh_objects:

        # convert all faces to triangles and extract UVs
        bm = bmesh.new()
        bm.from_mesh(blender_mesh)
        bmesh.ops.triangulate(bm, faces=bm.faces[:], quad_method=0, ngon_method=0)
        bm.verts.index_update()

        bm.to_mesh(blender_mesh)
        bm.free()

        blender_mesh.calc_normals()             # calculate normals
        blender_mesh.update(calc_tessface=True)

        # extract faces
        faces = []
        for i, face in enumerate(blender_mesh.tessfaces):
            faceVertices = []
            for n, vertIdx in enumerate(face.vertices):
                position = (blender_mesh.vertices[vertIdx].co.x, blender_mesh.vertices[vertIdx].co.y, blender_mesh.vertices[vertIdx].co.z)
                normal = (blender_mesh.vertices[vertIdx].normal.x, blender_mesh.vertices[vertIdx].normal.y, blender_mesh.vertices[vertIdx].normal.z)
                tex = blender_mesh.tessface_uv_textures[0]
                uvs = (tex.data[i].uv[n][0], tex.data[i].uv[n][1])
                blendWeights = [1.0, 0.0, 0.0, 0.0]
                blendIndices = [0, 0, 0, 0]

                groups = sorted(blender_mesh.vertices[vertIdx].groups, key=lambda item: item.weight, reverse=True)  
                sumweights = 0
                for g, group in enumerate(groups):
                    if g > 3:
                        break
                    sumweights += group.weight
                
                for g, group in enumerate(groups)
                    if g > 3:
                        print("data loss: vertex with more than 4 bones assigned")
                        break
                    blendWeights[g] = group.weight/sumweights
                    blendIndices[g] = ArmatureList[0].object.data.bones.find(objpar)
                
                faceVertices.append(Vertex(vertIdx, position, normal, uvs, blendWeights, blendIndices))
            faces.append(Face(faceVertices))
        
        vertices = []
        indices = []

        indexMap = {}
        for f in faces:
            ind = []
            for v in f.vertices:
                vTuple = v.get_tuple()
                if vTuple in indexMap:
                    ind.append(indexMap[vTuple])
                else:
                    ind.append(len(vertices))
                    indexMap[vTuple] = len(vertices)
                    vertices.append(v)
            indices.append(ind[0])
            indices.append(ind[1])
            indices.append(ind[2])
        
        # write submesh id
        file.write(struct.pack('<I', id))
        # write number of vertices
        file.write(struct.pack('<I', len(vertices)))
        # write interleaved vertex data as (position)(normal)(uvs)
        for i, v in enumerate(vertices):
            # position
            file.write(struct.pack('<f', v.position[0]))
            file.write(struct.pack('<f', v.position[1]))
            file.write(struct.pack('<f', v.position[2]))
            # normal
            file.write(struct.pack('<f', v.normal[0]))
            file.write(struct.pack('<f', v.normal[1]))
            file.write(struct.pack('<f', v.normal[2]))
            # uvs
            file.write(struct.pack('<f', v.uvs[0]))
            file.write(struct.pack('<f', v.uvs[1]))
            # blend weights
            file.write(struct.pack('<f', v.blendWeights[0]))
            file.write(struct.pack('<f', v.blendWeights[1]))
            file.write(struct.pack('<f', v.blendWeights[2]))
            file.write(struct.pack('<f', v.blendWeights[3]))
            # blend indices
            file.write(struct.pack('<I', v.blendIndices[0]))
            file.write(struct.pack('<I', v.blendIndices[1]))
            file.write(struct.pack('<I', v.blendIndices[2]))
            file.write(struct.pack('<I', v.blendIndices[3]))
            
        # write indices
        file.write(struct.pack('<I', len(indices)))
        for i in indices:
            file.write(struct.pack('<I', i))
        id = id + 1
        
    file.close()
    return {'FINISHED'}