Skip to content

Commit

Permalink
Merge pull request #2 from fr0nkk/mlx_examples
Browse files Browse the repository at this point in the history
Improve code and add examples
  • Loading branch information
fr0nkk committed Sep 18, 2023
2 parents 37a5b2d + 34f7210 commit c42b2d3
Show file tree
Hide file tree
Showing 28 changed files with 654 additions and 81 deletions.
53 changes: 53 additions & 0 deletions demos.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<demos><!--This is an autogenerated file, please do not modify-->
<name>FastVisualization</name>
<type>toolbox</type>
<icon>HelpIcon.DEMOS</icon>
<website/>
<description/>
<demosection>
<label>doc</label>
<demoitem>
<label>GettingStarted</label>
<type>other</type>
<source>GettingStarted</source>
<file>doc/html/GettingStarted.html</file>
</demoitem>
<demoitem>
<label>Images</label>
<type>other</type>
<source>Images</source>
<file>doc/html/Images.html</file>
</demoitem>
<demoitem>
<label>Lines</label>
<type>other</type>
<source>Lines</source>
<file>doc/html/Lines.html</file>
</demoitem>
<demoitem>
<label>Meshes</label>
<type>other</type>
<source>Meshes</source>
<file>doc/html/Meshes.html</file>
</demoitem>
<demoitem>
<label>Pointclouds</label>
<type>other</type>
<source>Pointclouds</source>
<file>doc/html/Pointclouds.html</file>
</demoitem>
<demoitem>
<label>Surfaces</label>
<type>other</type>
<source>Surfaces</source>
<file>doc/html/Surfaces.html</file>
</demoitem>
<demoitem>
<label>Text</label>
<type>other</type>
<source>Text</source>
<file>doc/html/Text.html</file>
</demoitem>
</demosection>
</demos>
Binary file modified doc/GettingStarted.mlx
Binary file not shown.
Binary file added doc/Images.mlx
Binary file not shown.
Binary file added doc/Lines.mlx
Binary file not shown.
Binary file added doc/Meshes.mlx
Binary file not shown.
Binary file added doc/Pointclouds.mlx
Binary file not shown.
Binary file added doc/Surfaces.mlx
Binary file not shown.
Binary file added doc/Text.mlx
Binary file not shown.
72 changes: 72 additions & 0 deletions doc/html/GettingStarted.html

Large diffs are not rendered by default.

30 changes: 30 additions & 0 deletions doc/html/Images.html

Large diffs are not rendered by default.

77 changes: 77 additions & 0 deletions doc/html/Lines.html

Large diffs are not rendered by default.

72 changes: 72 additions & 0 deletions doc/html/Meshes.html

Large diffs are not rendered by default.

60 changes: 60 additions & 0 deletions doc/html/Pointclouds.html

Large diffs are not rendered by default.

38 changes: 38 additions & 0 deletions doc/html/Surfaces.html

Large diffs are not rendered by default.

53 changes: 53 additions & 0 deletions doc/html/Text.html

Large diffs are not rendered by default.

9 changes: 9 additions & 0 deletions fastvis/+internal/fvChild.m
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,15 @@ function delete(obj)
catch
end
end

function newObj = fvCopy(obj,parent)
if nargin < 2
parent = obj.fvfig;
end
t = parent.PauseUpdates;
s = obj.fv2struct;
newObj = obj.struct2fv(s,parent);
end
end

methods(Hidden)
Expand Down
88 changes: 65 additions & 23 deletions fastvis/+internal/fvController.m
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
clearColor = {0 0 0};

drawnPrimitives = {}
lastViewMatrix
drawnParams
end

methods
Expand Down Expand Up @@ -58,6 +58,9 @@ function InitFcn(obj,gl,ax,msaaSamples)

% gl.glEnable(gl.GL_FRAMEBUFFER_SRGB);

gl.glEnable(gl.GL_POLYGON_OFFSET_FILL);
gl.glEnable(gl.GL_POLYGON_OFFSET_LINE);

gl.glPixelStorei(gl.GL_PACK_ALIGNMENT,1);

end
Expand Down Expand Up @@ -89,7 +92,11 @@ function UpdateFcn(obj,gl)
[drawnPrims,j] = C{i}.Draw(gl,M,j,drawnPrims);
end
obj.drawnPrimitives = drawnPrims;
obj.lastViewMatrix = {obj.fvfig.Camera.MView M};
cam = obj.fvfig.Camera;
obj.drawnParams.MView = cam.MView;
obj.drawnParams.MProj = cam.MProj;
obj.drawnParams.MFig = M;
obj.drawnParams.state = cam.getState;

obj.framebuffer.DrawTo(1:3);

Expand All @@ -102,6 +109,8 @@ function UpdateFcn(obj,gl)

