From 4b15e486d98fbed4ddc53f47b178d57983f9166c Mon Sep 17 00:00:00 2001 From: Soji Yamakawa Date: Sun, 8 Dec 2024 21:33:16 -0500 Subject: [PATCH] PLY writer. --- src/ysgebl/src/gui/filemenu/filemenu.cpp | 1 + src/ysgebl/src/gui/fsgui3dapp.cpp | 27 ++++++ src/ysgebl/src/kernel/ysshellextio.cpp | 100 +++++++++++++++++++++++ src/ysgebl/src/kernel/ysshellextio.h | 11 +++ 4 files changed, 139 insertions(+) diff --git a/src/ysgebl/src/gui/filemenu/filemenu.cpp b/src/ysgebl/src/gui/filemenu/filemenu.cpp index a4a9825..4093c6b 100644 --- a/src/ysgebl/src/gui/filemenu/filemenu.cpp +++ b/src/ysgebl/src/gui/filemenu/filemenu.cpp @@ -234,6 +234,7 @@ void GeblGuiEditorBase::File_SaveAs(FsGuiPopUpMenuItem *) fdlg->fileExtensionArray.Append(L".dnm"); fdlg->fileExtensionArray.Append(L".stl"); fdlg->fileExtensionArray.Append(L".obj"); + fdlg->fileExtensionArray.Append(L".ply"); fdlg->fileExtensionArray.Append(L".off"); fdlg->fileExtensionArray.Append(L".t3d"); fdlg->defaultFileName=def; diff --git a/src/ysgebl/src/gui/fsgui3dapp.cpp b/src/ysgebl/src/gui/fsgui3dapp.cpp index f7c726d..9bcfb1b 100644 --- a/src/ysgebl/src/gui/fsgui3dapp.cpp +++ b/src/ysgebl/src/gui/fsgui3dapp.cpp @@ -1003,6 +1003,33 @@ void GeblGuiEditorBase::SaveGeneral(const YsShellExtEdit &shl,const wchar_t fn[] MessageDialog(FSGUI_COMMON_ERROR,L"Cannot open the file in write-mode."); } } + else if(0==ext.STRCMP(".PLY")) + { + FILE *fp=YsFileIO::Fopen(fn,"w"); + if(NULL!=fp) + { + YsTextFileOutputStream outStream(fp); + + YsShellExtPlyWriter writer; + YsShellExtPlyWriter::WriteOption option; + writer.WritePly(outStream,(const YsShellExt &)shl,option); + fclose(fp); + + shl.SetFileName(fn); + shl.Saved(); + lastAccessedFileName.Set(fn); + if(YSTRUE==recordRecentFiles) + { + AddRecentlyUsedFile(fn); + } + + MessageDialog(FSGUI_DLG_SAVED_TITLE,savedMsg); + } + else + { + MessageDialog(FSGUI_COMMON_ERROR,L"Cannot open the file in write-mode."); + } + } else if(0==ext.STRCMP(".STL")) { /* for(auto plHd : shl.AllPolygon()) diff --git a/src/ysgebl/src/kernel/ysshellextio.cpp b/src/ysgebl/src/kernel/ysshellextio.cpp index dcc4cb4..e9f0b28 100644 --- a/src/ysgebl/src/kernel/ysshellextio.cpp +++ b/src/ysgebl/src/kernel/ysshellextio.cpp @@ -1578,6 +1578,91 @@ YSRESULT YsShellExtObjWriter::WriteObj(YsTextOutputStream &outStream,const YsShe return YSOK; } +//////////////////////////////////////////////////////////// + +YSRESULT YsShellExtPlyWriter::WritePly(YsTextOutputStream &outStream,const YsShellExt &shl,const WriteOption &option) +{ + shl.Encache(); + + outStream.Printf("ply\n"); + outStream.Printf("format ascii 1.0\n"); + outStream.Printf("comment PolygonCrest generated\n"); + + auto texFile=shl.FindMetaData(YsString("TextureFile")); + if(nullptr!=texFile && 0size()) + { + for(auto mdHd : *texFile) + { + auto str=shl.GetMetaDataValue(mdHd); + outStream.Printf("comment TextureFile %s\n",str.data()); + } + } + + bool vtxHasNormal=(nullptr!=shl.FindMetaData(YsString("VertexHasNormal"))); + outStream.Printf("element vertex %d\n",shl.GetNumVertex()); + outStream.Printf("property float x\n"); + outStream.Printf("property float y\n"); + outStream.Printf("property float z\n"); + if(true==vtxHasNormal) + { + outStream.Printf("property float nx\n"); + outStream.Printf("property float ny\n"); + outStream.Printf("property float nz\n"); + } + + bool plgHasTexCoord=(shl.FindNextTexCoord(nullptr)!=nullptr); + outStream.Printf("element face %d\n",shl.GetNumPolygon()); + outStream.Printf("property list uchar int vertex_indices\n"); + if(true==plgHasTexCoord) + { + outStream.Printf("property list uchar float texcoord\n"); + } + outStream.Printf("property uchar red\n"); + outStream.Printf("property uchar green\n"); + outStream.Printf("property uchar blue\n"); + outStream.Printf("property uchar alpha\n"); + + outStream.Printf("end_header\n"); + + for(auto vtHd : shl.AllVertex()) + { + YsVec3 vtx,nom; + vtx=shl.GetVertexPosition(vtHd); + nom=shl.GetVertexNormal(vtHd); + outStream.Printf("%lf %lf %lf",vtx.x(),vtx.y(),vtx.z()); + if(true==vtxHasNormal) + { + outStream.Printf(" %lf %lf %lf",nom.x(),nom.y(),nom.z()); + } + outStream.Printf("\n"); + } + for(auto plHd : shl.AllPolygon()) + { + auto plVtHd=shl.GetPolygonVertex(plHd); + auto plTcHd=shl.GetPolygonTexCoord(plHd); + auto col=shl.GetColor(plHd); + outStream.Printf("%d",plVtHd.size()); + for(auto vtHd : plVtHd) + { + outStream.Printf(" %d",shl.GetVertexIdFromHandle(vtHd)); + } + if(true==plgHasTexCoord) + { + outStream.Printf(" %d",plTcHd.size()*2); + for(auto tcHd : plTcHd) + { + auto tcPos=shl.GetTexCoordUV(tcHd); + outStream.Printf(" %lf %lf",tcPos.x(),tcPos.y()); + } + } + outStream.Printf(" %d %d %d %d\n",col.Ri(),col.Gi(),col.Bi(),col.Ai()); + } + + return YSOK; +} + +//////////////////////////////////////////////////////////// + YSRESULT YsShellExtFMTOWNSWriter::WriteFMTOWNST3D(FILE *ofp,const YsShellExt &shl,const WriteOption &opt) { if(nullptr!=ofp) @@ -2493,6 +2578,21 @@ YSRESULT YsShellExt_SaveGeneral(const char fnIn[],const YsShellExt &shl) return res; } } + else if(0==ext.STRCMP(".PLY")) + { + FILE *fp=fopen(fn,"w"); + if(nullptr!=fp) + { + YsShellExtPlyWriter::WriteOption defaultOption; + + YsShellExtPlyWriter writer; + YsTextFileOutputStream outStream(fp); + auto res=writer.WritePly(outStream,shl,defaultOption); + + fclose(fp); + return res; + } + } else if(0==ext.STRCMP(".T3D")) { FILE *fp=fopen(fn,"w"); diff --git a/src/ysgebl/src/kernel/ysshellextio.h b/src/ysgebl/src/kernel/ysshellextio.h index 21dcacf..435da1e 100644 --- a/src/ysgebl/src/kernel/ysshellextio.h +++ b/src/ysgebl/src/kernel/ysshellextio.h @@ -215,6 +215,17 @@ class YsShellExtObjWriter YSRESULT WriteObj(YsTextOutputStream &outStream,const YsShellExt &shl,const WriteOption &option); }; +class YsShellExtPlyWriter +{ +public: + class WriteOption + { + }; + +public: + YSRESULT WritePly(YsTextOutputStream &outStream,const YsShellExt &shl,const WriteOption &option); +}; + class YsShellExtFMTOWNSWriter { public: