From 4942ca34d22c39401f8bcb7b00956bab43548b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andreas=20R=C3=A5nman?= Date: Tue, 25 Jan 2022 10:13:54 +0100 Subject: [PATCH] Added argument with dropdown for selecting UV Map When deleting the initial visitor, I also refactored away checks for unmapped uvs, checks are back. Attempting to delete packer class failed due to nullpointer not being set. Users will now be able to select which texture map to perform the packing to. Incremented version in preparation for LPK release. Tested the kit, it seem to work from version 13, tested using 13.2v1 while versions 11 and 12 both crashed. --- index.cfg | 8 ++- index.xml | 2 +- source/uvpackit.cpp | 119 ++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 122 insertions(+), 7 deletions(-) diff --git a/index.cfg b/index.cfg index f8eedfa..271e638 100644 --- a/index.cfg +++ b/index.cfg @@ -1,7 +1,7 @@ - + @@ -89,6 +89,12 @@ If set to true, the packer will render the input UV map with invalid islands marked in red, every time invalid islands are found before executing operation. + + UV Map + Which texture vmap we should run the packing operation on + Which texture vmap we should run the packing operation on + + diff --git a/index.xml b/index.xml index 11b64da..a458bd5 100644 --- a/index.xml +++ b/index.xml @@ -1,5 +1,5 @@ - + index.cfg icons/uvp_20.png diff --git a/source/uvpackit.cpp b/source/uvpackit.cpp index 6782bb1..661c82f 100644 --- a/source/uvpackit.cpp +++ b/source/uvpackit.cpp @@ -29,6 +29,8 @@ #include #include +#include + using namespace uvpcore; using namespace lx_err; // gives us check() @@ -49,7 +51,7 @@ class UvpOpExecutorT bool m_DebugMode; - UvpOperationT* operation; + UvpOperationT* operation = nullptr; void destroyMessages() { @@ -260,6 +262,93 @@ void islandSolutionToMatrix(const UvpIslandPackSolutionT& islandSolution, CLxMat #define SRVNAME_COMMAND "uvp.pack" // Define for our command name, +class CMapPopup : public CLxDynamicUIValue +{ +public: + std::vector names; + int BuildNameList(); + + unsigned Flags() LXx_OVERRIDE + { + return LXfVALHINT_POPUPS; + } + + unsigned PopCount() LXx_OVERRIDE + { + return names.size(); + } + + const char* PopUserName(unsigned index) LXx_OVERRIDE + { + if (index >= names.size()) + return "OOB"; + return names[index].c_str(); + } + + const char* PopInternalName(unsigned index) LXx_OVERRIDE + { + if (index >= names.size()) + return "OOB"; + return names[index].c_str(); + } +}; + +class UVMapVisitor : public CLxImpl_AbstractVisitor +{ + CLxUser_MeshMap* vmap; + std::set names; + + virtual LxResult Evaluate() + { + const char* mapName; + if (LXx_OK(vmap->Name(&mapName))) { + names.insert(std::string(mapName)); + } + return LXe_OK; + } + +public: + UVMapVisitor(CLxUser_MeshMap* vmap) { this->vmap = vmap; } + std::set GetNames() { return names; } + void ClearNames() { names.clear(); } +}; + +int CMapPopup::BuildNameList() +{ + CLxUser_LayerService layer_service; + CLxUser_LayerScan layer_scan; + CLxUser_Mesh mesh; + CLxUser_MeshMap vmap; + std::set name_set; + + check(layer_service.ScanAllocate(LXf_LAYERSCAN_ACTIVE | LXf_LAYERSCAN_MARKPOLYS, layer_scan)); + unsigned layer_count; + layer_scan.Count(&layer_count); + for (unsigned layer_index = 0; layer_index < layer_count; layer_index++) + { + layer_scan.MeshBase(layer_index, mesh); + mesh.GetMaps(vmap); + UVMapVisitor visitor(&vmap); + vmap.FilterByType(LXi_VMAP_TEXTUREUV); + vmap.Enum(&visitor); + + std::set names = visitor.GetNames(); + name_set.insert(names.begin(), names.end()); + } + layer_scan.Apply(); + layer_scan.clear(); + layer_scan = NULL; + + std::set::iterator map_iterator; + for (map_iterator = name_set.begin(); map_iterator != name_set.end(); map_iterator++) { + names.push_back(*map_iterator); + } + + std::sort(names.begin() + 1, names.end()); + + return 0; +}; + class CCommand : public CLxBasicCommand { public: @@ -274,6 +363,7 @@ class CCommand : public CLxBasicCommand void cmd_error(LxResult rc, const char* message); bool selectedPolygons(); + CLxDynamicUIValue* atrui_UIValue(unsigned int index) LXx_OVERRIDE; }; // Initialize the command, creating the arguments @@ -292,6 +382,18 @@ CCommand::CCommand() dyna_Add("renderInvalid", LXsTYPE_BOOLEAN); dyna_SetFlags(7, LXfCMDARG_OPTIONAL); + + dyna_Add("texture", LXsTYPE_STRING); +} + +CLxDynamicUIValue* CCommand::atrui_UIValue(unsigned int index) +{ + if (index == 8) { + CMapPopup* ui_value = new CMapPopup; + ui_value->BuildNameList(); + return ui_value; + } + return 0; } // Set default values for the command dialog @@ -306,6 +408,8 @@ LxResult CCommand::cmd_DialogInit() attr_SetFlt(4, 0.0); // pixelPadding attr_SetInt(5, 2048); // pixelMarginTextureSize + attr_SetString(8, "Texture"); // set the default UV Map + return LXe_OK; } @@ -431,6 +535,9 @@ void CCommand::basic_Execute(unsigned flags) if(dyna_IsSet(7)) uvpInput.m_RenderInvalidIslands = dyna_Bool(7, false); + std::string map_name; + dyna_String(8, map_name, "Texture"); + // Set debug to false for release, #ifdef _DEBUG bool debugMode = true; @@ -489,7 +596,7 @@ void CCommand::basic_Execute(unsigned flags) check(vmap.fromMesh(mesh)); // Get the vmap, if not successful, skip layer - LxResult uv_lookup = vmap.SelectByName(LXi_VMAP_TEXTUREUV, "Texture"); + LxResult uv_lookup = vmap.SelectByName(LXi_VMAP_TEXTUREUV, map_name.c_str()); if (uv_lookup != LXe_OK) continue; @@ -533,8 +640,10 @@ void CCommand::basic_Execute(unsigned flags) point.Index(&point_index); // Get the UV coordinates for polygon vertex - polygon.MapEvaluate(vmap_id, point_id, texcoords); - + CLxResult uv_result = polygon.MapEvaluate(vmap_id, point_id, texcoords); + if (uv_result != LXe_OK) + cmd_error(LXe_FAILED, "unmappedUV"); + // And the positional data point.Select(point_id); point.Pos(position); @@ -752,7 +861,7 @@ void CCommand::basic_Execute(unsigned flags) check(vmap.fromMesh(mesh)); // Get the vmap, if not successful, skip layer - CLxResult uv_lookup = vmap.SelectByName(LXi_VMAP_TEXTUREUV, "Texture"); + CLxResult uv_lookup = vmap.SelectByName(LXi_VMAP_TEXTUREUV, map_name.c_str()); if (uv_lookup.fail()) continue;