Commit 5db14a389062b1e58193a036974d1f433dcbc683

Authored by David Mayerich
1 parent 1a31ffa0

added materials to the stim::obj object

stim/visualization/obj.h
@@ -7,6 +7,8 @@ @@ -7,6 +7,8 @@
7 #include <stdlib.h> 7 #include <stdlib.h>
8 #include <stim/parser/parser.h> 8 #include <stim/parser/parser.h>
9 #include <stim/math/vector.h> 9 #include <stim/math/vector.h>
  10 +#include <stim/visualization/obj/obj_material.h>
  11 +#include <stim/parser/filename.h>
10 #include <algorithm> 12 #include <algorithm>
11 13
12 #include <time.h> 14 #include <time.h>
@@ -93,13 +95,13 @@ protected: @@ -93,13 +95,13 @@ protected:
93 }; //end vertex 95 }; //end vertex
94 96
95 //triplet used to specify geometric vertices consisting of a position vertex, texture vertex, and normal 97 //triplet used to specify geometric vertices consisting of a position vertex, texture vertex, and normal
96 - struct triplet : public std::vector<unsigned int>{ 98 + struct triplet : public std::vector<size_t>{
97 99
98 //default constructor, empty triplet 100 //default constructor, empty triplet
99 triplet(){} 101 triplet(){}
100 102
101 //create a triplet given a parameter list (OBJ indices start at 1, so 0 can be used to indicate no value) 103 //create a triplet given a parameter list (OBJ indices start at 1, so 0 can be used to indicate no value)
102 - triplet(unsigned int v, unsigned int vt = 0, unsigned int vn = 0){ 104 + triplet(size_t v, size_t vt = 0, size_t vn = 0){
103 push_back(v); 105 push_back(v);
104 if(vn != 0){ 106 if(vn != 0){
105 push_back(vt); 107 push_back(vt);
@@ -140,12 +142,12 @@ protected: @@ -140,12 +142,12 @@ protected:
140 142
141 if(size() == 3){ 143 if(size() == 3){
142 if(at(1) == 0) 144 if(at(1) == 0)
143 - ss<<"\\\\"<<at(2); 145 + ss<<"//"<<at(2);
144 else 146 else
145 - ss<<'\\'<<at(1)<<'\\'<<at(2); 147 + ss<<'/'<<at(1)<<'/'<<at(2);
146 } 148 }
147 else if(size() == 2) 149 else if(size() == 2)
148 - ss<<"\\"<<at(1); 150 + ss<<"/"<<at(1);
149 151
150 return ss.str(); 152 return ss.str();
151 } 153 }
@@ -223,10 +225,16 @@ protected: @@ -223,10 +225,16 @@ protected:
223 std::vector<geometry> P; //list of points structures 225 std::vector<geometry> P; //list of points structures
224 std::vector<geometry> F; //list of faces 226 std::vector<geometry> F; //list of faces
225 227
  228 + //material lists
  229 + std::vector< obj_material<T> > M; //list of material descriptors
  230 + std::vector<size_t> Mf; //face index where each material begins
  231 +
226 //information for the current geometric object 232 //information for the current geometric object
227 geometry current_geo; 233 geometry current_geo;
228 vertex current_vt; 234 vertex current_vt;
229 vertex current_vn; 235 vertex current_vn;
  236 + obj_material<T> current_material; //stores the current material
  237 + bool new_material; //flags if a material property has been changed since the last material was pushed
230 238
231 //flags for the current geometric object 239 //flags for the current geometric object
232 obj_type current_type; 240 obj_type current_type;
@@ -258,9 +266,9 @@ protected: @@ -258,9 +266,9 @@ protected:
258 //create a triple and add it to the current geometry 266 //create a triple and add it to the current geometry
259 void update_v(vertex vv){ 267 void update_v(vertex vv){
260 268
261 - unsigned int v;  
262 - unsigned int vt = 0;  
263 - unsigned int vn = 0; 269 + size_t v;
  270 + size_t vt = 0;
  271 + size_t vn = 0;
264 272
265 //if the current geometry is using a texture coordinate, add the current texture coordinate to the geometry 273 //if the current geometry is using a texture coordinate, add the current texture coordinate to the geometry
266 if(geo_flag_vt){ 274 if(geo_flag_vt){
@@ -303,6 +311,8 @@ protected: @@ -303,6 +311,8 @@ protected:
303 geo_flag_vn = false; 311 geo_flag_vn = false;
304 vert_flag_vt = false; 312 vert_flag_vt = false;
305 vert_flag_vn = false; 313 vert_flag_vn = false;
  314 +
  315 + new_material = false; //initialize a new material to false (start with no material)
306 } 316 }
307 317
308 //gets the type of token representing the entry in the OBJ file 318 //gets the type of token representing the entry in the OBJ file
@@ -346,10 +356,80 @@ public: @@ -346,10 +356,80 @@ public:
346 void Vertex(T x, T y, T z){ update_v(vertex(x, y, z));} 356 void Vertex(T x, T y, T z){ update_v(vertex(x, y, z));}
347 void Vertex(T x, T y, T z, T w){ update_v(vertex(x, y, z, w));} 357 void Vertex(T x, T y, T z, T w){ update_v(vertex(x, y, z, w));}
348 358
  359 + ///Material functions
  360 + void matKa(T r, T g, T b) {
  361 + new_material = true;
  362 + current_material.ka[0] = r;
  363 + current_material.ka[1] = g;
  364 + current_material.ka[2] = b;
  365 + }
  366 + void matKa(std::string tex = std::string()) {
  367 + new_material = true;
  368 + current_material.tex_ka = tex;
  369 + }
  370 + void matKd(T r, T g, T b) {
  371 + new_material = true;
  372 + current_material.kd[0] = r;
  373 + current_material.kd[1] = g;
  374 + current_material.kd[2] = b;
  375 + }
  376 + void matKd(std::string tex = std::string()) {
  377 + new_material = true;
  378 + current_material.tex_kd = tex;
  379 + }
  380 + void matKs(T r, T g, T b) {
  381 + new_material = true;
  382 + current_material.ks[0] = r;
  383 + current_material.ks[1] = g;
  384 + current_material.ks[2] = b;
  385 + }
  386 + void matKs(std::string tex = std::string()) {
  387 + new_material = true;
  388 + current_material.tex_ks = tex;
  389 + }
  390 + void matNs(T n) {
  391 + new_material = true;
  392 + current_material.ns = n;
  393 + }
  394 + void matNs(std::string tex = std::string()) {
  395 + new_material = true;
  396 + current_material.tex_ns = tex;
  397 + }
  398 + void matIllum(int i) {
  399 + new_material = true;
  400 + current_material.illum = i;
  401 + }
  402 + void matD(std::string tex = std::string()) {
  403 + new_material = true;
  404 + current_material.tex_alpha = tex;
  405 + }
  406 + void matBump(std::string tex = std::string()) {
  407 + new_material = true;
  408 + current_material.tex_bump = tex;
  409 + }
  410 + void matDisp(std::string tex = std::string()) {
  411 + new_material = true;
  412 + current_material.tex_disp = tex;
  413 + }
  414 + void matDecal(std::string tex = std::string()) {
  415 + new_material = true;
  416 + current_material.tex_decal = tex;
  417 + }
  418 +
349 ///This function starts drawing of a primitive object, such as a line, face, or point set 419 ///This function starts drawing of a primitive object, such as a line, face, or point set
350 420
351 /// @param t is the type of object to be drawn: OBJ_POINTS, OBJ_LINE, OBJ_FACE 421 /// @param t is the type of object to be drawn: OBJ_POINTS, OBJ_LINE, OBJ_FACE
352 void Begin(obj_type t){ 422 void Begin(obj_type t){
  423 + if (new_material) { //if a new material has been specified
  424 + if (current_material.name == "") { //if a name wasn't given, create a new one
  425 + std::stringstream ss; //create a name for it
  426 + ss << "material" << M.size(); //base it on the material number
  427 + current_material.name = ss.str();
  428 + }
  429 + Mf.push_back(F.size()); //start the material at the current face index
  430 + M.push_back(current_material); //push the current material
  431 + current_material.name = ""; //reset the name of the current material
  432 + }
353 current_type = t; 433 current_type = t;
354 } 434 }
355 435
@@ -468,10 +548,15 @@ public: @@ -468,10 +548,15 @@ public:
468 } 548 }
469 } 549 }
470 550
471 - //output all of the lines 551 + //output all of the faces
472 if(F.size()){ 552 if(F.size()){
473 ss<<std::endl<<"#face structures"<<std::endl; 553 ss<<std::endl<<"#face structures"<<std::endl;
  554 + size_t mi = 0; //start the current material index at 0
474 for(i = 0; i < F.size(); i++){ 555 for(i = 0; i < F.size(); i++){
  556 + if (mi < M.size() && Mf[mi] == i) {
  557 + ss << "usemtl " << M[mi].name << std::endl;
  558 + mi++;
  559 + }
475 ss<<"f "<<F[i].str()<<std::endl; 560 ss<<"f "<<F[i].str()<<std::endl;
476 } 561 }
477 } 562 }
@@ -479,6 +564,14 @@ public: @@ -479,6 +564,14 @@ public:
479 return ss.str(); //return the constructed string 564 return ss.str(); //return the constructed string
480 } 565 }
481 566
  567 + ///Output the material file as a string
  568 + std::string matstr() {
  569 + std::stringstream ss;
  570 + for (size_t i = 0; i < M.size(); i++) {
  571 + ss << M[i].str() << std::endl;
  572 + }
  573 + }
  574 +