gl.glEnable(gl.GL_CULL_FACE);
gl.glFrontFace(gl.GL_CCW);
gl.glPolygonMode(gl.GL_FRONT_AND_BACK,gl.GL_FILL);
gl.glPolygonOffset(0,0);

obj.screen.program.uniforms.edlStrength.Set(obj.fvfig.EDL);
obj.screen.Draw;
Expand All @@ -113,6 +122,7 @@ function ResizeFcn(obj,gl,sz)
gl.glViewport(0,0,sz(1),sz(2));
obj.MSframebuffer.Resize(sz);
obj.framebuffer.Resize(sz);
structfun(@(s) progResize(s,obj.fvfig.Camera),obj.progs);
obj.fvfig.ResizeCallback(sz);
end

Expand Down Expand Up @@ -180,6 +190,7 @@ function ResizeFcn(obj,gl,sz)
obj.progs.(name) = glmu.Program(fullname);
end
prog = obj.progs.(name);
progResize(prog,obj.fvfig.Camera)
end

function s = coord2closest(obj,coord,radius)
Expand All @@ -195,30 +206,61 @@ function ResizeFcn(obj,gl,sz)

x = [nan nan nan];
s=struct('xyz',x,'xyz_gl',x,'xyz_view',x,'object',[],'info',struct);
if any(validId(:))
% coord is on an object
xyzs = obj.glGetZone(xy,[sz 3],2,'single','GL_RGB');
xyzs(repmat(~validId,1,1,3)) = nan;

z = xyzs(:,:,3);
[~,k] = max(z(:));
idx = k + prod(sz).*(0:2);

id = ids(idx(1:2));
drawId = mod1(id(1),65535);
o = obj.drawnPrimitives{drawId};
if isvalid(o)
s.object = o;
elemId = floor((id(1)-1)/65535)+1;
s.info = o.id2info(elemId,id(2));
end

s.xyz_view = double(xyzs(idx));
s.xyz_gl = mapply(s.xyz_view,obj.drawnParams.MView,0);
s.xyz = mapply(s.xyz_gl,obj.drawnParams.MFig,0);
else
% coord is in empty space (or on unclickable object)
% Return the intersection between the clicked "ray" and the
% plane normal to the camera direction passing through the
% camera's origin

params = obj.drawnParams;
state = params.state;

% camera position (line point 1)
l0 = mapply([0 0 0],params.MView,0);

% point corresponding to coord at the end of the clip box (line point 2)
l1 = mapply([coord.*2./state.Size-1 1],params.MProj * params.MView,0);

% camera orientation (plane normal)
n = [0 0 1] * params.MView(1:3,1:3);

% camera origin (plane point)
p0 = state.Origin;

% plane-line intersection
d = dot((p0-l0),n)/dot(l1-l0,n);
s.xyz_gl = l0 + (l1-l0).*d;

s.xyz = mapply(s.xyz_gl,params.MFig,0);
s.xyz_view = mapply(s.xyz_gl,params.MView,1);
end

if ~any(validId(:)), return, end

xyzs = obj.glGetZone(xy,[sz 3],2,'single','GL_RGB');
xyzs(repmat(~validId,1,1,3)) = nan;

z = xyzs(:,:,3);
[~,k] = max(z(:));
idx = k + prod(sz).*(0:2);

s.xyz_view = double(xyzs(idx));
s.xyz_gl = mapply(s.xyz_view,obj.lastViewMatrix{1},0);
id = ids(idx(1:2));
drawId = mod1(id(1),65535);
o = obj.drawnPrimitives{drawId};
elemId = floor((id(1)-1)/65535)+1;
s.xyz = mapply(s.xyz_gl,obj.lastViewMatrix{2},0);
s.object = o;
s.info = o.id2info(elemId,id(2));
end
end
end

function x = unpack3(x)
x = permute(x,[2 3 1]);
x = rot90(x);
function progResize(prog,cam)
prog.uniforms.scrSz.Set(max(cam.Size));
prog.uniforms.fov.Set(cam.FOV);
end
61 changes: 61 additions & 0 deletions fastvis/+internal/fvDrawable.m
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@
% Clickable - Enable or disable the ability to click the primitive
Clickable logical = true;

% LineWidth - Width of the lines to display
% Applies when the rendered object is a line
LineWidth = 1

% Camera - Camera to use for rendering
% If not set, it defaults to the parent's camera
% Setting a Camera for a drawable makes it unclickable
Expand Down Expand Up @@ -45,6 +49,22 @@
% If not set, it defaults to the parent's DepthRange
DepthRange

% DepthOffset - Offset to depth
% The value is scaled to the smallest change to avoid Z fighting
% Useful for drawing a primitive on top of another when they have
% the same depth.
DepthOffset = 0;

