Nomar记录一段历史
命令行重新划分和简化工具

我目前正在尝试重新划分和简化一些蛋白质结构模型(非常大)以减少我需要打印的 STL 的文件大小。

操作前的原始文件约为 4.9GB。

我目前正在我的家用电脑(16GB 内存、AMD FX9590、双 RX480s - 所以没有任何懈怠)尝试这个,但我目前正在观察进度(速度不快),而且 RAM 使用率非常接近现在到 16GB,还有大约 40% 的计算工作要做。

我正在使用 MeshLab 的 Quadratic Edge Collapse Decimation,因为有很多冗余的内部顶点等,所以下降了大约 60%,即使面数很少,打印也已经很困难了。

如果我的 PC 最终无法处理这个问题,有没有人知道我可以在我的一台服务器上使用的任何好的 Unix 命令行工具来处理重新划分和简化,在那里我有更多的内存和 CPU 能力可用。

在这个 SE 上的第一篇文章,如果这属于不同的地方,请道歉。

1个回答

Netfabb 提出了一些我发现的建议。看看Arch Linux 下的 3D 打印,它为Linux提供了许多解决方案,包括:

  • 开放SCAD
  • 自由CAD
  • 搅拌机
  • 网络工厂
  • Slic3r

网络制造商

以 Netfabb 部分为例:

netfabb Private 将为您提供一个完整的工具箱来完成所有这些以及更多:

  • 修复复杂的文件错误
  • 进行后期设计更改
  • 将部分合二为一
  • 将实心部分挖空成壳
  • 平滑网格以改善表面
  • 减小文件大小

安装它:

netfabb 不在官方存储库中,因此您必须使用 yaourt 从 AUR 安装它

$ yaourt netfabb-basic $ netfabb-basic

不过,目前还不清楚是否有cmd行接口。值得一读Netfabb 命令行执行中的问题,特别是有关Automating Netfabb的文档 - 尽管这似乎表明命令行功能仅适用于Ultimate订阅用户,而不适用于Basic 用户

Automating Netfabb

