DavidBrainard / RenderToolbox3

Matlab toolbox for managing graphics rendering for psychophysics
MIT License
11 stars 4 forks source link

Remove Matlab princomp() dependency #4

Closed benjamin-heasly closed 11 years ago

benjamin-heasly commented 11 years ago

The ConvertGeometry() function of the Collada to PBRT converter uses Matlab's princomp() function during mesh triangulation.

But princomp() is non-free and part of Matlab's statistics toolbox.

We should be able to use the FindLinMod() function of Psychtoolbox, instead. This is free and should provide a suitable 2D representation of polygons in 3D space.

benjamin-heasly commented 11 years ago

Using the new Utilities/FindDependencies() function, I searched for "stats" dependent functions:

Found 2 functions matching "stats":

/Applications/MATLAB_R2011a.app/toolbox/stats/stats/princomp.m called by /Users/ben/Documents/Projects/RenderToolbox3/Utilities/ColladaToPBRT/ConvertGeometry.m

/Applications/MATLAB_R2011a.app/toolbox/stats/stats/prctile.m called by /Users/ben/Documents/Projects/RenderToolbox3/ExampleScenes/Interreflection/MakeInterreflectionFigure.m

It should be easy to remove the prctile() dependency from MakeInterreflectionFigure. Then we would have a clean break from the stats toolbox.

benjamin-heasly commented 11 years ago

For MakeInterreflectionFigure(), I changed prctile() to max(). The figures are now scaled differently, but still look fine.

benjamin-heasly commented 11 years ago

I changed ConvertGeometry() to use FindLinMod() instead of princomp() during triangulation.

I note that the two functions can produce different triangulations from the same mesh! But this might not matter.

The results of the Dragon scene look good. In particular, a rectangular mesh area light shines in the correct direction.

benjamin-heasly commented 11 years ago

I have detected new errors using FindLinMod(). In some cases, the 2D representation of a polygon contains duplicate points--i.e. duplicate coefficients in the linear model. This makes it impossible to triangulate rectangles.

This seems to happen when a rectangle lies in the x-y plane and has all equal z-coordinates. For example, this part of the table in the TableSphere scene causes a triangulation error:

% xyz coordinates for 4 polygon vertices polyPos = -1 -1 -1 -1 1 -1 1 1 -1 1 -1 -1

% FindLinMod() basis vectors basis = 0 0 1 0 0 1

% FindLinMod() coefficients, the middle 2 are the same coefs = -1 1 1 -1 -1 -1 -1 -1

In this case, forming a 2D representation from the polyPos data would be trivial--just ignore the z-components. But treating this special case introduced artifacts into the TableSphere scene and CoordinatesTest scene.

I'm not sure of the best way to resolve this. I would prefer to use FindLinMod() in all cases, in a way that does not produce duplicate points.

benjamin-heasly commented 11 years ago

The duplicate points seem to occur when the z-components are all negative, not just when they are all the same.

I don't know all the linear algebra, but the fix seems straightforward: translate polygon vertices so that all components are non-negative, before triangulation. Since triangulation is about ordering vertex indices, not absolute polygon location, the translation should not matter.

I applied this translation in ConvertGeometry(), in 7ad5c718c60798ebee2aec3c6cf07c1258c8b8ca. It seems to work fine for the Dragon, CoordinatesTest, and TableSphere example scenes.

benjamin-heasly commented 11 years ago

David suggested centering vertices about the origin, rather than translating them to positive coordinates. cf509ca87277546e01bce84c8c3592f54053a617 does this. It works with the Dragon, CoordinatesTest, and TableSphere examples, and should be more general.