图片缩略图

surf2solid -从一个表面制造一个固体体积用于3D打印

version 1.5.0.0 (6.08 KB) by 斯文
通过添加平底或偏移给定厚度,将薄曲面转换为闭合实体。
4.8
41评级

58下载

更新2014年2月10

视图版本历史

查看许可协议

编者按:这个文件被选为MATLAB中心本周精选

SOLID_FV = SURF2SOLID(FV,…)采用由
FV(具有字段“顶点”和“面”的结构),并返回
solid补丁SOLID_FV由选项关闭(如下所述)。

SOLID_FV=SURF2SOLID(F,V,…)分别获取面和顶点。

[F,V] = SURF2SOLID(…)分别返回实体面和顶点。

没有输出参数的SURF2SOLID(…)绘制3个组件
(原表面,侧壁,下表面)到一个新的图形。

SURF2SOLID(X, Y, Z,…)读取X, Y, Z矩阵的表面数据,
然后用三角测量将网格数据三角化到一个表面上
下面指定的选项。Z必须是二维矩阵。X和Y可以是二维矩阵
与Z大小相同的矩阵,或长度等于size (Z,2)的向量
分别和大小(Z, 1)。如果X或Y是标量值,则使用它们
指定栅格点之间的X和Y间距的步骤。

SURF2SOLID(…,'PropertyName',VALUE,…)从thin创建一个固体卷
Surface使用下列任何属性/值选项:

仰角-在给定位置将平面向下延伸到一个平坦的基底
(Z)高程值。对变薄很有用
高程图进入一个坚实的块与一个平坦的基础。的
标高值应低于最低(或高于最低)
最高)数据点。如果没有其他选择,
高程默认为最小(Z)-0.1*(最大(Z)-最小(Z))。
可变仰角也可以通过a给出每个点
2D矩阵(X,Y,Z风格输入的尺寸与Z相同)或
一个一维数组(长度等于顶点的数量
给定的面/顶点输入)。

厚度-补偿给定薄表面的值
加厚实心板。表面上的每个节点将
按厚度沿其法线方向投影。当
给负厚度时,偏移不离不离
面对正常的方向。也可以变厚度
通过2D矩阵指定(X,Y,Z的大小与Z相同)
输入)或N × 1的厚度数组(其中N为
薄表面的顶点数)

TRIANGULATION -当使用网格数据,TRIANGULATION是:
'delaunay' -(默认)X, Y的delaunay三角剖分
'f' -网格四边形的前斜线分割
'b' -四边形的反斜杠分割
'x' -四边形的交叉分割
注意,'f', 'b'或'x'三角使用an
内置版本的FEX入口28327,“mesh2tri”。“x”
样式三角剖分不能与变量一起使用
标高或厚度参数。

法线-当厚度选项被使用,方向
加厚的表面(默认)是由
每个顶点的表面(单位向量)法线方向。
要覆盖这些默认方向,您可以指定
法线作为一个法线方向的n × 3数组(其中
N是薄表面的顶点数)。这
当底层数据更精确时有用吗
法线方向比面方向(对于一个
例如,请参见等法线函数)。

注1:目前surf2solid将返回一个带face的封闭曲面
法线指向“出来”。有了用户的反馈,我很乐意改变这一点
行为为“在”或“从输入方向不变”。
注2:如果指定了单个标高值(即平基),则
结果补丁将有最小的三角形在平坦的基础上减少
修补程序/文件大小。

示例(显示厚度和立面形式):
n = 30;
(X, Y) = meshgrid (linspace (0, 1, 2 * n + 1));
L=(40/51/0.9)*膜(1,n);
图,子批次(2,2,[13]),标题“薄表面”
冲浪(X, Y, L ' EdgeColor ', '没有');colormap粉色;轴形象;camlight
副地块(2,2,2),标题为“地块立面”
surf2solid (X, Y, L,海拔,-0.05分钟(L (:)));轴形象;camlight;camlight
次要情节(2,2,4),标题“厚度”
surf2solid (X, Y, L,“厚度”,-0.1);轴形象;camlight;

