From 0c07d03e26f5ae09e7bfda423475df394ecccd21 Mon Sep 17 00:00:00 2001 From: namespace Date: Thu, 28 Jun 2007 17:01:18 +0000 Subject: [PATCH] - Added material-support to brushexport-plugin (Shaderman) git-svn-id: svn://svn.icculus.org/gtkradiant/GtkRadiant/trunk@172 8a3a26a2-13c4-0310-b231-cf6edde360e5 --- CHANGES | 3 + contrib/brushexport/callbacks.cpp | 252 +++++++----- contrib/brushexport/callbacks.h | 23 +- contrib/brushexport/export.cpp | 647 +++++++++++++++++------------- contrib/brushexport/export.h | 30 +- contrib/brushexport/interface.cpp | 453 +++++++++++---------- contrib/brushexport/plugin.cpp | 268 ++++++------- contrib/brushexport/support.cpp | 62 +-- contrib/brushexport/support.h | 48 +-- 9 files changed, 981 insertions(+), 805 deletions(-) diff --git a/CHANGES b/CHANGES index 6abb592e..ae398ab3 100644 --- a/CHANGES +++ b/CHANGES @@ -1,6 +1,9 @@ This is the changelog for developers, != changelog for the end user that we distribute with the binaries. (see changelog) +28/06/2007 +- Added material-support to brushexport-plugin (Shaderman) + 26/04/2007 - Disabled auto-search for texbrowser and entityinspector even when the option is turned on in the gtkrc diff --git a/contrib/brushexport/callbacks.cpp b/contrib/brushexport/callbacks.cpp index 9d34c926..ab6396ee 100644 --- a/contrib/brushexport/callbacks.cpp +++ b/contrib/brushexport/callbacks.cpp @@ -1,104 +1,148 @@ -#include -#include -#include - -#include "qerplugin.h" -#include "debugging/debugging.h" -#include "support.h" -#include "export.h" - -// stuff from interface.cpp -void DestroyWindow(); - - -namespace callbacks { - -void OnDestroy(GtkWidget* w, gpointer data) -{ - DestroyWindow(); -} - -void OnExportClicked(GtkButton* button, gpointer user_data) -{ - GtkWidget* window = lookup_widget(GTK_WIDGET(button), "w_plugplug2"); - ASSERT_NOTNULL(window); - const char* path = GlobalRadiant().m_pfnFileDialog(window, false, "Save as Obj", 0, 0); - if(!path) - return; - - // get ignore list from ui - std::set ignore; - - GtkTreeView* view = GTK_TREE_VIEW(lookup_widget(GTK_WIDGET(button), "t_materialist")); - GtkListStore* list = GTK_LIST_STORE(gtk_tree_view_get_model(view)); - - GtkTreeIter iter; - gboolean valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list), &iter); - while(valid) - { - gchar* data; - gtk_tree_model_get(GTK_TREE_MODEL(list), &iter, 0, &data, -1); - globalOutputStream() << data << "\n"; - ignore.insert(std::string(data)); - g_free(data); - valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(list), &iter); - } - - for(std::set::iterator it(ignore.begin()); it != ignore.end(); ++it) - globalOutputStream() << it->c_str() << "\n"; - - // collapse mode - collapsemode mode = COLLAPSE_NONE; - - GtkWidget* radio = lookup_widget(GTK_WIDGET(button), "r_collapse"); - ASSERT_NOTNULL(radio); - - if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))) - mode = COLLAPSE_ALL; - else - { - radio = lookup_widget(GTK_WIDGET(button), "r_collapsebymaterial"); - ASSERT_NOTNULL(radio); - if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))) - mode = COLLAPSE_BY_MATERIAL; - else - { - radio = lookup_widget(GTK_WIDGET(button), "r_nocollapse"); - ASSERT_NOTNULL(radio); - ASSERT_NOTNULL(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))); - mode = COLLAPSE_NONE; - } - } - - // export - ExportSelection(ignore, mode, path); -} - -void OnAddMaterial(GtkButton* button, gpointer user_data) -{ - GtkEntry* edit = GTK_ENTRY(lookup_widget(GTK_WIDGET(button), "ed_materialname")); - ASSERT_NOTNULL(edit); - - const gchar* name = gtk_entry_get_text(edit); - if(g_utf8_strlen(name, -1) > 0) - { - GtkListStore* list = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(lookup_widget(GTK_WIDGET(button), "t_materialist")))); - GtkTreeIter iter; - gtk_list_store_append(list, &iter); - gtk_list_store_set(list, &iter, 0, name, -1); - gtk_entry_set_text(edit, ""); - } -} - -void OnRemoveMaterial(GtkButton* button, gpointer user_data) -{ - GtkTreeView* view = GTK_TREE_VIEW(lookup_widget(GTK_WIDGET(button), "t_materialist")); - GtkListStore* list = GTK_LIST_STORE(gtk_tree_view_get_model(view)); - GtkTreeSelection* sel = gtk_tree_view_get_selection(view); - - GtkTreeIter iter; - if(gtk_tree_selection_get_selected(sel, 0, &iter)) - gtk_list_store_remove(list, &iter); -} - -}// callbacks +#include +#include +#include + +#include "qerplugin.h" +#include "debugging/debugging.h" +#include "support.h" +#include "export.h" + +// stuff from interface.cpp +void DestroyWindow(); + + +namespace callbacks { + +void OnDestroy(GtkWidget* w, gpointer data) +{ + DestroyWindow(); +} + +void OnExportClicked(GtkButton* button, gpointer user_data) +{ + GtkWidget* window = lookup_widget(GTK_WIDGET(button), "w_plugplug2"); + ASSERT_NOTNULL(window); + const char* cpath = GlobalRadiant().m_pfnFileDialog(window, false, "Save as Obj", 0, 0); + if(!cpath) + return; + + std::string path(cpath); + + // get ignore list from ui + std::set ignore; + + GtkTreeView* view = GTK_TREE_VIEW(lookup_widget(GTK_WIDGET(button), "t_materialist")); + GtkListStore* list = GTK_LIST_STORE(gtk_tree_view_get_model(view)); + + GtkTreeIter iter; + gboolean valid = gtk_tree_model_get_iter_first(GTK_TREE_MODEL(list), &iter); + while(valid) + { + gchar* data; + gtk_tree_model_get(GTK_TREE_MODEL(list), &iter, 0, &data, -1); + globalOutputStream() << data << "\n"; + ignore.insert(std::string(data)); + g_free(data); + valid = gtk_tree_model_iter_next (GTK_TREE_MODEL(list), &iter); + } + + for(std::set::iterator it(ignore.begin()); it != ignore.end(); ++it) + globalOutputStream() << it->c_str() << "\n"; + + // collapse mode + collapsemode mode = COLLAPSE_NONE; + + GtkWidget* radio = lookup_widget(GTK_WIDGET(button), "r_collapse"); + ASSERT_NOTNULL(radio); + + if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))) + mode = COLLAPSE_ALL; + else + { + radio = lookup_widget(GTK_WIDGET(button), "r_collapsebymaterial"); + ASSERT_NOTNULL(radio); + if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))) + mode = COLLAPSE_BY_MATERIAL; + else + { + radio = lookup_widget(GTK_WIDGET(button), "r_nocollapse"); + ASSERT_NOTNULL(radio); + ASSERT_NOTNULL(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(radio))); + mode = COLLAPSE_NONE; + } + } + + // export materials? + GtkWidget* toggle = lookup_widget(GTK_WIDGET(button), "t_exportmaterials"); + ASSERT_NOTNULL(toggle); + + bool exportmat = FALSE; + + if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle))) + exportmat = TRUE; + + // limit material names? + toggle = lookup_widget(GTK_WIDGET(button), "t_limitmatnames"); + ASSERT_NOTNULL(toggle); + + bool limitMatNames = FALSE; + + if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)) && exportmat) + limitMatNames = TRUE; + + // create objects instead of groups? + toggle = lookup_widget(GTK_WIDGET(button), "t_objects"); + ASSERT_NOTNULL(toggle); + + bool objects = FALSE; + + if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(toggle)) && exportmat) + objects = TRUE; + + // export + ExportSelection(ignore, mode, exportmat, path, limitMatNames, objects); +} + +void OnAddMaterial(GtkButton* button, gpointer user_data) +{ + GtkEntry* edit = GTK_ENTRY(lookup_widget(GTK_WIDGET(button), "ed_materialname")); + ASSERT_NOTNULL(edit); + + const gchar* name = gtk_entry_get_text(edit); + if(g_utf8_strlen(name, -1) > 0) + { + GtkListStore* list = GTK_LIST_STORE(gtk_tree_view_get_model(GTK_TREE_VIEW(lookup_widget(GTK_WIDGET(button), "t_materialist")))); + GtkTreeIter iter; + gtk_list_store_append(list, &iter); + gtk_list_store_set(list, &iter, 0, name, -1); + gtk_entry_set_text(edit, ""); + } +} + +void OnRemoveMaterial(GtkButton* button, gpointer user_data) +{ + GtkTreeView* view = GTK_TREE_VIEW(lookup_widget(GTK_WIDGET(button), "t_materialist")); + GtkListStore* list = GTK_LIST_STORE(gtk_tree_view_get_model(view)); + GtkTreeSelection* sel = gtk_tree_view_get_selection(view); + + GtkTreeIter iter; + if(gtk_tree_selection_get_selected(sel, 0, &iter)) + gtk_list_store_remove(list, &iter); +} + +void OnExportMatClicked(GtkButton* button, gpointer user_data) +{ + GtkWidget* toggleLimit = lookup_widget(GTK_WIDGET(button), "t_limitmatnames"); + GtkWidget* toggleObject = lookup_widget(GTK_WIDGET(button), "t_objects"); + + if(gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button))) + { + gtk_widget_set_sensitive(GTK_WIDGET(toggleLimit), TRUE); + gtk_widget_set_sensitive(GTK_WIDGET(toggleObject), TRUE); + } else { + gtk_widget_set_sensitive(GTK_WIDGET(toggleLimit), FALSE); + gtk_widget_set_sensitive(GTK_WIDGET(toggleObject), FALSE); + } +} + +}// callbacks diff --git a/contrib/brushexport/callbacks.h b/contrib/brushexport/callbacks.h index afad96c9..9bf95684 100644 --- a/contrib/brushexport/callbacks.h +++ b/contrib/brushexport/callbacks.h @@ -1,11 +1,12 @@ -typedef struct _GtkWidget GtkWidget; -typedef struct _GtkButton GtkButton; - -namespace callbacks { - -void OnDestroy(GtkWidget*, gpointer); -void OnExportClicked(GtkButton*, gpointer); -void OnAddMaterial(GtkButton*, gpointer); -void OnRemoveMaterial(GtkButton*, gpointer); - -}// callbacks +typedef struct _GtkWidget GtkWidget; +typedef struct _GtkButton GtkButton; + +namespace callbacks { + +void OnDestroy(GtkWidget*, gpointer); +void OnExportClicked(GtkButton*, gpointer); +void OnAddMaterial(GtkButton*, gpointer); +void OnRemoveMaterial(GtkButton*, gpointer); +void OnExportMatClicked(GtkButton* button, gpointer); + +}// callbacks diff --git a/contrib/brushexport/export.cpp b/contrib/brushexport/export.cpp index ffa40201..a0964fbb 100644 --- a/contrib/brushexport/export.cpp +++ b/contrib/brushexport/export.cpp @@ -1,274 +1,373 @@ -#include "export.h" -#include "debugging/debugging.h" -#include "ibrush.h" -#include "iscenegraph.h" -#include "iselection.h" -#include "stream/stringstream.h" -#include "stream/textfilestream.h" - -// this is very evil, but right now there is no better way -#include "../../radiant/brush.h" - -/* - Abstract baseclass for modelexporters - the class collects all the data which then gets - exported through the WriteToFile method. -*/ -class ExportData -{ -public: - ExportData(const std::set& ignorelist, collapsemode mode); - virtual ~ExportData(void); - - virtual void BeginBrush(Brush& b); - virtual void AddBrushFace(Face& f); - virtual void EndBrush(void); - - virtual bool WriteToFile(const std::string& path) const = 0; - -protected: - - // a group of faces - class group - { - public: - std::string name; - std::list faces; - }; - - std::list groups; - -private: - - // "textures/common/caulk" -> "caulk" - void GetShaderNameFromShaderPath(const char* path, std::string& name); - - group* current; - collapsemode mode; - const std::set& ignorelist; -}; - -ExportData::ExportData(const std::set& _ignorelist, collapsemode _mode) - : mode(_mode), - ignorelist(_ignorelist) -{ - current = 0; - - // in this mode, we need just one group - if(mode == COLLAPSE_ALL) - { - groups.push_back(group()); - current = &groups.back(); - current->name = "all"; - } -} - -ExportData::~ExportData(void) -{ - -} - -void ExportData::BeginBrush(Brush& b) -{ - // create a new group for each brush - if(mode == COLLAPSE_NONE) - { - groups.push_back(group()); - current = &groups.back(); - - StringOutputStream str(256); - str << "Brush" << (const unsigned int)groups.size(); - current->name = str.c_str(); - } -} - -void ExportData::EndBrush(void) -{ - // all faces of this brush were on the ignorelist, discard the emptygroup - if(mode == COLLAPSE_NONE) - { - ASSERT_NOTNULL(current); - if(current->faces.empty()) - { - groups.pop_back(); - current = 0; - } - } -} - -void ExportData::AddBrushFace(Face& f) -{ - std::string shadername; - GetShaderNameFromShaderPath(f.GetShader(), shadername); - - // faces mit materials auf der ignoreliste ignorieren - if(ignorelist.find(shadername) != ignorelist.end()) - return; - - if(mode == COLLAPSE_BY_MATERIAL) - { - // find a group for this material - current = 0; - const std::list::iterator end(groups.end()); - for(std::list::iterator it(groups.begin()); it != end; ++it) - { - if(it->name == shadername) - current = &(*it); - } - - // no group found, create one - if(!current) - { - groups.push_back(group()); - current = &groups.back(); - current->name = shadername; - } - } - - ASSERT_NOTNULL(current); - - // add face to current group - current->faces.push_back(&f); - -#ifdef _DEBUG - globalOutputStream() << "Added Face to group " << current->name.c_str() << "\n"; -#endif -} - -void ExportData::GetShaderNameFromShaderPath(const char* path, std::string& name) -{ - std::string tmp(path); - - size_t last_slash = tmp.find_last_of("/"); - - if(last_slash != std::string::npos && last_slash == (tmp.length() - 1)) - name = path; - else - name = tmp.substr(last_slash + 1, tmp.length() - last_slash); - - globalOutputStream() << "Last: " << last_slash << " " << "lenght: " << (const unsigned int)tmp.length() << "Name: " << name.c_str() << "\n"; -} - -/* - Exporter writing facedata as wavefront object -*/ -class ExportDataAsWavefront : public ExportData -{ -public: - ExportDataAsWavefront(const std::set& _ignorelist, collapsemode _mode) - : ExportData(_ignorelist, _mode) - { - } - - bool WriteToFile(const std::string& path) const; -}; - -bool ExportDataAsWavefront::WriteToFile(const std::string& path) const -{ - TextFileOutputStream out(path.c_str()); - - if(out.failed()) - { - globalErrorStream() << "Unable to open file\n"; - return false; - } - - out << "# Wavefront Objectfile exported with radiants brushexport plugin 2.0 by Thomas 'namespace' Nitschke, spam@codecreator.net\n\n"; - - unsigned int vertex_count = 0; - - const std::list::const_iterator gend(groups.end()); - for(std::list::const_iterator git(groups.begin()); git != gend; ++git) - { - const std::list::const_iterator end(git->faces.end()); - - // submesh starts here - out << "\ng " << git->name.c_str() << "\n"; - - for(std::list::const_iterator it(git->faces.begin()); it != end; ++it) - { - const Winding& w((*it)->getWinding()); - - // vertices - for(size_t i = 0; i < w.numpoints; ++i) - out << "v " << FloatFormat(w[i].vertex.x(), 1, 6) << " " << FloatFormat(w[i].vertex.y(), 1, 6) << " " << FloatFormat(w[i].vertex.z(), 1, 6) << "\n"; - } - out << "\n"; - - for(std::list::const_iterator it(git->faces.begin()); it != end; ++it) - { - const Winding& w((*it)->getWinding()); - - // texcoords - for(size_t i = 0; i < w.numpoints; ++i) - out << "vt " << FloatFormat(w[i].texcoord.x(), 1, 6) << " " << FloatFormat(w[i].texcoord.y(), 1, 6) << "\n"; - } - - for(std::list::const_iterator it(git->faces.begin()); it != end; ++it) - { - const Winding& w((*it)->getWinding()); - - // faces - out << "\nf"; - for(size_t i = 0; i < w.numpoints; ++i, ++vertex_count) - { - out << " " << vertex_count+1 << "/" << vertex_count+1; - } - } - out << "\n"; - } - - return true; -} - - -class ForEachFace : public BrushVisitor -{ -public: - ForEachFace(ExportData& _exporter) - : exporter(_exporter) - {} - - void visit(Face& face) const - { - exporter.AddBrushFace(face); - } - -private: - ExportData& exporter; -}; - -class ForEachSelected : public SelectionSystem::Visitor -{ -public: - ForEachSelected(ExportData& _exporter) - : exporter(_exporter) - {} - - void visit(scene::Instance& instance) const - { - BrushInstance* bptr = InstanceTypeCast::cast(instance); - if(bptr) - { - Brush& brush(bptr->getBrush()); - - exporter.BeginBrush(brush); - ForEachFace face_vis(exporter); - brush.forEachFace(face_vis); - exporter.EndBrush(); - } - } - -private: - ExportData& exporter; -}; - -bool ExportSelection(const std::set& ignorelist, collapsemode m, const std::string& path) -{ - ExportDataAsWavefront exporter(ignorelist, m); - - ForEachSelected vis(exporter); - GlobalSelectionSystem().foreachSelected(vis); - - return exporter.WriteToFile(path); -} +#include "export.h" +#include "debugging/debugging.h" +#include "ibrush.h" +#include "iscenegraph.h" +#include "iselection.h" +#include "stream/stringstream.h" +#include "stream/textfilestream.h" + +#include + +// this is very evil, but right now there is no better way +#include "../../radiant/brush.h" + +/* + Abstract baseclass for modelexporters + the class collects all the data which then gets + exported through the WriteToFile method. +*/ +class ExportData +{ +public: + ExportData(const std::set& ignorelist, collapsemode mode, bool limNames, bool objs); + virtual ~ExportData(void); + + virtual void BeginBrush(Brush& b); + virtual void AddBrushFace(Face& f); + virtual void EndBrush(void); + + virtual bool WriteToFile(const std::string& path, collapsemode mode) const = 0; + +protected: + + // a group of faces + class group + { + public: + std::string name; + std::list faces; + }; + + std::list groups; + +private: + + // "textures/common/caulk" -> "caulk" + void GetShaderNameFromShaderPath(const char* path, std::string& name); + + group* current; + collapsemode mode; + const std::set& ignorelist; +}; + +ExportData::ExportData(const std::set& _ignorelist, collapsemode _mode, bool _limNames, bool _objs) + : mode(_mode), + ignorelist(_ignorelist) +{ + current = 0; + + // in this mode, we need just one group + if(mode == COLLAPSE_ALL) + { + groups.push_back(group()); + current = &groups.back(); + current->name = "all"; + } +} + +ExportData::~ExportData(void) +{ + +} + +void ExportData::BeginBrush(Brush& b) +{ + // create a new group for each brush + if(mode == COLLAPSE_NONE) + { + groups.push_back(group()); + current = &groups.back(); + + StringOutputStream str(256); + str << "Brush" << (const unsigned int)groups.size(); + current->name = str.c_str(); + } +} + +void ExportData::EndBrush(void) +{ + // all faces of this brush were on the ignorelist, discard the emptygroup + if(mode == COLLAPSE_NONE) + { + ASSERT_NOTNULL(current); + if(current->faces.empty()) + { + groups.pop_back(); + current = 0; + } + } +} + +void ExportData::AddBrushFace(Face& f) +{ + std::string shadername; + GetShaderNameFromShaderPath(f.GetShader(), shadername); + + // ignore faces from ignore list + if(ignorelist.find(shadername) != ignorelist.end()) + return; + + if(mode == COLLAPSE_BY_MATERIAL) + { + // find a group for this material + current = 0; + const std::list::iterator end(groups.end()); + for(std::list::iterator it(groups.begin()); it != end; ++it) + { + if(it->name == shadername) + current = &(*it); + } + + // no group found, create one + if(!current) + { + groups.push_back(group()); + current = &groups.back(); + current->name = shadername; + } + } + + ASSERT_NOTNULL(current); + + // add face to current group + current->faces.push_back(&f); + +#ifdef _DEBUG + globalOutputStream() << "Added Face to group " << current->name.c_str() << "\n"; +#endif +} + +void ExportData::GetShaderNameFromShaderPath(const char* path, std::string& name) +{ + std::string tmp(path); + + size_t last_slash = tmp.find_last_of("/"); + + if(last_slash != std::string::npos && last_slash == (tmp.length() - 1)) + name = path; + else + name = tmp.substr(last_slash + 1, tmp.length() - last_slash); + +#ifdef _DEBUG + globalOutputStream() << "Last: " << last_slash << " " << "length: " << (const unsigned int)tmp.length() << "Name: " << name.c_str() << "\n"; +#endif +} + +/* + Exporter writing facedata as wavefront object +*/ +class ExportDataAsWavefront : public ExportData +{ +private: + bool expmat; + bool limNames; + bool objs; + +public: + ExportDataAsWavefront(const std::set& _ignorelist, collapsemode _mode, bool _expmat, bool _limNames, bool _objs) + : ExportData(_ignorelist, _mode, _limNames, _objs) + { + expmat = _expmat; + limNames = _limNames; + objs = _objs; + } + + bool WriteToFile(const std::string& path, collapsemode mode) const; +}; + +bool ExportDataAsWavefront::WriteToFile(const std::string& path, collapsemode mode) const +{ + std::string objFile = path.substr(0, path.length() -4) + ".obj"; + std::string mtlFile = path.substr(0, path.length() -4) + ".mtl"; + + std::set materials; + + TextFileOutputStream out(objFile.c_str()); + + if(out.failed()) + { + globalErrorStream() << "Unable to open file\n"; + return false; + } + + out << "# Wavefront Objectfile exported with radiants brushexport plugin 3.0 by Thomas 'namespace' Nitschke, spam@codecreator.net\n\n"; + + if(expmat) + { + size_t last = mtlFile.find_last_of("//"); + std::string mtllib = mtlFile.substr(last + 1, mtlFile.size() - last).c_str(); + out << "mtllib " << mtllib.c_str() << "\n"; + } + + unsigned int vertex_count = 0; + + const std::list::const_iterator gend(groups.end()); + for(std::list::const_iterator git(groups.begin()); git != gend; ++git) + { + typedef std::multimap bm; + bm brushMaterials; + typedef std::pair String_Pair; + + const std::list::const_iterator end(git->faces.end()); + + // submesh starts here + if(objs) + { + out << "\no "; + } else { + out << "\ng "; + } + out << git->name.c_str() << "\n"; + + // material + if(expmat && mode == COLLAPSE_ALL) + { + out << "usemtl material" << "\n\n"; + materials.insert("material"); + } + + for(std::list::const_iterator it(git->faces.begin()); it != end; ++it) + { + const Winding& w((*it)->getWinding()); + + // vertices + for(size_t i = 0; i < w.numpoints; ++i) + out << "v " << FloatFormat(w[i].vertex.x(), 1, 6) << " " << FloatFormat(w[i].vertex.z(), 1, 6) << " " << FloatFormat(w[i].vertex.y(), 1, 6) << "\n"; + } + out << "\n"; + + for(std::list::const_iterator it(git->faces.begin()); it != end; ++it) + { + const Winding& w((*it)->getWinding()); + + // texcoords + for(size_t i = 0; i < w.numpoints; ++i) + out << "vt " << FloatFormat(w[i].texcoord.x(), 1, 6) << " " << FloatFormat(w[i].texcoord.y(), 1, 6) << "\n"; + } + + for(std::list::const_iterator it(git->faces.begin()); it != end; ++it) + { + const Winding& w((*it)->getWinding()); + + // faces + StringOutputStream faceLine(256); + faceLine << "\nf"; + for(size_t i = 0; i < w.numpoints; ++i, ++vertex_count) + { + faceLine << " " << vertex_count+1 << "/" << vertex_count+1; + } + + if(mode != COLLAPSE_ALL) + { + materials.insert((*it)->getShader().getShader()); + brushMaterials.insert(String_Pair((*it)->getShader().getShader(), faceLine.c_str())); + } else { + out << faceLine.c_str(); + } + } + + if(mode != COLLAPSE_ALL) + { + std::string lastMat; + std::string mat; + std::string faces; + + for(bm::iterator iter = brushMaterials.begin(); iter != brushMaterials.end(); iter++) + { + mat = (*iter).first.c_str(); + faces = (*iter).second.c_str(); + + if(mat != lastMat) + { + if(limNames && mat.size() > 20) + { + out << "\nusemtl " << mat.substr(mat.size() - 20, mat.size()).c_str(); + } else { + out << "\nusemtl " << mat.c_str(); + } + } + + out << faces.c_str(); + lastMat = mat; + } + } + + out << "\n"; + } + + if(expmat) + { + TextFileOutputStream outMtl(mtlFile.c_str()); + if(outMtl.failed()) + { + globalErrorStream() << "Unable to open material file\n"; + return false; + } + + outMtl << "# Wavefront material file exported with GtkRadiants brushexport plugin.\n"; + outMtl << "# Material Count: " << (const Unsigned)materials.size() << "\n\n"; + for(std::set::const_iterator it(materials.begin()); it != materials.end(); ++it) + { + if(limNames && it->size() > 20) + { + outMtl << "newmtl " << it->substr(it->size() - 20, it->size()).c_str() << "\n"; + } else { + outMtl << "newmtl " << it->c_str() << "\n"; + } + } + } + + return true; +} + + +class ForEachFace : public BrushVisitor +{ +public: + ForEachFace(ExportData& _exporter) + : exporter(_exporter) + {} + + void visit(Face& face) const + { + exporter.AddBrushFace(face); + } + +private: + ExportData& exporter; +}; + +class ForEachSelected : public SelectionSystem::Visitor +{ +public: + ForEachSelected(ExportData& _exporter) + : exporter(_exporter) + {} + + void visit(scene::Instance& instance) const + { + BrushInstance* bptr = InstanceTypeCast::cast(instance); + if(bptr) + { + Brush& brush(bptr->getBrush()); + + exporter.BeginBrush(brush); + ForEachFace face_vis(exporter); + brush.forEachFace(face_vis); + exporter.EndBrush(); + } + } + +private: + ExportData& exporter; +}; + +bool ExportSelection(const std::set& ignorelist, collapsemode m, bool exmat, const std::string& path, bool limNames, bool objs) +{ + ExportDataAsWavefront exporter(ignorelist, m, exmat, limNames, objs); + + ForEachSelected vis(exporter); + GlobalSelectionSystem().foreachSelected(vis); + + return exporter.WriteToFile(path, m); +} diff --git a/contrib/brushexport/export.h b/contrib/brushexport/export.h index 76f937b5..3482bbed 100644 --- a/contrib/brushexport/export.h +++ b/contrib/brushexport/export.h @@ -1,15 +1,15 @@ -#ifndef EXPORT_H -#define EXPORT_H -#include -#include - -enum collapsemode -{ - COLLAPSE_ALL, - COLLAPSE_BY_MATERIAL, - COLLAPSE_NONE -}; - -bool ExportSelection(const std::set& ignorelist, collapsemode m, const std::string& path); - -#endif +#ifndef EXPORT_H +#define EXPORT_H +#include +#include + +enum collapsemode +{ + COLLAPSE_ALL, + COLLAPSE_BY_MATERIAL, + COLLAPSE_NONE +}; + +bool ExportSelection(const std::set& ignorelist, collapsemode m, bool exmat, const std::string& path, bool limitMatNames, bool objects); + +#endif diff --git a/contrib/brushexport/interface.cpp b/contrib/brushexport/interface.cpp index dd40f3b9..6525e201 100644 --- a/contrib/brushexport/interface.cpp +++ b/contrib/brushexport/interface.cpp @@ -1,212 +1,241 @@ -#include -#include - -#include "debugging/debugging.h" -#include "callbacks.h" -#include "support.h" - -#define GLADE_HOOKUP_OBJECT(component,widget,name) \ - g_object_set_data_full (G_OBJECT (component), name, \ - gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) - -#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ - g_object_set_data (G_OBJECT (component), name, widget) - -// created by glade -GtkWidget* -create_w_plugplug2 (void) -{ - GtkWidget *w_plugplug2; - GtkWidget *vbox1; - GtkWidget *hbox2; - GtkWidget *vbox4; - GtkWidget *r_collapse; - GSList *r_collapse_group = NULL; - GtkWidget *r_collapsebymaterial; - GtkWidget *r_nocollapse; - GtkWidget *vbox3; - GtkWidget *b_export; - GtkWidget *b_close; - GtkWidget *vbox2; - GtkWidget *label1; - GtkWidget *scrolledwindow1; - GtkWidget *t_materialist; - GtkWidget *ed_materialname; - GtkWidget *hbox1; - GtkWidget *b_addmaterial; - GtkWidget *b_removematerial; - - w_plugplug2 = gtk_window_new (GTK_WINDOW_TOPLEVEL); - gtk_widget_set_name (w_plugplug2, "w_plugplug2"); - gtk_window_set_title (GTK_WINDOW (w_plugplug2), "BrushExport-Plugin 2.0 by namespace"); - gtk_window_set_position (GTK_WINDOW (w_plugplug2), GTK_WIN_POS_CENTER); - gtk_window_set_destroy_with_parent (GTK_WINDOW (w_plugplug2), TRUE); - - vbox1 = gtk_vbox_new (FALSE, 0); - gtk_widget_set_name (vbox1, "vbox1"); - gtk_widget_show (vbox1); - gtk_container_add (GTK_CONTAINER (w_plugplug2), vbox1); - gtk_container_set_border_width (GTK_CONTAINER (vbox1), 5); - - hbox2 = gtk_hbox_new (TRUE, 5); - gtk_widget_set_name (hbox2, "hbox2"); - gtk_widget_show (hbox2); - gtk_box_pack_start (GTK_BOX (vbox1), hbox2, FALSE, FALSE, 0); - gtk_container_set_border_width (GTK_CONTAINER (hbox2), 5); - - vbox4 = gtk_vbox_new (TRUE, 0); - gtk_widget_set_name (vbox4, "vbox4"); - gtk_widget_show (vbox4); - gtk_box_pack_start (GTK_BOX (hbox2), vbox4, TRUE, FALSE, 0); - - r_collapse = gtk_radio_button_new_with_mnemonic (NULL, "Collapse mesh"); - gtk_widget_set_name (r_collapse, "r_collapse"); - gtk_widget_show (r_collapse); - gtk_box_pack_start (GTK_BOX (vbox4), r_collapse, FALSE, FALSE, 0); - gtk_radio_button_set_group (GTK_RADIO_BUTTON (r_collapse), r_collapse_group); - r_collapse_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (r_collapse)); - - r_collapsebymaterial = gtk_radio_button_new_with_mnemonic (NULL, "Collapse by material"); - gtk_widget_set_name (r_collapsebymaterial, "r_collapsebymaterial"); - gtk_widget_show (r_collapsebymaterial); - gtk_box_pack_start (GTK_BOX (vbox4), r_collapsebymaterial, FALSE, FALSE, 0); - gtk_radio_button_set_group (GTK_RADIO_BUTTON (r_collapsebymaterial), r_collapse_group); - r_collapse_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (r_collapsebymaterial)); - - r_nocollapse = gtk_radio_button_new_with_mnemonic (NULL, "Don't collapse"); - gtk_widget_set_name (r_nocollapse, "r_nocollapse"); - gtk_widget_show (r_nocollapse); - gtk_box_pack_start (GTK_BOX (vbox4), r_nocollapse, FALSE, FALSE, 0); - gtk_radio_button_set_group (GTK_RADIO_BUTTON (r_nocollapse), r_collapse_group); - r_collapse_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (r_nocollapse)); - - vbox3 = gtk_vbox_new (FALSE, 0); - gtk_widget_set_name (vbox3, "vbox3"); - gtk_widget_show (vbox3); - gtk_box_pack_start (GTK_BOX (hbox2), vbox3, FALSE, FALSE, 0); - - b_export = gtk_button_new_from_stock ("gtk-save"); - gtk_widget_set_name (b_export, "b_export"); - gtk_widget_show (b_export); - gtk_box_pack_start (GTK_BOX (vbox3), b_export, TRUE, FALSE, 0); - gtk_container_set_border_width (GTK_CONTAINER (b_export), 5); - - b_close = gtk_button_new_from_stock ("gtk-cancel"); - gtk_widget_set_name (b_close, "b_close"); - gtk_widget_show (b_close); - gtk_box_pack_start (GTK_BOX (vbox3), b_close, TRUE, FALSE, 0); - gtk_container_set_border_width (GTK_CONTAINER (b_close), 5); - - vbox2 = gtk_vbox_new (FALSE, 5); - gtk_widget_set_name (vbox2, "vbox2"); - gtk_widget_show (vbox2); - gtk_box_pack_start (GTK_BOX (vbox1), vbox2, TRUE, TRUE, 0); - gtk_container_set_border_width (GTK_CONTAINER (vbox2), 2); - - label1 = gtk_label_new ("Ignored materials:"); - gtk_widget_set_name (label1, "label1"); - gtk_widget_show (label1); - gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0); - - scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); - gtk_widget_set_name (scrolledwindow1, "scrolledwindow1"); - gtk_widget_show (scrolledwindow1); - gtk_box_pack_start (GTK_BOX (vbox2), scrolledwindow1, TRUE, TRUE, 0); - gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); - gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_SHADOW_IN); - - t_materialist = gtk_tree_view_new (); - gtk_widget_set_name (t_materialist, "t_materialist"); - gtk_widget_show (t_materialist); - gtk_container_add (GTK_CONTAINER (scrolledwindow1), t_materialist); - gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (t_materialist), FALSE); - gtk_tree_view_set_enable_search (GTK_TREE_VIEW (t_materialist), FALSE); - - ed_materialname = gtk_entry_new (); - gtk_widget_set_name (ed_materialname, "ed_materialname"); - gtk_widget_show (ed_materialname); - gtk_box_pack_start (GTK_BOX (vbox2), ed_materialname, FALSE, FALSE, 0); - - hbox1 = gtk_hbox_new (TRUE, 0); - gtk_widget_set_name (hbox1, "hbox1"); - gtk_widget_show (hbox1); - gtk_box_pack_start (GTK_BOX (vbox2), hbox1, FALSE, FALSE, 0); - - b_addmaterial = gtk_button_new_from_stock ("gtk-add"); - gtk_widget_set_name (b_addmaterial, "b_addmaterial"); - gtk_widget_show (b_addmaterial); - gtk_box_pack_start (GTK_BOX (hbox1), b_addmaterial, FALSE, FALSE, 0); - - b_removematerial = gtk_button_new_from_stock ("gtk-remove"); - gtk_widget_set_name (b_removematerial, "b_removematerial"); - gtk_widget_show (b_removematerial); - gtk_box_pack_start (GTK_BOX (hbox1), b_removematerial, FALSE, FALSE, 0); - - using namespace callbacks; - g_signal_connect(G_OBJECT(w_plugplug2), "destroy", G_CALLBACK(OnDestroy), NULL); - g_signal_connect_swapped(G_OBJECT(b_close), "clicked", G_CALLBACK (OnDestroy), NULL); - - g_signal_connect ((gpointer) b_export, "clicked", G_CALLBACK (OnExportClicked), NULL); - g_signal_connect ((gpointer) b_addmaterial, "clicked", G_CALLBACK (OnAddMaterial), NULL); - g_signal_connect ((gpointer) b_removematerial, "clicked", G_CALLBACK (OnRemoveMaterial), NULL); - - /* Store pointers to all widgets, for use by lookup_widget(). */ - GLADE_HOOKUP_OBJECT_NO_REF (w_plugplug2, w_plugplug2, "w_plugplug2"); - GLADE_HOOKUP_OBJECT (w_plugplug2, vbox1, "vbox1"); - GLADE_HOOKUP_OBJECT (w_plugplug2, hbox2, "hbox2"); - GLADE_HOOKUP_OBJECT (w_plugplug2, vbox4, "vbox4"); - GLADE_HOOKUP_OBJECT (w_plugplug2, r_collapse, "r_collapse"); - GLADE_HOOKUP_OBJECT (w_plugplug2, r_collapsebymaterial, "r_collapsebymaterial"); - GLADE_HOOKUP_OBJECT (w_plugplug2, r_nocollapse, "r_nocollapse"); - GLADE_HOOKUP_OBJECT (w_plugplug2, vbox3, "vbox3"); - GLADE_HOOKUP_OBJECT (w_plugplug2, b_export, "b_export"); - GLADE_HOOKUP_OBJECT (w_plugplug2, b_close, "b_close"); - GLADE_HOOKUP_OBJECT (w_plugplug2, vbox2, "vbox2"); - GLADE_HOOKUP_OBJECT (w_plugplug2, label1, "label1"); - GLADE_HOOKUP_OBJECT (w_plugplug2, scrolledwindow1, "scrolledwindow1"); - GLADE_HOOKUP_OBJECT (w_plugplug2, t_materialist, "t_materialist"); - GLADE_HOOKUP_OBJECT (w_plugplug2, ed_materialname, "ed_materialname"); - GLADE_HOOKUP_OBJECT (w_plugplug2, hbox1, "hbox1"); - GLADE_HOOKUP_OBJECT (w_plugplug2, b_addmaterial, "b_addmaterial"); - GLADE_HOOKUP_OBJECT (w_plugplug2, b_removematerial, "b_removematerial"); - - return w_plugplug2; -} - -// global main window, is 0 when not created -GtkWidget* g_brushexp_window = 0; - -// spawn plugin window (and make sure it got destroyed first or never created) -void CreateWindow(void) -{ - ASSERT_NOTNULL(!g_brushexp_window); - - GtkWidget* wnd = create_w_plugplug2(); - - // column & renderer - GtkTreeViewColumn* col = gtk_tree_view_column_new(); - gtk_tree_view_column_set_title(col, "materials"); - gtk_tree_view_append_column(GTK_TREE_VIEW(lookup_widget(wnd, "t_materialist")), col); - GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); - gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(lookup_widget(wnd, "t_materialist")), -1, "", renderer, "text", 0, NULL); - - // list store - GtkListStore* ignorelist = gtk_list_store_new(1, G_TYPE_STRING); - gtk_tree_view_set_model(GTK_TREE_VIEW(lookup_widget(wnd, "t_materialist")), GTK_TREE_MODEL(ignorelist)); - g_object_unref(ignorelist); - - gtk_widget_show_all(wnd); - g_brushexp_window = wnd; -} - -void DestroyWindow(void) -{ - ASSERT_NOTNULL(g_brushexp_window); - gtk_widget_destroy(g_brushexp_window); - g_brushexp_window = 0; -} - -bool IsWindowOpen(void) -{ - return g_brushexp_window != 0; -} +#include +#include + +#include "debugging/debugging.h" +#include "callbacks.h" +#include "support.h" + +#define GLADE_HOOKUP_OBJECT(component,widget,name) \ + g_object_set_data_full (G_OBJECT (component), name, \ + gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) + +#define GLADE_HOOKUP_OBJECT_NO_REF(component,widget,name) \ + g_object_set_data (G_OBJECT (component), name, widget) + +// created by glade +GtkWidget* +create_w_plugplug2 (void) +{ + GtkWidget *w_plugplug2; + GtkWidget *vbox1; + GtkWidget *hbox2; + GtkWidget *vbox4; + GtkWidget *r_collapse; + GSList *r_collapse_group = NULL; + GtkWidget *r_collapsebymaterial; + GtkWidget *r_nocollapse; + GtkWidget *vbox3; + GtkWidget *b_export; + GtkWidget *b_close; + GtkWidget *vbox2; + GtkWidget *label1; + GtkWidget *scrolledwindow1; + GtkWidget *t_materialist; + GtkWidget *ed_materialname; + GtkWidget *hbox1; + GtkWidget *b_addmaterial; + GtkWidget *b_removematerial; + GtkWidget *t_exportmaterials; + GtkWidget *t_limitmatnames; + GtkWidget *t_objects; + GtkTooltips *tooltips; + + tooltips = gtk_tooltips_new(); + + w_plugplug2 = gtk_window_new (GTK_WINDOW_TOPLEVEL); + gtk_widget_set_name (w_plugplug2, "w_plugplug2"); + gtk_window_set_title (GTK_WINDOW (w_plugplug2), "BrushExport-Plugin 3.0 by namespace"); + gtk_window_set_position (GTK_WINDOW (w_plugplug2), GTK_WIN_POS_CENTER); + gtk_window_set_destroy_with_parent (GTK_WINDOW (w_plugplug2), TRUE); + + vbox1 = gtk_vbox_new (FALSE, 0); + gtk_widget_set_name (vbox1, "vbox1"); + gtk_widget_show (vbox1); + gtk_container_add (GTK_CONTAINER (w_plugplug2), vbox1); + gtk_container_set_border_width (GTK_CONTAINER (vbox1), 5); + + hbox2 = gtk_hbox_new (TRUE, 5); + gtk_widget_set_name (hbox2, "hbox2"); + gtk_widget_show (hbox2); + gtk_box_pack_start (GTK_BOX (vbox1), hbox2, FALSE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (hbox2), 5); + + vbox4 = gtk_vbox_new (TRUE, 0); + gtk_widget_set_name (vbox4, "vbox4"); + gtk_widget_show (vbox4); + gtk_box_pack_start (GTK_BOX (hbox2), vbox4, TRUE, FALSE, 0); + + r_collapse = gtk_radio_button_new_with_mnemonic (NULL, "Collapse mesh"); + gtk_widget_set_name (r_collapse, "r_collapse"); + gtk_tooltips_set_tip (GTK_TOOLTIPS(tooltips), r_collapse, "Collapse all brushes into a single group", "Collapse all brushes into a single group"); + gtk_widget_show (r_collapse); + gtk_box_pack_start (GTK_BOX (vbox4), r_collapse, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (r_collapse), r_collapse_group); + r_collapse_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (r_collapse)); + + r_collapsebymaterial = gtk_radio_button_new_with_mnemonic (NULL, "Collapse by material"); + gtk_widget_set_name (r_collapsebymaterial, "r_collapsebymaterial"); + gtk_tooltips_set_tip (GTK_TOOLTIPS(tooltips), r_collapsebymaterial, "Collapse into groups by material", "Collapse into groups by material"); + gtk_widget_show (r_collapsebymaterial); + gtk_box_pack_start (GTK_BOX (vbox4), r_collapsebymaterial, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (r_collapsebymaterial), r_collapse_group); + r_collapse_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (r_collapsebymaterial)); + + r_nocollapse = gtk_radio_button_new_with_mnemonic (NULL, "Don't collapse"); + gtk_widget_set_name (r_nocollapse, "r_nocollapse"); + gtk_tooltips_set_tip (GTK_TOOLTIPS(tooltips), r_nocollapse, "Every brush is stored in its own group", "Every brush is stored in its own group"); + gtk_widget_show (r_nocollapse); + gtk_box_pack_start (GTK_BOX (vbox4), r_nocollapse, FALSE, FALSE, 0); + gtk_radio_button_set_group (GTK_RADIO_BUTTON (r_nocollapse), r_collapse_group); + r_collapse_group = gtk_radio_button_get_group (GTK_RADIO_BUTTON (r_nocollapse)); + + vbox3 = gtk_vbox_new (FALSE, 0); + gtk_widget_set_name (vbox3, "vbox3"); + gtk_widget_show (vbox3); + gtk_box_pack_start (GTK_BOX (hbox2), vbox3, FALSE, FALSE, 0); + + b_export = gtk_button_new_from_stock ("gtk-save"); + gtk_widget_set_name (b_export, "b_export"); + gtk_widget_show (b_export); + gtk_box_pack_start (GTK_BOX (vbox3), b_export, TRUE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (b_export), 5); + + b_close = gtk_button_new_from_stock ("gtk-cancel"); + gtk_widget_set_name (b_close, "b_close"); + gtk_widget_show (b_close); + gtk_box_pack_start (GTK_BOX (vbox3), b_close, TRUE, FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (b_close), 5); + + vbox2 = gtk_vbox_new (FALSE, 5); + gtk_widget_set_name (vbox2, "vbox2"); + gtk_widget_show (vbox2); + gtk_box_pack_start (GTK_BOX (vbox1), vbox2, TRUE, TRUE, 0); + gtk_container_set_border_width (GTK_CONTAINER (vbox2), 2); + + label1 = gtk_label_new ("Ignored materials:"); + gtk_widget_set_name (label1, "label1"); + gtk_widget_show (label1); + gtk_box_pack_start (GTK_BOX (vbox2), label1, FALSE, FALSE, 0); + + scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL); + gtk_widget_set_name (scrolledwindow1, "scrolledwindow1"); + gtk_widget_show (scrolledwindow1); + gtk_box_pack_start (GTK_BOX (vbox2), scrolledwindow1, TRUE, TRUE, 0); + gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); + gtk_scrolled_window_set_shadow_type (GTK_SCROLLED_WINDOW (scrolledwindow1), GTK_SHADOW_IN); + + t_materialist = gtk_tree_view_new (); + gtk_widget_set_name (t_materialist, "t_materialist"); + gtk_widget_show (t_materialist); + gtk_container_add (GTK_CONTAINER (scrolledwindow1), t_materialist); + gtk_tree_view_set_headers_visible (GTK_TREE_VIEW (t_materialist), FALSE); + gtk_tree_view_set_enable_search (GTK_TREE_VIEW (t_materialist), FALSE); + + ed_materialname = gtk_entry_new (); + gtk_widget_set_name (ed_materialname, "ed_materialname"); + gtk_widget_show (ed_materialname); + gtk_box_pack_start (GTK_BOX (vbox2), ed_materialname, FALSE, FALSE, 0); + + hbox1 = gtk_hbox_new (TRUE, 0); + gtk_widget_set_name (hbox1, "hbox1"); + gtk_widget_show (hbox1); + gtk_box_pack_start (GTK_BOX (vbox2), hbox1, FALSE, FALSE, 0); + + b_addmaterial = gtk_button_new_from_stock ("gtk-add"); + gtk_widget_set_name (b_addmaterial, "b_addmaterial"); + gtk_widget_show (b_addmaterial); + gtk_box_pack_start (GTK_BOX (hbox1), b_addmaterial, FALSE, FALSE, 0); + + b_removematerial = gtk_button_new_from_stock ("gtk-remove"); + gtk_widget_set_name (b_removematerial, "b_removematerial"); + gtk_widget_show (b_removematerial); + gtk_box_pack_start (GTK_BOX (hbox1), b_removematerial, FALSE, FALSE, 0); + + t_limitmatnames = gtk_check_button_new_with_mnemonic ("Use short material names (max. 20 chars)"); + gtk_widget_set_name (t_limitmatnames, "t_limitmatnames"); + gtk_widget_show (t_limitmatnames); + gtk_box_pack_end (GTK_BOX (vbox2), t_limitmatnames, FALSE, FALSE, 0); + + t_objects = gtk_check_button_new_with_mnemonic ("Create (o)bjects instead of (g)roups"); + gtk_widget_set_name (t_objects, "t_objects"); + gtk_widget_show (t_objects); + gtk_box_pack_end (GTK_BOX (vbox2), t_objects, FALSE, FALSE, 0); + + t_exportmaterials = gtk_check_button_new_with_mnemonic ("Create material information (.mtl file)"); + gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(t_exportmaterials), true); + gtk_widget_set_name (t_exportmaterials, "t_exportmaterials"); + gtk_widget_show (t_exportmaterials); + gtk_box_pack_end (GTK_BOX (vbox2), t_exportmaterials, FALSE, FALSE, 10); + + using namespace callbacks; + g_signal_connect(G_OBJECT(w_plugplug2), "destroy", G_CALLBACK(OnDestroy), NULL); + g_signal_connect_swapped(G_OBJECT(b_close), "clicked", G_CALLBACK (OnDestroy), NULL); + + g_signal_connect ((gpointer) b_export, "clicked", G_CALLBACK (OnExportClicked), NULL); + g_signal_connect ((gpointer) b_addmaterial, "clicked", G_CALLBACK (OnAddMaterial), NULL); + g_signal_connect ((gpointer) b_removematerial, "clicked", G_CALLBACK (OnRemoveMaterial), NULL); + g_signal_connect ((gpointer) t_exportmaterials, "clicked", G_CALLBACK (OnExportMatClicked), NULL); + + /* Store pointers to all widgets, for use by lookup_widget(). */ + GLADE_HOOKUP_OBJECT_NO_REF (w_plugplug2, w_plugplug2, "w_plugplug2"); + GLADE_HOOKUP_OBJECT (w_plugplug2, vbox1, "vbox1"); + GLADE_HOOKUP_OBJECT (w_plugplug2, hbox2, "hbox2"); + GLADE_HOOKUP_OBJECT (w_plugplug2, vbox4, "vbox4"); + GLADE_HOOKUP_OBJECT (w_plugplug2, r_collapse, "r_collapse"); + GLADE_HOOKUP_OBJECT (w_plugplug2, r_collapsebymaterial, "r_collapsebymaterial"); + GLADE_HOOKUP_OBJECT (w_plugplug2, r_nocollapse, "r_nocollapse"); + GLADE_HOOKUP_OBJECT (w_plugplug2, vbox3, "vbox3"); + GLADE_HOOKUP_OBJECT (w_plugplug2, b_export, "b_export"); + GLADE_HOOKUP_OBJECT (w_plugplug2, b_close, "b_close"); + GLADE_HOOKUP_OBJECT (w_plugplug2, vbox2, "vbox2"); + GLADE_HOOKUP_OBJECT (w_plugplug2, label1, "label1"); + GLADE_HOOKUP_OBJECT (w_plugplug2, scrolledwindow1, "scrolledwindow1"); + GLADE_HOOKUP_OBJECT (w_plugplug2, t_materialist, "t_materialist"); + GLADE_HOOKUP_OBJECT (w_plugplug2, ed_materialname, "ed_materialname"); + GLADE_HOOKUP_OBJECT (w_plugplug2, hbox1, "hbox1"); + GLADE_HOOKUP_OBJECT (w_plugplug2, b_addmaterial, "b_addmaterial"); + GLADE_HOOKUP_OBJECT (w_plugplug2, b_removematerial, "b_removematerial"); + GLADE_HOOKUP_OBJECT (w_plugplug2, t_exportmaterials, "t_exportmaterials"); + GLADE_HOOKUP_OBJECT (w_plugplug2, t_limitmatnames, "t_limitmatnames"); + GLADE_HOOKUP_OBJECT (w_plugplug2, t_objects, "t_objects"); + + return w_plugplug2; +} + +// global main window, is 0 when not created +GtkWidget* g_brushexp_window = 0; + +// spawn plugin window (and make sure it got destroyed first or never created) +void CreateWindow(void) +{ + ASSERT_NOTNULL(!g_brushexp_window); + + GtkWidget* wnd = create_w_plugplug2(); + + // column & renderer + GtkTreeViewColumn* col = gtk_tree_view_column_new(); + gtk_tree_view_column_set_title(col, "materials"); + gtk_tree_view_append_column(GTK_TREE_VIEW(lookup_widget(wnd, "t_materialist")), col); + GtkCellRenderer* renderer = gtk_cell_renderer_text_new(); + gtk_tree_view_insert_column_with_attributes(GTK_TREE_VIEW(lookup_widget(wnd, "t_materialist")), -1, "", renderer, "text", 0, NULL); + + // list store + GtkListStore* ignorelist = gtk_list_store_new(1, G_TYPE_STRING); + gtk_tree_view_set_model(GTK_TREE_VIEW(lookup_widget(wnd, "t_materialist")), GTK_TREE_MODEL(ignorelist)); + g_object_unref(ignorelist); + + gtk_widget_show_all(wnd); + g_brushexp_window = wnd; +} + +void DestroyWindow(void) +{ + ASSERT_NOTNULL(g_brushexp_window); + gtk_widget_destroy(g_brushexp_window); + g_brushexp_window = 0; +} + +bool IsWindowOpen(void) +{ + return g_brushexp_window != 0; +} diff --git a/contrib/brushexport/plugin.cpp b/contrib/brushexport/plugin.cpp index 1b5e7c19..3b3fab09 100644 --- a/contrib/brushexport/plugin.cpp +++ b/contrib/brushexport/plugin.cpp @@ -1,134 +1,134 @@ -/* -Copyright (C) 2006, Thomas Nitschke. -All Rights Reserved. - -This file is part of GtkRadiant. - -GtkRadiant is free software; you can redistribute it and/or modify -it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2 of the License, or -(at your option) any later version. - -GtkRadiant is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU General Public License for more details. - -You should have received a copy of the GNU General Public License -along with GtkRadiant; if not, write to the Free Software -Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA -*/ -#include "plugin.h" - -#include "iplugin.h" -#include "qerplugin.h" - -#include -#include - -#include "debugging/debugging.h" -#include "string/string.h" -#include "modulesystem/singletonmodule.h" -#include "stream/textfilestream.h" -#include "stream/stringstream.h" -#include "gtkutil/messagebox.h" -#include "gtkutil/filechooser.h" - -#include "ibrush.h" -#include "iscenegraph.h" -#include "iselection.h" -#include "ifilesystem.h" -#include "ifiletypes.h" - -#include "support.h" - -#include "typesystem.h" - -void CreateWindow (void); -void DestroyWindow(void); -bool IsWindowOpen(void); - -namespace BrushExport -{ - GtkWindow* g_mainwnd; - - const char* init(void* hApp, void* pMainWidget) - { - g_mainwnd = (GtkWindow*)pMainWidget; - ASSERT_NOTNULL(g_mainwnd); - return ""; - } - const char* getName() - { - return "Brush export Plugin"; - } - const char* getCommandList() - { - return "Export selected as Wavefront Object;About"; - } - const char* getCommandTitleList() - { - return ""; - } - - void dispatch(const char* command, float* vMin, float* vMax, bool bSingleBrush) - { - if(string_equal(command, "About")) - { - GlobalRadiant().m_pfnMessageBox(GTK_WIDGET(g_mainwnd), "Brushexport plugin v 2.0 by namespace (www.codecreator.net)\n" - "Enjoy!\n\nSend feedback to spam@codecreator.net", "About me...", - eMB_OK, - eMB_ICONDEFAULT); - } - else if(string_equal(command, "Export selected as Wavefront Object")) - { - if(IsWindowOpen()) - DestroyWindow(); - CreateWindow(); - } - } -} - -class BrushExportDependencies : - public GlobalRadiantModuleRef, - public GlobalFiletypesModuleRef, - public GlobalBrushModuleRef, - public GlobalFileSystemModuleRef, - public GlobalSceneGraphModuleRef, - public GlobalSelectionModuleRef -{ -public: - BrushExportDependencies(void) - : GlobalBrushModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("brushtypes")) - {} -}; - -class BrushExportModule : public TypeSystemRef -{ - _QERPluginTable m_plugin; -public: - typedef _QERPluginTable Type; - STRING_CONSTANT(Name, "brushexport2"); - - BrushExportModule() - { - m_plugin.m_pfnQERPlug_Init = &BrushExport::init; - m_plugin.m_pfnQERPlug_GetName = &BrushExport::getName; - m_plugin.m_pfnQERPlug_GetCommandList = &BrushExport::getCommandList; - m_plugin.m_pfnQERPlug_GetCommandTitleList = &BrushExport::getCommandTitleList; - m_plugin.m_pfnQERPlug_Dispatch = &BrushExport::dispatch; - } - _QERPluginTable* getTable() - { - return &m_plugin; - } -}; - -typedef SingletonModule SingletonBrushExportModule; -SingletonBrushExportModule g_BrushExportModule; - -extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules(ModuleServer& server) -{ - initialiseModule(server); - g_BrushExportModule.selfRegister(); -} +/* +Copyright (C) 2006, Thomas Nitschke. +All Rights Reserved. + +This file is part of GtkRadiant. + +GtkRadiant is free software; you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation; either version 2 of the License, or +(at your option) any later version. + +GtkRadiant is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with GtkRadiant; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ +#include "plugin.h" + +#include "iplugin.h" +#include "qerplugin.h" + +#include +#include + +#include "debugging/debugging.h" +#include "string/string.h" +#include "modulesystem/singletonmodule.h" +#include "stream/textfilestream.h" +#include "stream/stringstream.h" +#include "gtkutil/messagebox.h" +#include "gtkutil/filechooser.h" + +#include "ibrush.h" +#include "iscenegraph.h" +#include "iselection.h" +#include "ifilesystem.h" +#include "ifiletypes.h" + +#include "support.h" + +#include "typesystem.h" + +void CreateWindow (void); +void DestroyWindow(void); +bool IsWindowOpen(void); + +namespace BrushExport +{ + GtkWindow* g_mainwnd; + + const char* init(void* hApp, void* pMainWidget) + { + g_mainwnd = (GtkWindow*)pMainWidget; + ASSERT_NOTNULL(g_mainwnd); + return ""; + } + const char* getName() + { + return "Brush export Plugin"; + } + const char* getCommandList() + { + return "Export selected as Wavefront Object;About"; + } + const char* getCommandTitleList() + { + return ""; + } + + void dispatch(const char* command, float* vMin, float* vMax, bool bSingleBrush) + { + if(string_equal(command, "About")) + { + GlobalRadiant().m_pfnMessageBox(GTK_WIDGET(g_mainwnd), "Brushexport plugin v 2.0 by namespace (www.codecreator.net)\n" + "Enjoy!\n\nSend feedback to spam@codecreator.net", "About me...", + eMB_OK, + eMB_ICONDEFAULT); + } + else if(string_equal(command, "Export selected as Wavefront Object")) + { + if(IsWindowOpen()) + DestroyWindow(); + CreateWindow(); + } + } +} + +class BrushExportDependencies : + public GlobalRadiantModuleRef, + public GlobalFiletypesModuleRef, + public GlobalBrushModuleRef, + public GlobalFileSystemModuleRef, + public GlobalSceneGraphModuleRef, + public GlobalSelectionModuleRef +{ +public: + BrushExportDependencies(void) + : GlobalBrushModuleRef(GlobalRadiant().getRequiredGameDescriptionKeyValue("brushtypes")) + {} +}; + +class BrushExportModule : public TypeSystemRef +{ + _QERPluginTable m_plugin; +public: + typedef _QERPluginTable Type; + STRING_CONSTANT(Name, "brushexport2"); + + BrushExportModule() + { + m_plugin.m_pfnQERPlug_Init = &BrushExport::init; + m_plugin.m_pfnQERPlug_GetName = &BrushExport::getName; + m_plugin.m_pfnQERPlug_GetCommandList = &BrushExport::getCommandList; + m_plugin.m_pfnQERPlug_GetCommandTitleList = &BrushExport::getCommandTitleList; + m_plugin.m_pfnQERPlug_Dispatch = &BrushExport::dispatch; + } + _QERPluginTable* getTable() + { + return &m_plugin; + } +}; + +typedef SingletonModule SingletonBrushExportModule; +SingletonBrushExportModule g_BrushExportModule; + +extern "C" void RADIANT_DLLEXPORT Radiant_RegisterModules(ModuleServer& server) +{ + initialiseModule(server); + g_BrushExportModule.selfRegister(); +} diff --git a/contrib/brushexport/support.cpp b/contrib/brushexport/support.cpp index 736c6b2f..2835b112 100644 --- a/contrib/brushexport/support.cpp +++ b/contrib/brushexport/support.cpp @@ -1,31 +1,31 @@ -#include - -#include "support.h" - -GtkWidget* -lookup_widget (GtkWidget *widget, - const gchar *widget_name) -{ - GtkWidget *parent, *found_widget; - - for (;;) - { - if (GTK_IS_MENU (widget)) - parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); - else - parent = widget->parent; - if (!parent) - parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey"); - if (parent == NULL) - break; - widget = parent; - } - - found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget), - widget_name); - if (!found_widget) - g_warning ("Widget not found: %s", widget_name); - return found_widget; -} - - +#include + +#include "support.h" + +GtkWidget* +lookup_widget (GtkWidget *widget, + const gchar *widget_name) +{ + GtkWidget *parent, *found_widget; + + for (;;) + { + if (GTK_IS_MENU (widget)) + parent = gtk_menu_get_attach_widget (GTK_MENU (widget)); + else + parent = widget->parent; + if (!parent) + parent = (GtkWidget*) g_object_get_data (G_OBJECT (widget), "GladeParentKey"); + if (parent == NULL) + break; + widget = parent; + } + + found_widget = (GtkWidget*) g_object_get_data (G_OBJECT (widget), + widget_name); + if (!found_widget) + g_warning ("Widget not found: %s", widget_name); + return found_widget; +} + + diff --git a/contrib/brushexport/support.h b/contrib/brushexport/support.h index d1cce97c..628885a5 100644 --- a/contrib/brushexport/support.h +++ b/contrib/brushexport/support.h @@ -1,24 +1,24 @@ -/* - * DO NOT EDIT THIS FILE - it is generated by Glade. - */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -/* - * Public Functions. - */ - -/* - * This function returns a widget in a component created by Glade. - * Call it with the toplevel widget in the component (i.e. a window/dialog), - * or alternatively any widget in the component, and the name of the widget - * you want returned. - */ -GtkWidget* lookup_widget (GtkWidget *widget, - const gchar *widget_name); - - +/* + * DO NOT EDIT THIS FILE - it is generated by Glade. + */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +/* + * Public Functions. + */ + +/* + * This function returns a widget in a component created by Glade. + * Call it with the toplevel widget in the component (i.e. a window/dialog), + * or alternatively any widget in the component, and the name of the widget + * you want returned. + */ +GtkWidget* lookup_widget (GtkWidget *widget, + const gchar *widget_name); + +