public static void ExportSocket() { if (OG.Model.HasSocket() == false) { return; } string filename = null; if (ShowExportDialogInEditor || FPlatform.InUnityEditor() == false) { filename = FPlatform.GetSaveFileName("Export Socket", Path.Combine(ExportSocketPath, "socket.obj"), new string[] { "*.obj" }, "Mesh Files (*.OBJ)"); } else { filename = Path.Combine(ExportSocketPath, "socket.obj"); } if (filename == null) { return; } DMesh3 SocketMesh = new DMesh3(OG.Socket.Socket.Mesh); AxisAlignedBox3d bounds = SocketMesh.CachedBounds; MeshTransforms.Translate(SocketMesh, -bounds.Min.y * Vector3d.AxisZ); MeshTransforms.FlipLeftRightCoordSystems(SocketMesh); // convert from unity coordinate system WriteOptions opt = WriteOptions.Defaults; opt.bWriteGroups = true; StandardMeshWriter.WriteMesh(filename, SocketMesh, opt); }
/// <summary> /// Writes a geometrymesh to a file, given a location. /// </summary> /// <param name="type">The geometry mesh.</param> /// <param name="location">The location of the file.</param> public void WriteFile(GeometryMesh type, string location) { if (type == null) { throw new ArgumentNullException(nameof(type)); } if (string.IsNullOrEmpty(location)) { throw new ArgumentNullException(nameof(location)); } IOWriteResult result = StandardMeshWriter.WriteMesh( location, type.Base, Options); if (result.code != IOCode.Ok) { throw new G3WriterException(result); } using (StreamWriter writer = File.AppendText(location)) { IOConventions.WriteIfNormalised(type.IsNormalised, writer); } }
void ThreadFunc() { Status = StandardMeshWriter.WriteFile(Filename, Meshes, options); if (CompletionF != null) { CompletionF(Status); } }
public static void WriteDebugMesh(IMesh mesh, string sPath) { WriteOptions options = WriteOptions.Defaults; options.bWriteGroups = true; StandardMeshWriter.WriteFile(sPath, new List <WriteMesh>() { new WriteMesh(mesh) }, options); }
private IEnumerator ExportOneFile(Generate generate, string path, string name, int num) { var mesh = generate.mesh; var filename = path + "/" + name + num + ".stl"; StandardMeshWriter.WriteFile(filename, new List <WriteMesh>() { new WriteMesh(mesh) }, WriteOptions.Defaults); yield return(null); }
public static void WriteFile(this DMesh3 mesh, string filePath, WriteOptions opts) { var writer = new StandardMeshWriter(); var m = new WriteMesh(mesh); var result = writer.Write(filePath, new List <WriteMesh> { m }, opts); if (!result.Equals(IOWriteResult.Ok)) { throw new Exception($"Failed to write file to {filePath} with result {result.ToString()}"); } }
private void OnPanelExportRequestMessage(PanelExportRequestMessage msg) { var list = new List <Geometry3D>(); MessengerInstance.Send(new PanelExportMessage() { AddSectionGeometry = (g) => list.Add(g) }); var dList = list.Select(g => (g as MeshGeometry3D).ToDMesh3()).ToList(); StandardMeshWriter.WriteMeshes(msg.FileName, dList, WriteOptions.Defaults); }
// Update is called once per frame void Update() { if (Input.GetKeyUp(KeyCode.R)) { Vector3d[] points = generate_sphere_points(500, SphereRadius * 1.0f); DMesh3 tmp = new DMesh3(sphereMesh); int[] point_to_vid_map = insert_points(points, tmp); remove_old_vertices(point_to_vid_map, tmp); g3UnityUtils.SetGOMesh(meshGO, tmp); StandardMeshWriter.WriteMesh("c:\\scratch\\FULL_COLLAPSE.obj", tmp, WriteOptions.Defaults); } }
private void bake_unwrap_uvs_Click(object sender, EventArgs e) { mmRemote = new mm.RemoteControl(); if (mmRemote.Initialize()) { statusLabel.Text = "Connected!"; } else { statusLabel.Text = "Could not connect!"; return; } List <int> vSelected = mmRemote.ListSelectedObjects(); if (vSelected.Count == 1) { statusLabel.Text = "Reading..."; DenseMeshUVSet uvSet; DMesh3 mesh = g3Conversion.ConvertUnwrapToUVs(mmRemote, out uvSet); //statusLabel.Text = "Writing..."; StandardMeshWriter writer = new StandardMeshWriter(); WriteOptions options = WriteOptions.Defaults; options.bWriteGroups = true; options.bWriteUVs = true; options.AsciiHeaderFunc = () => { return("mtllib default.mtl\r\nusemtl Texture_0\r\n"); }; WriteMesh wm = new WriteMesh(mesh) { UVs = uvSet }; writer.Write("c:\\scratch\\___EXPORT_UV.obj", new List <WriteMesh>() { wm }, options); statusLabel.Text = "Done!"; } else { MessageBox.Show("This command only works if a single object is selected"); } mmRemote.Shutdown(); statusLabel.Text = "(disconnected)"; }
private bool Export(List <WriteMesh> data, ExportParameters parameters) { var writeOptions = WriteOptions.Defaults; writeOptions.AsciiHeaderFunc = () => "Generated by Procedural Buildings Generator by Alexey Larionov"; writeOptions.bPerVertexNormals = data[0].Mesh.HasVertexNormals; var fileParameters = parameters as FileExportParameters; var ioResult = new StandardMeshWriter().Write(fileParameters.FilePath, data, writeOptions); if (ioResult.code != IOCode.Ok) { return(false); } return(true); }
public static void test_points() { string filename = "c:\\scratch\\bunny_solid.obj"; DMesh3 mesh = StandardMeshReader.ReadMesh(filename); PointSplatsGenerator pointgen = new PointSplatsGenerator() { PointIndices = IntSequence.Range(mesh.VertexCount), PointF = mesh.GetVertex, NormalF = (vid) => { return((Vector3d)mesh.GetVertexNormal(vid)); }, Radius = mesh.CachedBounds.DiagonalLength * 0.01 }; DMesh3 pointMesh = pointgen.Generate().MakeDMesh(); StandardMeshWriter.WriteMesh("c:\\scratch\\POINTS.obj", pointMesh, WriteOptions.Defaults); }
protected override void Recompute(DGArguments args) { string path = Inputs[0].Value <string>(args); DMesh3 mesh = Inputs[1].Value <DMesh3>(args); StandardMeshWriter writer = new StandardMeshWriter(); IOWriteResult result = writer.Write(path, new List <WriteMesh>() { new WriteMesh(mesh) }, WriteOptions.Defaults); if (result.code != IOCode.Ok) { // what?? } }
public static void WriteObj(FileInfo file, IGeometryData geo) { var meshes = new List <WriteMesh>(); var mesh = new SimpleMesh(); var map = new Dictionary <Vector3, int>(); var indeces = new List <int>(); for (var index = 0; index < geo.Positions.Length; index++) { var v = geo.Positions[index]; if (!map.ContainsKey(v)) { map.Add(v, map.Count); } } for (var index = 0; index < geo.Indices.Length; index++) { var i = geo.Indices[index]; var v = geo.Positions[i]; indeces.Add(map[v]); } var points = map.Keys.ToArray(); var pcount = points.Length * 3; var pp = new double[pcount]; var pindex = 0; for (var index = 0; index < points.Length; index++) { var v = points[index]; pp[pindex++] = v.X; pp[pindex++] = v.Y; pp[pindex++] = v.Z; } mesh.Initialize(new VectorArray3d(pp), new VectorArray3i(indeces.ToArray())); meshes.Add(new WriteMesh(mesh, $"d3dlab export")); StandardMeshWriter.WriteFile(file.FullName, meshes, WriteOptions.Defaults); }
public void ExportMesh(string filename) { //if there is a mold generated, save that one if (_moldMesh != null && _moldMesh.Count > 0) { if (_moldMesh.Count == 1) //if the mold wasn't sliced { StandardMeshWriter.WriteMesh(filename, _moldMesh[0], WriteOptions.Defaults); return; } else { for (int i = 0; i < _moldMesh.Count; i++) { string file = filename.Substring(0, filename.Length - 4); file += "_" + (i + 1) + ".stl"; StandardMeshWriter.WriteMesh(file, _moldMesh[i], WriteOptions.Defaults); } return; } } else { DMesh3 mesh = new DMesh3(); if (_moldMesh != null) { mesh = _moldMesh[0]; } else if (_smoothMesh != null) { mesh = _smoothMesh; } else { mesh = _mesh; } StandardMeshWriter.WriteMesh(filename, mesh, WriteOptions.Defaults); } }
protected override void SolveInstance(IGH_DataAccess DA) { this.Message = "." + type.ToString(); DMesh3_goo goo = null; string path = ""; string file = ""; DA.GetData(0, ref goo); DA.GetData(1, ref path); DA.GetData(2, ref file); DMesh3 mesh = new DMesh3(goo.Value); IOWriteResult result = StandardMeshWriter.WriteFile(Path.Combine(path, file) + "." + type.ToString(), new List <WriteMesh>() { new WriteMesh(mesh) }, WriteOptions.Defaults); DA.SetData(0, Path.Combine(path, file) + "." + type.ToString()); }
private void mesh_to_obj_button_Click(object sender, EventArgs e) { mmRemote = new mm.RemoteControl(); if (mmRemote.Initialize()) { statusLabel.Text = "Connected!"; } else { statusLabel.Text = "Could not connect!"; return; } List <int> vSelected = mmRemote.ListSelectedObjects(); if (vSelected.Count == 1) { statusLabel.Text = "Reading..."; DMesh3 mesh = g3Conversion.ReadMeshFromMM(mmRemote, vSelected[0]); statusLabel.Text = "Writing..."; StandardMeshWriter writer = new StandardMeshWriter(); WriteOptions options = WriteOptions.Defaults; options.bWriteGroups = true; writer.Write("c:\\scratch\\___EXPORT.obj", new List <WriteMesh>() { new WriteMesh(mesh) }, options); statusLabel.Text = "Done!"; } else { MessageBox.Show("This command only works if a single object is selected"); } mmRemote.Shutdown(); statusLabel.Text = "(disconnected)"; }
public static void test_simple_obj() { string cwd = System.IO.Directory.GetCurrentDirectory(); System.Console.WriteLine("MeshIOTests : test_simple_obj() starting"); //SimpleMeshBuilder builder = new SimpleMeshBuilder(); DMesh3Builder builder = new DMesh3Builder(); StandardMeshReader reader = new StandardMeshReader(); reader.MeshBuilder = builder; var readResult = reader.Read(Program.TEST_FILES_PATH + "socket_with_groups.obj", new ReadOptions()); System.Console.WriteLine("read complete"); if (readResult.code != IOCode.Ok) { System.Console.WriteLine("read failed : " + readResult.message); throw new Exception("failed"); } List <WriteMesh> meshes = new List <WriteMesh>(); foreach (IMesh m in builder.Meshes) { meshes.Add(new WriteMesh(m)); } var writeResult = StandardMeshWriter.WriteFile(Program.TEST_OUTPUT_PATH + "temp_write.obj", meshes, new WriteOptions()); System.Console.WriteLine("write complete"); if (writeResult.code != IOCode.Ok) { System.Console.WriteLine("write failed : " + writeResult.message); throw new Exception("f**k"); } }
public static void WriteDebugMeshAndMarkers(IMesh mesh, List <Vector3D> Markers, string sPath) { WriteOptions options = WriteOptions.Defaults; options.bWriteGroups = true; List <WriteMesh> meshes = new List <WriteMesh>() { new WriteMesh(mesh) }; double size = BoundsUtil.Bounds(mesh).Diagonal.Length * 0.01f; foreach (Vector3D v in Markers) { TrivialBox3Generator boxgen = new TrivialBox3Generator(); boxgen.Box = new Box3d(v, size * Vector3D.One); boxgen.Generate(); DMesh3 m = new DMesh3(); boxgen.MakeMesh(m); meshes.Add(new WriteMesh(m)); } StandardMeshWriter.WriteFile(sPath, meshes, options); }
public IOWriteResult RunBackgroundWrite() { // transform meshes gParallel.ForEach(Interval1i.Range(ExportMeshes.Length), (i) => { if (MeshFrames[i].Origin != Vector3f.Zero || MeshFrames[i].Rotation != Quaternionf.Identity) { MeshTransforms.FromFrame(ExportMeshes[i], MeshFrames[i]); } MeshTransforms.FlipLeftRightCoordSystems(ExportMeshes[i]); if (ExportYUp == false) { MeshTransforms.ConvertYUpToZUp(ExportMeshes[i]); } }); List <WriteMesh> writeMeshes = new List <WriteMesh>(); for (int i = 0; i < ExportMeshes.Length; ++i) { writeMeshes.Add(new WriteMesh(ExportMeshes[i])); } WriteOptions options = WriteOptions.Defaults; options.bWriteBinary = true; options.ProgressFunc = BackgroundProgressFunc; StandardMeshWriter writer = new StandardMeshWriter(); IOWriteResult result = writer.Write(WritePath, writeMeshes, options); return(result); }
void SaveMesh(PlateConfig config, [CallerMemberName] string fileName = null) { var output = Path.Combine(SolutionFolder(), "output"); if (!Directory.Exists(output)) { Directory.CreateDirectory(output); } var plate = new PlateGenerator(config); var meshGenerator = plate.Generate(); var mesh = meshGenerator.MakeSimpleMesh(); fileName = fileName != null ? $"{fileName}.stl" : $"output.stl"; IOWriteResult result = StandardMeshWriter.WriteFile( Path.Combine(output, fileName), new List <WriteMesh>() { new WriteMesh(mesh) }, WriteOptions.Defaults); }
public virtual ExportStatus Export(FScene scene, string filename) { int[] vertexMap = new int[2048]; // temp List <WriteMesh> vMeshes = new List <WriteMesh>(); if (WriteFaceGroups) { throw new Exception("SceneMeshExporter.Export: writing face groups has not yet been implemented!"); } // extract all the mesh data we want to export foreach (SceneObject so in scene.SceneObjects) { if (so.IsTemporary || so.IsSurface == false || SceneUtil.IsVisible(so) == false) { continue; } if (SOFilterF != null && SOFilterF(so) == false) { continue; } // if this SO has an internal mesh we can just copy, use it if (so is DMeshSO) { DMeshSO meshSO = so as DMeshSO; // todo: flags // make a copy of mesh DMesh3 m = new DMesh3(meshSO.Mesh, true); // transform to scene coords and swap left/right foreach (int vid in m.VertexIndices()) { Vector3f v = (Vector3f)m.GetVertex(vid); v = SceneTransforms.ObjectToScene(meshSO, v); v = UnityUtil.SwapLeftRight(v); m.SetVertex(vid, v); } m.ReverseOrientation(); vMeshes.Add(new WriteMesh(m, so.Name)); } // Look for lower-level fGameObject items to export. By default // this is anything with a MeshFilter, override CollectGOChildren // or use GOFilterF to add restrictions List <fGameObject> vExports = CollectGOChildren(so); if (vExports.Count > 0) { SimpleMesh m = new SimpleMesh(); m.Initialize(WriteNormals, WriteVertexColors, WriteUVs, WriteFaceGroups); int groupCounter = 1; foreach (fGameObject childgo in vExports) { if (GOFilterF != null && GOFilterF(so, childgo) == false) { continue; } if (AppendGOMesh(childgo, m, vertexMap, scene, groupCounter)) { groupCounter++; } } vMeshes.Add(new WriteMesh(m, so.Name)); } } // ok, we are independent of Scene now and can write in bg thread if (WriteInBackgroundThreads) { ExportStatus status = new ExportStatus() { Exporter = this, IsComputing = true }; WriteOptions useOptions = Options; useOptions.ProgressFunc = (cur, max) => { status.Progress = cur; status.MaxProgress = max; }; BackgroundWriteThread t = new BackgroundWriteThread() { Meshes = vMeshes, options = useOptions, Filename = filename, CompletionF = (result) => { LastWriteStatus = result.code; LastErrorMessage = result.message; status.LastErrorMessage = result.message; status.Ok = (result.code == IOCode.Ok); status.IsComputing = false; if (BackgroundWriteCompleteF != null) { BackgroundWriteCompleteF(this, status); } } }; t.Start(); return(status); } else { IOWriteResult result = StandardMeshWriter.WriteFile(filename, vMeshes, Options); LastWriteStatus = result.code; LastErrorMessage = result.message; return(new ExportStatus() { Exporter = this, IsComputing = false, Ok = (result.code == IOCode.Ok), LastErrorMessage = result.message }); } }
// make sure format writers all minimally function, and properly close file when completed public static void test_write_formats() { string out_path = Program.TEST_OUTPUT_PATH + "format_test"; DMesh3 mesh = StandardMeshReader.ReadMesh(Program.TEST_FILES_PATH + "bunny_solid.obj"); StandardMeshWriter writer = new StandardMeshWriter(); var list = new List <WriteMesh>() { new WriteMesh(mesh) }; if (writer.Write(out_path + ".obj", list, WriteOptions.Defaults).code != IOCode.Ok) { System.Console.WriteLine("test_write_formats: obj failed"); } if (writer.Write(out_path + ".stl", list, WriteOptions.Defaults).code != IOCode.Ok) { System.Console.WriteLine("test_write_formats: stl failed"); } if (writer.Write(out_path + ".off", list, WriteOptions.Defaults).code != IOCode.Ok) { System.Console.WriteLine("test_write_formats: off failed"); } if (writer.Write(out_path + ".g3mesh", list, WriteOptions.Defaults).code != IOCode.Ok) { System.Console.WriteLine("test_write_formats: g3mesh failed"); } if (writer.Write(out_path + ".obj", list, WriteOptions.Defaults).code != IOCode.Ok) { System.Console.WriteLine("test_write_formats: obj failed on second pass"); } if (writer.Write(out_path + ".stl", list, WriteOptions.Defaults).code != IOCode.Ok) { System.Console.WriteLine("test_write_formats: stl failed on second pass"); } if (writer.Write(out_path + ".off", list, WriteOptions.Defaults).code != IOCode.Ok) { System.Console.WriteLine("test_write_formats: off failed on second pass"); } if (writer.Write(out_path + ".g3mesh", list, WriteOptions.Defaults).code != IOCode.Ok) { System.Console.WriteLine("test_write_formats: g3mesh failed on second pass"); } MemoryStream fileStream = new MemoryStream(); MemoryStream mtlStream = new MemoryStream(); writer.OpenStreamF = (filename) => { return(filename.EndsWith(".mtl") ? mtlStream : fileStream); }; writer.CloseStreamF = (stream) => { }; WriteOptions opt = WriteOptions.Defaults; opt.bWriteMaterials = true; opt.MaterialFilePath = out_path + ".mtl"; if (writer.Write(out_path + ".obj", list, opt).code != IOCode.Ok) { System.Console.WriteLine("test_write_formats: write to memory stream failed"); } //string s = Encoding.ASCII.GetString(fileStream.ToArray()); if (fileStream.Length == 0) { System.Console.WriteLine("test_write_formats: write to memory stream produced zero-length stream"); } }
public static void Main(string[] args) { CommandArgumentSet arguments = new CommandArgumentSet(); //arguments.Register("-tcount", int.MaxValue); //arguments.Register("-percent", 50.0f); //arguments.Register("-v", false); arguments.Register("-output", ""); if (arguments.Parse(args) == false) { return; } if (arguments.Filenames.Count != 1) { print_usage(); return; } string inputFilename = arguments.Filenames[0]; if (!File.Exists(inputFilename)) { System.Console.WriteLine("File {0} does not exist", inputFilename); return; } string outputFilename = Path.GetFileNameWithoutExtension(inputFilename); string format = Path.GetExtension(inputFilename); outputFilename = outputFilename + ".repaired" + format; if (arguments.Saw("-output")) { outputFilename = arguments.Strings["-output"]; } //int triCount = int.MaxValue; //if (arguments.Saw("-tcount")) // triCount = arguments.Integers["-tcount"]; //float percent = 50.0f; //if (arguments.Saw("-percent")) // percent = arguments.Floats["-percent"]; bool verbose = true; //if (arguments.Saw("-v")) // verbose = arguments.Flags["-v"]; List <DMesh3> meshes; try { DMesh3Builder builder = new DMesh3Builder(); IOReadResult result = StandardMeshReader.ReadFile(inputFilename, ReadOptions.Defaults, builder); if (result.code != IOCode.Ok) { System.Console.WriteLine("Error reading {0} : {1}", inputFilename, result.message); return; } meshes = builder.Meshes; } catch (Exception e) { System.Console.WriteLine("Exception reading {0} : {1}", inputFilename, e.Message); return; } if (meshes.Count == 0) { System.Console.WriteLine("file did not contain any valid meshes"); return; } DMesh3 mesh = meshes[0]; for (int k = 1; k < meshes.Count; ++k) { MeshEditor.Append(mesh, meshes[k]); } if (mesh.TriangleCount == 0) { System.Console.WriteLine("mesh does not contain any triangles"); return; } if (verbose) { System.Console.WriteLine("initial mesh contains {0} triangles", mesh.TriangleCount); } if (verbose) { System.Console.WriteLine("Repairing...", mesh.TriangleCount); } MeshAutoRepair repair = new MeshAutoRepair(mesh); repair.RemoveMode = MeshAutoRepair.RemoveModes.None; bool bOK = repair.Apply(); if (verbose) { if (bOK == false) { System.Console.WriteLine("repair failed!"); } else { System.Console.WriteLine("done! repaired mesh contains {0} triangles", mesh.TriangleCount); } } try { IOWriteResult wresult = StandardMeshWriter.WriteMesh(outputFilename, mesh, WriteOptions.Defaults); if (wresult.code != IOCode.Ok) { System.Console.WriteLine("Error writing {0} : {1}", inputFilename, wresult.message); return; } } catch (Exception e) { System.Console.WriteLine("Exception reading {0} : {1}", inputFilename, e.Message); return; } return; }
// // [TODO] // static void Main(string[] args) { CommandArgumentSet arguments = new CommandArgumentSet(); arguments.Register("-output", ""); if (arguments.Parse(args) == false) { return; } if (arguments.Filenames.Count != 1) { print_usage(); return; } string sInputFile = arguments.Filenames[0]; string sFilenameRoot = Path.GetFileNameWithoutExtension(sInputFile); if (!File.Exists(sInputFile)) { System.Console.WriteLine("cannot find file " + sInputFile); return; } DMesh3Builder builder = new DMesh3Builder(); StandardMeshReader reader = new StandardMeshReader() { MeshBuilder = builder }; ReadOptions read_options = ReadOptions.Defaults; read_options.ReadMaterials = true; IOReadResult readOK = reader.Read(sInputFile, read_options); if (readOK.code != IOCode.Ok) { System.Console.WriteLine("Error reading " + sInputFile); System.Console.WriteLine(readOK.message); return; } if (builder.Meshes.Count == 0) { System.Console.WriteLine("did not find any valid meshes in " + sInputFile); return; } // [TODO] out if count == 0 string sOutRoot = arguments.Strings["-output"]; if (sOutRoot.Length > 0) { bool bOutIsFolder = Directory.Exists(sOutRoot); if (!bOutIsFolder) { System.Console.WriteLine("-output folder {0} does not exist", sOutRoot); return; } } Dictionary <int, List <int> > MeshesByMaterial = new Dictionary <int, List <int> >(); MeshesByMaterial[-1] = new List <int>(); for (int i = 0; i < builder.Materials.Count; ++i) { MeshesByMaterial[i] = new List <int>(); } int N = builder.Meshes.Count; for (int i = 0; i < N; ++i) { int mati = builder.MaterialAssignment[i]; if (mati >= builder.Materials.Count) { mati = -1; } MeshesByMaterial[mati].Add(i); } int file_i = 0; foreach (int mat_i in MeshesByMaterial.Keys) { List <int> mesh_idxs = MeshesByMaterial[mat_i]; if (mesh_idxs.Count == 0) { continue; } WriteMesh[] write_meshes = new WriteMesh[mesh_idxs.Count]; for (int i = 0; i < mesh_idxs.Count; ++i) { write_meshes[i] = new WriteMesh(builder.Meshes[mesh_idxs[i]]); } string suffix = string.Format("_material{0}", file_i++); string sOutPath = Path.Combine(sOutRoot, sFilenameRoot + suffix + ".obj"); StandardMeshWriter writer = new StandardMeshWriter(); WriteOptions write_options = WriteOptions.Defaults; if (mat_i != -1) { write_options.bWriteMaterials = true; write_options.bPerVertexUVs = true; write_options.MaterialFilePath = Path.Combine(sOutRoot, sFilenameRoot + suffix + ".mtl"); GenericMaterial mat = builder.Materials[mat_i]; List <GenericMaterial> matList = new List <GenericMaterial>() { mat }; ConstantIndexMap idxmap = new ConstantIndexMap(0); for (int i = 0; i < write_meshes.Length; ++i) { write_meshes[i].Materials = matList; write_meshes[i].TriToMaterialMap = idxmap; } } IOWriteResult writeOK = writer.Write(sOutPath, new List <WriteMesh>(write_meshes), write_options); if (writeOK.code != IOCode.Ok) { System.Console.WriteLine("Error writing " + sOutPath); System.Console.WriteLine(writeOK.message); } } // ok done! //System.Console.ReadKey(); }
// // [TODO] // - binary output option // - option to strip data from inputs (eg remove normals/colors/uv/material from obj) // - option to remove material props from OBJ // - option to combine input meshes // - option to set float precision // - option to estimate normals for writing (eg for obj) // - option to set constant color for vertices // static void Main(string[] args) { if (args.Length != 2) { System.Console.WriteLine("gsMeshConvert v1.0 - Copyright gradientspace / Ryan Schmidt 2017"); System.Console.WriteLine("Questions? Comments? www.gradientspace.com or @gradientspace"); System.Console.WriteLine("usage: gsMeshConvert <input_mesh.format> (output_mesh.format)"); return; } string sInputFile = args[0]; if (!File.Exists(sInputFile)) { System.Console.WriteLine("cannot find file " + sInputFile); return; } string sOutputFile = args[1]; // check that can write output file DMesh3Builder builder = new DMesh3Builder(); StandardMeshReader reader = new StandardMeshReader() { MeshBuilder = builder }; ReadOptions read_options = ReadOptions.Defaults; IOReadResult readOK = reader.Read(sInputFile, read_options); if (readOK.code != IOCode.Ok) { System.Console.WriteLine("Error reading " + sInputFile); System.Console.WriteLine(readOK.message); return; } if (builder.Meshes.Count == 0) { System.Console.WriteLine("did not find any valid meshes in " + sInputFile); return; } List <WriteMesh> write_meshes = new List <WriteMesh>(); foreach (DMesh3 mesh in builder.Meshes) { write_meshes.Add(new WriteMesh(mesh)); } StandardMeshWriter writer = new StandardMeshWriter(); WriteOptions write_options = WriteOptions.Defaults; IOWriteResult writeOK = writer.Write(sOutputFile, write_meshes, write_options); if (writeOK.code != IOCode.Ok) { System.Console.WriteLine("Error writing " + sOutputFile); System.Console.WriteLine(writeOK.message); return; } // ok done! //System.Console.ReadKey(); }
static void Main(string[] args) { CommandArgumentSet arguments = new CommandArgumentSet(); arguments.Register("-tcount", int.MaxValue); arguments.Register("-percent", 50.0f); arguments.Register("-v", false); arguments.Register("-output", ""); if (arguments.Parse(args) == false) { return; } if (arguments.Filenames.Count != 1) { print_usage(); return; } string inputFilename = arguments.Filenames[0]; if (!File.Exists(inputFilename)) { System.Console.WriteLine("File {0} does not exist", inputFilename); return; } string outputFilename = Path.GetFileNameWithoutExtension(inputFilename); string format = Path.GetExtension(inputFilename); outputFilename = outputFilename + ".reduced" + format; if (arguments.Saw("-output")) { outputFilename = arguments.Strings["-output"]; } int triCount = int.MaxValue; if (arguments.Saw("-tcount")) { triCount = arguments.Integers["-tcount"]; } float percent = 50.0f; if (arguments.Saw("-percent")) { percent = arguments.Floats["-percent"]; } bool verbose = false; if (arguments.Saw("-v")) { verbose = arguments.Flags["-v"]; } List <DMesh3> meshes; try { DMesh3Builder builder = new DMesh3Builder(); IOReadResult result = StandardMeshReader.ReadFile(inputFilename, ReadOptions.Defaults, builder); if (result.code != IOCode.Ok) { System.Console.WriteLine("Error reading {0} : {1}", inputFilename, result.message); return; } meshes = builder.Meshes; } catch (Exception e) { System.Console.WriteLine("Exception reading {0} : {1}", inputFilename, e.Message); return; } if (meshes.Count == 0) { System.Console.WriteLine("file did not contain any valid meshes"); return; } DMesh3 mesh = meshes[0]; for (int k = 1; k < meshes.Count; ++k) { MeshEditor.Append(mesh, meshes[k]); } if (mesh.TriangleCount == 0) { System.Console.WriteLine("mesh does not contain any triangles"); return; } if (verbose) { System.Console.WriteLine("initial mesh contains {0} triangles", mesh.TriangleCount); } Reducer r = new Reducer(mesh); if (triCount < int.MaxValue) { if (verbose) { System.Console.Write("reducing to {0} triangles...", triCount); } r.ReduceToTriangleCount(triCount); } else { int nT = (int)((float)mesh.TriangleCount * percent / 100.0f); nT = MathUtil.Clamp(nT, 1, mesh.TriangleCount); if (verbose) { System.Console.Write("reducing to {0} triangles...", nT); } r.ReduceToTriangleCount(nT); } if (verbose) { System.Console.WriteLine("done!"); } try { IOWriteResult wresult = StandardMeshWriter.WriteMesh(outputFilename, mesh, WriteOptions.Defaults); if (wresult.code != IOCode.Ok) { System.Console.WriteLine("Error writing {0} : {1}", inputFilename, wresult.message); return; } } catch (Exception e) { System.Console.WriteLine("Exception reading {0} : {1}", inputFilename, e.Message); return; } return; }
public static void WriteObj(FileInfo file, IEnumerable <IFileGeometry3D> geometries) { var meshes = new List <WriteMesh>(); var mesh = new SimpleMesh(); var map = new Dictionary <Vector3, int>(); var indeces = new List <int>(); foreach (var geo in geometries) { //var pcount = geo.Positions.Count * 3; //var pp = new double[pcount]; //var pindex = 0; //for(var index =0; index < geo.Positions.Count; index++) { // var v = geo.Positions[index]; // pp[pindex++] = v.X; // pp[pindex++] = v.Y; // pp[pindex++] = v.Z; //} //mesh.Initialize(new VectorArray3d(pp), new VectorArray3i(geo.Indices.ToArray())); for (var index = 0; index < geo.Positions.Count; index++) { var v = geo.Positions[index]; if (!map.ContainsKey(v)) { map.Add(v, map.Count); } } for (var index = 0; index < geo.Indices.Count; index++) { var i = geo.Indices[index]; var v = geo.Positions[i]; indeces.Add(map[v]); } } var points = map.Keys.ToArray(); var pcount = points.Length * 3; var pp = new double[pcount]; var pindex = 0; for (var index = 0; index < points.Length; index++) { var v = points[index]; pp[pindex++] = v.X; pp[pindex++] = v.Y; pp[pindex++] = v.Z; } mesh.Initialize(new VectorArray3d(pp), new VectorArray3i(indeces.ToArray())); meshes.Add(new WriteMesh(mesh, $"d3dlab export")); StandardMeshWriter.WriteFile(file.FullName, meshes, WriteOptions.Defaults); //var obj = new OBJWriter(); //System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture; //using (var stream = File.Open(file.FullName, FileMode.Create)) { // using (var writer = new StreamWriter(stream, Encoding.UTF8)) { // obj.Write(writer, meshes, WriteOptions.Defaults); // } //} }
public static void test_marching_cubes_demos() { // generateMeshF() meshes the input implicit function at // the given cell resolution, and writes out the resulting mesh Action <BoundedImplicitFunction3d, int, string> generateMeshF = (root, numcells, path) => { MarchingCubes c = new MarchingCubes(); c.Implicit = root; c.RootMode = MarchingCubes.RootfindingModes.LerpSteps; // cube-edge convergence method c.RootModeSteps = 5; // number of iterations c.Bounds = root.Bounds(); c.CubeSize = c.Bounds.MaxDim / numcells; c.Bounds.Expand(3 * c.CubeSize); // leave a buffer of cells c.Generate(); MeshNormals.QuickCompute(c.Mesh); // generate normals StandardMeshWriter.WriteMesh(path, c.Mesh, WriteOptions.Defaults); // write mesh }; // meshToImplicitF() generates a narrow-band distance-field and // returns it as an implicit surface, that can be combined with other implicits Func <DMesh3, int, double, BoundedImplicitFunction3d> meshToImplicitF = (meshIn, numcells, max_offset) => { double meshCellsize = meshIn.CachedBounds.MaxDim / numcells; MeshSignedDistanceGrid levelSet = new MeshSignedDistanceGrid(meshIn, meshCellsize); levelSet.ExactBandWidth = (int)(max_offset / meshCellsize) + 1; levelSet.Compute(); return(new DenseGridTrilinearImplicit(levelSet.Grid, levelSet.GridOrigin, levelSet.CellSize)); }; // meshToBlendImplicitF() computes the full distance-field grid for the input // mesh. The bounds are expanded quite a bit to allow for blending, // probably more than necessary in most cases Func <DMesh3, int, BoundedImplicitFunction3d> meshToBlendImplicitF = (meshIn, numcells) => { double meshCellsize = meshIn.CachedBounds.MaxDim / numcells; MeshSignedDistanceGrid levelSet = new MeshSignedDistanceGrid(meshIn, meshCellsize); levelSet.ExpandBounds = meshIn.CachedBounds.Diagonal * 0.25; // need some values outside mesh levelSet.ComputeMode = MeshSignedDistanceGrid.ComputeModes.FullGrid; levelSet.Compute(); return(new DenseGridTrilinearImplicit(levelSet.Grid, levelSet.GridOrigin, levelSet.CellSize)); }; // generate union/difference/intersection of sphere and cube ImplicitSphere3d sphere = new ImplicitSphere3d() { Origin = Vector3d.Zero, Radius = 1.0 }; ImplicitBox3d box = new ImplicitBox3d() { Box = new Box3d(new Frame3f(Vector3f.AxisX), 0.5 * Vector3d.One) }; generateMeshF(new ImplicitUnion3d() { A = sphere, B = box }, 128, "c:\\demo\\union.obj"); generateMeshF(new ImplicitDifference3d() { A = sphere, B = box }, 128, "c:\\demo\\difference.obj"); generateMeshF(new ImplicitIntersection3d() { A = sphere, B = box }, 128, "c:\\demo\\intersection.obj"); // generate bunny offset surfaces //double offset = 0.2f; //DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj"); //MeshTransforms.Scale(mesh, 3.0 / mesh.CachedBounds.MaxDim); //BoundedImplicitFunction3d meshImplicit = meshToImplicitF(mesh, 64, offset); //generateMeshF(meshImplicit, 128, "c:\\demo\\mesh.obj"); //generateMeshF(new ImplicitOffset3d() { A = meshImplicit, Offset = offset }, 128, "c:\\demo\\mesh_outset.obj"); //generateMeshF(new ImplicitOffset3d() { A = meshImplicit, Offset = -offset }, 128, "c:\\demo\\mesh_inset.obj"); // compare offset of sharp and smooth union //var smooth_union = new ImplicitSmoothDifference3d() { A = sphere, B = box }; //generateMeshF(smooth_union, 128, "c:\\demo\\smooth_union.obj"); //generateMeshF(new ImplicitOffset3d() { A = smooth_union, Offset = 0.2 }, 128, "c:\\demo\\smooth_union_offset.obj"); //var union = new ImplicitUnion3d() { A = sphere, B = box }; //generateMeshF(new ImplicitOffset3d() { A = union, Offset = offset }, 128, "c:\\demo\\union_offset.obj"); // blending //ImplicitSphere3d sphere1 = new ImplicitSphere3d() { // Origin = Vector3d.Zero, Radius = 1.0 //}; //ImplicitSphere3d sphere2 = new ImplicitSphere3d() { // Origin = 1.5 * Vector3d.AxisX, Radius = 1.0 //}; //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 1.0 }, 128, "c:\\demo\\blend_1.obj"); //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 4.0 }, 128, "c:\\demo\\blend_4.obj"); //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 16.0 }, 128, "c:\\demo\\blend_16.obj"); //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 64.0 }, 128, "c:\\demo\\blend_64.obj"); //sphere1.Radius = sphere2.Radius = 2.0f; //sphere2.Origin = 1.5 * sphere1.Radius * Vector3d.AxisX; //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 1.0 }, 128, "c:\\demo\\blend_2x_1.obj"); //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 4.0 }, 128, "c:\\demo\\blend_2x_4.obj"); //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 16.0 }, 128, "c:\\demo\\blend_2x_16.obj"); //generateMeshF(new ImplicitBlend3d() { A = sphere1, B = sphere2, Blend = 64.0 }, 128, "c:\\demo\\blend_2x_64.obj"); // mesh blending //DMesh3 mesh1 = TestUtil.LoadTestInputMesh("bunny_solid.obj"); //MeshTransforms.Scale(mesh1, 3.0 / mesh1.CachedBounds.MaxDim); //DMesh3 mesh2 = new DMesh3(mesh1); //MeshTransforms.Rotate(mesh2, mesh2.CachedBounds.Center, Quaternionf.AxisAngleD(Vector3f.OneNormalized, 45.0f)); //var meshImplicit1 = meshToImplicitF(mesh1, 64, 0); //var meshImplicit2 = meshToImplicitF(mesh2, 64, 0); //generateMeshF(new ImplicitBlend3d() { A = meshImplicit1, B = meshImplicit2, Blend = 0.0 }, 256, "c:\\demo\\blend_mesh_union.obj"); //generateMeshF(new ImplicitBlend3d() { A = meshImplicit1, B = meshImplicit2, Blend = 10.0 }, 256, "c:\\demo\\blend_mesh_bad.obj"); //var meshFullImplicit1 = meshToBlendImplicitF(mesh1, 64); //var meshFullImplicit2 = meshToBlendImplicitF(mesh2, 64); //generateMeshF(new ImplicitBlend3d() { A = meshFullImplicit1, B = meshFullImplicit2, Blend = 0.0 }, 256, "c:\\demo\\blend_mesh_union.obj"); //generateMeshF(new ImplicitBlend3d() { A = meshFullImplicit1, B = meshFullImplicit2, Blend = 1.0 }, 256, "c:\\demo\\blend_mesh_1.obj"); //generateMeshF(new ImplicitBlend3d() { A = meshFullImplicit1, B = meshFullImplicit2, Blend = 10.0 }, 256, "c:\\demo\\blend_mesh_10.obj"); //generateMeshF(new ImplicitBlend3d() { A = meshFullImplicit1, B = meshFullImplicit2, Blend = 50.0 }, 256, "c:\\demo\\blend_mesh_100.obj"); //DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj"); //MeshTransforms.Scale(mesh, 3.0 / mesh.CachedBounds.MaxDim); //MeshTransforms.Translate(mesh, -mesh.CachedBounds.Center); //Reducer r = new Reducer(mesh); //r.ReduceToTriangleCount(100); //double radius = 0.1; //List<BoundedImplicitFunction3d> Lines = new List<BoundedImplicitFunction3d>(); //foreach (Index4i edge_info in mesh.Edges()) { // var segment = new Segment3d(mesh.GetVertex(edge_info.a), mesh.GetVertex(edge_info.b)); // Lines.Add(new ImplicitLine3d() { Segment = segment, Radius = radius }); //} //ImplicitNaryUnion3d unionN = new ImplicitNaryUnion3d() { Children = Lines }; //generateMeshF(unionN, 128, "c:\\demo\\mesh_edges.obj"); //radius = 0.05; //List<BoundedImplicitFunction3d> Elements = new List<BoundedImplicitFunction3d>(); //foreach (int eid in mesh.EdgeIndices()) { // var segment = new Segment3d(mesh.GetEdgePoint(eid, 0), mesh.GetEdgePoint(eid, 1)); // Elements.Add(new ImplicitLine3d() { Segment = segment, Radius = radius }); //} //foreach (Vector3d v in mesh.Vertices()) // Elements.Add(new ImplicitSphere3d() { Origin = v, Radius = 2 * radius }); //generateMeshF(new ImplicitNaryUnion3d() { Children = Elements }, 256, "c:\\demo\\mesh_edges_and_vertices.obj"); //double lattice_radius = 0.05; //double lattice_spacing = 0.4; //double shell_thickness = 0.05; //int mesh_resolution = 64; // set to 256 for image quality //var shellMeshImplicit = meshToImplicitF(mesh, 128, shell_thickness); //double max_dim = mesh.CachedBounds.MaxDim; //AxisAlignedBox3d bounds = new AxisAlignedBox3d(mesh.CachedBounds.Center, max_dim / 2); //bounds.Expand(2 * lattice_spacing); //AxisAlignedBox2d element = new AxisAlignedBox2d(lattice_spacing); //AxisAlignedBox2d bounds_xy = new AxisAlignedBox2d(bounds.Min.xy, bounds.Max.xy); //AxisAlignedBox2d bounds_xz = new AxisAlignedBox2d(bounds.Min.xz, bounds.Max.xz); //AxisAlignedBox2d bounds_yz = new AxisAlignedBox2d(bounds.Min.yz, bounds.Max.yz); //List<BoundedImplicitFunction3d> Tiling = new List<BoundedImplicitFunction3d>(); //foreach (Vector2d uv in TilingUtil.BoundedRegularTiling2(element, bounds_xy, 0)) { // Segment3d seg = new Segment3d(new Vector3d(uv.x, uv.y, bounds.Min.z), new Vector3d(uv.x, uv.y, bounds.Max.z)); // Tiling.Add(new ImplicitLine3d() { Segment = seg, Radius = lattice_radius }); //} //foreach (Vector2d uv in TilingUtil.BoundedRegularTiling2(element, bounds_xz, 0)) { // Segment3d seg = new Segment3d(new Vector3d(uv.x, bounds.Min.y, uv.y), new Vector3d(uv.x, bounds.Max.y, uv.y)); // Tiling.Add(new ImplicitLine3d() { Segment = seg, Radius = lattice_radius }); //} //foreach (Vector2d uv in TilingUtil.BoundedRegularTiling2(element, bounds_yz, 0)) { // Segment3d seg = new Segment3d(new Vector3d(bounds.Min.x, uv.x, uv.y), new Vector3d(bounds.Max.x, uv.x, uv.y)); // Tiling.Add(new ImplicitLine3d() { Segment = seg, Radius = lattice_radius }); //} //ImplicitNaryUnion3d lattice = new ImplicitNaryUnion3d() { Children = Tiling }; //generateMeshF(lattice, 128, "c:\\demo\\lattice.obj"); //ImplicitIntersection3d lattice_clipped = new ImplicitIntersection3d() { A = lattice, B = shellMeshImplicit }; //generateMeshF(lattice_clipped, mesh_resolution, "c:\\demo\\lattice_clipped.obj"); //var shell = new ImplicitDifference3d() { // A = shellMeshImplicit, B = new ImplicitOffset3d() { A = shellMeshImplicit, Offset = -shell_thickness } //}; //var shell_cut = new ImplicitDifference3d() { // A = shell, B = new ImplicitAxisAlignedBox3d() { AABox = new AxisAlignedBox3d(Vector3d.Zero, max_dim / 2, 0.4, max_dim / 2) } //}; //generateMeshF(new ImplicitUnion3d() { A = lattice_clipped, B = shell_cut }, mesh_resolution, "c:\\demo\\lattice_result.obj"); }
public static void WriteMesh(DMesh3 inputMesh, string path) { StandardMeshWriter.WriteMesh(path, inputMesh, WriteOptions.Defaults); }
public ExportStatus Export(FScene s, string filename) { List <WriteMesh> vMeshes = new List <WriteMesh>(); if (WriteFaceGroups) { throw new Exception("SceneMeshExporter.Export: writing face groups has not yet been implemented!"); } foreach (SceneObject so in s.SceneObjects) { if (so.IsTemporary) { continue; } SimpleMesh m = new SimpleMesh(); m.Initialize(WriteNormals, WriteVertexColors, WriteUVs, WriteFaceGroups); int groupCounter = 1; GameObject rootgo = so.RootGameObject; int[] vertexMap = new int[2048]; foreach (GameObject childgo in rootgo.Children()) { MeshFilter filter = childgo.GetComponent <MeshFilter>(); if (filter == null || filter.mesh == null) { continue; } if (GOFilterF != null && GOFilterF(so, childgo) == false) { continue; } Mesh curMesh = filter.sharedMesh; Vector3[] vertices = curMesh.vertices; Vector3[] normals = (WriteNormals) ? curMesh.normals : null; Color[] colors = (WriteVertexColors) ? curMesh.colors : null; Vector2[] uvs = (WriteUVs) ? curMesh.uv : null; if (vertexMap.Length < curMesh.vertexCount) { vertexMap = new int[curMesh.vertexCount * 2]; } for (int i = 0; i < curMesh.vertexCount; ++i) { NewVertexInfo vi = new NewVertexInfo(); vi.bHaveN = WriteNormals; vi.bHaveC = WriteVertexColors; vi.bHaveUV = WriteUVs; Vector3 v = vertices[i]; // local to world v = filter.gameObject.transform.TransformPoint(v); // world back to scene vi.v = UnityUtil.SwapLeftRight(s.RootGameObject.transform.InverseTransformPoint(v)); if (WriteNormals) { Vector3 n = normals[i]; n = filter.gameObject.transform.TransformDirection(n); vi.n = UnityUtil.SwapLeftRight(s.RootGameObject.transform.InverseTransformDirection(n)); } if (WriteVertexColors) { vi.c = colors[i]; } if (WriteUVs) { vi.uv = uvs[i]; } vertexMap[i] = m.AppendVertex(vi); } int[] triangles = curMesh.triangles; int nTriangles = triangles.Length / 3; for (int i = 0; i < nTriangles; ++i) { int a = vertexMap[triangles[3 * i]]; int b = vertexMap[triangles[3 * i + 1]]; int c = vertexMap[triangles[3 * i + 2]]; m.AppendTriangle(a, c, b, groupCounter); // TRI ORIENTATION IS REVERSED HERE!! } groupCounter++; } vMeshes.Add(new WriteMesh(m, so.Name)); } if (WriteInBackgroundThreads) { ExportStatus status = new ExportStatus() { Exporter = this, IsComputing = true }; WriteOptions useOptions = Options; useOptions.ProgressFunc = (cur, max) => { status.Progress = cur; status.MaxProgress = max; }; BackgroundWriteThread t = new BackgroundWriteThread() { Meshes = vMeshes, options = useOptions, Filename = filename, CompletionF = (result) => { LastWriteStatus = result.code; LastErrorMessage = result.message; status.LastErrorMessage = result.message; status.Ok = (result.code == IOCode.Ok); status.IsComputing = false; } }; t.Start(); return(status); } else { IOWriteResult result = StandardMeshWriter.WriteFile(filename, vMeshes, Options); LastWriteStatus = result.code; LastErrorMessage = result.message; return(new ExportStatus() { Exporter = this, IsComputing = false, Ok = (result.code == IOCode.Ok), LastErrorMessage = result.message }); } }