482 obj(){ 575 obj(){
483 init(); //private function that initializes everything 576 init(); //private function that initializes everything
484 } 577 }
@@ -492,19 +585,42 @@ public: @@ -492,19 +585,42 @@ public:
492 /// @param filename is the name of the file to be saved 585 /// @param filename is the name of the file to be saved
493 bool save(std::string filename){ 586 bool save(std::string filename){
494 587
495 - std::ofstream outfile(filename.c_str()); 588 +
496 589
497 - if(!outfile){  
498 - std::cout<<"STIM::OBJ error opening file for writing"<<std::endl; 590 + std::string obj_ext = ".obj";
  591 + size_t ext_found = filename.find(obj_ext);
  592 + if (ext_found != std::string::npos) //if the extension was found
  593 + filename = filename.substr(0, ext_found);
  594 + std::string obj_filename;
  595 + std::string mtl_filename;
  596 + obj_filename = filename + ".obj";
  597 + mtl_filename = filename + ".mtl";
  598 +
  599 +
  600 + std::ofstream outfile(obj_filename.c_str());
  601 + if (!outfile) {
  602 + std::cout << "STIM::OBJ error opening file for writing" << std::endl;
499 return false; 603 return false;
500 } 604 }
501 605
  606 + if (M.size()) //if there are any materials, there will be a corresponding material file
  607 + outfile << "mtllib " << mtl_filename << std::endl; //output the material library name
  608 +
502 //output the OBJ data to the file 609 //output the OBJ data to the file
503 outfile<<str(); 610 outfile<<str();
504 611
505 //close the file 612 //close the file
506 outfile.close(); 613 outfile.close();
507 614
  615 + if (M.size()) { //if materials are used
  616 +
  617 + outfile.open(mtl_filename); //open the material file
  618 + for (size_t i = 0; i < M.size(); i++) { //for each material
  619 + outfile << M[i].str() << std::endl; //output the material name and properties
  620 + }
  621 + outfile.close();
  622 + }
  623 +
508 return true; 624 return true;
509 } 625 }
510 626
stim/visualization/obj/obj_material.h 0 → 100644
  1 +#ifndef OBJ_MATERIAL_H
  2 +#define OBJ_MATERIAL_H
  3 +
  4 +#include <sstream>
  5 +
  6 +namespace stim {
  7 +
  8 +template<typename T>
  9 +struct obj_material {
  10 + std::string name; //material name
  11 + T ka[3]; //ambient color
  12 + T kd[3]; //diffuse color
  13 + T ks[3]; //specular color
  14 + T ns; //specular exponent
  15 +
  16 + int illum; //illumination model
  17 +
  18 + std::string tex_ka; //ambient texture
  19 + std::string tex_kd; //diffuse texture
  20 + std::string tex_ks; //specular texture
  21 + std::string tex_ns; //texture map for the specular exponent
  22 + std::string tex_alpha; //texture map for the alpha component
  23 + std::string tex_bump; //bump map
  24 + std::string tex_disp; //displacement map
  25 + std::string tex_decal; //stencil decal
  26 +
  27 + obj_material() { //constructor
  28 + memset(ka, 0, sizeof(T) * 3);
  29 + memset(kd, 0, sizeof(T) * 3);
  30 + memset(ks, 0, sizeof(T) * 3);
  31 + ns = 10;
  32 + illum = 2;
  33 +
  34 + }
  35 + std::string str() {
  36 + std::stringstream ss;
  37 + ss << "newmtl " << name << std::endl;
  38 + ss << "Ka " << ka[0] << " " << ka[1] << " " << ka[2] << std::endl;
  39 + ss << "Kd " << kd[0] << " " << kd[1] << " " << kd[2] << std::endl;
  40 + ss << "Ks " << ks[0] << " " << ks[1] << " " << ks[2] << std::endl;
  41 + ss << "Ns " << ns << std::endl;
  42 + ss << "illum " << illum << std::endl;
  43 + if (tex_ka != "") ss << "map_Ka " << tex_ka << std::endl;
  44 + if (tex_kd != "") ss << "map_Kd " << tex_kd << std::endl;
  45 + if (tex_ks != "") ss << "map_Ks " << tex_ks << std::endl;
  46 + if (tex_ns != "") ss << "map_Ns " << tex_ns << std::endl;
  47 + if (tex_alpha != "") ss << "map_d " << tex_alpha << std::endl;
  48 + if (tex_bump != "") ss << "bump " << tex_bump << std::endl;
  49 + if (tex_disp != "") ss << "disp " << tex_disp << std::endl;
  50 + if (tex_decal != "") ss << "decal " << tex_decal << std::endl;
  51 + return ss.str();
  52 + }
  53 +};
  54 +
  55 +} //end namespace stim
  56 +
  57 +#endif
0 \ No newline at end of file 58 \ No newline at end of file