[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [22853] branches/ge_dyn_load/source/ gameengine: Python API function for loading in a mesh and loading into the BGE as a library which can be freed later .

Campbell Barton ideasman42 at gmail.com
Sat Aug 29 01:34:13 CEST 2009


Revision: 22853
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=22853
Author:   campbellbarton
Date:     2009-08-29 01:34:13 +0200 (Sat, 29 Aug 2009)

Log Message:
-----------
Python API function for loading in a mesh and loading into the BGE as a library which can be freed later.

This means python can create meshes at runtime and load into the BGE, looked into having python create GE meshes directly but the GE relies too much on links to blender data for this.

Modified Paths:
--------------
    branches/ge_dyn_load/source/gameengine/Converter/BL_BlenderDataConversion.cpp
    branches/ge_dyn_load/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
    branches/ge_dyn_load/source/gameengine/Converter/KX_BlenderSceneConverter.h
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_LogicManager.cpp
    branches/ge_dyn_load/source/gameengine/GameLogic/SCA_LogicManager.h
    branches/ge_dyn_load/source/gameengine/Ketsji/KX_PythonInit.cpp

Modified: branches/ge_dyn_load/source/gameengine/Converter/BL_BlenderDataConversion.cpp
===================================================================
--- branches/ge_dyn_load/source/gameengine/Converter/BL_BlenderDataConversion.cpp	2009-08-28 22:04:37 UTC (rev 22852)
+++ branches/ge_dyn_load/source/gameengine/Converter/BL_BlenderDataConversion.cpp	2009-08-28 23:34:13 UTC (rev 22853)
@@ -725,6 +725,7 @@
 
 	if ((meshobj = converter->FindGameMesh(mesh/*, ob->lay*/)) != NULL)
 		return meshobj;
+	
 	// Get DerivedMesh data
 	DerivedMesh *dm = CDDM_from_mesh(mesh, blenderobj);
 
@@ -838,9 +839,11 @@
 			if (mface->v4)
 				tan3 = tangent[f*4 + 3];
 		}
+		if(blenderobj)
+			ma = give_current_material(blenderobj, mface->mat_nr+1);
+		else
+			ma = mesh->mat[mface->mat_nr];
 
- 		ma = give_current_material(blenderobj, mface->mat_nr+1);
-
 		{
 			bool visible = true;
 			bool twoside = false;

Modified: branches/ge_dyn_load/source/gameengine/Converter/KX_BlenderSceneConverter.cpp
===================================================================
--- branches/ge_dyn_load/source/gameengine/Converter/KX_BlenderSceneConverter.cpp	2009-08-28 22:04:37 UTC (rev 22852)
+++ branches/ge_dyn_load/source/gameengine/Converter/KX_BlenderSceneConverter.cpp	2009-08-28 23:34:13 UTC (rev 22853)
@@ -76,6 +76,8 @@
 {
 #include "DNA_object_types.h"
 #include "DNA_curve_types.h"
+#include "DNA_mesh_types.h"
+#include "DNA_material_types.h"
 #include "BLI_blenlib.h"
 #include "MEM_guardedalloc.h"
 //XXX #include "BSE_editipo.h"
@@ -84,6 +86,8 @@
 #include "BKE_global.h"
 #include "BKE_library.h"
 #include "BKE_ipo.h" // eval_icu
+#include "BKE_material.h" // copy_material
+#include "BKE_mesh.h" // copy_mesh
 #include "DNA_space_types.h"
 }
 
@@ -975,15 +979,20 @@
 	return m_DynamicMaggie;
 }
 