这个创意来自于Paul Kassebaum的博客
http://blogs.mathworks.com/community/2013/06/20/paul-prints-the-l-shaped-membrane/
非常感谢Paul进一步的投入和改进。

引用作为

斯文(2021)。surf2solid -从一个表面制造一个固体体积用于3D打印(//www.tatmou.com/matlabcentral/fileexchange/42876-surf2solid-make-a-solid-volume-from-a-surface-for-3d-printing), MATLAB中央文件交换。检索

意见及评分(67

以利亚Uche

你好
请我想把我的粗糙表面转换成实体,然后再作为STL文件导入CST。这将使我能够在CST上对其进行分析,因为当前在CST上对我的粗糙表面进行的分析没有产生正确的结果。所以我认为,首先转换成固体将有助于我的RCS分析。我已经尝试了在这个平台上给出的一些建议,但是我还没有得到正确的结果。
非常感谢
以利亚

Teerapong Poltue

我的固体出现了一些意想不到的尖峰我该怎么解决这个问题呢?
https://drive.google.com/file/d/1CVpbtaEVstiCfQj2TetlOHOXcnCRBK-Y/view?usp=sharing

如何从两面增加均匀的厚度?

柏松 杨

侯赛因Babaei

大家好,我有一个点云,基本上是一个x y z的大矩阵,我想要得到它的stl曲面。我尝试使用这段代码,但我不知道如何将它形成的“固体”转换为stl。请帮助。

克雷格Puetz

我正在尝试做一个地形数据的3D模型。我有一个经度,纬度和海拔的文件,它是由一辆车在田野上行驶时记录的数据生成的。我已经转换成有规律间隔的x, y, z数据使用mechgrid和griddata。如果我用surf绘制我的结果,我会看到我预期的轮廓。如果我尝试使用surf2solid(或者上面提到的stlwrite)将它转换为实心(solid),我会得到一些非常高的线条,而不是一个表面。我可以分享x y z的数据如果有人有兴趣帮忙的话。

提前谢谢。

茱莉亚

你好
很好的代码!谢谢。我们可以做一个修改,包括指向“in”的面部法线吗?我想这会有帮助!我正在尝试通过将两个半球加在一起来制作一个球体的stl,我认为将一个半球设置为in,一个半球设置为out会有用吗?

玫瑰安顿下来

你如何保存这些文件?

布鲁诺陈德良

代码很好,但不能正确处理带有多个连接边界(洞)的网格

n = 4;
x=linspace(-1,1,n+1);
y = linspace (1, 1, n + 1);
(X, Y) = ndgrid (X, Y);
Z = 0(大小(X));
X = [X(:), y (:), z (:)];
F1 = 0 (n ^ 2, 3);
F2 = 0 (n ^ 2, 3);
i0 = 1: n
我= i0 + [0, 1];
j₀= 1:n
j = j₀+ [0,1];
(I, J) = ndgrid (I, J);
k = sub2ind([大小(x, 2),大小(y, 2)), I, J);
P = (i0-1)*n + j0;
F1(p,:) = k([1 2 4]);
F2(p,:) = k([1 4 3]);
结束
结束
F = (F1、F2);
Xc = X (F);
Xc =重塑(Xc [] 3, 3);
Xc =意味着(Xc, 2);
Xc_x = Xc (:,: 1);
Xc_y = Xc (:,:, 2);
b = abs(Xc_x)>0.5 | abs(Xc_y)>0.5;
F = F (b:);

V = surf2solid(F, X, '厚度',0.5);

无花果=图();
集(无花果、“颜色”、“k”);%黑色背景
ax = subplot(1,2,1,'Parent',图);
持有(ax,‘上’);
轴(ax,“平等”);
视图(ax, 3)
斧子。剪裁=“关闭”;
斧子。可见=“关闭”;
面片(ax,'面',F,'顶点',X,'面颜色',0.9+[0 0],'EdgeColor','b');

ax = subplot(1,2,2,'Parent',图);
持有(ax,‘上’);
轴(ax,“平等”);
视图(ax, 3)
斧子。剪裁=“关闭”;
斧子。可见=“关闭”;
面片(ax,'面',V面',顶点',V顶点,'面颜色',0.9+[0 0 0],'EdgeColor','b');

Xuzhe张

出色而鼓舞人心的工作!非常感谢斯文、保罗和查尔斯!

德里克。冯

功能很好,谢谢!

回到尼古拉斯·阿尔瓦雷斯的问题。如果我的模型不是规则形状,我如何使一些表面的厚度为0 ?

谢谢!

Kabilan K

你好
@charles tenney你能在这里分享你提到的修改的完整代码吗,因为按照你的评论,如果修改了代码,我得到了很多错误。surf2solid函数给了我一边的边界和另一边的边界连接得很差在从表面生成实体的时候。

Kabilan K

大家好,
我发现这篇文章对我很有用。
目前,我正试图增加厚度的陀螺表面,但我得到了一个不正确的体积。
有没有办法添加厚度作为一个函数或数组的值?这样我就可以创建可变增厚的陀螺。

亚西斯·阿马拉辛赫

大家好,
有人能告诉我如何把固体转换成。stl文件吗?

提前谢谢,
Yasith

查尔斯Tenney

这个脚本非常棒。然而,我必须编辑它,使其工作为我的项目。

看起来“墙”面的计算方法对单一周长很有效。然而,如果有两个不相连的周长,比如空心管的两个圆端,计算结果可能会很糟糕。

为了解决这个问题,我重写了surf2solid中的第164-172行,在构建墙面时使用连接列表,以防止连接属于不同周长的顶点:
%指定顶点引用数与[V;
% V_extrude]矩阵。
%边界边数(nbe)。
nbe = size(boundEdges, 1);
%每个曲面上的顶点数(nsv)。
nsv =长度(V);
%为wallFaces分配内存。
F_wall = 0 (2 * nbe, 3);
定义脸。
对于k = 1:nbe
a = boundEdges(k, 1);
b = boundEdges(k, 2);
F_wall(k,:) = [a+nsv,b,a];
F_wall (k + nbe:) = [+ nsv, b + nsv b);
结束

我所做的改变也需要改变输出的顶点/面(第208-212行):
%编译3套面在一起
allVertices = [V;V_extrude];
allFaces = [F;%使用原面
F_wall;添加墙面
F_extrude +大小(V, 1)];%添加相反的面(翻转)

以及第222行(如果需要绘图):
F_wall补丁(“脸”,“顶点”,[V;V_extrude],‘FaceColor’,‘g’);

我不知道这个代码是否正确地面向墙壁。它在我的项目中正确地定位了它们,但我不能证明它通常会正确地做到这一点。我也不知道它是否搅乱了“海拔”选项;我在我的项目中没有使用这个功能。

菲利普·梅西尔

@Philippe Mercier,我的错,似乎是其他地方出了问题,现在工作得很好。非常感谢!

斯文

@Pilippe Mercier, @Rose Haft
很抱歉,我无法再现你们所经历的麻烦。我目前可以运行surf2solid的例子使用matlab 2018a和2018b没有错误。请包括您收到的错误信息,以便我们可以了解问题可能是什么。

斯文

@mvulp看起来你正在尝试使用这个函数作为一个脚本。我最好的建议是从这里开始:
//www.tatmou.com/help/matlab/programming-and-data-types.html
你应该永远不需要直接运行surf2solid函数(或其他函数)中的任何代码。相反,只需调用surf2solid函数并提供您的输入。

玫瑰安顿下来

这似乎不再工作,甚至从例子。我之前确实有这个。

mvulp

你好,
当我发现这个代码时,我以为我可以解决我所有的问题,但我不能运行它。
我是新的matlab和从未使用任何函数下载从“文件交换”。
我有三个向量X Y和Z,分别是X轴,Y轴和表面粗糙度值。
首先,我把这3个向量输入到surf2solid函数中,得到如下错误

未定义函数或变量'varargin'。

surf2solid错误(第98行)
[F,V,options]=parseInputs(varargin{:});

当我把变量{:}和向量X Y Z交换时,我得到了另一个错误。

输入参数不足。

surf2solid错误(第98行)
[F, V, options] = parseInputs(A1,A2,A3);

你可以指导我通过它,我真的不知道如何使它工作,但我非常需要它。
谢谢。

瑞恩•斯科特

史蒂文

太酷了!谢谢你的才华!

Hans Scharler

利兰·穆勒

乔纳森Haydak

我用这玩意有段时间了。作者应该得到一块饼干。如果我遇见你,我会给你一块饼干。

安德鲁·布利斯

伟大的功能。谢谢!

@尼古拉斯我发现,仅仅是消除南起作用很好。例如,对于矩阵X、Y、Z,其中Z具有NaN:
印第安纳州= isnan (Z);
X(印第安纳州)= [];
Y(印第安纳州)= [];
Z(印第安纳州)= [];

汤姆

@Nicholas,你可以试试John D'Errico写的inpaint_nans或3d_inpaint_nans。它们提供了一种替代nan的更好值的方法。这些函数可以在Matlab文件交换中找到(就像这个)。我没有使用过这些特殊的函数,但在许多年前实现了类似的功能。

你好斯文,
不错的工作!我确实有一个问题。我的形状是不规则的,因此在矩阵中有许多点是空的(即零)。我通常将这些设置为NaN,这样surf就会忽略它们。但是,您的代码不允许使用NaN点。如果我让这些点为“0”,那么surf2solid就会使用它们来创建实体对象。你觉得我该怎么解决这个问题?提前谢谢你,尼古拉斯

阿基列什·古普塔

拉胡尔·杜塔

你好斯文,
我已经使用surf2solid创建了NURBs曲面的实体块。问题是,在曲面的槽部分,面形成,曲面看起来更像是由四面的墙包围,而不仅仅是有一个带底座的块。

约翰·洛根

Amirali Nojoomi

丹尼

你好Sven(+所有MATLAB大师),

我有一个关于在MATLAB中设置/固定3D打印尺寸的问题,希望您能给我一些建议。我已经读了你的代码(它是太好了!!),我的问题是,如果我想要厚度正好为1mm,对象的宽度打印为5cm长,我在哪里/如何指定尺寸。我要先画初始曲面吗?

非常感谢您的时间和智慧分享。

问候,

uncletat

uncletat

你好斯文,

我在使用surf2solid的厚度特性时遇到了问题。

我理解厚度特征将只创建一个偏移平面从表面法线和挤压空间之间(单面挤压)。

然而,在我的应用程序中,单面挤压会扰乱几何的比例。我需要双面挤压(或中平面挤压)。换句话说,有没有一种方法来创建两个偏移平面,这样我就可以从法线上向正和负方向挤压,这样几何图形的原始表面就会在平面的正中。

非常感谢!

亚历克斯

斯文

@Thalles,
我只是从代码生成的合成数据中选择要删除的特定顶点(我生成了MATLAB徽标,要删除的顶点位于徽标的一个象限)。
您可以自行选择要从数据中删除的顶点。

斯文

@Mico,
我不使用MuPAD,但是你是否可以在间隔时间内对函数进行采样,从而将隐式曲面进行去除并使其显式化(例如,在曲面上创建一组面/顶点)?

这似乎是困难的一步(抱歉,就像我说的,没有使用MuPAD的经验)。之后,你可以把你的表面发送到surf2solid,使它变厚。

Mico Stanojevic

第二个问题:)
如果我让隐式函数im:= plot::Implicit3d(cos(x) + cos(y) + cos(z) .....,是否有可能生成实体的厚度,然后为FE模型生成三维体积网格(例如导出Nastran文件)。尊重,Mico

Mico Stanojevic

亲爱的斯文,亲爱的所有人:
如果我有像im:=plot::Implicit3d(cos(x)+cos(y)+cos(z)这样的隐式函数,
x=0..2*PI,
y = 0 . . 2 *π,
z = 0 . . 2 *π):
如何给这个表面所需的厚度(获得“固体”3D打印)和出口到stl(在MuPAD)。BR, Mico

Thalles雷特

@Sven:

谢谢大家。

在这方面,我只有一个问题:

badVertIds=find(XX.顶点(:,1)<0.5&XX.顶点(:,2)>0.5);

为什么要在第一列和第二列搜索?

它们代表什么?很抱歉问了这么愚蠢的问题。

斯文

@Josafat:
在David Legland的geom3d包中有一个名为meshVolume的函数。

斯文

@Thales,也许你可以删除它们:

n = 10;
(X, Y) = meshgrid (linspace (0, 1, 2 * n + 1));
L=(40/51/0.9)*膜(1,n);
XX=表面2固体(X,Y,L,'elevation',0);
找到你想要删除的顶点
badVertIds=find(XX.顶点(:,1)<0.5&XX.顶点(:,2)>0.5);
找到使用这些顶点的面
badFaceIds =任何(ismember (XX.faces badVertIds), 2);
%删除它们
二十、 面(BadFaceID,:)=[];
人物,补丁(XX,‘FaceColor’,‘g’)

Thalles雷特

你好斯文,

我可以在没有标高的情况下使用这个代码吗?

我想用

fv=surf2solid(x,y,z,'elevation',0)

但是我得到了一个坏文件stl。

当我使用其他高度时,stl工作得很好。

我已经尝试在我不想要的节点中使用厚度0,但它生成了相同的坏文件,当我打印时,打印机仍然创建一个基础。

sumana

Josafat一

嗨,7个,

有办法得到生成的固体的面积和体积吗?

提前谢谢。

莱拉Ghanbari

你好斯文,

伟大的工作。我想生成一个光滑的表面;
FV_closed = surf2solid(x,y,z,'triangulation', 'delaunay', '厚度',-2);

我使用三角测量,delaunay,因为只有特定范围的x和y是可取的。但表面并不光滑。有什么办法补救吗?

提前谢谢。

梅根·Kazanski

有没有办法将多个曲面(作为两组X、Y、Z矩阵)组合成一个实体?

提前谢谢!

斯文

@莎拉:您提供的属性(“标高”)没有值。您需要指定所需的实际标高。请尝试以下代码,该代码将标高指定为“3”,以便将面向下拉伸到Z坐标3:

V = [0 0 10;1 2 11;2 4 12;4 2 11;5 0 10;2.5 0 9];
F = [1 2 6;6 4 5;2 4 6;2 3 4];
surf2solid (F, V,“海拔”,3)

这能解决你的问题吗?

莎拉韦森伯

你好斯文,

我想用你的代码,给它面和顶点。
我尝试使用:surf2solid (F,V, 'elevation');

但是Matlab抛出了一个错误。你能想象这有什么不对吗?

非常感谢。

埃文

嗨,这是一个问题,当你试图找出一个内部有洞的实体时。例如,“网格网格”创建了一个5*5的矩阵,但我只需要使用中心环形区域来创建实心环形圆柱体。我试图将这些像素的厚度(不需要的)设置为0,但它仍然执行一个平面图,覆盖整个5*5区域(我希望中心孔中没有实体)。我怎么能设定呢?非常感谢。

内森·汤姆林

工作真的很棒,导入到openscad完美!

内森·汤姆林

斯文

Hi Mona, surf2solid(一个面/顶点结构)的输出可以直接给stlwrite:

阵线= surf2solid(…)
stlwrite(“yourfile。stl的阵线”

莫娜Mahboob Kanafi

你好斯文,

你能给我一个关于如何将生成的实体地形转换成STL格式的线索吗?例如,使用旧的“stlwrite-Write binary或ascii STL file”代码。

提前感谢你的工作!:)

斯文

嗨腻过:

1)使用三角面/顶点输入(SURF2SOLID(F, V,…))而不是网格输入(SURF2SOLID(X, Y, Z,…)),你可以制作任意形状的曲面而不是网格。我将简单地在你不想要固体的节点上设置0厚度,而不是NaN厚度。

2) 这是可能的,您只需要计算希望每个节点偏移的距离并使用该“厚度”。基本上,将厚度作为原始曲面和所需曲面之间的差值。

