johnyf / fig2u3d

Export MATLAB figure as U3D file or directly to 3D interactive PDF
http://www.mathworks.com/matlabcentral/fileexchange/37640-export-figure-to-3d-interactive-pdf
BSD 2-Clause "Simplified" License
62 stars 24 forks source link

fig2u3d (partially) working on 2015a... #6

Open JavierBurg opened 7 years ago

JavierBurg commented 7 years ago

Thank you very much for this wonderful package that allows me to insert interactive 3d plots in my presentations!!!

Nevertheless, I had a lot of problems to make it work in Matlab R2015a, and my success is only partial...

First, I had a problem with the file mesh_normals.m in fig2idtf/auxiliary. It seems that this script does not produce / generate the correct normals for mesh surfaces. So, it generates an error when 'normals' is empty: when it tries to normalize the normal vectors, it complains about the operation ./ between empty matrices. I've included a check for this condition that returns an empty 'normals' without normalization.

And I had to manually comment some lines in other scripts that check the condition isnan() for various handles (two places): fig2idtf/preprocess/u3d_pre_contourgroup.m and fig2idtf/preprocess/u3d_pre_quivergroup.m

With these corrections, fig2u3d is able to generate the idtf file, but then the system explodes when it calls to IDTFConverter. I had the same error 81110005 that was previously commented in another message.

If I edit manually the IDTF file and remove from the MESH resource everything related to NORMALS (I set MODEL_NORMAL_COUNT to 0, and remove MESH_FACE_NORMAL_LIST and MODEL_NORMAL_LIST) I can run the IDTFConverter without any flaw and the u3d file works great in latex and PDF.

I guess that the problem comes from the file mesh_normals, but I cannot find useful information about this function.

Any comment that can help me to correct this issue will be welcome.

Javier

JavierBurg commented 7 years ago

I've seen in the MathWOrks FIle Exchange that there was a patch proposed by markusha slightly different to the on I've applied to mesh_normals.m

With the proposed change, everything works perfect! (At least for fig2u3d) Thanks again!!

johnyf commented 7 years ago

Thank you for reporting your findings, and confirming that the changes proposed by markusha work for you too.

For posterity, the file mentioned in the OP is mesh_normals.m. 'normals' appears to refer to the variable normals, assigned on line 27 with

normals = get(hp,'VertexNormals')

MathWorks changed the graphics API, and I haven't followed through, because I stopped using Matlab 4 years ago, and haven't found the time to update this package. From the information reported, it appears that 'VertexNormals' has been renamed or otherwise changed in the API, and get returns an empty array (similar to dict.get in Python, which would return a None though).

This results in a division between empty arrays later, on line 32.

Quoting the information provided by the user markusha at the FEX comments:

31 Oct 2016 markusha:

First off, thank you very much for this nice toolset! My PDF documents have truly benefited from it.

I was able to make this work in R2016b after following changes:

1) in u3d_pre_quivergroup.m change sh(isnan(sh) ) = []; into sh = []; 2) in u3d_pre_contourgroup.m, same as above 3) in mesh_normals.m, change normals = get(hp,'VertexNormals'); into normals = get(hp,'Vertices');

This works for me. It may or may not work for anyone else.

09 Nov 2016 markusha:

My usage of this package is restricted only to fig2u3d.m (and any functions it calls). In this scenario the changes below allow me to export U3D in R2016b, R2015a, R2014b and R2013b. I do not have access to other releases. It is probably the third change that needs to be chosen correctly for old vs. new ML releases.

johnyf commented 7 years ago

I cannot understand: "I had the same error 81110005 that was previously commented in another message." from the OP. Could you please elaborate on the "was previously commented in another message"?

johnyf commented 7 years ago

Relevant to #5.

prateekrajgautam commented 4 years ago

The mesh_normal function find the normal unit vector or direction vector, so I change the code to do that as

function [normals] = mesh_normals(points,faces)

% MESH_NORMALS   compute mesh normals
%
%   compute mesh normals using builtin matlab function
%
%   SYNTAX
%       [NORMALS] = MESH_NORMALS(POINTS,FACES)
%
%   Created by Alexandre Gramfort on 2007-11-27.
%   Copyright (c) 2007 Alexandre Gramfort. All rights reserved.

% $Id: mesh_normals.m 26 2008-11-03 10:14:12Z gramfort $
% $LastChangedBy: gramfort $
% $LastChangedDate: 2008-11-03 11:14:12 +0100 (Lun, 03 nov 2008) $
% $Revision: 26 $

me = 'MESH_NORMALS';

if nargin == 0
    eval(['help ',lower(me)])
    return
end

hf = figure('Visible','off');
hp = patch('vertices',points,'faces',faces);

for i=1:length(faces)
   A=faces(i,:);
   B=points(A',:);
   a=B(1,:);
   b=B(2,:);
   c=B(3,:);

   ab=a-b;
   ac=a-c;

   norm=cross(ab,ac);
   normMag=sqrt(sum(norm.^2));
   normals(i,:)=norm/normMag;
end

% normals = get(hp,'VertexNormals');
% close(hf);
% %Make the normals unit norm
% norms = sqrt(sum(normals.*conj(normals),2));
% gidx = find(norms);
% normals(gidx,:) = - normals(gidx,:) ./ repmat(norms(gidx),1,3);

end %  function