% FillPolygons - Flag to fill primitives
% When disabled, triangle primitves will display as wireframe
FillPolygons logical = true;

% Cull - Cull the front faces
% 0: no cull
% 1: cull font faces
% -1 cull back faces
Cull = 0;

% CallbackFcn - function_handle to call when the primitive is clicked
% Event contains the data property which contains the clicked
% index, material and world coordinate
Expand Down Expand Up @@ -98,6 +118,11 @@
obj.Update;
end

function set.LineWidth(obj,w)
obj.LineWidth = w;
obj.Update;
end

function set.ConstantSize(obj,sz)
obj.ConstantSize = sz;
obj.Update;
Expand All @@ -124,6 +149,24 @@
obj.Update;
end

function set.DepthOffset(obj,o)
if ~isscalar(o) || ~isfinite(o)
error('DepthOffset must be a finite scalar.')
end
obj.DepthOffset = o;
obj.Update;
end

function set.FillPolygons(obj,tf)
obj.FillPolygons = tf;
obj.Update;
end

function set.Cull(obj,c)
obj.Cull = c;
obj.Update;
end

function m = full_model(obj)
m = obj.relative_model(obj.parent.full_model);
end
Expand Down Expand Up @@ -214,6 +257,24 @@
gl.glColorMaski(3,tf,tf,tf,tf);
r = obj.validDepthRange;
gl.glDepthRange(r(1),r(2));
if obj.FillPolygons
polyMode = gl.GL_FILL;
else
polyMode = gl.GL_LINE;
end
gl.glPolygonMode(gl.GL_FRONT_AND_BACK,polyMode);
gl.glPolygonOffset(0,single(obj.DepthOffset));
gl.glLineWidth(obj.LineWidth);
if obj.Cull
gl.glEnable(gl.GL_CULL_FACE);
if obj.Cull > 0
gl.glFrontFace(gl.GL_CCW);
else
gl.glFrontFace(gl.GL_CW);
end
else
gl.glDisable(gl.GL_CULL_FACE);
end
obj.DrawFcn(M,j);
drawnPrims = [drawnPrims {obj}];
end
Expand Down
5 changes: 2 additions & 3 deletions fastvis/+internal/fvPopup.m
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,15 @@
function show(obj,evt)
cellfun(@delete,obj.objectButton.child);
isOnObject = ~isempty(evt.data.object);
obj.worldCoordButton.text = obj.CoordText(evt.data.xyz,'world');
obj.worldCoordButton.ActionFcn = @(~,~) assignans(evt.data.xyz);
if isOnObject
obj.worldCoordButton.text = obj.CoordText(evt.data.xyz,'world');
obj.worldCoordButton.ActionFcn = @(~,~) assignans(evt.data.xyz);
o = evt.data.object;
obj.objectButton.text = o.Name;
m = o.RightClickMenu(o,evt);
cellfun(@(c) obj.objectButton.add(c),m);
end
obj.objectButton.java.setVisible(isOnObject);
obj.worldCoordButton.java.setVisible(isOnObject);

obj.mainMenu.show(evt);
end
Expand Down
26 changes: 3 additions & 23 deletions fastvis/+internal/fvPrimitive.m
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,6 @@
% The struct must contain Offset, Ambient, Diffuse and Specular
Light = struct('Offset',[0 0 0],'Ambient',[0.3 0.3 0.3],'Diffuse',[0.8 0.8 0.8],'Specular',[1 1 1]);

% Cull - Cull the front faces
% 0: no cull
% 1: cull font faces
% -1 cull back faces
Cull = 0;

% Specular - Primitive's specular when rendering with color per vertex
Specular = [0.5 0.5 0.5];

Expand Down Expand Up @@ -221,11 +215,6 @@
obj.Update;
end

function set.Cull(obj,c)
obj.Cull = c;
obj.Update;
end

function set.Shininess(obj,s)
obj.Shininess = s;
obj.Update;
Expand Down Expand Up @@ -324,7 +313,10 @@ function ZoomTo(obj)
end
h = size(cmap,1);
if isfloat(c)
c(isnan(c)) = 0;
c = floor(c.*h)+1;
else
c = double(c)+1;
end

c = cmap(clamp(c,1,h),:);
Expand Down Expand Up @@ -385,18 +377,6 @@ function DrawFcn(obj,M,j)
end
end

gl = obj.glDrawable.gl;
if obj.Cull
gl.glEnable(gl.GL_CULL_FACE);
if obj.Cull > 0
gl.glFrontFace(gl.GL_CCW);
else
gl.glFrontFace(gl.GL_CW);
end
else
gl.glDisable(gl.GL_CULL_FACE);
end

obj.glDrawable.Draw;
end

Expand Down

0 comments on commit c42b2d3

Please sign in to comment.