## Posts Tagged ‘3d’

### Paper-worthy rendering in MATLAB

Thursday, July 20th, 2017

MATLAB is not a great tool for creating 3D renderings. However, the learning curves for most commercial rendering tools are quite steep. Other tools like Mitsuba can create beautiful pictures, but can feel quite cumbersome for rendering pure geometry rather than the physical scenes their designed for.

Over the years, I’ve developed a way of creating plots of 3D shapes in MATLAB using a few extra functions in gptoolbox. This started as a way to just make images from research prototypes more palatable, but eventually became the usual way that I render images for papers. If the code for my research is already written in MATLAB then one huge advantage is that every image in my paper can have a *.m script that deterministically generates the result and the corresponding image with user intervention. This helps with reproducibility, editing and sharing between collaborators.

Here’s a “VFX Breakdown” of rendering a 3D shape in MATLAB.

t = tsurf(F,V);
set(gcf,'COlor',0.94*[1 1 1]);
teal = [144 216 196]/255;
pink = [254 194 194]/255;
bg_color = pink;
fg_color = teal;
for pass = 1:10
switch pass
case 1
% blank run
axis([-209.4       119.38      -181.24       262.67      -247.28 247.38]);
case 2
axis equal;
axis([-209.4       119.38      -181.24       262.67      -247.28 247.38]);
axis vis3d;
case 3
t.EdgeColor = 'none';
case 4
set(t,fphong,'FaceVertexCData',repmat(fg_color,size(V,1),1));
case 5
set(t,fsoft);
case 6
l = light('Position',[0.2 -0.2 1]);
case 7
set(gca,'Visible','off');
case 8
set(gcf,'Color',bg_color);
case 9
case 10
end

vidObj = VideoWriter(sprintf('nefertiti-%02d.mp4',pass),'MPEG-4');
vidObj.Quality = 100;
vidObj.open;
thetas = linspace(30,-30,450);
for theta = thetas(1:end-1)
view(theta,30);
drawnow;
vidObj.writeVideo(getframe(gcf));
end
vidObj.close;

end


### Skinning Subdivision Surfaces

Monday, March 16th, 2015

Songrun and Yotam have wrapped up the little 3D demo of our Siggraph Asia 2014 paper Skinning Cubic Bézier Splines and Catmull-Clark Subdivision Surfaces. Build the demo from source on github.

### Stable triangle normals

Wednesday, February 11th, 2015

Here’s one way to compute a triangle’s normal using floating point arithmetic that is stable with respect to the order the triangle’s vertices are given in. To demonstrate the issue, consider:

% Vertex positions
A = [1/8 1 1/6];
B = [1/3 1/5 1/7];
C = [1/4 1/9 1/2];
% normals via cross product of different edge vectors
NB = cross(A-B,C-B);
NC = cross(B-C,A-C);
NA = cross(C-A,B-A);
NA-NB
NB-NC


producing

ans =
0            0  -2.7756e-17
ans =
5.5511e-17   1.3878e-17            0


Computing the normals three different ways, I get three different floating point errors. The right thing to do I guess is analyze the vertex positions and design a normal computation that minimizes floating point error (the solution hopefully being stable via uniqueness). I took a lazier route and take a careful average of the three solutions. The might also have the effect of cutting down floating point error a bit. But at least it’s stable.

Unfortunately it’s not enough to naively sum N1, N2, and N3 entry-wise and divide by 3. The summation could incur roundoff error depending on the order of the three arguments. So first we must sort the arguments. If going to the trouble of sorting we might as well sort in a way that reduces roundoff error: descending order of absolute value. The matlab syntax for this is a little clunky:

