Skip to content

Commit

Permalink
Batch import and export of .tri (head) files
Browse files Browse the repository at this point in the history
  • Loading branch information
ousnius committed Jun 21, 2019
1 parent a9710f0 commit 64234c5
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 31 deletions.
4 changes: 4 additions & 0 deletions res/xrc/OutfitStudio.xrc
Original file line number Diff line number Diff line change
Expand Up @@ -1066,6 +1066,10 @@
<label>To FBX...</label>
<help>Export the current project as an FBX file.</help>
</object>
<object class="wxMenuItem" name="exportTRIHead">
<label>To TRI (Head)...</label>
<help>Export head morphs to a TRI file.</help>
</object>
<object class="wxMenu" name="menuExportData">
<label>Export Data</label>
<object class="wxMenuItem" name="exportPhysicsData">
Expand Down
102 changes: 71 additions & 31 deletions src/program/OutfitStudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,8 @@ wxBEGIN_EVENT_TABLE(OutfitStudioFrame, wxFrame)
EVT_MENU(XRCID("exportShapeFBX"), OutfitStudioFrame::OnExportShapeFBX)

EVT_MENU(XRCID("importTRIHead"), OutfitStudioFrame::OnImportTRIHead)
EVT_MENU(XRCID("exportShapeTRIHead"), OutfitStudioFrame::OnExportTRIHead)
EVT_MENU(XRCID("exportTRIHead"), OutfitStudioFrame::OnExportTRIHead)
EVT_MENU(XRCID("exportShapeTRIHead"), OutfitStudioFrame::OnExportShapeTRIHead)

EVT_MENU(XRCID("importPhysicsData"), OutfitStudioFrame::OnImportPhysicsData)
EVT_MENU(XRCID("exportPhysicsData"), OutfitStudioFrame::OnExportPhysicsData)
Expand Down Expand Up @@ -2853,51 +2854,65 @@ void OutfitStudioFrame::OnExportShapeFBX(wxCommandEvent& WXUNUSED(event)) {
}