Reducing Size of STL file to upload to shapeways这篇文章(#10)指出:

您还可以轻松地在 Netfabb 中抽取模型 - 右键单击​​ > 细节级别 > 根据所需的细节级别选择 50%... 或更多或更少。

虽然,这在基本订阅中不可用,或者帖子 #12 是这样说


网格混合器

我也遇到过这个非命令行选项。

如何减小 .STL 和 .OBJ 3D 模型的文件大小

例如,您可以试用免费的 3D 建模程序Meshmixer 。从右侧菜单中选择“选择”工具,然后双击您的模型(这将选择您的整个网格)。然后单击“编辑...”选项并选择“减少”。

您现在可以使用多个选项减少多边形数量。最好的工作选择是使用百分比工具。它会立即告诉您文件大小(和多边形数量)减少了多少百分比。

适用于 Windows 和 OSX。

Reducing Size of STL file to upload to shapeways这篇文章(#8)指出:

meshlab 教程正是您想要做的 - 所描述的选项有助于保留模型的整体几何形状,同时减少多边形数量。从 150,000 个多边形的目标开始,直到保留所需的细节,记住我上面提到的可印刷性。

另外,通过 Quora, 如何减小 STL 文件的大小?它会影响 3D 打印的 CAD 坐标吗? ,我还发现了这个 Meshmixer 教程:关于如何修复 .STL 文件的简易指南。在“问题 4:文件大小对于 3D 打印来说太大”部分下,有以下步骤:

您可能会遇到的最后一个问题,尤其是当您的对象变大且其复杂性增加时,生成的.stl文件大小对于您选择的 3D 打印机或 3D 打印服务来说太大了。 i.materialiseShapeways等第三方打印服务有上传限制,因此您可能需要更改文件的大小(imaterialise 限制为 100 MB,Shapeways 限制为 64 MB)。在不牺牲质量的情况下减少网格是很重要的,我应该说一开始最好在从 CAD 软件的初始导出时完成,以最大程度地减少任何失真。我的第一个快速提示是确保在导出设置中保存为“二进制”格式,而不是“ASCII”——对于.stl来说,这是一种更加紧凑的文件格式,而不会降低质量)。然而,如果它不是一个选项,Meshmixer 可以非常有用地快速减小文件大小并可视化这将如何影响您的表面质量。

对于这个例子,我将回到问题 1 中的叶子,它作为.stl文件是 30.757 MB - 对于如此小的设计来说非常大,如果我想发送它肯定超过某人的电子邮件的限制。因此,让我们看看如何将其压缩到 10 MB 以下。

  1. 按键盘上的 Ctrl + A 选择整个模型以全选。
  2. 转到编辑>减少以调出减少网格的选项。本质上, .stl的文件大小与构成所有表面的多边形(三角形)的数量直接相关。我们将使用 Reduce 工具来减少多边形的数量,从而减少文件大小。
  3. 该菜单将为您提供一系列减小文件大小的选项。最简单的是使用默认的百分比选项,允许您确定所需的最终文件大小,而无需确切知道将使用多少个三角形来组成文件。在这种情况下,我计算出为了使我的原始 .stl 文件小于 10 MB,我需要减少 70% 或更多。调整这些值时,您将预览模型的外观,从而在模型变得过于扭曲和“像素化”之前控制使用的减少量。

Reduce dialog

  1. 满意并接受更改后,您可以单击“导出”按钮或转到“文件”>“导出”以保存这个新的简化.stl文件。正如您在下面的比较中所看到的,30.757 MB 文件的质量与最终缩减版本 9.362 MB 的质量几乎没有明显差异。我只是增加了三角形的大小,最大限度地减少了创建相同体积所需的数量。您的普通 3D 打印机,甚至是高度精确的 SLS 打印机永远不会知道这种变化的区别。只有当您真的对文件缩减感到疯狂时,您才可能会在最终印刷品中开始注意到它们(事实上,许多在 Pinshape 上流行的低多边形模型都可以使用这种技术制作——从详细的 . stl 的对象,然后继续减少三角形的数量!)。

Reduction of file size

搅拌机

Reducing Size of STL file to upload to shapeways这篇文章(#8)指出:

另一种选择是将模型导入 Blender,然后使用 Remesh 或 Decimate 修改器。 Blender 一开始可能很难入门,但 YouTube 上有很多介绍教程可以提供帮助。

Blender确实提供了命令行界面 (CLI),请参阅命令行参数

 Usage: blender [args …] [file] [args …]

但是, RemeshDecimate似乎没有选项。虽然看看是否有可能通过 CLI 抽取或重新划分?

您可以指定要运行的 Python 脚本,请参阅您链接的文档Python 选项部分。在此脚本中,您可以导入模型、添加修改器、应用它们并导出结果。

相关 - 是否可以在不丢失对象形状的情况下自动简化搅拌机中的几何图形? ,其中有这样的评论

有没有办法从命令行执行这个修饰符并导出结果?

然后导致可以从命令行计算和应用修饰符吗?

你必须使用bpy.ops.object.modifier_apply ,例如

import bpy for obj in bpy.context.scene.objects: bpy.context.scene.objects.active = obj count = 1 length = len(obj.modifiers) while obj.modifiers: name = obj.modifiers[0].name print("%s: Applying %s (%d/%d)" % (obj, name, count, length)) bpy.ops.object.modifier_apply(modifier=name) count += 1 print("All done.")

有关如何运行上述内容的信息,请参见此处

网状实验室

看到您已经在使用 Meshlab,可能值得阅读从命令行执行 meshlab 以迭代方式减少网格的面(awesomebytes/ reduce_faces.py

 #!/usr/bin/env python import sys import os import subprocess # Script taken from doing the needed operation # (Filters > Remeshing, Simplification and Reconstruction > # Quadric Edge Collapse Decimation, with parameters: # 0.9 percentage reduction (10%), 0.3 Quality threshold (70%) # Target number of faces is ignored with those parameters # conserving face normals, planar simplification and # post-simplimfication cleaning) # And going to Filter > Show current filter script filter_script_mlx = """<!DOCTYPE FilterScript> <FilterScript> <filter name="Quadric Edge Collapse Decimation"> <Param type="RichInt" value="1448" name="TargetFaceNum"/> <Param type="RichFloat" value="0.9" name="TargetPerc"/> <Param type="RichFloat" value="0.3" name="QualityThr"/> <Param type="RichBool" value="false" name="PreserveBoundary"/> <Param type="RichFloat" value="1" name="BoundaryWeight"/> <Param type="RichBool" value="true" name="PreserveNormal"/> <Param type="RichBool" value="false" name="PreserveTopology"/> <Param type="RichBool" value="false" name="OptimalPlacement"/> <Param type="RichBool" value="true" name="PlanarQuadric"/> <Param type="RichBool" value="false" name="QualityWeight"/> <Param type="RichBool" value="true" name="AutoClean"/> <Param type="RichBool" value="false" name="Selected"/> </filter> </FilterScript> """ def create_tmp_filter_file(filename='filter_file_tmp.mlx'): with open('/tmp/' + filename, 'w') as f: f.write(filter_script_mlx) return '/tmp/' + filename def reduce_faces(in_file, out_file, filter_script_path=create_tmp_filter_file()): # Add input mesh command = "meshlabserver -i " + in_file # Add the filter script command += " -s " + filter_script_path # Add the output filename and output flags command += " -o " + out_file + " -om vn fn" # Execute command print "Going to execute: " + command output = subprocess.check_output(command, shell=True) last_line = output.splitlines()[-1] print print "Done:" print in_file + " > " + out_file + ": " + last_line if __name__ == '__main__': if len(sys.argv) < 3: print "Usage:" print sys.argv[0] + " /path/to/input_mesh num_iterations" print "For example, reduce 10 times:" print sys.argv[0] + " /home/myuser/mymesh.dae 10" exit(0) in_mesh = sys.argv[1] filename = in_mesh.split('/')[-1] num_iterations = int(sys.argv[2]) folder_name = filename.replace('.', '_') tmp_folder_name = '/tmp/' + folder_name + '_meshes/ print "Input mesh: " + in_mesh + " (filename: " + filename + ")" print "Num iterations: " + str(num_iterations) print "Output folder: " + tmp_folder_name try: os.mkdir(tmp_folder_name) except OSError as e: print >> sys.stderr, "Exception creating folder for meshes: " + str(e) exit(0) for it in range(1, num_iterations): if it == 1: out_mesh = tmp_folder_name + folder_name + "_it" + str(it) + ".dae" reduce_faces(in_mesh, out_mesh) else: out_mesh = tmp_folder_name + folder_name + "_it" + str(it) + ".dae" reduce_faces(last_out_mesh, out_mesh) last_out_mesh = out_mesh print print "Done reducing, find the files at: " + tmp_folder_name

还有

以下是 python 3.6.2 的一些更新: https : //gist.github.com/tylerlindell/7435ca2261e7c404ccc1241f18e483aa

这很有用谢谢!我将补充一点,我随后发现 Meshlab 有一个带有 GUI 工具的 `meshlab-server` CLI 工具。我还没有测试过它,但理论上它应该像弄清楚命令行语法/命令来调用二次抽取等东西一样简单。
啊,干得好@JoeHealey,太棒了。也许你可以发布一个答案,一旦你想通了?它可能会帮助其他人解决同样的问题。我自己会对这样的解决方案感兴趣。
我一定会的。在我写完论文的时候,我不得不暂时搁置印刷工作,但我打算在有更多空闲时间时再回来:)

随机文章