Open Charles75382 opened 1 year ago
Hi! I'm not sure I understand what the ask is here. Are you defining custom structures? You should be able to set a custom name string for any new structure classes you define and everything will 'just work'.
If you're saying you want to have variable / dynamic structureName
s for your structure classes, rather than fixed static ones, I'm not sure that's possible to support. The structure management GUI / logic is pretty deeply baked in to have a single fixed string name per type of structure class. (One might argue that tracking classes by strings is bad C++ design, but at this point that design is pretty deeply baked in.)
Maybe you can be more specific about the kind of UI changes you're trying to make that are currently impossible? You should be able to disable the default UI and create pretty much anything you want in ImGUI.
Yeah, asking for the latter so I don't have to create a new copy of a class just to change the name. You're right that the dynamic structureName is not a viable option given your current architecture, but there is a workaround that I have implemented for my own means, but it's a little janky in my opinion, but maybe that's just the nature of workarounds for things like this. I was asking for a more officially supported means to accomplish this or perhaps advice on a better workaround:
`void buildStructureGui() { // Create window static bool showStructureWindow = true;
ImGui::SetNextWindowPos(ImVec2(imguiStackMargin, lastWindowHeightPolyscope + 2 imguiStackMargin)); ImGui::SetNextWindowSize( ImVec2(leftWindowsWidth, view::windowHeight - lastWindowHeightPolyscope - 3 imguiStackMargin));
ImGui::Begin("Structures", &showStructureWindow);
std::map<std::string, std::vector<VolumeMesh>> volumeMeshLabelMap; std::map<std::string, std::vector<Structure>> nonVolumeMeshMap;
for (auto catMapEntry : state::structures) { std::string catName = catMapEntry.first; std::map<std::string, Structure*>& structureMap = catMapEntry.second;
for (auto x : structureMap) {
Structure* structure = x.second;
if (VolumeMesh* volumeMesh = dynamic_cast<VolumeMesh*>(structure)) {
volumeMeshLabelMap[volumeMesh->getStructureTypeLabel()].push_back(volumeMesh);
} else {
nonVolumeMeshMap[catName].push_back(structure);
}
}
}
for (auto& entry : volumeMeshLabelMap) { auto& label = entry.first; auto& meshes = entry.second;
ImGui::PushID(label.c_str());
ImGui::SetNextTreeNodeOpen(meshes.size() > 0, ImGuiCond_FirstUseEver);
if (ImGui::CollapsingHeader((label + " (" + std::to_string(meshes.size()) + ")").c_str())) {
if (!meshes.empty()) {
meshes.front()->buildSharedStructureUI();
}
for (auto* mesh : meshes) {
ImGui::SetNextTreeNodeOpen(meshes.size() <= 8, ImGuiCond_FirstUseEver);
mesh->buildUI();
}
}
ImGui::PopID();
}
for (auto& entry : nonVolumeMeshMap) { std::string catName = entry.first; std::vector<Structure*>& structures = entry.second;
ImGui::PushID(catName.c_str());
ImGui::SetNextTreeNodeOpen(structures.size() > 0, ImGuiCond_FirstUseEver);
if (ImGui::CollapsingHeader((catName + " (" + std::to_string(structures.size()) + ")").c_str())) {
if (!structures.empty()) {
structures.front()->buildSharedStructureUI();
}
for (auto* structure : structures) {
ImGui::SetNextTreeNodeOpen(structures.size() <= 8, ImGuiCond_FirstUseEver);
structure->buildUI();
}
}
ImGui::PopID();
}
leftWindowsWidth = ImGui::GetWindowWidth();
ImGui::End(); }`
Here I am looping through the structures, classifying the ones I want by type (VolumeMesh), then setting the label based on a var I added to the VolumeMesh class.
While I have your attention, I would like to add that we can't really do everything we want in IMGUI if we are using the Python implementation of Polyscope as far as I can reckon. There is no way to get window information for the docking and placement of various UI elements it would seem. If that is true then it would be much appreciated to pass that information along through to Python so that new UI elements can be placed well.
I'm working mainly off the Python version but have been wanting UI customizations and so have been making changes to the C++ side and rebuilding the wheel. One of the things I've had to implement so far is customization for how the Structure GUI adds structures to itself. Right now it adds structures by the typeName, which itself is a hardcoded string in the respective structure class and set as a static variable. It's used all over the place in that context so I ended up adding a defining a new var setting it all in the header for the structure class I wanted to customize the GUI for, then modifying the structureGUI build method to check for this new var and set it in a collapsing header by that instead of its typeName. In the end my solution is kind of hacky and relies on type casting. I would like to request a more official implementation of this feature as well as more customizability for UI elements, etc. as built in.