Esempio n. 1
0
int id_copy(ID *id, ID **newid, int test)
{
    if (!test) *newid = NULL;

    /* conventions:
     * - make shallow copy, only this ID block
     * - id.us of the new ID is set to 1 */
    switch (GS(id->name)) {
    case ID_SCE:
        return 0; /* can't be copied from here */
    case ID_LI:
        return 0; /* can't be copied from here */
    case ID_OB:
        if (!test) *newid = (ID *)BKE_object_copy((Object *)id);
        return 1;
    case ID_ME:
        if (!test) *newid = (ID *)BKE_mesh_copy((Mesh *)id);
        return 1;
    case ID_CU:
        if (!test) *newid = (ID *)BKE_curve_copy((Curve *)id);
        return 1;
    case ID_MB:
        if (!test) *newid = (ID *)BKE_mball_copy((MetaBall *)id);
        return 1;
    case ID_MA:
        if (!test) *newid = (ID *)BKE_material_copy((Material *)id);
        return 1;
    case ID_TE:
        if (!test) *newid = (ID *)BKE_texture_copy((Tex *)id);
        return 1;
    case ID_IM:
        if (!test) *newid = (ID *)BKE_image_copy((Image *)id);
        return 1;
    case ID_LT:
        if (!test) *newid = (ID *)BKE_lattice_copy((Lattice *)id);
        return 1;
    case ID_LA:
        if (!test) *newid = (ID *)BKE_lamp_copy((Lamp *)id);
        return 1;
    case ID_SPK:
        if (!test) *newid = (ID *)BKE_speaker_copy((Speaker *)id);
        return 1;
    case ID_CA:
        if (!test) *newid = (ID *)BKE_camera_copy((Camera *)id);
        return 1;
    case ID_IP:
        return 0; /* deprecated */
    case ID_KE:
        if (!test) *newid = (ID *)BKE_key_copy((Key *)id);
        return 1;
    case ID_WO:
        if (!test) *newid = (ID *)BKE_world_copy((World *)id);
        return 1;
    case ID_SCR:
        return 0; /* can't be copied from here */
    case ID_VF:
        return 0; /* not implemented */
    case ID_TXT:
        if (!test) *newid = (ID *)BKE_text_copy((Text *)id);
        return 1;
    case ID_SCRIPT:
        return 0; /* deprecated */
    case ID_SO:
        return 0; /* not implemented */
    case ID_GR:
        if (!test) *newid = (ID *)BKE_group_copy((Group *)id);
        return 1;
    case ID_AR:
        if (!test) *newid = (ID *)BKE_armature_copy((bArmature *)id);
        return 1;
    case ID_AC:
        if (!test) *newid = (ID *)BKE_action_copy((bAction *)id);
        return 1;
    case ID_NT:
        if (!test) *newid = (ID *)ntreeCopyTree((bNodeTree *)id);
        return 1;
    case ID_BR:
        if (!test) *newid = (ID *)BKE_brush_copy((Brush *)id);
        return 1;
    case ID_PA:
        if (!test) *newid = (ID *)BKE_particlesettings_copy((ParticleSettings *)id);
        return 1;
    case ID_WM:
        return 0; /* can't be copied from here */
    case ID_GD:
        return 0; /* not implemented */
    }

    return 0;
}
Esempio n. 2
0
/* This function merges a mesh from the current scene into another main
 * it does not convert */
RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene* kx_scene, Main *maggie, const char *name)
{
	/* Find a mesh in the current main */
	ID *me= static_cast<ID *>(BLI_findstring(&m_maggie->mesh, name, offsetof(ID, name) + 2));
	
	if (me==NULL) {
		printf("Could not be found \"%s\"\n", name);
		return NULL;
	}
	
	/* Watch this!, if its used in the original scene can cause big troubles */
	if (me->us > 0) {
		printf("Mesh has a user \"%s\"\n", name);
		me = (ID*)BKE_mesh_copy((Mesh*)me);
		me->us--;
	}
	BLI_remlink(&m_maggie->mesh, me); /* even if we made the copy it needs to be removed */
	BLI_addtail(&maggie->mesh, me);

	
	/* Must copy the materials this uses else we cant free them */
	{
		Mesh *mesh= (Mesh *)me;
		
		/* ensure all materials are tagged */
		for (int i=0; i<mesh->totcol; i++)
			if (mesh->mat[i])
				mesh->mat[i]->id.flag &= ~LIB_DOIT;
		
		for (int i=0; i<mesh->totcol; i++)
		{
			Material *mat_old= mesh->mat[i];
			
			/* if its tagged its a replaced material */
			if (mat_old && (mat_old->id.flag & LIB_DOIT)==0)
			{
				Material *mat_old= mesh->mat[i];
				Material *mat_new= BKE_material_copy( mat_old );
				
				mat_new->id.flag |= LIB_DOIT;
				mat_old->id.us--;
				
				BLI_remlink(&m_maggie->mat, mat_new);
				BLI_addtail(&maggie->mat, mat_new);
				
				mesh->mat[i]= mat_new;
				
				/* the same material may be used twice */
				for (int j=i+1; j<mesh->totcol; j++)
				{
					if (mesh->mat[j]==mat_old)
					{
						mesh->mat[j]= mat_new;
						mat_new->id.us++;
						mat_old->id.us--;
					}
				}
			}
		}
	}
	
	RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this);
	kx_scene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
	m_map_mesh_to_gamemesh.clear(); /* This is at runtime so no need to keep this, BL_ConvertMesh adds */
	return meshobj;
}
/* This function merges a mesh from the current scene into another main
 * it does not convert */
RAS_MeshObject *KX_BlenderSceneConverter::ConvertMeshSpecial(KX_Scene *kx_scene, Main *maggie, const char *name)
{
	/* Find a mesh in the current main */
	ID *me= static_cast<ID *>(BLI_findstring(&m_maggie->mesh, name, offsetof(ID, name) + 2));
	Main *from_maggie = m_maggie;

	if (me == NULL) {
		// The mesh wasn't in the current main, try any dynamic (i.e., LibLoaded) ones
		vector<Main *>::iterator it;

		for (it = GetMainDynamic().begin(); it != GetMainDynamic().end(); it++) {
			me = static_cast<ID *>(BLI_findstring(&(*it)->mesh, name, offsetof(ID, name) + 2));
			from_maggie = *it;

			if (me)
				break;
		}
	}

	if (me == NULL) {
		printf("Could not be found \"%s\"\n", name);
		return NULL;
	}

	/* Watch this!, if its used in the original scene can cause big troubles */
	if (me->us > 0) {
#ifdef DEBUG
		printf("Mesh has a user \"%s\"\n", name);
#endif
		me = (ID*)BKE_mesh_copy_ex(from_maggie, (Mesh*)me);
		id_us_min(me);
	}
	BLI_remlink(&from_maggie->mesh, me); /* even if we made the copy it needs to be removed */
	BLI_addtail(&maggie->mesh, me);

	/* Must copy the materials this uses else we cant free them */
	{
		Mesh *mesh = (Mesh *)me;

		/* ensure all materials are tagged */
		for (int i = 0; i < mesh->totcol; i++) {
			if (mesh->mat[i])
				mesh->mat[i]->id.tag &= ~LIB_TAG_DOIT;
		}

		for (int i = 0; i < mesh->totcol; i++) {
			Material *mat_old = mesh->mat[i];

			/* if its tagged its a replaced material */
			if (mat_old && (mat_old->id.tag & LIB_TAG_DOIT) == 0) {
				Material *mat_old = mesh->mat[i];
				Material *mat_new = BKE_material_copy(mat_old);

				mat_new->id.tag |= LIB_TAG_DOIT;
				id_us_min(&mat_old->id);

				BLI_remlink(&G.main->mat, mat_new); // BKE_material_copy uses G.main, and there is no BKE_material_copy_ex
				BLI_addtail(&maggie->mat, mat_new);

				mesh->mat[i] = mat_new;

				/* the same material may be used twice */
				for (int j = i + 1; j < mesh->totcol; j++) {
					if (mesh->mat[j] == mat_old) {
						mesh->mat[j] = mat_new;
						id_us_plus(&mat_new->id);
						id_us_min(&mat_old->id);
					}
				}
			}
		}
	}

	m_currentScene = kx_scene; // This needs to be set in case we LibLoaded earlier
	RAS_MeshObject *meshobj = BL_ConvertMesh((Mesh *)me, NULL, kx_scene, this, false);
	kx_scene->GetLogicManager()->RegisterMeshName(meshobj->GetName(),meshobj);
	m_map_mesh_to_gamemesh.clear(); /* This is at runtime so no need to keep this, BL_ConvertMesh adds */
	return meshobj;
}