+Main* KX_BlenderSceneConverter::GetMainDynamicPath(const char *path)
+{
+	for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++)
+		if(strcmp((*it)->name, path)==0)
+			return *it;
+	
+	return NULL;
+}
 
 bool KX_BlenderSceneConverter::LinkBlendFile(const char *path)
 {
-
-	for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) {
-		if(strcmp((*it)->name, path)==0) {
-			printf( "blend file alredy open \"%s\"\n", path);
-			return false;
-		}
+	if(GetMainDynamicPath(path)) {
+		printf( "blend file alredy open \"%s\"\n", path);
+		return false;
 	}
 
 	BlendHandle *bpy_openlib = NULL;	/* ptr to the open .blend file */
@@ -1268,6 +1277,24 @@
 			scene_idx--;
 		}
 		else {
+			
+			/* incase the mesh might be refered to later */
+			{
+				GEN_Map<STR_HashedString,void*> &mapStringToMeshes = scene->GetLogicManager()->GetMeshMap();
+				
+				for(int i=0; i<mapStringToMeshes.size(); i++)
+				{
+					RAS_MeshObject *meshobj= (RAS_MeshObject *) *mapStringToMeshes.at(i);
+					if(meshobj && IS_TAGGED(meshobj->GetMesh()))
+					{	
+						STR_HashedString mn = meshobj->GetName();
+						mapStringToMeshes.remove(mn);
+						printf("REMIOVE %d\n", i);
+						i--;
+					}
+				}
+			}
+			
 			//scene->FreeTagged(); /* removed tagged objects and meshes*/
 			CListValue *obj_lists[] = {scene->GetObjectList(), scene->GetInactiveList(), NULL};
 
@@ -1478,12 +1505,7 @@
 
 bool KX_BlenderSceneConverter::FreeBlendFile(const char *path)
 {
-	for (vector<Main*>::iterator it=m_DynamicMaggie.begin(); !(it==m_DynamicMaggie.end()); it++) {
-		if(strcmp((*it)->name, path)==0)
-			return KX_BlenderSceneConverter::FreeBlendFile(*it);
-	}
-
-	return false;
+	return FreeBlendFile(GetMainDynamicPath(path));
 }
 
 bool KX_BlenderSceneConverter::MergeScene(KX_Scene *to, KX_Scene *from)
@@ -1531,3 +1553,76 @@
 	}
 
 }
