Загрузите STL-файл в Matlab и конвертировать в 3D-массив - PullRequest
0 голосов
/ 03 июля 2018

У меня есть файл stl, и я загрузил его в Matlab, используя функцию stlread. На данный момент у меня есть набор граней и вершин. Как я могу преобразовать эти грани и вершины в трехмерный двоичный массив, такой как массив 512x512x100, чтобы получить двоичный трехмерный объем?

1 Ответ

0 голосов
/ 03 июля 2018

Ах, счастливчик. Я недавно работаю с файлами STL, и я написал некоторые функции, чтобы сделать именно это.

Во-первых, обратите внимание, что вы теряете точность. Файлы STL представляют произвольные формы с произвольной точностью, и преобразование их в объем приводит к дискретизации и потерям.

Тем не менее, существует очень простой способ узнать, находится ли что-то внутри или снаружи замкнутой, связанной триангулированной поверхности, независимо от того, является ли она выпуклой или нет: бросить луч в бесконечное и пересчитать пересечение с поверхность. Если нечетно, его внутри, если даже, снаружи.

Единственный специальный код, который вам нужен, - это пересечение линии и треугольника, и алгоритм Мёллера-Тумбора является одним из наиболее распространенных.

function in=inmesh(fv,points)
%INMESH tells you if a point is inside a closed,connected triangulated surface mesh
% Author: Ander Biguri
maxZ=max(fv.vertices(:,3));
counts=zeros(size(points,1),1);
for ii=1:size(points,1)
    ray=[points(ii,:);points(ii,1:2) maxZ+1];
    for jj=1:size(fv.faces,1)
        v=fv.vertices(fv.faces(jj,:),:);
        if all(v(:,3)<ray(1,3))
            continue;
        end
        isin=mollerTrumbore(ray, fv.vertices(fv.faces(jj,:),:));
        counts(ii)=counts(ii)+isin;
    end

end
in=mod(counts,2);
end

С FileExchange , с небольшими изменениями:

function [flag, u, v, t] = mollerTrumbore (ray,tri)
% Ray/triangle intersection using the algorithm proposed by Moller and Trumbore (1997).
%
% IMPORTANT NOTE: Assumes infinite legth rays.
% Input:
%    ray(1,:) : origin.
%    d : direction.
%    tri(1,:), tri(2,:), tri(3,:): vertices of the triangle.
% Output:
%    flag: (0) Reject, (1) Intersect.
%    u,v: barycentric coordinates.
%    t: distance from the ray origin.
% Author: 
%    Jesus Mena

    d=ray(2,:)-ray(1,:);
    epsilon = 0.00001;

    e1 = tri(2,:)-tri(1,:);
    e2 = tri(3,:)-tri(1,:);
    q  = cross(d,e2);
    a  = dot(e1,q); % determinant of the matrix M

    if (a>-epsilon && a<epsilon) 
        % the vector is parallel to the plane (the intersection is at infinity)
        [flag, u, v, t] = deal(0,0,0,0);
        return;
    end

    f = 1/a;
    s = ray(1,:)-tri(1,:);
    u = f*dot(s,q);

    if (u<0.0)
        % the intersection is outside of the triangle
        [flag, u, v, t] = deal(0,0,0,0);
        return;          
    end

    r = cross(s,e1);
    v = f*dot(d,r);

    if (v<0.0 || u+v>1.0)
        % the intersection is outside of the triangle
        [flag, u, v, t] = deal(0,0,0,0);
        return;
    end
    if nargout>3
        t = f*dot(e2,r); % verified! 
    end
    flag = 1;
    return
end

Просто сгенерируйте свои очки:

yourboundaries=% get the range of your data from the STL file.
[x,y,z]=meshgrid(yourboundaries);
P=[x(:) y(:) z(:)];
in=inmesh(fv,P);
img=reshape(in,yourboundariesSize);
...