void OutfitStudioFrame::OnImportTRIHead(wxCommandEvent& WXUNUSED(event)) {
wxString fn = wxFileSelector(_("Import .tri morphs"), wxEmptyString, wxEmptyString, ".tri", "*.tri", wxFD_FILE_MUST_EXIST, this);
if (fn.IsEmpty())
wxFileDialog importDialog(this, _("Import .tri morphs"), wxEmptyString, wxEmptyString, "TRI (Head) Files (*.tri)|*.tri", wxFD_FILE_MUST_EXIST | wxFD_MULTIPLE);
if (importDialog.ShowModal() == wxID_CANCEL)
return;

wxLogMessage("Importing morphs from TRI (head) file '%s'...", fn);

TriHeadFile tri;
if (!tri.Read(fn.ToUTF8().data())) {
wxLogError("Failed to load TRI file '%s'!", fn);
wxMessageBox(_("Failed to load TRI file!"), _("Error"), wxICON_ERROR);
return;
}
wxArrayString fileNames;
importDialog.GetPaths(fileNames);

sliderScroll->Freeze();
glView->SetStrokeManager(nullptr);
MenuExitSliderEdit();
sliderScroll->FitInside();
activeSlider.clear();

std::string shapeName = wxGetTextFromUser(_("Please specify a name for the new shape"), _("New Shape Name"), wxEmptyString, this).ToUTF8();
if (shapeName.empty())
return;
for (auto &fn : fileNames) {
wxFileName fileName(fn);
wxLogMessage("Importing morphs from TRI (head) file '%s'...", fn);

auto shape = project->CreateNifShapeFromData(shapeName, tri.GetVertices(), tri.GetTriangles(), tri.GetUV());
if (!shape)
return;
TriHeadFile tri;
if (!tri.Read(fn.ToUTF8().data())) {
wxLogError("Failed to load TRI file '%s'!", fn);
wxMessageBox(_("Failed to load TRI file!"), _("Error"), wxICON_ERROR);
return;
}

RefreshGUIFromProj();
std::string shapeName = fileName.GetName().ToUTF8();
while (project->IsValidShape(shapeName)) {
std::string result = wxGetTextFromUser(_("Please enter a new unique name for the shape."), _("Rename Shape"), shapeName, this).ToUTF8();
if (result.empty())
continue;

auto morphs = tri.GetMorphs();
for (auto &morph : morphs) {
morph.morphName = morph.morphName.c_str();
if (!project->ValidSlider(morph.morphName)) {
createSliderGUI(morph.morphName, project->SliderCount(), sliderScroll, sliderScroll->GetSizer());
project->AddEmptySlider(morph.morphName);
ShowSliderEffect(morph.morphName);
shapeName = std::move(result);
}

std::unordered_map<ushort, Vector3> diff;
diff.reserve(morph.vertices.size());
auto verts = tri.GetVertices();
auto tris = tri.GetTriangles();
auto uvs = tri.GetUV();
auto shape = project->CreateNifShapeFromData(shapeName, verts, tris, uvs);
if (!shape)
return;

RefreshGUIFromProj();

auto morphs = tri.GetMorphs();
for (auto &morph : morphs) {
morph.morphName = morph.morphName.c_str();
if (!project->ValidSlider(morph.morphName)) {
createSliderGUI(morph.morphName, project->SliderCount(), sliderScroll, sliderScroll->GetSizer());
project->AddEmptySlider(morph.morphName);
ShowSliderEffect(morph.morphName);
}

for (int i = 0; i < morph.vertices.size(); i++)
diff[i] = morph.vertices[i];
std::unordered_map<ushort, Vector3> diff;
diff.reserve(morph.vertices.size());

project->SetSliderFromDiff(morph.morphName, shape, diff);
for (int i = 0; i < morph.vertices.size(); i++)
diff[i] = morph.vertices[i];

project->SetSliderFromDiff(morph.morphName, shape, diff);
}
}

sliderScroll->FitInside();
Expand All @@ -2917,6 +2932,32 @@ void OutfitStudioFrame::OnExportTRIHead(wxCommandEvent& WXUNUSED(event)) {
return;
}

wxString dir = wxDirSelector(_("Export .tri morphs"), wxEmptyString, wxDD_DEFAULT_STYLE, wxDefaultPosition, this);
if (dir.IsEmpty())
return;

for (auto &shape : project->GetWorkNif()->GetShapes()) {
std::string fn = dir + "/" + shape->GetName() + ".tri";

wxLogMessage("Exporting TRI (head) morphs of '%s' to '%s'...", shape->GetName(), fn);
if (!project->WriteHeadTRI(shape, fn)) {
wxLogError("Failed to export TRI file to '%s'!", fn);
wxMessageBox(_("Failed to export TRI file!"), _("Error"), wxICON_ERROR);
}
}
}

void OutfitStudioFrame::OnExportShapeTRIHead(wxCommandEvent& WXUNUSED(event)) {
if (!project->GetWorkNif()->IsValid()) {
wxMessageBox(_("There are no valid shapes loaded!"), _("Error"));
return;
}

if (!activeItem) {
wxMessageBox(_("There is no shape selected!"), _("Error"));
return;
}

wxString fn = wxFileSelector(_("Export .tri morphs"), wxEmptyString, wxEmptyString, ".tri", "*.tri", wxFD_SAVE | wxFD_OVERWRITE_PROMPT, this);
if (fn.IsEmpty())
return;
Expand All @@ -2925,7 +2966,6 @@ void OutfitStudioFrame::OnExportTRIHead(wxCommandEvent& WXUNUSED(event)) {
if (!project->WriteHeadTRI(activeItem->GetShape(), fn.ToUTF8().data())) {
wxLogError("Failed to export TRI file to '%s'!", fn);
wxMessageBox(_("Failed to export TRI file!"), _("Error"), wxICON_ERROR);
return;
}
}

Expand Down
1 change: 1 addition & 0 deletions src/program/OutfitStudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -1018,6 +1018,7 @@ class OutfitStudioFrame : public wxFrame {

void OnImportTRIHead(wxCommandEvent& event);
void OnExportTRIHead(wxCommandEvent& event);
void OnExportShapeTRIHead(wxCommandEvent& event);

void OnImportPhysicsData(wxCommandEvent &event);
void OnExportPhysicsData(wxCommandEvent &event);
Expand Down

0 comments on commit 64234c5

Please sign in to comment.