%'set_object': GUI to edit a projection object %------------------------------------------------------------------------ % function hset_object= set_object(data, PlotHandles,ZBounds) % associated with the GUI set_object.fig % % OUTPUT: % hset_object: handle of the GUI figure % % INPUT:u % data: structure describing the object properties % .Style=... % .ProjMode % .CoordType: 'phys' or 'px' % .num_DX,.num_DY,.num_DZ : mesh along each dirction % .RangeX, RangeY % .Coord(j,i), i=1, 2, 3, components x, y, z of j=1...n position(s) characterizing the object components % PlotHandles: handles for projection plots NO MORE USED % Zbounds: bounds on Z ( 3D case) %======================================================================= % Copyright 2008-2019, LEGI UMR 5519 / CNRS UGA G-INP, Grenoble, France % http://www.legi.grenoble-inp.fr % Joel.Sommeria - Joel.Sommeria (A) legi.cnrs.fr % % This file is part of the toolbox UVMAT. % % UVMAT is free software; you can redistribute it and/or modify % it under the terms of the GNU General Public License as published % by the Free Software Foundation; either version 2 of the license, % or (at your option) any later version. % % UVMAT is distributed in the hope that it will be useful, % but WITHOUT ANY WARRANTY; without even the implied warranty of % MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the % GNU General Public License (see LICENSE.txt) for more details. %======================================================================= function varargout = set_object(varargin) % Last Modified by GUIDE v2.5 09-Nov-2016 15:46:04 % Begin initialization code - DO NOT REFRESH gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @set_object_OpeningFcn, ... 'gui_OutputFcn', @set_object_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin & ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT REFRESH %------------------------------------------------------------------------ %------------------------------------------------------------------------ % --- Executes just before set_object is made visible. %INPUT: % handles: handles of the set_object interface elements %'IndexObj': NON USED ANYMORE (To suppress) index of the object (on the UvData list) that set_object will modify % if =[] or absent: index still undefined (create mode in uvmat) % if=0; no associated object (used for series), the button 'REFRESH' is then unvisible %'data': read from an existing object selected in the interface % .Name : class of object ('POINTS','LINE',....) % .num_DX,num_DY,num_DZ; meshes for regular grids % .Coord: object position coordinates % .ParentButton: handle of the uicontrol object calling the interface % PlotHandles: set of handles of the elements contolling the plotting of the projected field: % if =[] or absent, no refresh (mask mode in uvmat) % parameters on the uvmat interface (obtained by 'get_plot_handle.m') function set_object_OpeningFcn(hObject, eventdata, handles, data, PlotHandles,ZBounds) %------------------------------------------------------------------- % Choose default command line output for set_object handles.output = hObject; % Update handles structure guidata(hObject, handles); %% position set(0,'Unit','pixels') ScreenSize=get(0,'ScreenSize');% get the size of the screen, to put the fig on the upper right PosGUI=get(handles.set_object,'Position');% fig width in pixels Width=PosGUI(3);%width of the gui set_object in pixels Height=PosGUI(4); Left=ScreenSize(3)- Width-40; %right edge close to the right, with margin=40 Bottom=ScreenSize(4)-Height-40; %put fig at top right set(handles.set_object,'Unit','pixels') set(handles.set_object,'Position',[Left Bottom Width Height]) %default if ~exist('ZBounds','var') ZBounds=0; %default end set(hObject,'WindowButtonDownFcn',{'mouse_down'})%set mouse click action function set(hObject,'DeleteFcn',{@closefcn}) % fill the interface as set in the input data: if exist('data','var') if isfield(data,'Coord') set(handles.Coord,'Data',data.Coord) if size(data.Coord,2)==3 set(handles.z_slider,'Visible','on') end else set(handles.z_slider,'Visible','off') end if isfield(data,'TypeMenu') set(handles.Type,'String',data.TypeMenu) end if isfield(data,'ProjModeMenu') set(handles.ProjMode,'UserData',data.ProjModeMenu)% data.ProjModeMenu as default menu (used in Type_Callback) end errormsg=fill_GUI(data,handles.set_object); if ~isempty(errormsg) msgbox_uvmat('ERROR','bad data input in set_object') return end Type_Callback(hObject, eventdata, handles)% update the GUI set_object depending on the object type set(handles.REFRESH,'BackgroundColor',[1 0 0]) if isfield(data,'RangeZ') set(handles.num_RangeZ_2,'String',num2str(max(data.RangeZ),3)) if length(ZBounds) >= 2 DZ=max(data.RangeZ);%slider step if ~isnan(ZBounds(1)) && ZBounds(2)~=ZBounds(1) rel_step(1)=min(DZ/(ZBounds(2)-ZBounds(1)),0.2);%must be smaller than 1 rel_step(2)=0.1; set(handles.z_slider,'Visible','on') set(handles.z_slider,'Min',ZBounds(1)) set(handles.z_slider,'Max',ZBounds(2)) set(handles.z_slider,'SliderStep',rel_step) set(handles.z_slider,'Value',(ZBounds(1)+ZBounds(2))/2) end end end if isfield(data,'RangeX')&& ~strcmp(data.Type,'plane_z')%TODO: generalise if ischar(data.RangeX) data.RangeX=str2num(data.RangeX); end set(handles.num_RangeX_2,'String',num2str(max(data.RangeX),3)) set(handles.num_RangeX_1,'String',num2str(min(data.RangeX),3)) end if isfield(data,'RangeY')&& ~strcmp(data.Type,'plane_z')%TODO: generalise if ischar(data.RangeY) data.RangeY=str2num(data.RangeY); end set(handles.num_RangeY_2,'String',num2str(max(data.RangeY),3)) set(handles.num_RangeY_1,'String',num2str(min(data.RangeY),3)) end if isfield(data,'RangeZ')&& ~strcmp(data.Type,'plane_z')%TODO: generalise if ischar(data.RangeZ) data.RangeZ=str2num(data.RangeZ); end set(handles.num_RangeZ_2,'String',num2str(max(data.RangeZ),3)) if numel(data.RangeZ)>=2 set(handles.num_RangeZ_1,'String',num2str(min(data.RangeZ),3)) end end if ~isfield(data,'Angle') data.Angle=[0 0]; end % if isfield(data,'Angle') && isequal(numel(data.Angle),3) set(handles.num_Angle_1,'String',num2str(data.Angle(1))) % set(handles.num_Angle_2,'String',num2str(data.Angle(2))) % set(handles.num_Angle_3,'String',num2str(data.Angle(3))) % end end set(get(handles.set_object,'children'),'enable','off') set(handles.SAVE,'enable','on') % set(handles.REFRESH,'enable','off') %------------------------------------------------------------------------ % --- Outputs from this function are returned to the command line. function varargout = set_object_OutputFcn(hObject, eventdata, handles) %------------------------------------------------------------------------ % Get default command line output from handles structure varargout{1} = handles.output; varargout{2}=handles; %------------------------------------------------------------------------ % executed when closing the GUI set_object function closefcn(gcbo,eventdata) %------------------------------------------------------------------------ huvmat=findobj(allchild(0),'Tag','uvmat');%find the current uvmat interface handle if ~isempty(huvmat) hhuvmat=guidata(huvmat); set(hhuvmat.CheckViewObject,'value',0)% set(hhuvmat.CheckEditObject,'Value',0)% desactivate the edit option % deselect the object in ListObject when view_field is closed if isempty(findobj(allchild(0),'Tag','view_field')) ObjIndex=get(hhuvmat.ListObject,'Value'); ObjIndex=ObjIndex(1);%keep only the first object selected set(hhuvmat.ListObject,'Value',ObjIndex) % draw all object colors in blue (unselected) in uvmat hother=[findobj(hhuvmat.PlotAxes,'Tag','proj_object');findobj(hhuvmat.PlotAxes,'Tag','DeformPoint')];%find all the proj object and deform point representations for iobj=1:length(hother) if isequal(get(hother(iobj),'Type'),'rectangle')||isequal(get(hother(iobj),'Type'),'patch') set(hother(iobj),'EdgeColor','b') if isequal(get(hother(iobj),'FaceColor'),'m') set(hother(iobj),'FaceColor','b') end elseif isequal(get(hother(iobj),'Type'),'image') Acolor=get(hother(iobj),'CData'); Acolor(:,:,1)=zeros(size(Acolor,1),size(Acolor,2)); set(hother(iobj),'CData',Acolor); else set(hother(iobj),'Color','b') end set(hother(iobj),'Selected','off') end end end hseries=findobj(allchild(0),'Name','series');%find the current series interface handle if ~isempty(hseries) hhseries=guidata(hseries); set(hhseries.EditObject,'Value',0) end %------------------------------------------------------------------------ % --- Executes on selection change in Type. function Type_Callback(hObject, eventdata, handles) %------------------------------------------------------------------------ ListType=get(handles.Type,'String'); Type=ListType{get(handles.Type,'Value')}; % make correspondance between different object styles Coord=get(handles.Coord,'Data'); %% set the number of lines in the Coord table depending on object type switch Type case {'line'} if size(Coord,1)<2 if isequal(size(Coord,2),3) Coord=[Coord; 0 0 0];%add a line for edition (3D case) else Coord=[Coord; 0 0]; %add a line for edition (2D case) end else Coord=Coord(1:2,:); end case {'rectangle','ellipse','plane','volume'} Coord=Coord(1,:); end set(handles.Coord,'Data',Coord) %% set the projection menu and the corresponding options if isempty(get(handles.ProjMode,'UserData')) switch Type case 'polyline' menu_proj={'interp_lin';'interp_tps';'none'}; case {'polygon','rectangle','ellipse'} menu_proj={'inside';'outside';'mask_inside';'mask_outside';'interp_lin';'interp_tps';'none'}; case 'volume' menu_proj={'interp_lin';'none'}; otherwise menu_proj={'projection';'interp_lin';'interp_tps';'none'};%default end else menu_proj=get(handles.ProjMode,'UserData'); end ProjModeList=get(handles.ProjMode,'String'); menu_index=find(strcmp(ProjModeList{get(handles.ProjMode,'Value')},menu_proj)); if isempty(menu_index) menu_index=1;% end set(handles.ProjMode,'Value',menu_index);% value index must not exceed the menu length set(handles.ProjMode,'String',menu_proj) ProjMode_Callback(hObject, eventdata, handles) %------------------------------------------------------------------------ % --- Executes on selection change in ProjMode. %------------------------------------------------------------------------ function ProjMode_Callback(hObject, eventdata, handles) set(handles.REFRESH,'BackgroundColor',[1 0 1]) menu=get(handles.ProjMode,'String'); value=get(handles.ProjMode,'Value'); ProjMode=menu{value}; menu=get(handles.Type,'String'); value=get(handles.Type,'Value'); ObjectStyle=menu{value}; %%%%%%%%% TODO test3D=strcmp(ObjectStyle,'plane_z'); %TODO: generalize %%%%%%%%% %default setting set(handles.num_Angle_1,'Visible','off') set(handles.num_Angle_2,'Visible','off') %set(handles.num_Angle_3,'Visible','off') set(handles.num_RangeX_1,'Visible','off') set(handles.num_RangeX_2,'Visible','off') set(handles.num_RangeY_1,'Visible','off') if isequal(ProjMode,'interp_lin')|| isequal(ProjMode,'interp_tps') set(handles.num_RangeY_2,'Visible','off') else set(handles.num_RangeY_2,'Visible','on') end if strcmp(ObjectStyle,'rectangle')||strcmp(ObjectStyle,'ellipse') set(handles.num_RangeX_2,'Visible','on') else set(handles.num_RangeX_2,'Visible','off') end set(handles.num_RangeZ_1,'Visible','off') set(handles.num_RangeZ_2,'Visible','off') set(handles.num_DX,'Visible','off') set(handles.num_DY,'Visible','off') set(handles.num_DZ,'Visible','off') set(handles.num_RangeInterp,'Visible','off') switch ObjectStyle case 'points' set(handles.num_RangeY_2,'TooltipString','num_RangeY_2: range of projection around each point') % set(handles.XObject,'TooltipString','XObject: set of x coordinates of the points') % set(handles.YObject,'TooltipString','YObject: set of y coordinates of the points') % set(handles.ZObject,'TooltipString','ZObject: set of z coordinates of the points') case {'line','polyline','polygon'} set(handles.num_RangeY_2,'TooltipString','num_RangeY_2: range of projection around the line') set(handles.Coord,'TooltipString','Coord: table of x,y, z coordinates defining the line') % set(handles.YObject,'TooltipString','YObject: set of y coordinates defining the line') % set(handles.ZObject,'TooltipString','ZObject: set of z coordinates defining the line') if isequal(ProjMode,'interp_lin')|| isequal(ProjMode,'interp_tps') set(handles.num_DX,'Visible','on') set(handles.num_DX,'TooltipString','num_DX: mesh for the interpolated field along the line') set(handles.num_RangeInterp,'Visible','on') end case {'rectangle','ellipse'} set(handles.num_RangeX_2,'TooltipString',['num_RangeX_2: half length of the ' ObjectStyle]) set(handles.num_RangeY_2,'TooltipString',['num_RangeY_2: half width of the ' ObjectStyle]) case {'plane','plane_z'} set(handles.num_Angle_1,'Visible','on') set(handles.num_RangeX_1,'Visible','on') set(handles.num_RangeX_2,'Visible','on') set(handles.num_RangeY_1,'Visible','on') set(handles.num_RangeY_2,'Visible','on') set(handles.num_RangeZ_2,'TooltipString','num_ZMax: range of projection normal to the plane') if test3D set(handles.num_Angle_2,'Visible','on') set(handles.num_Angle_1,'Visible','on') set(handles.num_Angle_1,'String','90') %set(handles.Coord,'Data',[0 0 0]) set(handles.num_RangeZ_2,'Visible','on') end if isequal(ProjMode,'interp_lin')|| isequal(ProjMode,'interp_tps') set(handles.num_DX,'Visible','on') set(handles.num_DY,'Visible','on') set(handles.num_RangeInterp,'Visible','on') else set(handles.num_DX,'Visible','off') set(handles.num_DY,'Visible','off') end % if isequal(ProjMode,'interp_lin') % set(handles.num_DZ,'Visible','on') % end case {'volume'} set(handles.num_RangeX_1,'Visible','on') set(handles.num_RangeX_2,'Visible','on') set(handles.num_RangeY_1,'Visible','on') set(handles.num_RangeY_2,'Visible','on') set(handles.XObject,'TooltipString',['XObject: x coordinate of the axis origin for the ' ObjectStyle]) set(handles.YObject,'TooltipString',['YObject: y coordinate of the axis origin for the ' ObjectStyle]) set(handles.num_Angle_1,'Visible','on') set(handles.num_Angle_2,'Visible','on') %set(handles.num_Angle_3,'Visible','on') set(handles.num_RangeZ_1,'Visible','on') set(handles.num_RangeZ_2,'Visible','on') if isequal(ProjMode,'interp_lin')|| isequal(ProjMode,'interp_tps') set(handles.num_DX,'Visible','on') set(handles.num_DY,'Visible','on') set(handles.num_DZ,'Visible','on') else set(handles.num_DX,'Visible','off') set(handles.num_DY,'Visible','off') set(handles.num_DZ,'Visible','off') end end % set default values read in the plot of uvmat to initiate the mesh if isequal(ProjMode,'interp_lin')|| isequal(ProjMode,'interp_tps') huvmat=findobj('Tag','uvmat');%find the current uvmat interface handle if ~isempty(huvmat) UvData=get(huvmat,'UserData');%Data associated to the current uvmat interface if isempty(str2num(get(handles.num_DX,'String')))||isempty(str2num(get(handles.num_DY,'String'))); % Field=UvData.Field; if isfield(UvData.Field,'CoordMesh')&&~isempty(UvData.Field.CoordMesh) set(handles.num_DX,'String',num2str(UvData.Field.CoordMesh)) set(handles.num_DY,'String',num2str(UvData.Field.CoordMesh)) set(handles.num_RangeX_1,'String',num2str(UvData.Field.XMin)) set(handles.num_RangeX_2,'String',num2str(UvData.Field.XMax)) set(handles.num_RangeY_1,'String',num2str(UvData.Field.YMin)) set(handles.num_RangeY_2,'String',num2str(UvData.Field.YMax)) end if isempty(get(handles.CoordUnit,'String'))&& isfield(UvData.Field,'CoordUnit') set(handles.CoordUnit,'String',UvData.Field.CoordUnit) end end end if isempty(str2num(get(handles.num_RangeInterp,'String'))) && isfield(UvData,'Field') set(handles.num_RangeInterp,'String',num2str(3*UvData.Field.CoordMesh))% default interpolationlength= 3 meshes end end %------------------------------------------------------------------------ %------------------------------------------------------------------------ function num_Angle_1_Callback(hObject, eventdata, handles) update_slider(hObject, eventdata,handles) %------------------------------------------------------------------------ %------------------------------------------------------------------------ function num_Angle_2_Callback(hObject, eventdata, handles) update_slider(hObject, eventdata,handles) %------------------------------------------------------------------------ function update_slider(hObject, eventdata,handles) %rotation angles PlaneAngle(1)=str2num(get(handles.num_Angle_1,'String'));%first angle in degrees PlaneAngle(2)=str2num(get(handles.num_Angle_2,'String'));%second angle in degrees %PlaneAngle(3)=str2num(get(handles.num_Angle_3,'String'));%second angle in degrees % om=norm(PlaneAngle);%norm of rotation angle in radians % OmAxis=PlaneAngle/om; %unit vector marking the rotation axis cos_om1=cos(pi*PlaneAngle(1)/180); sin_om1=sin(pi*PlaneAngle(1)/180); cos_om2=cos(pi*PlaneAngle(2)/180); sin_om2=sin(pi*PlaneAngle(2)/180); %components of the unity vector norm_plane normal to the projection plane % norm_plane(1)=OmAxis(1)*coeff+OmAxis(2)*sin_om; % norm_plane(2)=OmAxis(2)*coeff-OmAxis(1)*sin_om; % norm_plane(3)=OmAxis(3)*coeff+cos_om; huvmat=findobj('Tag','uvmat');%find the current uvmat interface handle UvData=get(huvmat,'UserData');%Data associated to the current uvmat interface if isfield(UvData,'X') && isfield(UvData,'Y') && isfield(UvData,'Z') Z=sin_om2*(cos_om1*(UvData.X)+sin_om1*(UvData.Y))+cos_om2*(UvData.Z); set(handles.z_slider,'Min',min(Z)) set(handles.z_slider,'Max',max(Z)) ZMax_Callback(hObject, eventdata, handles) end %------------------------------------------------------------------------ function num_DX_Callback(hObject, eventdata, handles) %------------------------------------------------------------------------ %------------------------------------------------------------------------ function num_DY_Callback(hObject, eventdata, handles) %------------------------------------------------------------------------ %------------------------------------------------------------------------ function num_DZ_Callback(hObject, eventdata, handles) %------------------------------------------------------------------------ %------------------------------------------------------------------------ % --- Executes on button press in REFRESH: refresh the current object , refresh the object and its projected field %------------------------------------------------------------------------ function REFRESH_Callback(hObject, eventdata, handles) set(handles.REFRESH,'BackgroundColor',[1 1 0])% indicate activation of REFRESH drawnow %% update the object in the GUI series if relevant if strcmp(get(handles.set_object,'Name'),'edit_object_series') hseries=findobj(allchild(0),'Tag','series'); if ~isempty(hseries) SeriesData=get(hseries,'UserData'); SeriesData.ProjObject=read_GUI(handles.set_object);%read the parameters defining the object in the GUI set_object set(hseries,'UserData',SeriesData); end set(handles.REFRESH,'BackgroundColor',[1 0 0]) return end %% read the object parameters in the GUI set_object ObjectData=read_GUI(handles.set_object);%read the parameters defining the object in the GUI set_object if isfield(ObjectData,'CoordLine')% remove CoordLine (not used as object feature) ObjectData=rmfield(ObjectData,'CoordLine'); end if iscell(ObjectData.Coord)%check for empty line ObjectData.Coord=[0 0 0]; hhset_object=guidata(handles.set_object); set(hhset_object.Coord,'Data',ObjectData.Coord) end checknan=isnan(sum(ObjectData.Coord,2));%check for NaN lines if ~isempty(checknan) ObjectData.Coord(checknan,:)=[];%remove the NaN lines end ObjectName=ObjectData.Name;%name of the current object defined in set_object if isempty(ObjectName) ObjectName=ObjectData.Type;% name the object by the object type type by default end %% read the current object selection in the GUI uvmat huvmat=findobj('tag','uvmat');%find the current uvmat GUI handle UvData=get(huvmat,'UserData');%Data associated to the GUI uvmat hhuvmat=guidata(huvmat);%handles of the objects children of the GUI uvmat ListObject=get(hhuvmat.ListObject,'String');% list of objects displayed in uvmat if isequal(get(hhuvmat.CheckEditObject,'Value'),0) %we append a new object ListObject=[ListObject;{''}]; IndexObj=length(ListObject); set(hhuvmat.ListObject,'String',ListObject) set(hhuvmat.ListObject,'Value',IndexObj) UvData.ProjObject{IndexObj}=[]; %create a new empty object UvData.ProjObject{IndexObj}.DisplayHandle.uvmat=hhuvmat.PlotAxes; % axes for plot_object UvData.ProjObject{IndexObj}.DisplayHandle.view_field=[]; %no plot handle before plot_field operation else IndexObj=get(hhuvmat.ListObject,'Value');% index of the selected object for display in uvmat end %set or modify(edit mode) the name of the currently selected object detectname=1; ObjectNameNew=ObjectName; vers=0;% index of the name ListOther=ListObject; ListOther(IndexObj)=[]; while ~isempty(detectname) detectname=find(strcmp(ObjectNameNew,ListOther),1);%test the existence of the proposed name in the list if detectname% if the object name already exists indstr=regexp(ObjectNameNew,'\D');%indices of non number characters if indstr(end)