下面是一个使用了大部分选项的小例子:

v=[2 4 0;2 6 0;8 4 1;8 0 0;0 4 0]
F = [1 2 3;1 3 4;5 2 1)
图,surf2solid(f,v,'thickness',[0 0 3 2 0])

腻过

你好斯文,

很好的工作。两个问题。

1)我可以将矩形网格改为不规则(弯曲)网格吗?我有NaN到我不想创建一个实体的区域,但它说它是不支持的。金宝app

2)是否可能用户提供了不同的底面(假设上下面的x、y坐标相同)。

亚当·哈特

太棒了!

亚当

太棒了!谢谢!

丹尼尔

谢谢Sven的更新!在从我的曲面中删除退化的面之后,我觉得这样做非常有效。我甚至通过stlwrite输入了结果,并成功地打印了一个。

丹尼尔

斯文

你好Daniel,我已经有时间做了这个修复——这只是在第100行中添加了一个if-isempty子句来检测没有任何边界的表面。它现在已经提交了,这是一个环面的工作例子,它有你描述的错误,但现在工作正常:

%做一个圆环
a=5;
c = 10;
[u, v] = meshgrid (0:10:360);
x = (c + a * cosd (v))。* cosd (u);
y = (c + a * cosd (v))。*信德(u);
z=a*sind(v);
%得到四边形面
图,t = surf(x,y,z);p = surf2patch (t);关上(gcf)
%三角化面(删除重合顶点)
三=猫(1,p.faces (:, (1 2 3)), p.faces (: [1 3 4]));
[unqV, ~, unqI] = unique(p.vertices,'rows');
unqV pTri =结构(“顶点”,“脸”,unqI(三));
固化薄表面
pSol=surf2solid(pTri,'Thickness',1)
%显示结果
人物,补丁(pSol‘FaceColor’,‘g’,‘FaceAlpha’,0.2)

