]> Creatis software - CreaPhase.git/blob - octave_packages/vrml-1.0.13/vrml_faces.m
Add a useful package (from Source forge) for octave
[CreaPhase.git] / octave_packages / vrml-1.0.13 / vrml_faces.m
1 ## Copyright (C) 2002-2012 Etienne Grossmann <etienne@egdn.net>
2 ##
3 ## This program is free software; you can redistribute it and/or modify it under
4 ## the terms of the GNU General Public License as published by the Free Software
5 ## Foundation; either version 3 of the License, or (at your option) any later
6 ## version.
7 ##
8 ## This program is distributed in the hope that it will be useful, but WITHOUT
9 ## ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
10 ## FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
11 ## details.
12 ##
13 ## You should have received a copy of the GNU General Public License along with
14 ## this program; if not, see <http://www.gnu.org/licenses/>.
15
16 ## s = vrml_faces(x,f,...) - VRML facet object (IndexedFaceSet node)
17 ##
18 ## x : 3xP   : The 3D points
19 ## f : 3xQ   : The indexes of the points forming the faces. Indexes
20 ##             should have values in 1:P.
21 ##
22 ## Returns a Shape -> IndexedFaceSet vrml node.
23 ##
24 ## No check is done on anything
25 ##
26 ## Options :
27 ## 
28 ## "col" , col  : 3   : Color,                      default = [0.3,0.4,0.9]
29 ##             or 3xP : Color of vertices
30 ##             or 3xQ : Color of facets   (use "colorPerVertex" below to
31 ##                                         disambiguate the case P==Q).
32 ## 
33 ## "emit", em   : 3   : Emissive color of the surface
34 ##              : 3XP : (same as color)
35 ##              : 3xQ :
36 ##              : 1   : Use color as emissive color too         default = 0
37 ##
38 ## "tran", tran : 1x1 : Transparency,                           default = 0
39 ##
40 ## "creaseAngle", a 
41 ##              :  1  : vrml creaseAngle value. The browser may smoothe the
42 ##                      crease between facets whose angle is less than a.
43 ##                                                              default = 0
44 ## "tex", texfile 
45 ##              : string : Name of file containing texture.   default : none
46 ##
47 ## "imsz", sz   : 2   : Size of texture image 
48 ##                                       default is determined by imginfo()
49 ##
50 ## "tcoord", tcoord
51 ##              : 2x3Q : Coordinates of vertices in texture image. Each 2x3
52 ##                       block contains coords of one facet's corners. The
53 ##                       coordinates should be in [0,1], as in a VRML
54 ##                       TextureCoordinate node.
55 ##                                       default assumes faces are returned
56 ##                                       by extex()
57 ##
58 ## "smooth"           : same as "creaseAngle",pi.
59 ## "convex"
60 ## "colorPerVertex", c: If 1, col specifies color of vertices. If 0,
61 ##                       col specifies color of facets.         Default = 1
62 ##
63 ## "DEFcoord",n : string : DEF the coord VRML node with name n. Default = ''
64 ## "DEFcol",  n : string : DEF the color VRML node with name n. Default = ''
65 ##
66 ## See also: vrml_surf(), vmesh(), test_vrml_faces()
67
68 function s = vrml_faces (x,f,varargin)
69
70   ## mytic; starttime = cputime();
71
72   if rows (x) != 3
73     if columns (x) != 3
74       error ("x is %i x %i, has neither 3 rows nor 3 columns.", size (x));
75     else
76       x = x';
77     end
78   end
79
80   tran = 0 ;
81   col = [0.3, 0.4, 0.9] ;
82   convex = emit = 0;
83   tcoord = imsz = tex = smooth = creaseAngle = nan ;
84   colorPerVertex = nan;
85   DEFcol = DEFcoord = "";
86
87   ## Read options ######################################################
88   opt1 = " tex DEFcoord DEFcol imsz tcoord tran col creaseAngle colorPerVertex emit " ;
89   opt0 = " smooth convex " ;
90
91   verbose = 0 ;
92
93   i = 1;
94
95   while numel(varargin)>=i
96
97     tmp = varargin{i++};
98     if ! ischar(tmp) ,
99       error ("vrml_faces : Non-string option : \n") ;
100       ## keyboard
101     end
102
103     if index(opt1,[" ",tmp," "]) ,
104       
105       tmp2 = varargin{i++} ;
106
107       eval([tmp,"=tmp2;"]) ;
108
109       if verbose , printf ("vrml_faces : Read option : %s.\n",tmp); end
110
111     elseif index(opt0,[" ",tmp," "]) ,
112       
113       eval([tmp,"=1;"]) ;
114       if verbose , printf ("vrml_faces : Read boolean option : %s\n",tmp); end
115
116     else
117       error ("vrml_faces : Unknown option : %s\n",tmp) ;
118       ## keyboard
119     end
120   endwhile
121   ## printf ("  Options : %f\n",mytic()); ## Just for measuring time
122   ## End of reading options ############################################
123
124   if !isempty (DEFcol), col_def_str = ["DEF ",DEFcol]; 
125   else                  col_def_str = ""; 
126   end
127
128
129   if ! isnan (smooth), creaseAngle = pi ; end
130
131   ## printf ("creaseAngle = %8.3f\n",creaseAngle);
132
133   nfaces = columns (f); 
134   if ismatrix(f)
135     if rows (f) < 3
136       error ("Faces matrix 'f' has %i < 3 rows, so it does not define faces",
137              rows (f));
138     end
139     if any (f > columns (x))
140       error ("Faces matrix 'f' has value %i greater than number of points %i",
141              max (f(:)), columns (x));
142     end
143   end
144
145   if ! isnan (tcoord)
146
147     col_str_1 = sprintf (["  appearance Appearance {\n",...
148                           "    texture ImageTexture {\n",...
149                           "      url \"%s\"\n",...
150                           "    }\n",...
151                           "  }\n"],...
152                          tex);
153
154     texcoord_point_str = sprintf ("    %8.5f %8.5f\n", tcoord);
155     
156     col_str_2 = sprintf (["  texCoord TextureCoordinate {\n",\
157                           "    point [\n      %s]\n",\
158                           "  }\n"\
159                           ],\
160                          texcoord_point_str\
161                          );
162     
163                                 # If texture has been provided
164   elseif ischar (tex),          # Assume triangles
165
166     ## printf ("Using texture\n");
167     
168     col_str_1 = sprintf (["  appearance Appearance {\n",...
169                           "    texture ImageTexture {\n",...
170                           "      url \"%s\"\n",...
171                           "    }\n",...
172                           "  }\n"],...
173                          tex);
174     
175                                 # Eventually determine size of image
176     if isnan(imsz), imsz = imginfo (tex); end
177
178     if isnan (tcoord),
179
180       nb = ceil (nfaces/2);     # n of blocks
181       lo = [0:nb-1]/nb; hi = [1:nb]/nb;
182       on = ones (1,nb); ze = zeros (1,nb);
183       
184       sm = (1/nb) /(imsz(2)+1); 
185       tcoord = [lo; on; lo; ze; hi-sm; ze;  lo+sm; on; hi-sm; on; hi-sm; ze];
186       tcoord = reshape (tcoord, 2, 6*nb);
187       tcoord = tcoord (:,1:3*nfaces);
188     end
189
190     col_str_2 = sprintf (["  texCoord TextureCoordinate {\n",\
191                           "    point [\n      %s]\n",\
192                           "  }\n",\
193                           "  texCoordIndex [\n      %s]\n",\
194                           "  coordIndex [\n      %s]\n",\
195                           ],\
196                          sprintf ("%10.8f %10.8f,\n      ",tcoord),\
197                          sprintf ("%-4d, %-4d, %-4d, -1,\n     ",0:3*nfaces-1),\
198                          sprintf ("%-4d, %-4d, %-4d, -1,\n     ",f-1)
199                          );
200     
201     ## TODO : f-1 abobe seems to not work if f is a cell or list (check
202     ## whether this is possible here)
203
204   elseif prod (size (col))==3,  # One color has been specified for the whole
205                                 # surface
206
207     col_str_1 = ["  appearance Appearance {\n",...
208                  vrml_material(col, emit, tran,DEFcol),\
209                  "  }\n"];
210
211     col_str_2 = "";
212   else
213     if (emit)                   # Color is emissive by default
214       col_str_1 = "";
215       
216
217     else                                # If there's a material node, it is not
218                                 # emissive.
219       if tran, ts = sprintf ("transparency %8.3f",tran);
220       else     ts = "";
221       end
222       col_str_1 = ["appearance Appearance {\n",\
223                    "    material Material {",ts,"}\n}\n"];
224     end
225     if isnan (colorPerVertex)
226       if     prod (size (col)) == 3*columns (x), colorPerVertex = 1;
227       elseif prod (size (col)) == 3*columns (f), colorPerVertex = 0;
228       end
229     end
230     if colorPerVertex, cPVs = "TRUE"; else cPVs = "FALSE"; end
231
232     col_str_2 = sprintf (["     colorPerVertex %s\n",\
233                           "     color %s Color {\n",\
234                           "       color [\n%s\n",\
235                           "       ]\n",\
236                           "     }"],\
237                          cPVs,\
238                          col_def_str,\
239                          sprintf("         %8.3f %8.3f %8.3f,\n",col));
240   end
241
242   ## printf ("  Colors  : %f\n",mytic()); ## Just for measuring time
243
244   etc_str = "" ;
245   if ! isnan (creaseAngle),
246     etc_str = [etc_str, sprintf("    creaseAngle    %8.3f\n",creaseAngle)];
247   end
248
249   ## TODO : s/list/cell/g; Should put this code in sometime soon
250   ## Code below seems useless
251                                 # Faces 
252   if iscell (f), nfaces = length (f); else nfaces = columns (f); end
253
254
255   tpl0 = sprintf ("%%%dd, ",floor (log10 (max (1, columns (x))))+1);
256   ltpl0 = length (tpl0);
257
258   ptsface = zeros (1,nfaces);
259
260                                 # Determine total number of vertices, number
261                                 # of vertices per face and indexes of
262                                 # vertices of each face
263   if iscell (f)                 
264     npts = 0;
265     for i = 1:length (f), 
266        ptsface(i) = 1+length (f{i});
267        npts += ptsface(i);  
268     end
269     ii = [0, cumsum(ptsface)]';
270     all_indexes = -ones (1,npts);
271     for i = 1:length (f), all_indexes(ii(i)+1:ii(i+1)-1) = f{i} - 1; end
272   else
273     f = [f;-ones(1,columns(f))];
274     npts = sum (ptsface = (sum (!! f)));
275     all_indexes = nze (f) - 1; 
276     all_indexes(find (all_indexes<0)) = -1;
277   end
278   ## printf ("  Indexes  : %f\n",mytic()); ## Just for measuring time
279
280   coord_str = sprintf (tpl0, all_indexes);
281   ## That's too slow coord_str = strrep (coord_str, "-1, ","-1,\n");
282
283   ## printf ("  Faces  : %f\n",mytic()); ## Just for measuring time
284
285   if ! convex, etc_str = [etc_str,"    convex FALSE\n"]; end
286
287   if !isempty (DEFcoord), coord_def_str = ["DEF ",DEFcoord]; 
288   else                    coord_def_str = ""; 
289   end
290
291   s = sprintf([...                      # string of indexed face set
292                "Shape {\n",...
293                col_str_1,...
294                "  geometry IndexedFaceSet {\n",...
295                "    solid FALSE     # Show back of faces too\n",...
296                col_str_2,...
297                etc_str,...
298                "    coordIndex [\n%s]\n",...
299                "    coord %s Coordinate {\n",...
300                "      point [\n%s]\n",...
301                "    }\n",...
302                "  }\n",...
303                "}\n",...
304                ],...
305               coord_str,...
306               coord_def_str,...
307               sprintf("                 %8.3f %8.3f %8.3f,\n",x)) ;
308   ## printf ("  Assembly :  %f\n",mytic()); ## Just for measuring time
309   ## printf ("Total Time : %f\n",cputime() - starttime);
310
311 %!demo
312 %! % Test the vrml_faces and vrml_browse functions with the test_vrml_faces script
313 %! test_vrml_faces
314 endfunction
315