BaseModel.cpp
Go to the documentation of this file.
1 #include "BaseModel.h"
2 #include "Parameters.h"
3 //#include <windows.h> // dsy: comment out.
4 //#include "gl\gl.h" // dsy: comment out.
5 //#include "gl\glu.h" // dsy: comment out.
6 #include <float.h>
7 #include <iostream>
8 //#include "gl\glut.h"
9 //#pragma comment(lib, "OPENGL32.LIB") // dsy: comment out.
10 //#pragma comment(lib, "GLU32.LIB") // dsy: comment out.
11 #include <fstream>
12 #include <sstream>
13 #include <algorithm>
14 using namespace std;
15 
16 
18 // Construction/Destruction
20 CBaseModel::CBaseModel(const string& filename) : m_filename(filename)
21 {
22 }
23 /*
24 void CBaseModel::Render() const
25 {
26  glPushMatrix();
27  GLint shadeModel;
28  glGetIntegerv(GL_SHADE_MODEL, &shadeModel);
29  if (shadeModel == GL_SMOOTH)
30  {
31  for (int i = 0; i < GetNumOfFaces(); ++i)
32  {
33  glBegin(GL_POLYGON);
34  for (int j = 0; j < 3; ++j)
35  {
36  const CPoint3D &pt = Vert(Face(i)[j]);
37  if (!m_NormalsToVerts.empty())
38  {
39  const CPoint3D &normal = Normal(Face(i)[j]);
40  glNormal3f((float)normal.x, (float)normal.y, (float)normal.z);
41  }
42  glVertex3f((float)pt.x, (float)pt.y, (float)pt.z);
43  }
44  glEnd();
45  }
46  }
47  else
48  {
49  for (int i = 0; i < GetNumOfFaces(); ++i)
50  {
51  glBegin(GL_POLYGON);
52  CPoint3D normal = VectorCross(Vert(Face(i)[0]), Vert(Face(i)[1]), Vert(Face(i)[2]));
53  normal.Normalize();
54  glNormal3f((float)normal.x, (float)normal.y, (float)normal.z);
55  for (int j = 0; j < 3; ++j)
56  {
57  const CPoint3D &pt = Vert(Face(i)[j]);
58  glVertex3f((float)pt.x, (float)pt.y, (float)pt.z);
59  }
60  glEnd();
61  }
62  }
63 
64  glPopMatrix();
65 }
66 */
68 {
69  if (m_Verts.empty())
70  return;
71  m_NormalsToVerts.resize(m_Verts.size(), CPoint3D(0, 0, 0));
72  CPoint3D center(0, 0, 0);
73  double sumArea(0);
74  CPoint3D sumNormal(0, 0, 0);
75  double deta(0);
76  for (int i = 0; i < (int)m_Faces.size(); ++i)
77  {
78  CPoint3D normal = VectorCross(Vert(Face(i)[0]),
79  Vert(Face(i)[1]),
80  Vert(Face(i)[2]));
81  double area = normal.Len();
82  CPoint3D gravity3 = Vert(Face(i)[0]) + Vert(Face(i)[1]) + Vert(Face(i)[2]);
83  center += area * gravity3;
84  sumArea += area;
85  sumNormal += normal;
86  deta += gravity3 ^ normal;
87  normal.x /= area;
88  normal.y /= area;
89  normal.z /= area;
90  for (int j = 0; j < 3; ++j)
91  {
92  m_NormalsToVerts[Face(i)[j]] += normal;
93  }
94  }
95  center /= sumArea * 3;
96  deta -= 3 * (center ^ sumNormal);
97  if (true)//deta > 0)
98  {
99  for (int i = 0; i < GetNumOfVerts(); ++i)
100  {
101  if (fabs(m_NormalsToVerts[i].x)
102  + fabs(m_NormalsToVerts[i].y)
103  + fabs(m_NormalsToVerts[i].z) >= FLT_EPSILON)
104  {
105  m_NormalsToVerts[i].Normalize();
106  }
107  }
108  }
109  else
110  {
111  for (int i = 0; i < GetNumOfFaces(); ++i)
112  {
113  int temp = m_Faces[i][0];
114  m_Faces[i][0] = m_Faces[i][1];
115  m_Faces[i][1] = temp;
116  }
117  for (int i = 0; i < GetNumOfVerts(); ++i)
118  {
119  if (fabs(m_NormalsToVerts[i].x)
120  + fabs(m_NormalsToVerts[i].y)
121  + fabs(m_NormalsToVerts[i].z) >= FLT_EPSILON)
122  {
123  double len = m_NormalsToVerts[i].Len();
124  m_NormalsToVerts[i].x /= -len;
125  m_NormalsToVerts[i].y /= -len;
126  m_NormalsToVerts[i].z /= -len;
127  }
128  }
129  }
130 
131  CPoint3D ptUp(m_Verts[0]);
132  CPoint3D ptDown(m_Verts[0]);
133  for (int i = 1; i < GetNumOfVerts(); ++i)
134  {
135  if (m_Verts[i].x > ptUp.x)
136  ptUp.x = m_Verts[i].x;
137  else if (m_Verts[i].x < ptDown.x)
138  ptDown.x = m_Verts[i].x;
139  if (m_Verts[i].y > ptUp.y)
140  ptUp.y = m_Verts[i].y;
141  else if (m_Verts[i].y < ptDown.y)
142  ptDown.y = m_Verts[i].y;
143  if (m_Verts[i].z > ptUp.z)
144  ptUp.z = m_Verts[i].z;
145  else if (m_Verts[i].z < ptDown.z)
146  ptDown.z = m_Verts[i].z;
147  }
148 
149  double maxEdgeLenOfBoundingBox = -1;
150  if (ptUp.x - ptDown.x > maxEdgeLenOfBoundingBox)
151  maxEdgeLenOfBoundingBox = ptUp.x - ptDown.x;
152  if (ptUp.y - ptDown.y > maxEdgeLenOfBoundingBox)
153  maxEdgeLenOfBoundingBox = ptUp.y - ptDown.y;
154  if (ptUp.z - ptDown.z > maxEdgeLenOfBoundingBox)
155  maxEdgeLenOfBoundingBox = ptUp.z - ptDown.z;
156  m_scale = maxEdgeLenOfBoundingBox / 2;
157  //m_center = center;
158  //m_ptUp = ptUp;
159  //m_ptDown = ptDown;
160 }
161 
163 {
166 }
167 
168 
170 {
171  int pos = (int)m_filename.size() - 1;
172  while (pos >= 0)
173  {
174  if (m_filename[pos] == '\\')
175  break;
176  --pos;
177  }
178  ++pos;
179  int pos2 = (int)m_filename.size() - 1;
180  while (pos2 >= 0)
181  {
182  if (m_filename[pos2] == '.')
183  break;
184  --pos2;
185  }
186  string str(m_filename.substr(pos, pos2 - pos));
187  return str;
188 }
189 
191 {
192  int pos = (int)m_filename.size() - 1;
193  while (pos >= 0)
194  {
195  if (m_filename[pos] == '\\')
196  break;
197  --pos;
198  }
199  ++pos;
200  string str(m_filename.substr(pos));
201  return str;
202 }
203 
205 {
206  return m_filename;
207 }
208 
209 void CBaseModel::ReadObjFile(const string& filename)
210 {
211  ifstream in(filename.c_str());
212  if (in.fail())
213  {
214  throw "fail to read file";
215  }
216  char buf[256];
217  while (in.getline(buf, sizeof buf))
218  {
219  istringstream line(buf);
220  string word;
221  line >> word;
222  if (word == "v")
223  {
224  CPoint3D pt;
225  line >> pt.x;
226  line >> pt.y;
227  line >> pt.z;
228 
229  m_Verts.push_back(pt);
230  }
231  else if (word == "f")
232  {
233  CFace face;
234  int tmp;
235  vector<int> polygon;
236  polygon.reserve(4);
237  while (line >> tmp)
238  {
239  polygon.push_back(tmp);
240  char tmpBuf[256];
241  line.getline(tmpBuf, sizeof tmpBuf, ' ');
242  }
243  for (int j = 1; j < (int)polygon.size() - 1; ++j)
244  {
245  face[0] = polygon[0] - 1;
246  face[1] = polygon[j] - 1;
247  face[2] = polygon[j + 1] - 1;
248  m_Faces.push_back(face);
249  }
250  }
251  else
252  {
253  continue;
254  }
255  }
256  //m_Verts.swap(vector<CPoint3D>(m_Verts)); // dsy: comment out.
257  //m_Faces.swap(vector<CFace>(m_Faces)); // dsy: comment out.
258  in.close();
259 }
260 
261 void CBaseModel::ReadFile(const string& filename)
262 {
263  int nDot = (int)filename.rfind('.');
264  if (nDot == -1)
265  {
266  throw "File name doesn't contain a dot!";
267  }
268  string extension = filename.substr(nDot + 1);
269 
270  if (extension == "obj")
271  {
272  ReadObjFile(filename);
273  }
274  else if (extension == "off")
275  {
276  ReadOffFile(filename);
277  }
278  else if (extension == "m")
279  {
280  ReadMFile(filename);
281  }
282  else
283  {
284  throw "This format can't be handled!";
285  }
286 }
287 
288 void CBaseModel::ReadOffFile(const string& filename)
289 {
290  ifstream in(filename.c_str());
291  if (in.fail())
292  {
293  throw "fail to read file";
294  }
295  char buf[256];
296  in.getline(buf, sizeof buf);
297  int vertNum, faceNum, edgeNum;
298  in >> vertNum >> faceNum >> edgeNum;
299 
300  for (int i = 0; i < vertNum; ++i)
301  {
302  CPoint3D pt;
303  in >> pt.x;
304  in >> pt.y;
305  in >> pt.z;
306  m_Verts.push_back(pt);
307  }
308  //m_Verts.swap(vector<CPoint3D>(m_Verts)); // dsy: comment out.
309 
310  int degree;
311  while (in >> degree)
312  {
313  int first, second;
314  in >> first >> second;
315 
316  for (int i = 0; i < degree - 2; ++i)
317  {
318  CFace f;
319  f[0] = first;
320  f[1] = second;
321  in >> f[2];
322  m_Faces.push_back(f);
323  second = f[2];
324  }
325  }
326 
327  in.close();
328  //m_Faces.swap(vector<CFace>(m_Faces)); // dsy: comment out.
329 }
330 
331 void CBaseModel::ReadMFile(const string& filename)
332 {
333  ifstream in(filename.c_str());
334  if (in.fail())
335  {
336  throw "fail to read file";
337  }
338  char buf[256];
339  while (in.getline(buf, sizeof buf))
340  {
341  istringstream line(buf);
342  if (buf[0] == '#')
343  continue;
344  string word;
345  line >> word;
346  if (word == "Vertex")
347  {
348  int tmp;
349  line >> tmp;
350  CPoint3D pt;
351  line >> pt.x;
352  line >> pt.y;
353  line >> pt.z;
354 
355  m_Verts.push_back(pt);
356  }
357  else if (word == "Face")
358  {
359  CFace face;
360  int tmp;
361  line >> tmp;
362  vector<int> polygon;
363  polygon.reserve(4);
364  while (line >> tmp)
365  {
366  polygon.push_back(tmp);
367  }
368  for (int j = 1; j < (int)polygon.size() - 1; ++j)
369  {
370  face[0] = polygon[0] - 1;
371  face[1] = polygon[j] - 1;
372  face[2] = polygon[j + 1] - 1;
373  m_Faces.push_back(face);
374  }
375  }
376  else
377  {
378  continue;
379  }
380  }
381  //m_Verts.swap(vector<CPoint3D>(m_Verts)); // dsy: comment out.
382  //m_Faces.swap(vector<CFace>(m_Faces)); // dsy: comment out.
383  in.close();
384 }
385 
386 
387 void CBaseModel::SaveMFile(const string& filename) const
388 {
389  ofstream outFile(filename.c_str());
390  for (int i = 0; i < (int)GetNumOfVerts(); ++i)
391  {
392  outFile << "Vertex " << i + 1 << " " << Vert(i).x << " " << Vert(i).y << " " << Vert(i).z << endl;
393  }
394  int cnt(0);
395  for (int i = 0; i < (int)GetNumOfFaces(); ++i)
396  {
397  if (m_UselessFaces.find(i) != m_UselessFaces.end())
398  continue;
399  outFile <<"Face " << ++cnt << " " << Face(i)[0] + 1 << " " << Face(i)[1] + 1 << " " << Face(i)[2] + 1 << endl;
400  }
401  outFile.close();
402 }
403 
404 void CBaseModel::SaveOffFile(const string& filename) const
405 {
406  ofstream outFile(filename.c_str());
407  outFile << "OFF" << endl;
408  outFile << GetNumOfVerts() << " " << GetNumOfFaces() << " " << 0 << endl;
409  for (int i = 0; i < (int)GetNumOfVerts(); ++i)
410  {
411  outFile << Vert(i).x << " " << Vert(i).y << " " << Vert(i).z << endl;
412  }
413  for (int i = 0; i < (int)GetNumOfFaces(); ++i)
414  {
415  if (m_UselessFaces.find(i) != m_UselessFaces.end())
416  continue;
417  outFile << 3 << " " << Face(i)[0]<< " " << Face(i)[1] << " " << Face(i)[2] << endl;
418  }
419  outFile.close();
420 }
421 
422 void CBaseModel::SaveObjFile(const string& filename) const
423 {
424  ofstream outFile(filename.c_str());
425  outFile << "g " << filename.substr(filename.rfind("\\") + 1, filename.rfind('.') - filename.rfind("\\") - 1) << endl;
426  for (int i = 0; i < (int)GetNumOfVerts(); ++i)
427  {
428  outFile << "v " << Vert(i).x << " " << Vert(i).y << " " << Vert(i).z << endl;
429  }
430  for (int i = 0; i < (int)GetNumOfFaces(); ++i)
431  {
432  if (m_UselessFaces.find(i) != m_UselessFaces.end())
433  continue;
434  outFile << "f " << Face(i)[0] + 1 << " " << Face(i)[1] + 1<< " " << Face(i)[2] + 1<< endl;
435  }
436  outFile.close();
437 }
438 
439 void CBaseModel::SaveScalarFieldObjFile(const vector<double>& vals, const string& filename) const
440 {
441  ofstream outFile(filename.c_str());
442  outFile << "g " << filename.substr(filename.rfind("\\") + 1, filename.rfind('.') - filename.rfind("\\") - 1) << endl;
443  outFile << "# maxDis: " << *max_element(vals.begin(), vals.end()) << endl;
444  for (int i = 0; i < (int)GetNumOfVerts(); ++i)
445  {
446  outFile << "v " << Vert(i).x << " " << Vert(i).y << " " << Vert(i).z << endl;
447  }
448  for (int i = 0; i < (int)vals.size(); ++i)
449  {
450  outFile << "vt " << vals[i] << " " << 0 << endl;
451  }
452  for (int i = 0; i < (int)GetNumOfFaces(); ++i)
453  {
454  if (m_UselessFaces.find(i) != m_UselessFaces.end())
455  continue;
456  outFile << "f " << Face(i)[0] + 1 << "/" << Face(i)[0] + 1
457  << " " << Face(i)[1] + 1 << "/" << Face(i)[1] + 1
458  << " " << Face(i)[2] + 1 << "/" << Face(i)[2] + 1 << endl;
459  }
460  outFile.close();
461 }
462 
463 void CBaseModel::SaveScalarFieldObjFile(const vector<double>& vals, const string& comments, const string& filename) const
464 {
465  ofstream outFile(filename.c_str());
466  outFile << "g " << filename.substr(filename.rfind("\\") + 1, filename.rfind('.') - filename.rfind("\\") - 1) << endl;
467  outFile << comments << endl;
468  for (int i = 0; i < (int)GetNumOfVerts(); ++i)
469  {
470  outFile << "v " << Vert(i).x << " " << Vert(i).y << " " << Vert(i).z << endl;
471  }
472  for (int i = 0; i < (int)vals.size(); ++i)
473  {
474  outFile << "vt " << vals[i] << " " << 0 << endl;
475  }
476  for (int i = 0; i < (int)GetNumOfFaces(); ++i)
477  {
478  if (m_UselessFaces.find(i) != m_UselessFaces.end())
479  continue;
480  outFile << "f " << Face(i)[0] + 1 << "/" << Face(i)[0] + 1
481  << " " << Face(i)[1] + 1 << "/" << Face(i)[1] + 1
482  << " " << Face(i)[2] + 1 << "/" << Face(i)[2] + 1 << endl;
483  }
484  outFile.close();
485 }
486 
487 void CBaseModel::SaveScalarFieldObjFile(const vector<double>& vals, double maxV, const string& filename) const
488 {
489  ofstream outFile(filename.c_str());
490  outFile << "g " << filename.substr(filename.rfind("\\") + 1, filename.rfind('.') - filename.rfind("\\") - 1) << endl;
491  outFile << "# maxValue = " << *max_element(vals.begin(), vals.end()) / maxV << endl;
492 
493  for (int i = 0; i < (int)GetNumOfVerts(); ++i)
494  {
495  outFile << "v " << Vert(i).x << " " << Vert(i).y << " " << Vert(i).z << endl;
496  }
497  for (int i = 0; i < (int)vals.size(); ++i)
498  {
499  outFile << "vt " << vals[i] / maxV << " " << 0 << endl;
500  }
501  for (int i = 0; i < (int)GetNumOfFaces(); ++i)
502  {
503  if (m_UselessFaces.find(i) != m_UselessFaces.end())
504  continue;
505  outFile << "f " << Face(i)[0] + 1 << "/" << Face(i)[0] + 1
506  << " " << Face(i)[1] + 1 << "/" << Face(i)[1] + 1
507  << " " << Face(i)[2] + 1 << "/" << Face(i)[2] + 1 << endl;
508  }
509  outFile.close();
510 }
511 
512 void CBaseModel::SavePamametrizationObjFile(const vector<pair<double, double>>& uvs, const string& filename) const
513 {
514  ofstream outFile(filename.c_str());
515  outFile << "g " << filename.substr(filename.rfind("\\") + 1, filename.rfind('.') - filename.rfind("\\") - 1) << endl;
516  for (int i = 0; i < (int)GetNumOfVerts(); ++i)
517  {
518  outFile << "v " << Vert(i).x << " " << Vert(i).y << " " << Vert(i).z << endl;
519  }
520  for (int i = 0; i < (int)uvs.size(); ++i)
521  {
522  outFile << "vt " << uvs[i].first << " " << uvs[i].second << endl;
523  }
524  for (int i = 0; i < (int)GetNumOfFaces(); ++i)
525  {
526  if (m_UselessFaces.find(i) != m_UselessFaces.end())
527  continue;
528  outFile << "f " << Face(i)[0] + 1 << "/" << Face(i)[0] + 1
529  << " " << Face(i)[1] + 1 << "/" << Face(i)[1] + 1
530  << " " << Face(i)[2] + 1 << "/" << Face(i)[2] + 1 << endl;
531  }
532  outFile.close();
533 }
534 
535 void CBaseModel::PrintInfo(ostream& out) const
536 {
537  out << "Model info is as follows.\n";
538  out << "Name: " << GetFileShortName() << endl;
539  out << "VertNum = " << GetNumOfVerts() << endl;
540  out << "FaceNum = " << GetNumOfFaces() << endl;
541  out << "Scale = " << m_scale << endl;
542 }
543 
544 CPoint3D CBaseModel::GetShiftVertex(int indexOfVert) const
545 {
546  return Vert(indexOfVert) + Normal(indexOfVert) * RateOfNormalShift * GetScale();
547 }
548 
549 //CPoint3D CBaseModel::ShiftVertex(int indexOfVert, double epsilon) const
550 //{
551 // return Vert(indexOfVert) + Normal(indexOfVert) * epsilon;
552 //}
553 
554 int CBaseModel::GetVertexID(const CPoint3D& pt) const
555 {
556  double dis = DBL_MAX;
557  int id;
558  for (int i = 0; i < GetNumOfVerts(); ++i)
559  {
560  if ((Vert(i) - pt).Len() < dis)
561  {
562  id = i;
563  dis = (Vert(id)-pt).Len();
564  }
565  }
566  return id;
567 }
568 
569 string CBaseModel::GetComments(const char* filename)
570 {
571  ifstream in(filename);
572  char buf[256];
573  string result;
574  while (in.getline(buf, sizeof buf))
575  {
576  if (buf[0] == '#')
577  {
578  result += buf;
579  result += "\n";
580  }
581  }
582  in.close();
583  return result;
584 }
585 
586 vector<double> CBaseModel::GetScalarField(string filename)
587 {
588  vector<double> scalarField;
589  ifstream in(filename);
590  char buf[256];
591  while (in.getline(buf, sizeof buf))
592  {
593  istringstream line(buf);
594  string word;
595  line >> word;
596  if (word == "vt")
597  {
598  double value;
599  line >> value;
600  scalarField.push_back(value);
601  }
602  }
603 
604  in.close();
605  return scalarField;
606 }
607 
608 void CBaseModel::SetFaces(const vector<CBaseModel::CFace>& faces)
609 {
610  m_Faces = faces;
611 }
612 
613 const vector<CBaseModel::CFace>& CBaseModel::GetFaces() const
614 {
615  return m_Faces;
616 }
void ReadOffFile(const string &filename)
Definition: BaseModel.cpp:288
static vector< double > GetScalarField(string filename)
Definition: BaseModel.cpp:586
virtual void LoadModel()
Definition: BaseModel.cpp:162
string GetFileFullName() const
Definition: BaseModel.cpp:204
vector< CPoint3D > m_Verts
Definition: BaseModel.h:38
double x
Definition: Point3D.h:14
string GetFileShortName() const
Definition: BaseModel.cpp:190
f
double GetScale() const
Definition: BaseModel.h:75
void SaveObjFile(const string &filename) const
Definition: BaseModel.cpp:422
int GetNumOfFaces() const
Definition: BaseModel.h:85
string m_filename
Definition: BaseModel.h:42
CPoint3D VectorCross(const CPoint3D &pt1, const CPoint3D &pt2, const CPoint3D &pt3)
Definition: Point3D.cpp:43
string GetFileShortNameWithoutExtension() const
Definition: BaseModel.cpp:169
double y
Definition: Point3D.h:14
void SaveOffFile(const string &filename) const
Definition: BaseModel.cpp:404
double Len() const
Definition: Point3D.h:87
int GetVertexID(const CPoint3D &pt) const
Definition: BaseModel.cpp:554
void ReadMFile(const string &filename)
Definition: BaseModel.cpp:331
const CPoint3D & Normal(int vertIndex) const
Definition: BaseModel.h:95
vector< CFace > m_Faces
Definition: BaseModel.h:37
static string GetComments(const char *filename)
Definition: BaseModel.cpp:569
int GetNumOfVerts() const
Definition: BaseModel.h:80
const vector< CBaseModel::CFace > & GetFaces() const
Definition: BaseModel.cpp:613
void SaveMFile(const string &filename) const
Definition: BaseModel.cpp:387
void SetFaces(const vector< CBaseModel::CFace > &faces)
Definition: BaseModel.cpp:608
const double RateOfNormalShift
Definition: Parameters.h:1
const CPoint3D & Vert(int vertIndex) const
Definition: BaseModel.h:90
void ReadObjFile(const string &filename)
Definition: BaseModel.cpp:209
void SaveScalarFieldObjFile(const vector< double > &vals, const string &filename) const
Definition: BaseModel.cpp:439
vector< CPoint3D > m_NormalsToVerts
Definition: BaseModel.h:40
CPoint3D GetShiftVertex(int indexOfVert) const
Definition: BaseModel.cpp:544
void SavePamametrizationObjFile(const vector< pair< double, double >> &uvs, const string &filename) const
Definition: BaseModel.cpp:512
const CFace & Face(int faceIndex) const
Definition: BaseModel.h:100
set< int > m_UselessFaces
Definition: BaseModel.h:41
void ReadFile(const string &filename)
Definition: BaseModel.cpp:261
double z
Definition: Point3D.h:14
void ComputeScaleAndNormals()
Definition: BaseModel.cpp:67
CBaseModel(const string &filename)
Definition: BaseModel.cpp:20
double m_scale
Definition: BaseModel.h:43
virtual void PrintInfo(ostream &out) const
Definition: BaseModel.cpp:535


co_scan
Author(s):
autogenerated on Mon Feb 28 2022 23:00:39