Logo Search packages:      
Sourcecode: octave-vrml version File versions  Download package

vrml_faces.m

## Copyright (C) 2002 Etienne Grossmann.  All rights reserved.
##
## This program 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, or (at your option) any
## later version.
##
## This 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
## for more details.
##

## s = vrml_faces(x,f,...) - VRML facet object (IndexedFaceSet node)
##
## x : 3xP   : The 3D points
## f : 3xQ   : The indexes of the points forming the faces. Indexes
##             should have values in 1:P.
##
## Returns a Shape -> IndexedFaceSet vrml node.
##
## No check is done on anything
##
## Options :
## 
## "col" , col  : 3   : Color,                      default = [0.3,0.4,0.9]
##             or 3xP : Color of vertices
##             or 3xQ : Color of facets   (use "colorPerVertex" below to
##                                         disambiguate the case P==Q).
## 
## "emit", em   : 3   : Emissive color of the surface
##              : 3XP : (same as color)
##              : 3xQ :
##              : 1   : Use color as emissive color too         default = 0
##
## "tran", tran : 1x1 : Transparency,                           default = 0
##
## "creaseAngle", a 
##              :  1  : vrml creaseAngle value. The browser may smoothe the
##                      crease between facets whose angle is less than a.
##                                                              default = 0
## "tex", texfile 
##              : string : Name of file containing texture.   default : none
##
## "imsz", sz   : 2   : Size of texture image 
##                                       default is determined by imginfo()
##
## "tcoord", tcoord
##              : 2x3Q : Coordinates of vertices in texture image. Each 2x3
##                       block contains coords of one facet's corners. The
##                       coordinates should be in [0,1], as in a VRML
##                       TextureCoordinate node.
##                                       default assumes faces are returned
##                                       by extex()
##
## "smooth"           : same as "creaseAngle",pi.
## "convex"
## "colorPerVertex", c: If 1, col specifies color of vertices. If 0,
##                       col specifies color of facets.         Default = 1
##
## "DEFcoord",n : string : DEF the coord VRML node with name n. Default = ''
## "DEFcol",  n : string : DEF the color VRML node with name n. Default = ''
##
## See also: vrml_surf(), vmesh(), test_vrml_faces()



