- Alpha Value Tuning: The alphaValue in alphaShape is crucial. It should be small enough to capture the detail but large enough to merge the two spheres correctly.
- Mesh Quality: You may need additional post-processing if the mesh quality is not satisfactory. Tools like MeshLab can help with smoothing and repairing meshes.
- Custom STL Export: The provided function is a simple ASCII STL writer. For large datasets, consider using binary STL for efficiency.
Make valid STL file from overlapping spheres
9 次查看(过去 30 天)
显示 更早的评论
I'm trying to make an STL file from surface data of 2 overlapping spheres (made from [x,y,z] = sphere(n)) by using surf2stl.m available in file exchange but the stl file created is invalid since surfaces are self-intersecting. How to remove faces inside the other sphere and consider bounding surfaces only for the creation of the STL file?
0 个评论
回答(1 个)
Shubham
2024-9-3
Hi Sabyasachi,
Creating a valid STL file from overlapping spheres involves removing the intersecting parts and keeping only the outer boundary. Here’s a step-by-step approach to achieve this:
1. Generate the Spheres
First, create the two spheres using MATLAB's sphere function. You can translate one of them to ensure they overlap:
n = 50; % Resolution of the spheres
[x1, y1, z1] = sphere(n);
[x2, y2, z2] = sphere(n);
% Translate the second sphere
x2 = x2 + 1.5; % Adjust translation to ensure overlap
2. Convert to Point Clouds
Convert the surface data of the spheres into point clouds:
points1 = [x1(:), y1(:), z1(:)];
points2 = [x2(:), y2(:), z2(:)];
3. Use Alpha Shape for Boundary Extraction
Use the alphaShape function to extract the boundary of the combined spheres:
% Combine points
combinedPoints = [points1; points2];
% Create alpha shape
alphaValue = 1.0; % Adjust this value as needed
shp = alphaShape(combinedPoints, alphaValue);
% Extract boundary facets
[faces, vertices] = boundaryFacets(shp);
4. Create a Triangulation and Export to STL
Create a triangulation object and export it using a custom STL export function:
TR = triangulation(faces, vertices);
% Custom function to write STL
function writeSTL(filename, TR)
fid = fopen(filename, 'w');
fprintf(fid, 'solid OpenSCAD_Model\n');
for i = 1:size(TR.ConnectivityList, 1)
face = TR.ConnectivityList(i, :);
v1 = TR.Points(face(1), :);
v2 = TR.Points(face(2), :);
v3 = TR.Points(face(3), :);
normal = cross(v2 - v1, v3 - v1);
normal = normal / norm(normal);
fprintf(fid, ' facet normal %.7f %.7f %.7f\n', normal);
fprintf(fid, ' outer loop\n');
fprintf(fid, ' vertex %.7f %.7f %.7f\n', v1);
fprintf(fid, ' vertex %.7f %.7f %.7f\n', v2);
fprintf(fid, ' vertex %.7f %.7f %.7f\n', v3);
fprintf(fid, ' endloop\n');
fprintf(fid, ' endfacet\n');
end
fprintf(fid, 'endsolid OpenSCAD_Model\n');
fclose(fid);
end
% Write to STL
writeSTL('output.stl', TR);
5. Validate the STL File
After exporting, validate the STL file using software like MeshLab or an STL viewer to ensure there are no self-intersections and that the mesh represents only the outer boundary.
Notes
By following these steps, you should be able to create a valid STL file representing the outer boundary of the overlapping spheres.
1 个评论
DGM
2025-2-25
编辑:DGM
2025-2-25
I not real familiar with getting the most out of alphaShape, but in practice, I don't see that it is a substitute for doing CSG. In this case, the given value of 1.0 for alpha is enough to produce manifold geometry, but it's not what I'd call a useful result.

We can try to tweak alpha to get better recovery of the concave region, but we'll start dropping points long before we ever get close. For alpha = 0.5, this isn't valid geometry anymore.

I don't know if there's anything that can be done to improve the results from alphaShape(), but I'll leave it to someone else to figure that out.
It's interesting that you're including the optional string "OpenSCAD_Model" in the header and footer, even though this is not a file being created by OpenSCAD. There's nothing really wrong with that, but if we're taking cues on how to write an STL file from an existing OpenSCAD render, then that suggests that we already have other ways of solving the problem.
If you have OpenSCAD, you can just use it. GPToolbox also has CSG tools, but both of these options rely on the same external tools (the CGAL library).
You could do it from MATLAB:
% say we have some sphere parameters
Sradius = [8 12 6]; % one for each sphere
Soffset = [0 0 0; 15 0 0; 6 6 8]; % one row for each sphere
Snfaces = [51 51 15]; % one for each sphere (51 mimics the default for sphere())
% create a simple SCAD model
% writing scripts via fprintf() is ridiculously cumbersome
% but i'm pretending that it's important to do this from MATLAB
fid = fopen('mymodel.scad','w');
% write the parameters at the top of the file
% all this mess is just to translate everything to SCAD list formatting
nspheres = numel(Sradius);
fmtstr = ['Sradius = [', repmat('%g, ',[1 nspheres-1]), '%g];\n'];
fprintf(fid,fmtstr,Sradius); % radius parameters
fprintf(fid,'Soffset = [');
for k = 1:nspheres
fmtstr = ['[', repmat('%g, ',[1 2]), '%g]'];
fprintf(fid,fmtstr,Soffset(k,:)); % offset parameters
if k < nspheres
fprintf(fid,', ');
end
end
fprintf(fid,'];\n');
fmtstr = ['Snfaces = [', repmat('%g, ',[1 nspheres-1]), '%g];\n'];
fprintf(fid,fmtstr,Snfaces); % facecount parameters
% the actual working SCAD is small
% the union() call isn't strictly necessary, but illustrative
fprintf(fid,'\n$fn=0;\n$fs=0.3;\n\n');
fprintf(fid,'union(){\n');
fprintf(fid,'\tfor (k = [0:len(Sradius)-1]){\n');
fprintf(fid,'\t\ttranslate(Soffset[k])\n');
fprintf(fid,'\t\t\tsphere(r = Sradius[k], $fa = 360/Snfaces[k]);\n');
fprintf(fid,'\t}\n}');
fclose(fid);
% compute the composite geometry, output as a new STL
[status,result] = system('openscad -o output.stl mymodel.scad');
% read the new STL as a triangulation object and display it
% (if we actually need it in MATLAB again)
TRnew = stlread('output.stl');
hs = trisurf(TRnew,'facecolor',[1 1 1]*0.7);
hs.EdgeColor = 'none';
material('shiny') % or whatever reflectance you prefer
camlight
axis equal
view(-22,35)

AFAIK, using OpenSCAD from the CLI like this doesn't allow it to do any caching of the computed geometries. As a consequence, it'll always be slow. How much of a penalty that is, depends on how you're using it.
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!