斯文

嗨,丹尼尔,
这听起来像是surf2solid应该处理的类型,但我从未将其用作测试用例。我认为,当“边缘”面是空的时候,应该是可控的。我会尽量放点东西进去的,但得等上一个星期左右……我现在正在旅行。

丹尼尔

谢谢你的m-file!总的来说,我对我所看到的感到满意。

我想用这个文件来加厚由隐式方程生成的表面。这样一个例子就是环面。我有一个粗糙的面集来描述表面,并想通过增稠器打印,但我得到了一个错误在和超过第99行(获得boundvert),因为没有边界顶点(表面是封闭的!)你有变通办法吗?我现在还不清楚如何纠正这一点。
再次感谢!

兰德

很棒的工作!
下面是一个链接,指向一篇优秀的博客文章(由Sven撰写),其中附有如何使用surf2solid函数的示例:
http://imageprocessingblog.com/surf2solid-a-tool-for-3d-printing/

Phalgun Lolur

我想说的是,我使用hold on命令向我的轴添加新对象。但我如何从它创建一个stl文件?我的目标是打印一个多层的3D文件。但我不太确定该怎么做。

斯文

嗨,法尔根,
我不太明白你所说的“多层数据”是什么意思。据我所知,“hold on”命令只是让你向当前的情节轴添加新对象……没有多层,也没有打印。什么是你的3d打印机接受的“多层3d图像文件”类型,你通常如何创建这些文件之一?

Phalgun Lolur

亲爱的斯文,

文件运行得非常好。但是如果我需要用它来打印多层数据,我该怎么做呢?我通常使用“hold on”命令在matlab中生成这些多层3d图像文件。但是我想知道如何从它创建一个stl文件。

保罗Kassebaum

爱死它了!

mathgirl

功能是惊人的。它的工作速度快,效率高,非常容易使用。得到的stl具有较高的分辨率和合理的尺寸。

谢谢你斯文!
非常感谢你的工作。

MATLAB版本兼容性
创建R2013a
与任何版本兼容
平台的兼容性
窗户 macOS Linux
确认

启发:mesh2tri

启发:punctureSurface

社区寻宝

在MATLAB中心找到宝藏,并发现社区如何可以帮助你!

开始狩猎!