我有 .stl 用于 3d 打印。我想在打印前分析这个模型的壁厚。我不知道任何工具。我可以创建任何控制台或 wpf 应用程序来计算壁厚和打印成本吗?请帮我。
如何为我的 .net 项目实施壁厚分析
如果您谈论的是空心物体,例如具有空心中心的立方体。壁厚由模型决定。
如果您谈论的是固体物体,壁厚由您的喷嘴直径乘以您的壁数决定。这都是由你的拼接软件调整的。如果您有一个 0.5 毫米的喷嘴并在 3 个周长处打印,那么您的墙壁应该是 1.5 毫米。如果您希望墙为 2 毫米,那么您将周长调整为 4。这些墙内的所有内容都将是您选择的填充物。
我自己使用 ASP.NET、Windows 窗体和控制台应用程序。我相信您可以找到能够采用 3D 模型的库,但我认为这无关紧要,因为打印厚度由您的拼接设置决定。
同样对于打印成本,我建议只使用 Cura,您只需插入一些有关灯丝的成本信息,它就会告诉您估计的成本、灯丝使用的毫米数和时间。
如果您担心 stl 文件的壁太薄而无法在打印机上打印,MeshMixer是Autodesk提供的一款出色工具,可帮助检查和修复网格问题(包括壁厚)。它对制造商和教育者免费。
有很多有用的教程这里是一个https://all3dp.com/meshmixer-tutorial/
我不完全确定你想做什么,但我会添加一些我认为会有所帮助的信息,然后希望你能弄清楚你需要知道什么或提出另一个问题。
当您询问壁厚时,您可能会提到两种不同的情况。模型中有一面墙,因此您可能正在谈论尝试打印从模型中出来的薄墙。对于分析薄壁设置,一些切片器会更改挤出量以打印更粗或更细的线条,要找到这些设置,您需要查看 g 代码。或者您可以谈论模型的外壳、外表面,为此您还可以通过查看切片器将尝试打印的周长数在切片器设置中进行分析。
为了计算打印成本,您需要使用的材料量,这也将在 g 代码文件中。您可以通过执行每个 G1 命令并找出打印机每次移动挤出了多少细丝来计算此值。(并非某些切片机在每层后将其重置为零,当打印机在行进时开始收回灯丝时,这会变得棘手)。或者大多数切片器在文件的开头或结尾都有注释掉的 g 代码行,列出将使用多少灯丝。
如果您分析 .stl 文件,您可能还会发现您还需要修复模型文件,因为很多 .stl 文件是为 3D 图形制作的,而不是用于打印的,因此它们可以有相交的三角形而不是水密的.
并非所有 .stl 文件都相同,它们可以是文本文件或二进制文件,这是一些 C# 代码,可以将两种格式读取到文件中的三角形列表中。
using System.Numerics.Vectors;
void Main(){
var facets = readStl(@"C:\stls\teapot.stl");}
public class facet
{
public Vector3 norm = new Vector3();
public Vector3 vecA = new Vector3();
public Vector3 vecB = new Vector3();
public Vector3 vecC = new Vector3();
public facet(Vector3 A, Vector3 B, Vector3 C, Vector3 N)
{
norm = N;
vecA = A;
vecB = B;
vecC = C;
}
}/* facet */
public static System.Collections.Generic.List<facet> readStl(string file)
{
// check if binary or text fomat
//Console.WriteLine("the middle");
bool isText;
System.Collections.Generic.List<facet> facets = new System.Collections.Generic.List<facet>();
using (System.IO.BinaryReader reader = new System.IO.BinaryReader(System.IO.File.Open(file, System.IO.FileMode.Open)))
{
//Console.WriteLine("Checking if binary");
string fileHeading;
fileHeading = new string(reader.ReadChars(80));
if (fileHeading.Contains(@"solid"))
{
isText = true;
//Console.WriteLine("isText true");
}
else
{
isText = false;
//Console.WriteLine("isText false");
}
if(!isText)
{
// process binary file
Console.WriteLine("Is binary");
uint numberOfTriangles = reader.ReadUInt32();
//Debug.Log("Number of Triangles: " + numberOfTriangles.ToString());
System.Console.WriteLine("Number of Triangles: " + numberOfTriangles.ToString());
for(int i = 0; i < numberOfTriangles - 1; i++)
{
Vector3 normals = new Vector3();
Vector3 vecA = new Vector3();
Vector3 vecB = new Vector3();
Vector3 vecC = new Vector3();
System.UInt16 byteCount = new System.UInt16();
normals.X = reader.ReadSingle();
normals.Y = reader.ReadSingle();
normals.Z = reader.ReadSingle();
vecA.X = reader.ReadSingle();
vecA.Y = reader.ReadSingle();
vecA.Z = reader.ReadSingle();
vecB.X = reader.ReadSingle();
vecB.Y = reader.ReadSingle();
vecB.Z = reader.ReadSingle();
vecC.X = reader.ReadSingle();
vecC.Y = reader.ReadSingle();
vecC.Z = reader.ReadSingle();
byteCount = reader.ReadUInt16();
facets.Add(new facet(vecA, vecB, vecC, normals));
}
}
}
if (isText)
{
// read text format file
Console.WriteLine("Is text file");
//Console.WriteLine("reading text file");
using (System.IO.StreamReader reader = System.IO.File.OpenText(file))
{
string line = @"";
string fileHeader = @"";
line = reader.ReadLine();
fileHeader = line.Substring(line.IndexOf("solid") + 5).Trim();
line = "";
System.Console.WriteLine(@"file header: " + fileHeader);
bool endOfFile = true;
while (endOfFile)
{
line = reader.ReadLine();
if (!reader.EndOfStream)
{
Vector3 normals = new Vector3();
Vector3 vecA = new Vector3();
Vector3 vecB = new Vector3();
Vector3 vecC = new Vector3();
string[] nums = line.Replace("facet", "").Replace("normal", "").Trim().Split(' ');
normals.X = (float)System.Double.Parse(nums[0], System.Globalization.NumberStyles.Float);
normals.Y = (float)System.Double.Parse(nums[1], System.Globalization.NumberStyles.Float);
normals.Z = (float)System.Double.Parse(nums[2], System.Globalization.NumberStyles.Float);
line = "";
line = reader.ReadLine(); // outer loop
line = reader.ReadLine(); // vertex
string[] vecsA = line.Replace("vertex", "").Trim().Split(' ');
vecA.X = (float)System.Double.Parse(vecsA[0], System.Globalization.NumberStyles.Float);
vecA.Y = (float)System.Double.Parse(vecsA[1], System.Globalization.NumberStyles.Float);
vecA.Z = (float)System.Double.Parse(vecsA[2], System.Globalization.NumberStyles.Float);
line = "";
line = reader.ReadLine(); // vertex
string[] vecsB = line.Replace("vertex", "").Trim().Split(' ');
vecB.X = (float)System.Double.Parse(vecsB[0], System.Globalization.NumberStyles.Float);
vecB.Y = (float)System.Double.Parse(vecsB[1], System.Globalization.NumberStyles.Float);
vecB.Z = (float)System.Double.Parse(vecsB[2], System.Globalization.NumberStyles.Float);
line = "";
line = reader.ReadLine(); // vertex
string[] vecsC = line.Replace("vertex", "").Trim().Split(' ');
vecC.X = (float)System.Double.Parse(vecsC[0], System.Globalization.NumberStyles.Float);
vecC.Y = (float)System.Double.Parse(vecsC[1], System.Globalization.NumberStyles.Float);
vecC.Z = (float)System.Double.Parse(vecsC[2], System.Globalization.NumberStyles.Float);
line = "";
line = reader.ReadLine(); // endloop
line = reader.ReadLine(); // endfacet
facets.Add(new facet(vecA, vecB, vecC, normals));
}
else
{
endOfFile = false;
}
}// while loop
System.Console.WriteLine("finished reading file");
}
}
return facets;
}/* readStl */