Changeset 98

Show
Ignore:
Timestamp:
10/17/07 04:32:31 (1 year ago)
Author:
baxissimo
Message:

* Found bug in the OFF binary implementation (reader and writer)
* Added new ability to get writer to update Option flags, removing those it doesn't support. MeshIO.supported_writer_options(...).
* Changed add_face API slightly. Previously TriConnectivity? would triangulate polygons, but provided no way to get the list of face handles added. Now add_face takes an optional out parameter for returning the list. Also removed redundant add_face options. They were needed in C++ but in D the single VertexHandle?[] version is really all you need.

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/OpenMeshD/OpenMesh/Apps/GLViewer/MeshDrawerT.d

    r92 r98  
    359359    } 
    360360 
     361    /// Get current two-sided lighting state. 
     362    /// Must be called when the GL context is active. 
    361363    bool two_sided_lighting() { 
    362364        GLboolean ion; 
     
    702704        else if (_draw_mode == "Solid Flat") // ------------------------------------- 
    703705        { 
     706            bool docolor = mesh_.has_face_colors() && use_color_; 
     707            if (docolor) { 
     708                glEnable(GL_COLOR_MATERIAL); 
     709            } 
    704710            glBegin(GL_TRIANGLES); 
    705711            for (; fIt!=fEnd; ++fIt) 
    706712            { 
    707713                glNormal3fv( mesh_.normal_ptr(fIt.handle).ptr ); 
     714                if (docolor) 
     715                    glColor3ubv( mesh_.color_ptr(fIt.handle).ptr ); 
    708716       
    709                 fvIt = mesh_.cfv_iter(fIt.handle());  
    710                 glVertex3fv( mesh_.point_ptr(fvIt.handle).ptr ); 
    711                 ++fvIt; 
    712                 glVertex3fv( mesh_.point_ptr(fvIt.handle).ptr ); 
    713                 ++fvIt; 
    714                 glVertex3fv( mesh_.point_ptr(fvIt.handle).ptr );       
     717                foreach(fvh; mesh_.fv_iter(fIt.handle)) {  
     718                    glVertex3fv( mesh_.point_ptr(fvh).ptr ); 
     719                } 
    715720            } 
    716721            glEnd(); 
     722            if (docolor) { 
     723                glDisable(GL_COLOR_MATERIAL); 
     724            } 
    717725     
    718726        } 
  • trunk/OpenMeshD/OpenMesh/Apps/GLViewer/dsss.conf

    r75 r98  
    33buildflags += -I../../.. -I../../../Helix 
    44buildflags += -debug -g  
    5 #buildflags += -release -O -inline 
     5#buildflags += -release -O 
  • trunk/OpenMeshD/OpenMesh/Apps/MeshConvert/dsss.conf

    r64 r98  
    33buildflags += -I../../.. 
    44buildflags += -debug -g  
     5#buildflags += -release -O -inline 
  • trunk/OpenMeshD/OpenMesh/Apps/MeshConvert/mconvert.d

    r78 r98  
    342342        bool rc; 
    343343        timer.start(); 
    344         rc = meshio.write_mesh( mesh, ofname, opt );           
     344        // remove any unsupported options before writing 
     345        io_opt.Options wantopt = opt; 
     346        meshio.supported_writer_options(ofname, opt); 
     347        rc = meshio.write_mesh( mesh, ofname, opt ); 
    345348        timer.stop(); 
    346349        
     
    356359            dout.writefln("  Binary size: %s bytes", meshio.binary_size(mesh, ofname, opt)); 
    357360        } 
     361        else if ( wantopt.check(io_opt.Options.Binary) ) 
     362        { 
     363            dout.writefln("  [binary output not supported]"); 
     364        } 
     365 
    358366        if ( opt.vertex_has_normal() ) 
    359367            dout.writefln("  with vertex normals"); 
     368        else if ( wantopt.vertex_has_normal() ) 
     369            dout.writefln("  [vertex normals not supported]"); 
     370         
    360371        if ( opt.vertex_has_color() ) 
    361372            dout.writefln("  with vertex colors"); 
     373        else if ( wantopt.vertex_has_color() ) 
     374            dout.writefln("  [vertex colors not supported]"); 
     375 
    362376        if ( opt.vertex_has_texcoord() ) 
    363377            dout.writefln("  with vertex texcoord"); 
     378        else if ( wantopt.vertex_has_texcoord() ) 
     379            dout.writefln("  [vertex texcoord not supported]"); 
     380 
    364381        if ( opt.face_has_normal() ) 
    365382            dout.writefln("  with face normals"); 
     383        else if ( wantopt.face_has_normal() ) 
     384            dout.writefln("  [face normals not supported]"); 
     385 
    366386        if ( opt.face_has_color() ) 
    367387            dout.writefln("  with face colors"); 
     388        else if ( wantopt.face_has_color() ) 
     389            dout.writefln("  [face colors not supported]"); 
     390 
    368391        dout.writefln("  wrote in " , timer.as_string()); 
    369392        timer.reset();        
  • trunk/OpenMeshD/OpenMesh/Apps/Subdivider/subdivider.d

    r96 r98  
    8686    scope         t = new Timer; 
    8787    scope subdivide = new Subdivider; 
    88  
     88     
    8989    dout.writefln("Subdivide %s times with '%s'" , _n, subdivide.name); 
    9090     
     
    145145    // -------------------- write mesh 
    146146 
    147     dout.writefln( "  #V " , mesh.n_vertices()
    148                    ", #F " , mesh.n_faces()
    149                    ", #E " , mesh.n_edges()); 
     147    dout.writefln( "  #V " , mesh.n_vertices
     148                   ", #F " , mesh.n_faces
     149                   ", #E " , mesh.n_edges); 
    150150 
    151151    if ( _ofname ) 
    152152    { 
    153         dout.writefln( "Write resulting mesh to file " , _ofname , ".."); 
    154         if (force_mode=='b') { opt += Options.Binary; } 
    155         else if (force_mode=='a') { opt -= Options.Binary; } 
    156         if (meshio.write_mesh(mesh, _ofname, opt)) 
     153        dout.writefln("opt = %s", opt); 
     154        Options oopt; 
     155        dout.writefln( "Write resulting mesh to file " , _ofname , "..").flush; 
     156        if (force_mode=='b') { oopt += Options.Binary; } 
     157        else if (force_mode=='a') { oopt -= Options.Binary; } 
     158        dout.writefln("oopt = %s", oopt).flush; 
     159        if (meshio.write_mesh(mesh, _ofname, oopt)) 
    157160        { 
    158161            dout.writefln( "OK").flush; 
     
    191194 
    192195    void get_iters() { 
    193         writefln("Optarg is ", optarg); 
    194196        n = std.conv.toInt(optarg); 
    195197    } 
     
    218220            break; 
    219221        } 
    220         case 'h': usage(); return 0; 
    221         case '?': 
     222        case 'h': 
     223        case '?': usage(); return 0; 
    222224        default:  usage(); return 1; 
    223225        } 
     
    229231 
    230232    // input file 
    231     ifname = argv[optind++]
     233    ifname = argv[optind++].dup
    232234 
    233235    // output file, if provided 
    234     if ( optind < argv.length ) 
    235         ofname = argv[optind++]
    236  
     236    if ( optind < argv.length ) { 
     237        ofname = argv[optind++].dup
     238    } 
    237239 
    238240    // -------------------- 
  • trunk/OpenMeshD/OpenMesh/Core/IO/IOManager.d

    r62 r98  
    152152 
    153153    
     154    /** Ask the writer that will be used to update the options passed in. 
     155     *  Since writers fail if asked to write files in a format they aren't 
     156     *  capable of it is necessary to get the closest set of options that 
     157     *  the writer supports.  This will only turn off options in _opt, not 
     158     *  enable new ones (unless the format is incapable of writing without 
     159     *  that particular feature for some reason.) 
     160     * 
     161     *  Returns false if there's no writer that can handle a file of the given type. 
     162     */ 
     163    bool supported_writer_options(string _filename, ref Options _opt) { 
     164        if (!writer_modules_)  
     165        { 
     166            derr.writefln("[OpenMesh.IO._IOManager_] No writing modules available!"); 
     167            return false; 
     168        } 
     169 
     170        // Try all registered modules 
     171        foreach(it,_; writer_modules_)  
     172        { 
     173            if (it.can_u_write(_filename)) 
     174            { 
     175                it.update_options(_filename, _opt); 
     176                return true; 
     177            } 
     178        } 
     179   
     180        // All modules failed to recognize the filename. 
     181        return false; 
     182    } 
     183 
     184    /** Get an option set containing all options supported by the writer. 
     185     *  The writer checked is the same as the one used by write()  
     186     *  given the same filename. 
     187     */ 
     188    Options supported_writer_options(string _filename) { 
     189        auto opt = Options(Options.All); 
     190        supported_writer_options(_filename, opt); 
     191        return opt; 
     192    } 
    154193 
    155194    /// Returns true if the format is supported by one of the reader modules. 
     
    188227 
    189228 
    190 public: //-- QT convenience function ------------------------------------------ 
    191     
    192  
    193     /** Returns all readable file extension + descriptions in one string. 
    194         File formats are separated by <c>;;</c>. 
    195         Convenience function for Qt file dialogs. 
    196     */ 
    197     /*const*/ string qt_read_filters()  /*const*/ { return read_filters_;  } 
    198  
    199  
    200     /** Returns all writeable file extension + descriptions in one string. 
    201         File formats are separated by <c>;;</c>.  
    202         Convenience function for Qt file dialogs. 
    203     */ 
    204     /*const*/ string qt_write_filters() /*const*/ { return write_filters_; } 
    205  
     229public: 
    206230 
    207231 
  • trunk/OpenMeshD/OpenMesh/Core/IO/MeshIO.d

    r65 r98  
    111111 
    112112 
    113 /** Write a mesh to the file _filename. The file format is determined 
    114     by _filename's extension. */ 
     113/** Write a mesh to the file _filename.  
     114 
     115    The file format is guessed from _filename's extension.  
     116*/ 
    115117bool write_mesh(Mesh)(/*const*/ Mesh _mesh, /*const*/ string _filename, 
    116118                      Options _opt = Options(Options.Default)) 
     
    118120    scope exporter = new ExporterT!(Mesh)(_mesh); 
    119121    return IOManager().write(_filename, exporter, _opt); 
     122} 
     123 
     124 
     125/** Ask the IOManager to update _opt by removing options that the target writer 
     126 *  does not support. 
     127 * 
     128 *  Just calls the method of the same name in the IOManager class. 
     129 */ 
     130bool supported_writer_options(string _filename, ref Options _opt) { 
     131    return IOManager().supported_writer_options(_filename, _opt); 
     132} 
     133 
     134/** Ask the IOManager for the full set of options supported by the target writer. 
     135 * 
     136 *  Just calls the method of the same name in the IOManager class. 
     137 */ 
     138Options supported_writer_options(string _filename) { 
     139    return IOManager().supported_writer_options(_filename); 
    120140} 
    121141 
  • trunk/OpenMeshD/OpenMesh/Core/IO/Options.d

    r62 r98  
    9292        VertexTexCoord = 0x0040, ///< Has (r) / store (w) texture coordinates 
    9393        FaceNormal     = 0x0100, ///< Has (r) / store (w) face normals 
    94         FaceColor      = 0x0200  ///< Has (r) / store (w) face colors 
     94        FaceColor      = 0x0200,  ///< Has (r) / store (w) face colors 
     95 
     96        AllProperties = VertexNormal|VertexColor|VertexTexCoord 
     97                        |FaceNormal|FaceColor, /// Every vertex or face property 
     98        All = Binary|AllProperties, /// All properties + binary 
    9599    } 
    96100 
     
    105109    alias Flag.FaceNormal     FaceNormal; 
    106110    alias Flag.FaceColor      FaceColor; 
     111    alias Flag.AllProperties  AllProperties; 
     112    alias Flag.All            All; 
    107113 
    108114public: 
     
    135141public: 
    136142 
    137     //@{ 
    138143    /// Unset options defined in _rhs. 
    139144 
     
    141146    { flags_ &= ~_rhs; /*return *this;*/ } 
    142147 
     148    /// ditto 
    143149    void unset( /*const*/ value_type _rhs) 
    144150    { /*return*/ (*this -= _rhs); } 
    145151 
    146     //@} 
    147  
    148  
    149  
    150     //@{ 
     152 
     153 
    151154    /// Set options defined in _rhs 
    152155 
     
    154157    { flags_ |= _rhs; /*return *this;*/ } 
    155158 
     159    /// ditto 
    156160    void set( /*const*/ value_type _rhs) 
    157161    { /*return*/ (*this += _rhs); } 
    158162 
    159     //@} 
    160163 
    161164public: 
     
    180183    bool face_has_normal()     /*const*/ { return check(Flag.FaceNormal); } 
    181184    bool face_has_color()      /*const*/ { return check(Flag.FaceColor); } 
     185 
     186    string toString() { 
     187        string ret = "Options("; 
     188        if (check(Binary)) ret ~= "Binary|"; 
     189        if (check(MSB)) ret ~= "MSB|"; 
     190        if (check(LSB)) ret ~= "LSB|"; 
     191        if (check(Swap)) ret ~= "Swap|"; 
     192        if (check(VertexNormal)) ret ~= "VertexNormal|"; 
     193        if (check(VertexColor)) ret ~= "VertexColor|"; 
     194        if (check(VertexTexCoord)) ret ~= "VertexTexCoord|"; 
     195        if (check(FaceNormal)) ret ~= "FaceNormal|"; 
     196        if (check(FaceColor)) ret ~= "FaceColor|"; 
     197        if (ret[$-1]=='|') ret[$-1]=')'; 
     198        else ret ~= ")"; 
     199        return ret; 
     200    } 
    182201 
    183202private: 
  • trunk/OpenMeshD/OpenMesh/Core/IO/importer/BaseImporter.d

    r5 r98  
    6969public: 
    7070 
    71     // add a vertex with coordinate \c _point 
     71    /// add a vertex with coordinate \c _point 
    7272    abstract VertexHandle add_vertex(/*const*/ ref Vec3f _point); 
    7373    
    74     // add a face with indices _indices refering to vertices 
    7574    alias VertexHandle[] VHandles; 
    76     abstract FaceHandle add_face(/*const*/ VHandles _indices); 
    7775 
    78     // set vertex normal 
     76    /// add a face with indices _indices refering to vertices 
     77    /// Optionally return a list of added faces  
     78    /// (for trimeshes, which triangulate every face) 
     79    abstract FaceHandle add_face(/*const*/ VHandles _indices, FaceHandle[]* _fhout=null); 
     80 
     81    /// set vertex normal 
    7982    abstract void set_normal(VertexHandle _vh, /*const*/ ref Vec3f _normal); 
    8083 
    81     // set vertex color 
     84    /// set vertex color 
    8285    abstract void set_color(VertexHandle _vh, /*const*/ ref Vec3ub _color); 
    8386 
    84     // set vertex texture coordinate 
     87    /// set vertex texture coordinate 
    8588    abstract void set_texcoord(VertexHandle _vh, /*const*/ ref Vec2f _texcoord); 
    8689 
    87     // set face normal 
     90    /// set face normal 
    8891    abstract void set_normal(FaceHandle _fh, /*const*/ ref Vec3f _normal); 
    8992 
    90     // set face color 
     93    /// set face color 
    9194    abstract void set_color(FaceHandle _fh, /*const*/ ref Vec3ub _color); 
    9295 
    93     // get reference to base kernel 
     96    /// get reference to base kernel 
    9497    BaseKernel kernel() { return null; } 
    9598 
  • trunk/OpenMeshD/OpenMesh/Core/IO/importer/ImporterT.d

    r83 r98  
    8585    
    8686 
    87     FaceHandle add_face(/*const*/ VHandles _indices)  
     87    FaceHandle add_face(/*const*/ VHandles _indices, FaceHandle[]* _fh_out = null)  
    8888    { 
    8989        FaceHandle fh; 
     
    112112 
    113113            // try to add face 
    114             fh = mesh_.add_face(_indices); 
     114            fh = mesh_.add_face(_indices, _fh_out); 
    115115            if (!fh.is_valid())  
    116116            { 
  • trunk/OpenMeshD/OpenMesh/Core/IO/reader/OFFReader.d

    r79 r98  
    11//============================================================================ 
    2 // OFFReader.d -  
    3 // 
    4 // Description:  
    5 //   <TODO:> 
     2// OFFReader.d 
    63// 
    74// Author:  William V. Baxter III 
     
    96// Written in the D Programming Language (http://www.digitalmars.com/d) 
    107//============================================================================ 
    11  
     8/** 
     9 *   This module implements a reader for the OFF File Format. 
     10 * 
     11 *   For details on the format see: 
     12 *      http://people.scs.fsu.edu/~burkardt/html/off_format.html 
     13 **/ 
    1214module OpenMesh.Core.IO.reader.OFFReader; 
    1315 
     
    3739 *                                                                           * 
    3840\*===========================================================================*/ 
    39  
    40  
    41 //============================================================================= 
    42 // 
    43 //  Implements a reader module for OFF files 
    44 // 
    45 //============================================================================= 
    4641 
    4742 
     
    183178                    read_ascii(_in, _bi)); 
    184179 
     180        // Can't tell if there were face colors or not till after you read it. 
    185181        if (options_.face_has_color) _opt += Options.FaceColor; 
    186182        return ret; 
     
    272268        // faces 
    273269        // #N <v1> <v2> .. <v(n-1)> [color spec] 
    274         // So far color spec is unsupported! 
     270        FaceHandle[] fh_list; fh_list.length = 10; 
    275271        for (i=0; i<nF; ++i) 
    276272        { 
     
    290286            } 
    291287     
    292             FaceHandle fh = _bi.add_face(vhandles); 
     288            fh_list.length = 0; 
     289            _bi.add_face(vhandles, &fh_list); 
    293290 
    294291            if (parts.length-ipart>=3) { 
    295                 Vec3ub rgb = Vec3ub(0,0,0); 
     292                Vec3ub rgb = Vec3ub(255,255,255); 
    296293                // read face color 
    297294                options_.face_has_color = true; 
    298                 rgb[0] = cast(ubyte)(255.0 * (std.conv.toDouble(parts[ipart++])+0.5)); 
    299                 rgb[1] = cast(ubyte)(255.0 * (std.conv.toDouble(parts[ipart++])+0.5)); 
    300                 rgb[2] = cast(ubyte)(255.0 * (std.conv.toDouble(parts[ipart++])+0.5)); 
    301                 _bi.set_color(fh,rgb); 
     295                rgb[0] = cast(ubyte)((255.0 *std.conv.toDouble(parts[ipart++]))+0.5); 
     296                rgb[1] = cast(ubyte)((255.0 *std.conv.toDouble(parts[ipart++]))+0.5); 
     297                rgb[2] = cast(ubyte)((255.0 *std.conv.toDouble(parts[ipart++]))+0.5); 
     298                foreach(fh; fh_list) { 
     299                    _bi.set_color(fh,rgb); 
     300                } 
    302301            } 
    303302             
     
    410409        // faces 
    411410        // #N <v1> <v2> .. <v(n-1)> [color spec] 
    412         // So far color spec is unsupported! 
     411        FaceHandle[] fh_list; fh_list.length = 10; 
    413412        for (i=0; i<nF; ++i) 
    414413        { 
     
    428427                    vhandles ~= VertexHandle(read_int(_in, _swap)); 
    429428            } 
    430      
    431             _bi.add_face(vhandles); 
     429 
     430            // Spec says all OFF files must specify the number of face colors 
     431            int nC = read_int(_in, _swap); 
     432            Vec3ub rgb = Vec3ub(255,255,255); 
     433            for (j=0; j<nC; ++j) { 
     434                options_.face_has_color = true; 
     435                ubyte cc = cast(ubyte)((read_float(_in, _swap)*255.0f)+0.5f); 
     436                if (j<3) { 
     437                    rgb[j] = cc; 
     438                } 
     439            } 
     440            // Face added could be triangulated by actual mesh type,  
     441            // so get all handles back & set colors 
     442            fh_list.length = 0; 
     443            _bi.add_face(vhandles, &fh_list); 
     444            if (options_.face_has_color) { 
     445                foreach(fh; fh_list) { 
     446                    _bi.set_color(fh,rgb); 
     447                } 
     448            } 
    432449        } 
    433450 
  • trunk/OpenMeshD/OpenMesh/Core/IO/writer/BaseWriter.d

    r46 r98  
    102102    size_t binary_size(BaseExporter, Options) /*const*/ { return 0; } 
    103103 
     104    /// Turn off any options that are not supported. 
     105    /// For some formats there are options that depend on the filename 
     106    /// (namely ascii/binary specific names) so the filename is passed as well. 
     107    abstract void update_options(string _filename, ref Options opt); 
    104108 
    105109 
  • trunk/OpenMeshD/OpenMesh/Core/IO/writer/OBJWriter.d

    r5 r98  
    9999    size_t binary_size(BaseExporter, Options) /*const*/ { return 0; } 
    100100 
     101    void update_options(string _filename, ref Options _opt) { 
     102        _opt -= Options.Binary; 
     103        _opt -= Options.FaceNormal; 
     104        _opt -= Options.FaceColor; 
     105    } 
     106 
    101107  private: 
    102108 
  • trunk/OpenMeshD/OpenMesh/Core/IO/writer/OFFWriter.d

    r51 r98  
    11//============================================================================ 
    2 // OFFWriter.d - 
     2// OFFWriter.d 
    33// 
    4 // Description: 
    5 //   <TODO:> 
    6 // 
    7 // Author:  William V. Baxter III 
     4// Author:  William V. Baxter III  
    85// Created: 05 Oct 2007 
    96// Written in the D Programming Language (http://www.digitalmars.com/d) 
    107//============================================================================ 
    11 // $Id:$ 
    12 //============================================================================ 
    13  
     8/** 
     9 *   This module implements a writer for the OFF File Format. 
     10 * 
     11 *   For details on the format see: 
     12 *      http://people.scs.fsu.edu/~burkardt/html/off_format.html 
     13 **/ 
    1414module OpenMesh.Core.IO.writer.OFFWriter; 
    1515 
     
    4040 
    4141 
    42 //============================================================================= 
    43 // 
    44 //  Implements a writer module for OFF files 
    45 // 
    46 //============================================================================= 
    47  
    48  
    4942//=== INCLUDES ================================================================ 
    5043 
     
    5649 
    5750import OpenMesh.Core.Geometry.VectorT; 
     51import OpenMesh.Core.Utils.color_cast; 
    5852import OpenMesh.Core.Mesh.Handles; 
    5953import OpenMesh.Core.IO.BinaryHelper; 
     
    8377    string get_extensions() /*const*/  { return "off"; } 
    8478 
     79    void update_options(string _filename, ref Options _opt) { 
     80        _opt -= Options.VertexColor; 
     81        _opt -= Options.FaceNormal; 
     82    } 
     83 
    8584    bool write(/*const*/ string _filename, BaseExporter _be, Options _opt) /*const*/ 
    8685    { 
     
    9291        // check writer features 
    9392        if ( _opt.check(Options.VertexColor) || // not supported by module 
    94              _opt.check(Options.FaceNormal)  || // not supported by format 
    95              _opt.check(Options.FaceColor)  )   // not supported by module 
     93             _opt.check(Options.FaceNormal)  )   // not supported by module 
    9694            return false; 
    9795 
     
    204202            for (i=0, nV=_be.n_vertices(); i<nV; ++i) 
    205203            { 
     204 
    206205                vh = VertexHandle(i); 
    207206                v  = _be.point(vh); 
     
    245244 
    246245 
    247  
    248  
    249246        // faces (indices starting at 0) 
     247        bool fcolor = _opt.check(Options.FaceColor) && _be.has_face_colors(); 
    250248        if (_be.is_triangle_mesh()) 
    251249        { 
    252             for (i=0, nF=_be.n_faces(); i<nF; ++i) 
    253             { 
    254                 _be.get_vhandles(FaceHandle(i), vhandles); 
    255                 fprintf(_out, "3 %d %d %d\n", 
    256                         vhandles[0].idx(), 
    257                         vhandles[1].idx(), 
    258                         vhandles[2].idx()); 
    259             } 
    260         } 
    261         else 
    262         { 
     250            if (fcolor) { 
     251                float cscale = 1.0f/255.0f; 
     252                for (i=0, nF=_be.n_faces(); i<nF; ++i) 
     253                { 
     254                    _be.get_vhandles(FaceHandle(i), vhandles); 
     255                    Vec3ub color = _be.color(FaceHandle(i)); 
     256                    fprintf(_out, "3 %d %d %d %f %f %f\n", 
     257                            vhandles[0].idx,vhandles[1].idx,vhandles[2].idx, 
     258                            color[0]*cscale,color[1]*cscale,color[2]*cscale 
     259                            ); 
     260                } 
     261            } 
     262            else { 
     263                for (i=0, nF=_be.n_faces(); i<nF; ++i) 
     264                { 
     265                    _be.get_vhandles(FaceHandle(i), vhandles); 
     266                    fprintf(_out, "3 %d %d %d\n", 
     267                            vhandles[0].idx, 
     268                            vhandles[1].idx, 
     269                            vhandles[2].idx); 
     270                } 
     271            } 
     272        } 
     273        else 
     274        { 
     275            float cscale = 1.0f/255.0f; 
    263276            for (i=0, nF=_be.n_faces(); i<nF; ++i) 
    264277            { 
     
    266279                fprintf(_out, "%d", nV); 
    267280                for (j=0; j<vhandles.length; ++j) 
    268                     fprintf(_out, " %d", vhandles[j].idx()); 
     281                    fprintf(_out, " %d", vhandles[j].idx); 
     282                if (fcolor) {  
     283                    Vec3ub color = _be.color(FaceHandle(i)); 
     284                    fprintf(_out, " %f %f %f",  
     285                            color[0]*cscale,color[1]*cscale,color[2]*cscale); 
     286                }                     
    269287                fprintf(_out, "\n"); 
    270288            } 
     
    361379 
    362380        // faces (indices starting at 0) 
     381        bool fcolor = _opt.check(Options.FaceColor) && _be.has_face_colors(); 
    363382        if (_be.is_triangle_mesh()) 
    364383        { 
     
    370389                write_int(vhandles[1].idx(), _out, swap); 
    371390                write_int(vhandles[2].idx(), _out, swap); 
     391                // According to the spec linked above, the binary 
     392                // version must have a # of color components after  
     393                // each face, for face colors.  0 of no face colors. 
     394                if (fcolor) { 
     395                    write_int(3, _out, swap); 
     396                    Vec3f color = color_cast!(Vec3f)(_be.color(FaceHandle(i))); 
     397                    write_float(color[0],_out, swap); 
     398                    write_float(color[1],_out, swap); 
     399                    write_float(color[2],_out, swap); 
     400                } else { 
     401                    write_int(0, _out, swap); 
     402                } 
    372403            } 
    373404        } 
     
    380411                foreach(vhn; vhandles) 
    381412                    write_int(vhn.idx, _out, swap); 
     413                if (fcolor) { 
     414                    write_int(3, _out, swap); 
     415                    Vec3f color = color_cast!(Vec3f)(_be.color(FaceHandle(i))); 
     416                    write_float(color[0],_out, swap); 
     417                    write_float(color[1],_out, swap); 
     418                    write_float(color[2],_out, swap); 
     419                } else { 
     420                    write_int(0, _out, swap); 
     421                } 
     422 
    382423            } 
    383424        } 
  • trunk/OpenMeshD/OpenMesh/Core/IO/writer/PLYWriter.d

    r79 r98  
    5858    string get_extensions()  /*const*/  { return "ply"; } 
    5959 
     60    void update_options(string _filename, ref Options _opt) { 
     61        // everything supported! 
     62    } 
     63 
    6064    bool write(/*const*/ string _filename, BaseExporter _be, Options _opt) /*const*/ 
    6165    { 
  • trunk/OpenMeshD/OpenMesh/Core/IO/writer/STLWriter.d

    r76 r98  
    102102    string get_extensions()  /*const*/ { return "stla stlb"; } 
    103103   
     104    void update_options(string _filename, ref Options _opt) { 
     105        _opt -= Options.VertexNormal; 
     106        _opt -= Options.VertexTexCoord; 
     107        _opt -= Options.FaceColor; 
     108    } 
     109 
    104110    bool write(/*const*/ string _filename, BaseExporter _be, Options _opt) /*const*/ 
    105111    { 
  • trunk/OpenMeshD/OpenMesh/Core/Mesh/PolyConnectivity.d

    r62 r98  
    185185    { return new_vertex(); } 
    186186 
    187     /// Add and connect a new face 
    188     FaceHandle add_face(/*const*/ ref VertexHandle[] _vhandles) 
    189     { return add_face(&_vhandles[0], _vhandles.length); } 
    190    
    191     FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2) 
    192     {  
    193         VertexHandle[3] vhs = [ _vh0, _vh1, _vh2 ]; 
    194         return add_face(vhs.ptr, vhs.length); 
    195     } 
    196    
    197     FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2, VertexHandle _vh3) 
    198     {  
    199         VertexHandle[4] vhs = [ _vh0, _vh1, _vh2, _vh3 ]; 
    200         return add_face(vhs.ptr, vhs.length);  
    201     } 
    202    
    203187    struct NextCacheEntryT(_Handle) 
    204188    { 
     
    217201    } 
    218202 
    219     FaceHandle add_face(/*const*/ VertexHandle* _vertex_handles, uint _vhs_size) 
    220     { 
     203 
     204    ///  
     205 
     206    /** Add and connect a new face.  
     207        A handle to the added face is returned. 
     208 
     209        Subclasses like TriConnectivity override this method to 
     210        triangulate any non-triangle faces added, and so may add 
     211        more than one face with this one call. 
     212 
     213        So If an array pointer is passed for _faces_out, 
     214        handles to all newly added faces will be appended to it. 
     215        It is the caller's responsibility to make sure  
     216        _faces_out is initially empty. 
     217    */ 
     218    FaceHandle add_face(/*const*/ VertexHandle[] _vertex_handles, 
     219                        FaceHandle[]* _faces_out=null) 
     220    { 
     221        uint _vhs_size  = _vertex_handles.length; 
    221222        VertexHandle                   vh; 
    222223        uint                           i, ii, n=(_vhs_size), id; 
     
    379380                adjust_outgoing_halfedge(_vertex_handles[i]); 
    380381 
     382        if (_faces_out) (*_faces_out) ~= fh; 
    381383        return fh; 
    382384 
  • trunk/OpenMeshD/OpenMesh/Core/Mesh/TriConnectivity.d

    r16 r98  
    6262    } 
    6363   
    64     /** \name Addding items to a mesh 
    65      */ 
    66     //@{ 
    6764    /** Override OpenMesh.Mesh.PolyMeshT.add_face(). Faces that aren't 
    68         triangles will be triangulated and added. In this case an 
    69         invalid face handle will be returned.  */ 
    70     FaceHandle add_face(/*const*/ ref VertexHandle[] _vhandles) 
    71     { return add_face(&_vhandles[0], _vhandles.length); } 
    72    
    73     FaceHandle add_face(/*const*/ VertexHandle* _vertex_handles, uint _vhs_size) 
    74     { 
     65        triangles will be triangulated and added. 
     66        In either case the last face added is returned. 
     67 
     68        If an array pointer is passed into _faces_out,  
     69        all handles to all newly added faces will be appended to it. 
     70        It is the caller's responsibility to make sure  
     71        it is empty initially. 
     72    */ 
     73    FaceHandle add_face(/*const*/ VertexHandle[] _vertex_handles, 
     74                        FaceHandle[]* _faces_out = null) 
     75    { 
     76        uint _vhs_size = _vertex_handles.length; 
    7577        // need at least 3 vertices 
    7678        if (_vhs_size < 3) return InvalidFaceHandle; 
    7779 
     80        FaceHandle fh; 
    7881        /// face is triangle -> ok 
    79         if (_vhs_size == 3) 
    80             return super.add_face(_vertex_handles, _vhs_size); 
     82        if (_vhs_size == 3) { 
     83            return super.add_face(_vertex_handles, _faces_out); 
     84        } 
    8185 
    8286        /// face is not a triangle -> triangulate 
     
    8892            vhandles[0] = _vertex_handles[0]; 
    8993 
    90             FaceHandle fh; 
    9194            uint i = 1; 
    9295            --_vhs_size; 
    9396 
     97            // Simple fan triangulation from the first vertex; 
    9498            while (i < _vhs_size) 
    9599            { 
    96100                vhandles[1] = _vertex_handles[i]; 
    97101                vhandles[2] = _vertex_handles[++i]; 
    98                 fh = super.add_face(vhandles.ptr, 3); 
     102                fh = super.add_face(vhandles,_faces_out); 
    99103            } 
    100104 
     
    103107    } 
    104108   
    105     FaceHandle add_face(VertexHandle _vh0, VertexHandle _vh1, VertexHandle _vh2) 
    106     {  
    107         VertexHandle vhs[3] = [ _vh0, _vh1, _vh2 ]; 
    108         return super.add_face(vhs.ptr, 3);  
    109     } 
    110    
    111     //@} 
    112109 
    113110    /** Returns the opposite vertex to the halfedge _heh in the face