%% Simple Scene Editor
%
% This example shows how a simple scene can be defined
% using purely MATLAB functions associated with 
% F3D Viewer window custom buttons.
% 
% How to control the editor
% 1) use ctrl+left mouse button to select objects
% 2) use user buttons to:
% - create (+) or remove (×) objects
% - assign (=) a new shape to selected actors 
%   through a simple GUI
% 3) use context menu to edit transforms and visual 
% parameters through the Actor Inspector

%   Copyright 1998-2021 HUMUSOFT s.r.o.

%% Initialize the 3D Foundation object
FW = F3D.World(mfilename);
initialize(FW, [0 6 4]);

% Units and coordinate system
FW.AngleUnits = 'deg';

% Set the viewport properties
VP = FW.Viewports.Main;
VP.Title = mfilename;
Path = fileparts(which(mfilename));
setLogo(VP, fullfile(Path, 'data', 'MatlabLogo.png'));

Path = fileparts(which(mfilename));
F3D.Geometry.templateFloor(FW.Root, [10 10 0.1]);

Base = addChild(FW.Root, 'Base');
createShape(Base, 'box', [1 1 1]);
Base.Location = [0 0 1];

% User buttons
VP.Button3 = F3D.Type.Button([0 0 10]/4, 'S', 'Save to file', @SaveFile);
VP.Button4 = F3D.Type.Button([0 0 10]/4, 'L', 'Load from file', @LoadFile);
VP.Button6 = F3D.Type.Button([0 0 0]/4, '×', 'Delete selected', @DeleteObject);
VP.Button7 = F3D.Type.Button([0 0 0]/4, '=', 'Assign shape to selected', @ModifyObject);
VP.Button8 = F3D.Type.Button([0 0 0]/4, '+', 'Add new to selected', @AddObject);

VP.message(help(mfilename));

%% Callbacks
function SaveFile(World, ~)
    file = uiputfile('*.f3d', 'Save scene');
    if ischar(file)
        save(World.Root, file);
        label(World.Viewports.Main, 'The file was successfully saved...');
        pause(2.0);
        label(World.Viewports.Main, '');
    end
end

function LoadFile(World, ~)
    file = uigetfile('*.f3d', 'Open scene');
    if ischar(file)
        removeChildren(World.Root);
        load(World.Root, file);
        label(World.Viewports.Main, 'The file was successfully loaded...');
        pause(2.0);
        label(World.Viewports.Main, '');
    end
end

function AddObject(World, ~)
    Sel = World.Root.findBy('Selected', true);
    if isempty(Sel)
        A = addChild(World.Root);
        A.Location = [0 0 1];
        createShape(A, 'box', [1 1 1]);
    else
        for i = 1:numel(Sel)
            A(i) = addChild(Sel(i));
        end
        set(A, 'Location', [0 0 1]);
        createShape(A, 'box', [1 1 1]);
        set(Sel, 'Selected', false);
    end
end

function DeleteObject(World, ~)
    remove(World.Root.findBy('Selected', true));
    World.UserData.Selected = [];
end

function ModifyObject(World, ~)
    Sel = World.Root.findBy('Selected', true);
    if ~isempty(Sel)
        F3D.Examples.ShapeEditor(Sel);
    end
end