## Author:        Etienne Grossmann <etienne@isr.ist.utl.pt>
function s = vrml_faces (x,f,varargin)

  ## mytic; starttime = cputime();

  if rows (x) != 3
    if columns (x) != 3
      error ("x is %i x %i, has neither 3 rows nor 3 columns.", size (f));
    else
      x = x';
    end
  end

  tran = 0 ;
  col = [0.3, 0.4, 0.9] ;
  convex = emit = 0;
  tcoord = imsz = tex = smooth = creaseAngle = nan ;
  colorPerVertex = nan;
  DEFcol = DEFcoord = "";

  ## Read options ######################################################
  opt1 = " tex DEFcoord DEFcol imsz tcoord tran col creaseAngle colorPerVertex emit " ;
  opt0 = " smooth convex " ;

  verbose = 0 ;
  nargin = nargin();
  nargin -= 2 ;

  i = 1;
  while nargin>=i 
    tmp = nth (varargin, i++);
    if ! ischar(tmp) ,
      error ("vrml_faces : Non-string option : \n") ;
      ## keyboard
    end

    if index(opt1,[" ",tmp," "]) ,
      
      tmp2 = nth (varargin, i++) ;

      eval([tmp,"=tmp2;"]) ;

      if verbose , printf ("vrml_faces : Read option : %s.\n",tmp); end

    elseif index(opt0,[" ",tmp," "]) ,
      
      eval([tmp,"=1;"]) ;
      if verbose , printf ("vrml_faces : Read boolean option : %s\n",tmp); end

    else
      error ("vrml_faces : Unknown option : %s\n",tmp) ;
      ## keyboard
    end
  endwhile
  ## printf ("  Options : %f\n",mytic()); ## Just for measuring time
  ## End of reading options ############################################

  if !isempty (DEFcol), col_def_str = ["DEF ",DEFcol]; 
  else                  col_def_str = ""; 
  end


  if ! isnan (smooth), creaseAngle = pi ; end

  ## printf ("creaseAngle = %8.3f\n",creaseAngle);

  ## TODO : s/list/cell/g; Should put this code in sometime soon
  ## if is_list (f), tmp={}; for i=1:length(f), tmp{i}=nth(f,i);end; f=tmp; end;
  ## if is_list (f), nfaces = length (f); else nfaces = columns (f); end

  if is_list (f), nfaces = length (f); else nfaces = columns (f); end
  if ismatrix(f)
    if rows (f) < 3
      error ("Faces matrix 'f' has %i < 3 rows, so it does not define faces",
           rows (f));
    end
    if any (f > columns (x))
      error ("Faces matrix 'f' has value %i greater than number of points %i",
           max (f(:)), columns (x));
    end
  end

  if ! isnan (tcoord)

    col_str_1 = sprintf (["  appearance Appearance {\n",...
                    "    texture ImageTexture {\n",...
                    "      url \"%s\"\n",...
                    "    }\n",...
                    "  }\n"],...
                   tex);

    texcoord_point_str = sprintf ("    %8.5f %8.5f\n", tcoord);
    
    col_str_2 = sprintf (["  texCoord TextureCoordinate {\n",\
                    "    point [\n      %s]\n",\
                    "  }\n"\
                    ],\
                   texcoord_point_str\
                   );
    
                        # If texture has been provided
  elseif ischar (tex),        # Assume triangles

    ## printf ("Using texture\n");
    
    col_str_1 = sprintf (["  appearance Appearance {\n",...
                    "    texture ImageTexture {\n",...
                    "      url \"%s\"\n",...
                    "    }\n",...
                    "  }\n"],...
                   tex);
    
                        # Eventually determine size of image
    if isnan(imsz), imsz = imginfo (tex); end

    if isnan (tcoord),

      nb = ceil (nfaces/2);   # n of blocks
      lo = [0:nb-1]/nb; hi = [1:nb]/nb;
      on = ones (1,nb); ze = zeros (1,nb);
      
      sm = (1/nb) /(imsz(2)+1);     
      tcoord = [lo; on; lo; ze; hi-sm; ze;  lo+sm; on; hi-sm; on; hi-sm; ze];
      tcoord = reshape (tcoord, 2, 6*nb);
      tcoord = tcoord (:,1:3*nfaces);
    end

    col_str_2 = sprintf (["  texCoord TextureCoordinate {\n",\
                    "    point [\n      %s]\n",\
                    "  }\n",\
                    "  texCoordIndex [\n      %s]\n",\
                    "  coordIndex [\n      %s]\n",\
                    ],\
                   sprintf ("%10.8f %10.8f,\n      ",tcoord),\
                   sprintf ("%-4d, %-4d, %-4d, -1,\n     ",0:3*nfaces-1),\
                   sprintf ("%-4d, %-4d, %-4d, -1,\n     ",f-1)
                   );
    
    ## TODO : f-1 abobe seems to not work if f is a cell or list (check
    ## whether this is possible here)

  elseif prod (size (col))==3,      # One color has been specified for the whole
                        # surface

    col_str_1 = ["  appearance Appearance {\n",...
             vrml_material(col, emit, tran,DEFcol),\
             "  }\n"];

    col_str_2 = "";
  else
    if (emit)                 # Color is emissive by default
      col_str_1 = "";
      

    else                      # If there's a material node, it is not
                        # emissive.
      if tran, ts = sprintf ("transparency %8.3f",tran);
      else     ts = "";
      end
      col_str_1 = ["appearance Appearance {\n",\
               "    material Material {",ts,"}\n}\n"];
    end
    if isnan (colorPerVertex)
      if     prod (size (col)) == 3*columns (x), colorPerVertex = 1;
      elseif prod (size (col)) == 3*columns (f), colorPerVertex = 0;
      end
    end
    if colorPerVertex, cPVs = "TRUE"; else cPVs = "FALSE"; end

    col_str_2 = sprintf (["     colorPerVertex %s\n",\
                    "     color %s Color {\n",\
                    "       color [\n%s\n",\
                    "       ]\n",\
                    "     }"],\
                   cPVs,\
                   col_def_str,\
                   sprintf("         %8.3f %8.3f %8.3f,\n",col));
  end

  ## printf ("  Colors  : %f\n",mytic()); ## Just for measuring time

  etc_str = "" ;
  if ! isnan (creaseAngle),
    etc_str = [etc_str, sprintf("    creaseAngle    %8.3f\n",creaseAngle)];
  end

  ## TODO : s/list/cell/g; Should put this code in sometime soon
  ## Code below seems useless
                        # Faces 
  if is_list (f), nfaces = length (f); else nfaces = columns (f); end


  tpl0 = sprintf ("%%%dd, ",floor (log10 (columns (x)))+1);
  ltpl0 = length (tpl0);

  ptsface = zeros (1,nfaces);

                        # Determine total number of vertices, number
                        # of vertices per face and indexes of
                        # vertices of each face
  ## TODO : s/list/cell/g; Should put this code in sometime soon
  ## if iscell (f), ... f{i} 
  if is_list (f)              

    npts = 0;
    for i = 1:length (f), npts += ptsface(i) = 1+length (nth (f,i)); end
    ii = [0, cumsum(ptsface)]';
    all_indexes = -ones (1,npts);
    for i = 1:length (f), all_indexes(ii(i)+1:ii(i+1)-1) = nth (f,i) - 1; end
  else
    f = [f;-ones(1,columns(f))];
    npts = sum (ptsface = (sum (!! f)));
    all_indexes = nze (f) - 1; 
    all_indexes(find (all_indexes<0)) = -1;
  end
  ## printf ("  Indexes  : %f\n",mytic()); ## Just for measuring time

  coord_str = sprintf (tpl0, all_indexes);
  ## That's too slow coord_str = strrep (coord_str, "-1, ","-1,\n");

  ## printf ("  Faces  : %f\n",mytic()); ## Just for measuring time

  if ! convex, etc_str = [etc_str,"    convex FALSE\n"]; end

  if !isempty (DEFcoord), coord_def_str = ["DEF ",DEFcoord]; 
  else                    coord_def_str = ""; 
  end

  s = sprintf([...                  # string of indexed face set
             "Shape {\n",...
             col_str_1,...
             "  geometry IndexedFaceSet {\n",...
             "    solid FALSE     # Show back of faces too\n",...
             col_str_2,...
             etc_str,...
             "    coordIndex [\n%s]\n",...
             "    coord %s Coordinate {\n",...
             "      point [\n%s]\n",...
             "    }\n",...
             "  }\n",...
             "}\n",...
             ],...
            coord_str,...
            coord_def_str,...
            sprintf("                 %8.3f %8.3f %8.3f,\n",x)) ;
  ## printf ("  Assembly :  %f\n",mytic()); ## Just for measuring time
  ## printf ("Total Time : %f\n",cputime() - starttime);

%!demo
%! % Test the vrml_faces and vrml_browse functions with the test_vrml_faces script
%! test_vrml_faces
endfunction


Generated by  Doxygen 1.6.0   Back to index