LCOV - code coverage report
Current view: top level - ugbase/common/util/loader - loader_obj.cpp (source / functions) Coverage Total Hit
Test: coverage.info Lines: 0.0 % 183 0
Test Date: 2025-09-21 23:31:46 Functions: 0.0 % 7 0

            Line data    Source code
       1              : /*
       2              :  * Copyright (c) 2009-2015:  G-CSC, Goethe University Frankfurt
       3              :  * Author: Sebastian Reiter
       4              :  * 
       5              :  * This file is part of UG4.
       6              :  * 
       7              :  * UG4 is free software: you can redistribute it and/or modify it under the
       8              :  * terms of the GNU Lesser General Public License version 3 (as published by the
       9              :  * Free Software Foundation) with the following additional attribution
      10              :  * requirements (according to LGPL/GPL v3 §7):
      11              :  * 
      12              :  * (1) The following notice must be displayed in the Appropriate Legal Notices
      13              :  * of covered and combined works: "Based on UG4 (www.ug4.org/license)".
      14              :  * 
      15              :  * (2) The following notice must be displayed at a prominent place in the
      16              :  * terminal output of covered works: "Based on UG4 (www.ug4.org/license)".
      17              :  * 
      18              :  * (3) The following bibliography is recommended for citation and must be
      19              :  * preserved in all covered files:
      20              :  * "Reiter, S., Vogel, A., Heppner, I., Rupp, M., and Wittum, G. A massively
      21              :  *   parallel geometric multigrid solver on hierarchically distributed grids.
      22              :  *   Computing and visualization in science 16, 4 (2013), 151-164"
      23              :  * "Vogel, A., Reiter, S., Rupp, M., Nägel, A., and Wittum, G. UG4 -- a novel
      24              :  *   flexible software system for simulating pde based models on high performance
      25              :  *   computers. Computing and visualization in science 16, 4 (2013), 165-179"
      26              :  * 
      27              :  * This program is distributed in the hope that it will be useful,
      28              :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      29              :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
      30              :  * GNU Lesser General Public License for more details.
      31              :  */
      32              : 
      33              : #include <vector>
      34              : #include <fstream>
      35              : #include <cstring>
      36              : #include <string>
      37              : #include "loader_obj.h"
      38              : #include "loader_util.h"
      39              : 
      40              : using namespace std;
      41              : 
      42              : namespace ug
      43              : {
      44              : ////////////////////////////////////////////////////////////////////////////////////////////////
      45              : //      some string functions
      46              : //TODO: IMPROVE THIS FUNCTION!!! MOVE IT TO A COMMON UTIL-FILE
      47              : typedef vector<string>            ParameterList;
      48            0 : static void split_parameters(ParameterList* pParamList, const char* pParamString)
      49              : {
      50            0 :         string param(pParamString);
      51              : 
      52            0 :         while(param.size())
      53              :         {
      54              :         //      delete empty spaces at the front of the string
      55            0 :                 while(param.find(" ", 0) == 0)
      56              :                 {
      57            0 :                         param.erase(0, 1);
      58              :                 }
      59              :         //      find the next empty space
      60            0 :                 int iSpace = param.find(" ", 0);
      61            0 :                 if(iSpace == -1)
      62              :                 {
      63              :                 //      there is no -> the rest of the string is a parameter
      64            0 :                         if(param.size() > 0)
      65              :                         {
      66              :                         /*
      67              :                                 SParameter nParam;
      68              :                                 nParam.pFirst = pParamString + PosIndex;
      69              :                                 nParam.size = param.size();
      70              :                         */
      71              :                                 string nParam = param;
      72            0 :                                 pParamList->push_back(nParam);
      73              :                                 break;
      74              :                         }
      75              :                 }
      76              :                 else
      77              :                 {
      78              :                 //      extract the parameter from param and push back to ParamList
      79              :                 /*
      80              :                         SParameter nParam;
      81              :                         nParam.pFirst = pParameterString + PosIndex;
      82              :                         nParam.size = iSpace;
      83              :                 */
      84              :                         string nParam;
      85            0 :                         nParam.assign(param, 0, iSpace);
      86            0 :                         pParamList->push_back(nParam);
      87            0 :                         param.erase(0, iSpace + 1);
      88              :                 }
      89              :         }
      90            0 : }
      91              : 
      92              : //TODO: IMPROVE THIS FUNCTION!!! MOVE IT TO A COMMON UTIL-FILE
      93            0 : string replace_chars(string& str, char cToR, char cNew)
      94              : {
      95            0 :         char* nStr = new char[str.length() + 1];
      96              :         memcpy(nStr, str.c_str(), str.length());
      97            0 :         nStr[str.length()] = 0;
      98              :         char* tPtr = nStr;
      99            0 :         while(*tPtr)
     100              :         {
     101            0 :                 if(*tPtr == cToR)
     102            0 :                         *tPtr = cNew;
     103            0 :                 tPtr++;
     104              :         }
     105            0 :         string Ret = nStr;
     106            0 :         delete[] nStr;
     107            0 :         return Ret;
     108              : }
     109              : 
     110              : //TODO: IMPROVE THIS FUNCTION!!! MOVE IT TO A COMMON UTIL-FILE
     111            0 : string extract_path(const string& filename)
     112              : {
     113              :         string::size_type idx1 = filename.rfind("/");
     114              :         string::size_type idx2 = filename.rfind("\\");
     115              : 
     116            0 :         if(idx2 < idx1)
     117              :                 idx1 = idx2;
     118            0 :         return filename.substr(0, idx1+1);
     119              : }
     120              : 
     121              : /*
     122              : **
     123              : */
     124              : ////////////////////////////////////////////////////////////////////////////////////////////////
     125              : //      LoaderObj implementation
     126            0 : LoaderObj::~LoaderObj()
     127              : {
     128            0 :         clear();
     129            0 : }
     130              : 
     131            0 : void LoaderObj::clear()
     132              : {
     133            0 :         for(LoaderObj::ObjectIterator iter = m_vObjects.begin(); iter != m_vObjects.end(); iter++)
     134            0 :                 delete (*iter);
     135              :         m_vObjects.clear();
     136            0 : }
     137              : 
     138            0 : bool LoaderObj::load_file(const char* strFilename, bool convertQuadsToTris)
     139              : {
     140            0 :         clear();
     141              : 
     142            0 :         ifstream in(strFilename);
     143            0 :         if(!in)
     144              :                 return false;
     145              : 
     146            0 :         string strObj = "o";
     147            0 :         string strPos = "v";
     148            0 :         string strNorm = "vn";
     149            0 :         string strTex1 = "vt";
     150            0 :         string strFace = "f";
     151            0 :         string strMtrl = "usemtl";
     152            0 :         string strMtrlLib = "mtllib";
     153              : 
     154              :         bool bGotPosition = false;
     155              :         bool bGotTexture = false;
     156              :         bool bGotNormal = false;
     157              : 
     158            0 :         Object* pActiveObject = NULL;
     159              : 
     160              :         string strCommand;
     161              :         char BUFFER[256];
     162            0 :         BUFFER[255] = 0;
     163            0 :         for(uint i = 0; i < 256; ++i)
     164            0 :                 BUFFER[i] = 0;
     165              :         ParameterList   lstParams;
     166              :         ParameterList::iterator PIter;
     167              : 
     168              :         int lineNumber = 0;
     169              : 
     170            0 :         while(!in.eof())
     171              :         {
     172            0 :                 in.getline(BUFFER, 256);
     173            0 :                 ++lineNumber;
     174            0 :                 if(BUFFER[255] != 0)
     175              :                         return false;
     176              : 
     177              : //      files that come from a windows environment always have '\r' at the end of each line.
     178              : //      the following code removes those '\r'. The implementation is far from optimal!!
     179              :                 /*
     180              :                 string tStr(BUFFER);
     181              :                 tStr = replace_chars(tStr, '\r', '\0');
     182              : 
     183              :                 lstParams.clear();
     184              : 
     185              :                 split_parameters(&lstParams, tStr.c_str());
     186              :                 */
     187            0 :                 split_parameters(lstParams, BUFFER, " \r\t");
     188              : 
     189            0 :                 if(lstParams.empty())
     190            0 :                         continue;
     191              : 
     192              :                 strCommand = *lstParams.begin();
     193              :                 lstParams.erase(lstParams.begin());
     194              : 
     195            0 :                 if(strCommand == strObj)
     196              :                 {
     197            0 :                         if(pActiveObject)
     198            0 :                                 m_vObjects.push_back(pActiveObject);
     199              : 
     200            0 :                         pActiveObject = new LoaderObj::Object;
     201            0 :                         pActiveObject->m_strName = *lstParams.begin();
     202            0 :                         pActiveObject->m_iMaterialIndex = -1;
     203              :                 }
     204            0 :                 else if(strCommand == strMtrlLib)
     205              :                 {//     read materials
     206            0 :                         string mtlLib = extract_path(string(strFilename));
     207              :                         mtlLib.append(*lstParams.begin());
     208              : 
     209            0 :                         string newMaterial = "newmtl";
     210            0 :                         string colorDiffuse = "Kd";
     211            0 :                         string textureDiffuse = "map_Kd";
     212            0 :                         string colorAlpha = "d";
     213              : 
     214            0 :                         ifstream mtlIn(mtlLib.c_str());
     215            0 :                         if(!mtlIn)
     216              :                                 continue;
     217              : 
     218              :                         Material* pActMaterial = NULL;
     219            0 :                         while(!mtlIn.eof())
     220              :                         {
     221            0 :                                 mtlIn.getline(BUFFER, 256);
     222            0 :                                 ++lineNumber;
     223            0 :                                 if(BUFFER[255] != 0)
     224              :                                         return false;
     225              : 
     226              :                                 lstParams.clear();
     227            0 :                                 split_parameters(&lstParams, BUFFER);
     228            0 :                                 if(lstParams.empty())
     229            0 :                                         continue;
     230              : 
     231              :                                 strCommand = *lstParams.begin();
     232              :                                 lstParams.erase(lstParams.begin());
     233              : 
     234            0 :                                 if(strCommand == newMaterial)
     235              :                                 {
     236            0 :                                         m_vMaterials.push_back(Material());
     237              :                                         pActMaterial = &m_vMaterials[m_vMaterials.size() - 1];
     238            0 :                                         if(!lstParams.empty())
     239            0 :                                                 pActMaterial->m_strName = *lstParams.begin();
     240              :                                 }
     241            0 :                                 else if(pActMaterial)
     242              :                                 {
     243            0 :                                         if(strCommand == colorDiffuse)
     244              :                                         {
     245            0 :                                                 if(lstParams.size() != 3)
     246            0 :                                                         continue;
     247              :                                                 PIter = lstParams.begin();
     248            0 :                                                 pActMaterial->m_vDiffuse.x() = atof((*PIter).c_str());
     249              :                                                 PIter++;
     250            0 :                                                 pActMaterial->m_vDiffuse.y() = atof((*PIter).c_str());
     251              :                                                 PIter++;
     252            0 :                                                 pActMaterial->m_vDiffuse.z() = atof((*PIter).c_str());
     253              :                                         }
     254            0 :                                         else if(strCommand == colorAlpha)
     255              :                                         {
     256            0 :                                                 if(lstParams.size() != 1)
     257            0 :                                                         continue;
     258              :                                                 PIter = lstParams.begin();
     259            0 :                                                 pActMaterial->m_fAlpha = pActMaterial->m_vDiffuse.w() = atof((*PIter).c_str());
     260              :                                         }
     261            0 :                                         else if(strCommand == textureDiffuse)
     262              :                                         {
     263            0 :                                                 if(lstParams.size() != 1)
     264            0 :                                                         continue;
     265            0 :                                                 pActMaterial->m_strTextureDiffuse = *lstParams.begin();
     266              :                                         }
     267              :                                 }
     268              :                         }
     269            0 :                 }
     270            0 :                 else if(strCommand == strPos)
     271              :                 {
     272              :                         bGotPosition = true;
     273            0 :                         if(lstParams.size() != 3)
     274            0 :                                 continue;
     275              :                         vector3 v;
     276              :                         PIter = lstParams.begin();
     277            0 :                         v.x() = atof((*PIter).c_str());
     278              :                         PIter++;
     279            0 :                         v.y() = atof((*PIter).c_str());
     280              :                         PIter++;
     281            0 :                         v.z() = atof((*PIter).c_str());
     282            0 :                         m_vPoints.push_back(v);
     283              :                 }
     284            0 :                 else if(strCommand == strNorm)
     285              :                 {
     286              :                         bGotNormal = true;
     287              :                 }
     288            0 :                 else if(strCommand == strTex1)
     289              :                 {
     290              :                         bGotTexture = true;
     291            0 :                         if(lstParams.size() < 2)
     292            0 :                                 continue;
     293              :                         vector2 v;
     294              :                         PIter = lstParams.begin();
     295            0 :                         v.x() = atof((*PIter).c_str());
     296              :                         PIter++;
     297            0 :                         v.y() = -atof((*PIter).c_str());
     298            0 :                         m_vTexCoords.push_back(v);
     299              :                 }
     300            0 :                 else if(strCommand == strFace){
     301            0 :                         if(!pActiveObject){
     302            0 :                                 pActiveObject = new LoaderObj::Object;
     303            0 :                                 pActiveObject->m_strName = "default";
     304            0 :                                 pActiveObject->m_iMaterialIndex = -1;
     305              :                         }
     306              : 
     307              :                         PIter = lstParams.begin();
     308              : 
     309            0 :                         if(lstParams.size() == 2)
     310              :                         {
     311            0 :                                 for(; PIter != lstParams.end(); PIter++)
     312              :                                 {
     313            0 :                                         string tStr = replace_chars((*PIter), '/', ' ');
     314              :                                         ParameterList   lstIndexParams;
     315            0 :                                         split_parameters(&lstIndexParams, tStr.c_str());
     316              :                                         uint iCount = 0;
     317            0 :                                         if(bGotPosition && (iCount < lstIndexParams.size()))
     318              :                                         {
     319            0 :                                                 pActiveObject->m_vEdgeList.push_back(atoi(lstIndexParams[iCount].c_str()) - 1);
     320              :                                                 iCount++;
     321              :                                         }
     322            0 :                                 }
     323              :                         }
     324            0 :                         else if(lstParams.size() == 3)
     325              :                         {
     326            0 :                                 for(; PIter != lstParams.end(); PIter++)
     327              :                                 {
     328            0 :                                         string tStr = replace_chars((*PIter), '/', ' ');
     329              :                                         ParameterList   lstIndexParams;
     330            0 :                                         split_parameters(&lstIndexParams, tStr.c_str());
     331              : 
     332              :                                         uint iCount = 0;
     333            0 :                                         if(bGotPosition)
     334              :                                         {
     335            0 :                                                 pActiveObject->m_vTriangleList.push_back(atoi(lstIndexParams[iCount].c_str()) - 1);
     336              :                                                 iCount++;
     337              :                                         }
     338            0 :                                         if(bGotTexture && iCount < lstIndexParams.size())
     339              :                                         {
     340            0 :                                                 pActiveObject->m_vTriangleListTex.push_back(atoi(lstIndexParams[iCount].c_str()) - 1);
     341              :                                                 iCount++;
     342              :                                         }
     343              :                                         if(bGotNormal && iCount < lstIndexParams.size())
     344              :                                         {
     345              :                                                 //pActiveObject->m_vTriangleList.push_back(atoi(lstIndexParams[iCount].c_str()) - 1);
     346              :                                                 iCount++;
     347              :                                         }
     348              : 
     349              : 
     350            0 :                                 }
     351              :                         }
     352            0 :                         else if(lstParams.size() == 4)
     353              :                         {
     354              :                                 unsigned int tInd[4];
     355              :                                 unsigned int tIndTex[4];
     356              : 
     357              :                                 int counter = 0;
     358            0 :                                 for(; PIter != lstParams.end(); PIter++)
     359              :                                 {
     360            0 :                                         string tStr = replace_chars((*PIter), '/', ' ');
     361              :                                         ParameterList   lstIndexParams;
     362            0 :                                         split_parameters(&lstIndexParams, tStr.c_str());
     363            0 :                                         tInd[counter] = atoi((*lstIndexParams.begin()).c_str());
     364              :                                         uint iCount = 0;
     365            0 :                                         if(bGotPosition)
     366              :                                         {
     367            0 :                                                 tInd[counter] = atoi(lstIndexParams[iCount].c_str());
     368              :                                                 iCount++;
     369              :                                         }
     370            0 :                                         if(bGotTexture && iCount < lstIndexParams.size())
     371              :                                         {
     372            0 :                                                 tIndTex[counter] = atoi(lstIndexParams[iCount].c_str());
     373              :                                                 iCount++;
     374              :                                         }
     375              :                                         if(bGotNormal && iCount < lstIndexParams.size())
     376              :                                         {
     377              :                                                 //iIndNorm
     378              :                                                 iCount++;
     379              :                                         }
     380            0 :                                         counter++;
     381            0 :                                 }
     382            0 :                                 if(convertQuadsToTris)
     383              :                                 {
     384            0 :                                         if(bGotPosition)
     385              :                                         {
     386            0 :                                                 pActiveObject->m_vTriangleList.push_back(tInd[0] - 1);
     387            0 :                                                 pActiveObject->m_vTriangleList.push_back(tInd[1] - 1);
     388            0 :                                                 pActiveObject->m_vTriangleList.push_back(tInd[2] - 1);
     389            0 :                                                 pActiveObject->m_vTriangleList.push_back(tInd[0] - 1);
     390            0 :                                                 pActiveObject->m_vTriangleList.push_back(tInd[2] - 1);
     391            0 :                                                 pActiveObject->m_vTriangleList.push_back(tInd[3] - 1);
     392              :                                         }
     393            0 :                                         if(bGotTexture)
     394              :                                         {
     395            0 :                                                 pActiveObject->m_vTriangleListTex.push_back(tIndTex[0] - 1);
     396            0 :                                                 pActiveObject->m_vTriangleListTex.push_back(tIndTex[1] - 1);
     397            0 :                                                 pActiveObject->m_vTriangleListTex.push_back(tIndTex[2] - 1);
     398            0 :                                                 pActiveObject->m_vTriangleListTex.push_back(tIndTex[0] - 1);
     399            0 :                                                 pActiveObject->m_vTriangleListTex.push_back(tIndTex[2] - 1);
     400            0 :                                                 pActiveObject->m_vTriangleListTex.push_back(tIndTex[3] - 1);
     401              :                                         }
     402              :                                 }
     403              :                                 else
     404              :                                 {
     405            0 :                                         if(bGotPosition)
     406              :                                         {
     407            0 :                                                 pActiveObject->m_vQuadList.push_back(tInd[0] - 1);
     408            0 :                                                 pActiveObject->m_vQuadList.push_back(tInd[1] - 1);
     409            0 :                                                 pActiveObject->m_vQuadList.push_back(tInd[2] - 1);
     410            0 :                                                 pActiveObject->m_vQuadList.push_back(tInd[3] - 1);
     411              :                                         }
     412            0 :                                         if(bGotTexture)
     413              :                                         {
     414            0 :                                                 pActiveObject->m_vQuadListTex.push_back(tIndTex[0] - 1);
     415            0 :                                                 pActiveObject->m_vQuadListTex.push_back(tIndTex[1] - 1);
     416            0 :                                                 pActiveObject->m_vQuadListTex.push_back(tIndTex[2] - 1);
     417            0 :                                                 pActiveObject->m_vQuadListTex.push_back(tIndTex[3] - 1);
     418              :                                         }
     419              :                                 }
     420              :                         }
     421              :                         else {
     422            0 :                                 UG_LOG("WARNING: Couldn't read face in line " << lineNumber 
     423              :                                                 << ". Bad number of vertices: " << lstParams.size()
     424              :                                                 << ". Only 3 and 4 supported.\n");
     425              :                         }
     426              :                 }
     427            0 :                 else if(strCommand == strMtrl)
     428              :                 {
     429            0 :                         if(!pActiveObject){
     430            0 :                                 pActiveObject = new LoaderObj::Object;
     431            0 :                                 pActiveObject->m_strName = "default";
     432            0 :                                 pActiveObject->m_iMaterialIndex = -1;
     433              :                         }
     434              : 
     435            0 :                         if(lstParams.empty())
     436              :                         {
     437            0 :                                 pActiveObject->m_strMaterialName = *lstParams.begin();
     438            0 :                                 pActiveObject->m_iMaterialIndex = get_material_index_by_name(pActiveObject->m_strMaterialName.c_str());
     439              :                         }
     440              :                 }
     441              :         }
     442              : 
     443            0 :         if(pActiveObject)
     444            0 :                 m_vObjects.push_back(pActiveObject);
     445              : 
     446              :         return true;
     447            0 : }
     448              : 
     449            0 : int LoaderObj::get_material_index_by_name(const char* name) const
     450              : {
     451              :         int counter = 0;
     452            0 :         for(MaterialVector::const_iterator iter = m_vMaterials.begin(); iter != m_vMaterials.end(); iter++)
     453              :         {
     454            0 :                 if((*iter).m_strName.compare(name) == 0)
     455              :                         return counter;
     456            0 :                 counter++;
     457              :         }
     458              :         return -1;
     459              : }
     460              : 
     461              : }
        

Generated by: LCOV version 2.0-1