简体   繁体   English

平滑 STL 文件

[英]Smoothing STL file

So in our 3D Scan application, I should scan a foambox and save the result as an STL file.所以在我们的 3D 扫描应用程序中,我应该扫描一个泡沫箱并将结果保存为 STL 文件。

In order to keep only the foot print part, I remove some vertexes which is above a Z value using CropStl method in the class.为了只保留足迹部分,我使用 class 中的 CropStl 方法删除了一些高于 Z 值的顶点。

At the end of the CropStl method and the brut stl goes from img1 to img2.在 CropStl 方法结束时,粗制滥造的 stl 从 img1 变为 img2。 But as you can see on the images, the border of the result is not smooth.但是正如您在图像上看到的那样,结果的边界并不平滑。

在此处输入图像描述 在此处输入图像描述

Is there a way to smooth the border of the second stl in C# or is there a tool for this?有没有办法平滑 C# 中第二个 stl 的边框,或者有没有工具?

Note: I use IxMilia and geometry3Sharp whici I Installed from NuGet.注意:我使用从 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;
    }
}

As I understood that it was not a easy task, I tried many ways and ended by finding the solution.当我明白这不是一件容易的事时,我尝试了很多方法,最终找到了解决方案。

I want to share my experience.我想分享我的经验。

The best way I found is applying a laplacian smoothing.我发现最好的方法是应用拉普拉斯平滑。 To do this, I installed Meshlab which is a free and incredibly nice tool.为此,我安装了 Meshlab,这是一个免费且非常棒的工具。

Using Meshlab server, it is possible to select the boundaries of a 3D object and apply a laplacian smoothing like a magic touch.使用 Meshlab 服务器,可以对 select 的边界进行 3D object 并像魔术一样应用拉普拉斯平滑。

To do this, you need an.mlx file to tell to the Meshlab server which operation you want to process.为此,您需要一个 .mlx 文件来告诉 Meshlab 服务器您要处理哪个操作。

Here is the content of my.mlx file:这是 my.mlx 文件的内容:

<!DOCTYPE FilterScript>
<FilterScript>
  <filter name="Select Border"/>
  <filter name="Laplacian Smooth">
  <Param description="Smoothing steps" name="stepSmoothNum" value="72" isxmlparam="0" 
   tooltip="The number of times that the whole algorithm (normal smoothing + vertex 
   fitting) is iterated." type="RichInt"/>
  <Param description="1D Boundary Smoothing" name="Boundary" value="true" 
  isxmlparam="0" tooltip="Smooth boundary edges only by themselves (e.g. the polyline 
  forming the boundary of the mesh is independently smoothed). This can reduce the 
  shrinking on the border but can have strange effects on very small boundaries." 
  type="RichBool"/>
  <Param description="Cotangent weighting" name="cotangentWeight" value="true" 
  isxmlparam="0" tooltip="Use cotangent weighting scheme for the averaging of the 
  position. Otherwise the simpler umbrella scheme (1 if the edge is present) is used." 
  type="RichBool"/>
  <Param description="Affect only selection" name="Selected" value="true" 
  isxmlparam="0" tooltip="If checked the filter is performed only on the selected area" 
 type="RichBool"/>
 </filter>
</FilterScript>

This filter script tells which operation to do exactly to Meshlab.此过滤器脚本告诉 Meshlab 究竟要执行哪个操作。 The parameter stepSmoothNum is to precise how many times to apply the smoothing.参数 stepSmoothNum 用于精确应用平滑的次数。

Briefly, this filter script serves to select the boundary of the 3D object and apply a laplacian smoothing 72 times to only the selected faces.简而言之,此过滤器脚本用于 select 3D object 的边界,并仅对选定的面应用拉普拉斯平滑 72 次。 The objectif of smoothing only the boundaries is not loosing the details of the scan of the surface.仅平滑边界的目的是不丢失表面扫描的细节。

And calling this method in C# opens the 3D object in Meshlab, smoothes the boundaries and saves it to the folder precised in the method:并在 C# 中调用此方法在 Meshlab 中打开 3D object,平滑边界并将其保存到方法中精确的文件夹中:

  //input => the path of the 3D object to smooth
  //output => the path where the smoothed object will be saved.
  public static bool BoundrySmoothing(string input, string output)
    {
        bool retVal = true;
        try
        {
            string strCmdText;
            string mlxPath = Tools.MeshLabRoot + "BoundrySmoothing.mlx";
            strCmdText = "/C " + Tools.MeshLabRoot +
                @"meshlabserver " +
                @"-i " + input + " " +
                @"-o " + output + " -m wt -s " +
                mlxPath;

            System.Diagnostics.Process process = new System.Diagnostics.Process();
            System.Diagnostics.ProcessStartInfo startInfo = new System.Diagnostics.ProcessStartInfo();
            startInfo.WindowStyle = System.Diagnostics.ProcessWindowStyle.Hidden;
            startInfo.FileName = "cmd.exe";
            startInfo.Arguments = strCmdText;
            startInfo.WindowStyle = ProcessWindowStyle.Hidden;
            process.StartInfo = startInfo;

            process.Start();

            process.WaitForExit();
        }
        catch (Exception ex)
        {
            UserMethods.ParseError(ex, "BoundrySmoothing");
            retVal = false;
        }

        return retVal;
    }

And the result is incredibly fine!结果非常好!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM