Developer documentation | Axl-2.5.1

axlMeshReader.cpp
Go to the documentation of this file.
1 /* axlMeshReader.cpp ---
2  *
3  * Author: Meriadeg Perrinel
4  * Copyright (C) 2008-2011 - Meriadeg Perrinel, Inria.
5  * Created: Wed Sep 21 11:36:52 2011 (+0200)
6  * Version: $Id$
7  * Last-Updated: Wed Sep 21 12:11:29 2011 (+0200)
8  * By: Meriadeg Perrinel
9  * Update #: 88
10  */
11 
12 /* Commentary:
13  *
14  */
15 
16 /* Change log:
17  *
18  */
19 
20 #include "axlMeshReader.h"
21 
22 #include <axlCore/axlPoint.h>
23 #include <axlCore/axlMesh.h>
26 
27 #include <dtkCoreSupport/dtkAbstractData.h>
28 #include <dtkCoreSupport/dtkAbstractDataFactory.h>
31 
32 // /////////////////////////////////////////////////////////////////
33 // axlMeshReader
34 // /////////////////////////////////////////////////////////////////
35 
37 {
38  this->setObjectName(this->description());
39 }
40 
42 {
43 
44 }
45 
46 QString axlMeshReader::identifier(void) const
47 {
48  return "axlMeshReader";
49 }
50 
51 QString axlMeshReader::description(void) const
52 {
53  return "axlMeshReader";
54 }
55 
56 QStringList axlMeshReader::handled(void) const
57 {
58  return QStringList() << "axlMesh";
59 }
60 
62 {
63  return dtkAbstractDataFactory::instance()->registerDataReaderType("axlMeshReader", QStringList(), createaxlMeshReader);
64 }
65 
66 bool axlMeshReader::accept(const QDomNode& node)
67 {
68  QDomElement element = node.toElement();
69 
70  if(element.tagName() != "mesh")
71  return false;
72 
73  if(!hasChildNode(element, "count"))
74  return false;
75 
76  if(!hasChildNode(element, "points"))
77  return false;
78 
79  //only off works for the moment
80  // if(element.attribute("type") != "off")
81  // return false;
82 
83  return true;
84 }
85 
86 bool axlMeshReader::reject(const QDomNode& node)
87 {
88  return !this->accept(node);
89 }
90 
91 axlAbstractData *axlMeshReader::read(const QDomNode& node)
92 {
93  QDomElement element = node.toElement();
94 
95  axlMesh *mesh = new axlMesh;
96 
97  // mesh name
98  QString name = element.attribute("name");
99  if(!name.isEmpty())
100  {
101  mesh->setObjectName(name);
102  }
103  // mesh Color
104  QString color = element.attribute("color");
105  if(!color.isEmpty())
106  {
107  QStringList colorList = color.split(" ");
108  if(colorList.size() > 2) // rgb components
109  mesh->setColor(QColor(colorList.at(0).toInt(), colorList.at(1).toInt(), colorList.at(2).toInt()));
110  if(colorList.size() > 3) // opacity
111  mesh->setOpacity(colorList.at(3).toDouble());
112  }
113 
114  // mesh shader
115  QString shader = element.attribute("shader");
116  QString dirShader;
117  if(!shader.isEmpty())
118  {
119  // try to read from axelShader.qrc
120  dirShader = ":axlShader/shader/"+shader;
121  if(!QFile::exists(dirShader))
122  {
123  QSettings settings("inria", "dtk");
124  QString defaultPath;
125  settings.beginGroup("shader");
126  dirShader = settings.value("path", defaultPath).toString();
127  // dirShader = this->file().left(this->file().lastIndexOf("axel-data") + 9); // to Remove later
128  dirShader.append("/"+shader);
129  }
130  mesh->setShader(dirShader);
131  }
132 
133  // mesh size
134  QString size = element.attribute("size");
135  if(!size.isEmpty())
136  mesh->setSize(size.toFloat());
137 
138 
139  // Count
140  QDomNodeList nodelist_count = element.elementsByTagName("count") ;
141  QDomElement count = nodelist_count.item(0).toElement();
142  QString *text_count = new QString(count.text());
143  QTextStream in(text_count);
144 
145  int vertexCount = 0;
146  int edgeCount = 0;
147  int faceCount = 0;
148 
149  in.skipWhiteSpace();
150  in >> vertexCount;
151  if(!in.atEnd()){
152  in.skipWhiteSpace();
153  in >> edgeCount;
154  }
155  if(!in.atEnd()) {
156  in.skipWhiteSpace();
157  in >> faceCount;
158  }
159 
160  delete text_count;
161 
162  // Points
163  double vx = 0.0;
164  double vy = 0.0;
165  double vz = 0.0;
166  int r = 255;
167  int g = 0;
168  int b = 0;
169 
170  if(vertexCount>0){
171 
172  QDomNodeList nodelist_points = element.elementsByTagName("points") ;
173  QDomElement points = nodelist_points.item(0).toElement();
174 
175  QString *text_points = new QString(points.text());
176  QTextStream in_points(text_points);
177 
178  QString color = points.attribute("color");
179  if(color == "rgb")
180  mesh->color_used()=true;
181 
182  for(int i = 0 ; i < vertexCount ; i++)
183  {
184  in_points.skipWhiteSpace();
185  in_points >> vx;
186  in_points.skipWhiteSpace();
187  in_points >> vy;
188  in_points.skipWhiteSpace();
189  in_points >> vz;
190  mesh->push_back_vertex(vx, vy, vz);
191 
192  if (mesh->color_used()) {
193  in_points.skipWhiteSpace();
194  in_points >> r;
195  in_points.skipWhiteSpace();
196  in_points >> g;
197  in_points.skipWhiteSpace();
198  in_points >> b;
199  mesh->push_back_color(r, g, b);
200  }
201  }
202 
203  delete text_points;
204  }
205 
206 
207  //colors
208  QDomNodeList nodelist_colors = element.elementsByTagName("colors") ;
209  QString *text_colors;
210  if(nodelist_colors.size()>0 && !mesh->color_used()) {
211  text_colors = new QString(nodelist_colors.item(0).toElement().text());
212 
213  QTextStream in_colors(text_colors);
214 
215  for(int i = 0 ; i < vertexCount ; i++)
216  {
217  in_colors.skipWhiteSpace();
218  in_colors >> r;
219  in_colors.skipWhiteSpace();
220  in_colors >> g;
221  in_colors.skipWhiteSpace();
222  in_colors >> b;
223  mesh->push_back_color(r, g, b);
224  }
225  delete text_colors;
226  }
227 
228 
229  // Normals
230  QDomNodeList nodelist_normals = element.elementsByTagName("normals") ;
231  if(nodelist_normals.size()>0) {
232  QString *text_normals = new QString(nodelist_normals.item(0).toElement().text());
233  QTextStream in_normals(text_normals);
234 
235  mesh->normal_used()=true;
236 
237  for(int i = 0 ; i < vertexCount ; i++)
238  {
239  in_normals.skipWhiteSpace();
240  in_normals >> vx;
241  in_normals.skipWhiteSpace();
242  in_normals >> vy;
243  in_normals.skipWhiteSpace();
244  in_normals >> vz;
245  mesh->push_back_normal(vx, vy, vz);
246  }
247 
248  delete text_normals;
249  }
250 
251  // //fields
252  // QDomNodeList nodelist_fields = element.elementsByTagName("field") ;
253  // int numOccurence = 1;
254  // for(int e = 0; e < nodelist_fields.count(); e++)
255  // {
256  // axlAbstractFieldDiscrete *field = dynamic_cast<axlAbstractFieldDiscrete *>(dtkAbstractDataFactory::instance()->create("axlFieldDiscrete"));
257 
258  // QDomElement CurrentNodeElement = nodelist_fields.item(e).toElement();
259 
260  // // Name
261  // QString fieldName = CurrentNodeElement.attribute("name");
262 
263  // if(fieldName.isEmpty()){
264  // fieldName = "field";
265  // fieldName.append(QString::number(numOccurence));
266  // numOccurence++;
267  // }
268 
269 
270  // bool fieldWithSameNameExit = false;
271  // foreach(axlAbstractField *field, mesh->fields() )
272  // if(field->name().toLower() == fieldName.toLower())
273  // fieldWithSameNameExit = true;
274 
275 
276  // if(fieldWithSameNameExit)
277  // {
278  // qDebug()<< "Sorry, but you put two Fields with same name. The second one are not accepted";
279  // delete field; // free memory
280  // }
281  // else
282  // {
283  // // Type
284  // QString fieldType= CurrentNodeElement.attribute("type");
285  // if(fieldType.toLower() == "int")
286  // field->setType(axlAbstractFieldDiscrete::Int);
287  // else if (fieldType.toLower() == "float")
288  // field->setType(axlAbstractFieldDiscrete::Float);
289  // else if(fieldType.toLower() == "double")
290  // field->setType(axlAbstractFieldDiscrete::Double);
291  // else
292  // {
293  // qDebug()<<mesh->name()<< "havn't accepted Type";
294  // break;
295  // }
296 
297  // // Kind
298  // QString fieldKind = CurrentNodeElement.attribute("kind");
299  // if(fieldKind.toLower() == "scalar")
300  // field->setKind(axlAbstractFieldDiscrete::Scalar);
301  // else if (fieldKind.toLower() == "vector")
302  // field->setKind(axlAbstractFieldDiscrete::Vector);
303  // else if(fieldKind.toLower() == "tensor")
304  // field->setKind(axlAbstractFieldDiscrete::Tensor);
305  // else
306  // {
307  // qDebug()<<mesh->name()<< "havn't accepted kind";
308  // break;
309  // }
310 
311  // // Support
312  // QString fieldSupport = CurrentNodeElement.attribute("support");
313  // if(fieldSupport.toLower() == "point")
314  // field->setSupport(axlAbstractFieldDiscrete::Point);
315  // else if (fieldSupport.toLower() == "cell")
316  // field->setSupport(axlAbstractFieldDiscrete::Cell);
317  // else if(fieldSupport.toLower() == "custom")
318  // field->setSupport(axlAbstractFieldDiscrete::Custom);
319  // else
320  // {
321  // qDebug()<<mesh->name()<< "havn't accepted Support";
322  // break;
323  // }
324 
325  // field->setObjectName(fieldName);
326 
327 
328  // QString *text_fields;
329  // if(nodelist_fields.size()>0)
330  // {
331  // //Field Values reading
332  // field->setSize(vertexCount);
333  // text_fields = new QString(CurrentNodeElement.text());
334 
335  // QTextStream in_fields(text_fields);
336 
337  // if(fieldKind.toLower() == "scalar")
338  // {
339  // for(int i = 0 ; i < vertexCount ; i++)
340  // {
341  // in_fields.skipWhiteSpace();
342  // in_fields >> s;
343  // field->setScalar(i, s);
344  // }
345  // }
346  // else if(fieldKind.toLower() == "vector")
347  // {
348  // for(int i = 0 ; i < vertexCount ; i++)
349  // {
350  // in_fields.skipWhiteSpace();
351  // in_fields >> vx;
352  // in_fields.skipWhiteSpace();
353  // in_fields >> vy;
354  // in_fields.skipWhiteSpace();
355  // in_fields >> vz;
356  // field->setVector(i, vx, vy, vy);
357  // }
358  // }
359 
360  // mesh->addField(field);
361  // field->update();
362 
363  // delete text_fields;
364 
365  // }
366  // }
367  // }// End Fields
368 
369  //if there are some field, read them thanks to the factory.
370  QDomNodeList nodeListField = element.elementsByTagName("field");
371  if(!nodeListField.isEmpty()){
372  for(int i =0; i < nodeListField.size(); i++){
373  QDomElement fieldElement = nodeListField.at(i).toElement();
374  QString fieldType = fieldElement.attribute("type");
375  if(!fieldType.isEmpty()){
376  axlAbstractDataReader *field_reader = dynamic_cast<axlAbstractDataReader *>(axlFieldReadersFactory::instance()->create(fieldType));
377  if(field_reader){
378  axlAbstractField * fieldToAdd = dynamic_cast<axlAbstractField *>(field_reader->read(fieldElement));
379 
380  if(fieldToAdd){
381  QString newName = mesh->changeFieldName(fieldToAdd->name());
382  fieldToAdd->setObjectName(newName);
383  mesh->addField(fieldToAdd);
384  }
385  }else{
386  qDebug() << Q_FUNC_INFO << "no reader available";
387  }
388  }
389  }
390  }
391 
392  // Edges
393  if(edgeCount>0) {
394 
395  QDomNodeList nodelist_edges = element.elementsByTagName("edges") ;
396  if (nodelist_edges.size()==0) {
397  dtkWarn() <<"Error in mesh format: no edge but edgeCount>0";
398  return NULL;
399  }
400 
401  QString *text_edges = new QString(nodelist_edges.item(0).toElement().text());
402  QTextStream in_edges(text_edges);
403 
404  int l0, e1;
405  for(int i = 0 ; i < edgeCount ; i++)
406  {
407  in_edges.skipWhiteSpace();
408  in_edges >> l0;
409 
410  axlMesh::Edge newEdge;
411  for(int j=0; j< l0; j++) {
412  in_edges.skipWhiteSpace();
413  in_edges >> e1;
414  newEdge << e1;
415  }
416  mesh->push_back_edge(newEdge);
417  }
418 
419  delete text_edges;
420  }
421 
423  if(faceCount>0) {
424 
425  QDomNodeList nodelist_faces = element.elementsByTagName("faces") ;
426  if (nodelist_faces.size()==0) {
427  dtkWarn() <<"Error in mesh format: no face but faceCount>0";
428  return NULL;
429  }
430 
431  QString *text_faces = new QString(nodelist_faces.item(0).toElement().text());
432  QTextStream in_faces(text_faces);
433 
434  QVector<int> currentFace;
435  int currentFaceSize = 0;
436  int currentFaceIndex = 0;
437  for(int i = 0 ; i < faceCount ; i++)
438  {
439  currentFace.clear();
440  in_faces.skipWhiteSpace();
441  in_faces >> currentFaceSize;
442 
443  // current face reading
444  for(int j = 0 ; j < currentFaceSize ; j++)
445  {
446  in_faces.skipWhiteSpace();
447  in_faces >> currentFaceIndex;
448  currentFace << currentFaceIndex;
449  }
450  in_faces.readLine(75);
451  mesh->push_back_face(currentFace);
452  }
453 
454  delete text_faces;
455  }
456 
457  mesh->face_show() = false;
458  mesh->edge_show() = false;
459  mesh->vertex_show() = false;
460 
461  if(mesh->face_count() >0)
462  {
463  mesh->face_show() = true;
464  // mesh->edge_show() = false;
465  // mesh->vertex_show() = false;
466  }
467 
468  if(mesh->edge_count() != 0)
469  {
470  // mesh->face_show() = false;
471  mesh->edge_show() = true;
472  // mesh->vertex_show() = false;
473  }
474 
475  if(mesh->vertex_count() > 0 && mesh->edge_count() ==0 && mesh->face_count() ==0 )
476  {
477  //mesh->face_show() = false;
478  //mesh->edge_show() = false;
479  mesh->vertex_show() = true;
480  }
481  return mesh;
482 }
483 
484 dtkAbstractDataReader *createaxlMeshReader(void)
485 {
486  return new axlMeshReader;
487 }
int face_count(void) const
Definition: axlMesh.cpp:138
axlAbstractData * read(const QDomNode &node)
bool vertex_show(void) const
Definition: axlMesh.cpp:159
void push_back_edge(int, int)
Definition: axlMesh.cpp:669
QStringList handled(void) const
void setShader(const QString &shader)
bool normal_used(void) const
Definition: axlMesh.cpp:170
QVector< int > Edge
An edge is represented by a sequence of vertices.
Definition: axlMesh.h:55
QString changeFieldName(QString fieldName)
bool reject(const QDomNode &node)
bool accept(const QDomNode &node)
dtkAbstractDataReader * create(const QString &interface_name)
bool edge_show(void) const
Definition: axlMesh.cpp:190
QString description(void) const
void push_back_color(const int &r, const int &g, const int &b)
Add color to the mesh.
Definition: axlMesh.cpp:542
int edge_count(void) const
Definition: axlMesh.cpp:143
virtual axlAbstractData * read(const QDomNode &node)=0
Class axlAbstractField defines an API for arrays of numeric data.
bool face_show(void) const
Definition: axlMesh.cpp:200
bool hasChildNode(QDomElement element, const QString &tag)
Definition: axlFormat.h:20
void push_back_face(const Face &face)
Definition: axlMesh.cpp:735
void setOpacity(const double &opacity)
bool color_used(void) const
Definition: axlMesh.cpp:180
static bool registered(void)
static axlFieldReadersFactory * instance(void)
void addField(axlAbstractField *field)
Add a field to the field list of the object.
void setSize(const double &size)
void setColor(double r, double g, double b)
void push_back_normal(axlPoint *normal)
Definition: axlMesh.cpp:613
int vertex_count(void) const
Definition: axlMesh.cpp:122
Class axlAbstractData defines an API for all type of axel data.
QString identifier(void) const
Class axlMesh defines a piecewise-linear 3D object.
Definition: axlMesh.h:41
dtkAbstractDataReader * createaxlMeshReader(void)
void push_back_vertex(const double &x, const double &y, const double &z)
Add a new vertex to the mesh.
Definition: axlMesh.cpp:333