NABC = [NA(:) NB(:) NC(:)];
[~,I] = sort([NABC],2,'descend');
sNABC = reshape( ...
NABC(sub2ind(size(NABC),repmat(1:size(NABC,1),size(NABC,2),1)',I)),size(NABC));
N = 1/3*reshape(sum(sNABC,2),shape);


### Extruding a Bezier curve into a triangle mesh in maya

Friday, October 17th, 2014

Today I struggled to convince Maya to let me extrude a Bezier Curve into a solid shape (sweep a closed curve and finish with planar end caps). I could used the Surface > Extrude tool to extrude the curve and then select the boundary edges and use the Surface > Planar tool to close the endcaps, but this just creates a group of 3 surfaces which are not topologically connected.

My end goal today was to create something to send to the 3D printer. So in this case I eventually wanted a triangle mesh. Here’re the steps I took to convert a bezier curve to a polygonal mesh:

1. draw bezier curves
2. find the Polygons > Plane tool
3. draw a plane behind the curves
4. Select one of the curves and the plane
5. Choose Edit Mesh > Project curve onto mesh
6. Select the new projected curve and the plane
7. Choose Edit Mesh > Split Mesh with projected curve
8. Right click and hold and drag to select “Face” selection mode
9. Mouse over the plane until just the filled curve appears (there seem to be many overlapping faces.
10. Choose Edit > Invert Selection
11. Then choose Edit > Delete
12. Select just the original Bezier curve and delete it.
13. Repeat steps 2-12 for the other curves (why can’t we do all curves at once?)
14. Select both filled curves and choose the Polygons > Extrude tool
15. Pull down on the widget’s arrow to extrude.
16. Select both extruded surfaces and choose Mesh > Cleanup...
17. Make sure 4-sided faces is unchecked
18. Make sure Faces with zero geometry area is checked with very small Area tolerance (e.g. 0.00001)
19. Hit Cleanup
20. The choose Mesh > Triangulate
21. The surface is now triangulated. Select everything.
22. File > Export Selection and save as an obj

Wow. So 21 steps. Not particularly easy for a task I thought would be dead simple. I must be missing some faster way to do this.

### Bounded biharmonic weights c++ demo for surfaces/volumes in 3d

Monday, December 24th, 2012

By popular demand I’ve created a quick-and-dirty 3d C++ demo of our paper “Bounded Biharmonic Weights for Real-time Deformation” [Jacobson et al. 2011].

The demo takes a mesh (.obj or .off) and a description of a skeleton (in my own ridiculous .bf and .tgf file formats) and computes a tetrahedral volume mesh using tetgen (saved to a .mesh file) and then computed bounded biharmonic weights for each handle over this mesh (save to my not-so-ridiculous .dmat file format).

This is a small program that illustrates how to compute Bounded Biharmonic Weights (BBW) for a given surface mesh and skeleton description. This only supports point handles and skeleton trees (bones). Cages are not supported. This program only computes and outputs the weight function values. You should be able to load them into matlab or maya or whatever.

### COMPILE

First install the dependencies (e.g. mosek). If your on a mac, and why wouldn’t you be, then you *should* with any luck and by the grace of God be able to compile with:


make


### RUN

Then run an example with (e.g.):


./bbw_demo examples/brick.obj examples/brick.tgf


This will produce at least 2 files:


examples/brick-volume.mesh  Tetrahedral mesh over which weights were computed
examples/brick-volume.dmat  Coefficients of weights defined over .mesh


### File Formats

See file-formats/index.html

The dependencies are:

  igl_lib
eigen3
tetgen
mosek

### Igl lib

IGL_lib is our groups internal library. It will someday be publicly available, but not yet. Thus I only include here a bare minimum to get this demo to work. The library functions as an inlined header library. All the source is located in ./igl_lib/include/igl

Eigen3: The igl dependencies rely on a depracted version of the Sparse Matrix suite in eigen 3. Thus you need the correct version of eigen. To make this easier I have included the necessary version of eigen here: ./eigen3

Tetgen Tetgen is also free and easy to install. Be sure to compile the library version, i.e.:


make tetlib


To make life a little easier I include a working version of tetgen in ./igl_lib/external/tetgen/. You can go there and compile libtet.a or download the tetgen source and do that on your own. Whatever.

You can try to contact me with questions. Especially regarding the algorithm described in “Bounded biharmonic weights for real-time deformation” by [Jacobson et al. 2011]. However, please
try to solve compilation troubles on your own. I didn’t intend for this code to be machine independent or even necessarily easy to compile. This is a quick and dirty demo because so many people requested it.

Sometime in the not too distant future I still plan to release a *nice* 3d, C++ demo.

Update: I have updated this demo to use the libigl library. Please find the new version on the bbw project page.

### calistatics

Wednesday, October 5th, 2011

### Hide bounding box and axes in MATLAB 3D plots

Monday, December 13th, 2010

Took me a while to track this down.

To get rid of the bounding box and axes that matlab puts under your 3D plot use:


set(gca, 'visible', 'off');


### MATLAB display certain vertex indices

Friday, July 9th, 2010

When I’m prototyping with meshes in MATLAB it is often useful to plot the meshes in 3D.
Then I might want to examine individual vertices. So say I have defined vertices V and faces F:


[x,y]=meshgrid(1:10,1:10);
z = peaks(size(x,1));
V = [x(:),y(:),z(:)];
F = delaunay(x,y);


I can plot these normally with:


trisurf(F, V(:,1),V(:,2),V(:,3))


I can create an array to hold the vertex indices, then plot the labels at corresponding points in 3d:


indices = 1:size(V,1);
text(V(:,1),V(:,2),V(:,3),num2str(indices'))


And sometimes it helps to plot the labels in bold:


text(V(:,1),V(:,2),V(:,3),num2str(indices'),'FontWeight','Bold')


Other times it is nice to push the labels off the vertex positions. Here I move them to the right a little:


text(V(:,1),V(:,2),V(:,3),[repmat(' ',size(indices',1),1) num2str(indices')],'FontWeight','Bold')