+
+/* 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)
+{
+	ID *me;
+	
+	/* Find a mesh in the current main */
+	for(me = (ID *)m_maggie->mesh.first; me; me= (ID *)me->next)
+		if(strcmp(name, me->name+2)==0)
+			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) {
+		printf("Mesh has a user \"%s\"\n", name);
+		me = (ID*)copy_mesh((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= copy_material( 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;
+}

Modified: branches/ge_dyn_load/source/gameengine/Converter/KX_BlenderSceneConverter.h
===================================================================
--- branches/ge_dyn_load/source/gameengine/Converter/KX_BlenderSceneConverter.h	2009-08-28 22:04:37 UTC (rev 22852)
+++ branches/ge_dyn_load/source/gameengine/Converter/KX_BlenderSceneConverter.h	2009-08-28 23:34:13 UTC (rev 22853)
@@ -142,11 +142,13 @@
 
 	struct Scene* GetBlenderSceneForName(const STR_String& name);
 
-	//struct Main* GetMain() { return m_maggie; };
+//	struct Main* GetMain() { return m_maggie; };
+	struct Main*		  GetMainDynamicPath(const char *path);
 	vector<struct Main*> &GetMainDynamic();
-
+	
 	bool LinkBlendFile(const char *path);
 	bool MergeScene(KX_Scene *to, KX_Scene *from);
+	RAS_MeshObject *ConvertMeshSpecial(KX_Scene* kx_scene, Main *maggie, const char *name);
 	bool FreeBlendFile(struct Main *maggie);
 	bool FreeBlendFile(const char *path);
 

Modified: branches/ge_dyn_load/source/gameengine/GameLogic/SCA_LogicManager.cpp
===================================================================
--- branches/ge_dyn_load/source/gameengine/GameLogic/SCA_LogicManager.cpp	2009-08-28 22:04:37 UTC (rev 22852)
+++ branches/ge_dyn_load/source/gameengine/GameLogic/SCA_LogicManager.cpp	2009-08-28 23:34:13 UTC (rev 22853)
@@ -283,6 +283,11 @@
 	m_mapStringToMeshes.insert(mn,mesh);
 }
 
+void SCA_LogicManager::UnregisterMeshName(const STR_String& meshname,void* mesh)
+{
+	STR_HashedString mn = meshname;
+	m_mapStringToMeshes.remove(mn);
+}
 
 
 void SCA_LogicManager::RegisterActionName(const STR_String& actname,void* action)

Modified: branches/ge_dyn_load/source/gameengine/GameLogic/SCA_LogicManager.h
===================================================================
--- branches/ge_dyn_load/source/gameengine/GameLogic/SCA_LogicManager.h	2009-08-28 22:04:37 UTC (rev 22852)
+++ branches/ge_dyn_load/source/gameengine/GameLogic/SCA_LogicManager.h	2009-08-28 23:34:13 UTC (rev 22853)
@@ -125,6 +125,9 @@
 
 	// for the scripting... needs a FactoryManager later (if we would have time... ;)
 	void	RegisterMeshName(const STR_String& meshname,void* mesh);
+	void	UnregisterMeshName(const STR_String& meshname,void* mesh);
+	GEN_Map<STR_HashedString,void*>&	GetMeshMap() { return m_mapStringToMeshes; };
+	
 	void	RegisterActionName(const STR_String& actname,void* action);
 
 	void*	GetActionByName (const STR_String& actname);

Modified: branches/ge_dyn_load/source/gameengine/Ketsji/KX_PythonInit.cpp
===================================================================
--- branches/ge_dyn_load/source/gameengine/Ketsji/KX_PythonInit.cpp	2009-08-28 22:04:37 UTC (rev 22852)
+++ branches/ge_dyn_load/source/gameengine/Ketsji/KX_PythonInit.cpp	2009-08-28 23:34:13 UTC (rev 22853)
@@ -652,6 +652,37 @@
 #endif
 }
 
+#include "KX_MeshProxy.h"
+static PyObject *gNewLibrary(PyObject*, PyObject* args)
+{
+	KX_Scene *kx_scene= gp_KetsjiScene;
+	char *path;
+	char *name;
+
+	if (!PyArg_ParseTuple(args,"ss:LibNew",&path, &name))
+		return NULL;
+	
+	if(kx_scene->GetSceneConverter()->GetMainDynamicPath(path))
+	{
+		PyErr_SetString(PyExc_KeyError, "the name of the path given exists");
+		return NULL;
+	}
+	
+	Main *maggie= (Main *)MEM_callocN( sizeof(Main), "BgeMain");
+	kx_scene->GetSceneConverter()->GetMainDynamic().push_back(maggie);
+	
+	strncpy(maggie->name, path, sizeof(maggie->name));
+	
+	/* Copy the object into main */
+	//kx_scene->GetSceneConverter()->GetMain();
+	RAS_MeshObject *meshobj= kx_scene->GetSceneConverter()->ConvertMeshSpecial(kx_scene, maggie, name);
+	if(meshobj) {
+		KX_MeshProxy* meshproxy = new KX_MeshProxy(meshobj);
+		return meshproxy->NewProxy(true);
+	}
+	Py_RETURN_NONE;
+}
+
 static PyObject *gFreeLibrary(PyObject*, PyObject* args)
 {
 	KX_Scene *kx_scene= gp_KetsjiScene;
@@ -664,8 +695,20 @@
 	Py_RETURN_NONE;
 }
 
+static PyObject *gListLibrary(PyObject*, PyObject* args)
+{
+	vector<Main*> &dynMaggie = gp_KetsjiScene->GetSceneConverter()->GetMainDynamic();
+	int i= 0;
+	PyObject *list= PyList_New(dynMaggie.size());
+	
+	for (vector<Main*>::iterator it=dynMaggie.begin(); !(it==dynMaggie.end()); it++)
+	{
+		PyList_SET_ITEM(list, i++, PyUnicode_FromString( (*it)->name) );
+	}
+	
+	return list;
+}
 
-
 static struct PyMethodDef game_methods[] = {
 	{"expandPath", (PyCFunction)gPyExpandPath, METH_VARARGS, (const char *)gPyExpandPath_doc},
 	{"sendMessage", (PyCFunction)gPySendMessage, METH_VARARGS, (const char *)gPySendMessage_doc},
@@ -694,8 +737,13 @@
 	{"PrintGLInfo", (PyCFunction)pyPrintExt, METH_NOARGS, (const char *)"Prints GL Extension Info"},
 	{"PrintMemInfo", (PyCFunction)pyPrintStats, METH_NOARGS, (const char *)"Print engine stastics"},

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list