【发布时间】:2021-03-05 18:16:27
【问题描述】:
所以在我们的 3D 扫描应用程序中,我应该扫描一个泡沫盒并将结果保存为 STL 文件。
为了只保留足迹部分,我使用类中的 CropStl 方法删除了一些高于 Z 值的顶点。
在 CropStl 方法结束时,brut stl 从 img1 变为 img2。但正如您在图像上看到的那样,结果的边界并不平滑。
有没有办法在 C# 中平滑第二个 stl 的边框,或者有什么工具可以做到这一点?
注意:我使用从 NuGet 安装的 IxMilia 和 geometry3Sharp。
public class STLEditor
{
//Takes the path of the brut stl file.
string stlPath;
public STLEditor(string _stlPath)
{
stlPath = _stlPath;
}
internal void CropStl()
{
try
{
using (FileStream fs = new FileStream(stlPath, FileMode.Open))
{
//Load the stl file
var stl = IxMilia.Stl.StlFile.Load(fs);
//Gets all triangles of the stl file into a list.
var triangles = stl.Triangles.ToList();
stl.Triangles.Clear();
//Removes vertexes which have the Z value > -15
Predicate<IxMilia.Stl.StlTriangle> predicate = FindTriangle;
triangles.RemoveAll(predicate);
stl.Triangles.AddRange(triangles);
using (FileStream fsSave = new FileStream(System.IO.Path.GetDirectoryName(stlPath) + "\\croped.stl", FileMode.Create))
{
stl.Save(fsSave, false);
}
System.Threading.Thread.Sleep(500);
//Tried some smoothing methods but it doesn't work as expected.
GeometricOperations();
System.IO.File.Delete(System.IO.Path.GetDirectoryName(stlPath) + "\\croped.stl");
}
}
catch (Exception ex)
{
UserMethods.ParseError(ex, "CropSTL");
}
}
//Gets the croped stl and smooths it. (It doesn't change the result).
private void GeometricOperations()
{
g3.ReadOptions optRead = new g3.ReadOptions();
g3.WriteOptions optWrite = new g3.WriteOptions();
optWrite.bWriteBinary = true;
g3.DMesh3Builder meshBuilder = new g3.DMesh3Builder();
g3.StandardMeshReader.ReadFile(System.IO.Path.GetDirectoryName(stlPath) + "\\croped.stl", optRead, meshBuilder);
var mesh = meshBuilder.Meshes[0];
mesh = SmoothMesh(mesh);
using (g3.StandardMeshWriter mr = new g3.StandardMeshWriter())
{
g3.STLWriter sr = new g3.STLWriter();
List<g3.WriteMesh> wMeshList = new List<g3.WriteMesh>();
g3.WriteMesh wMesh = new g3.WriteMesh(meshBuilder.Meshes[0]);
wMeshList.Add(wMesh);
mr.Write(System.IO.Path.GetDirectoryName(stlPath) + "\\smoothed.stl", wMeshList, optWrite);
}
}
private DMesh3 SmoothMesh(DMesh3 mesh)
{
Remesher r = new Remesher(mesh);
r.SetTargetEdgeLength(0.0240);
for (int k = 0; k < 5; ++k)
r.BasicRemeshPass();
return mesh;
}
public static bool FindTriangle(IxMilia.Stl.StlTriangle triangle)
{
return triangle.Vertex1.Z > -15;
}
}
【问题讨论】: