krita/ui
kis_3d_object_model.cppGo to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <QFile>
00021 #include <QTextStream>
00022 #include <QString>
00023 #include <QStringList>
00024 #include <QHash>
00025
00026 #include "kis_3d_object_model.h"
00027 #include "kis_vec.h"
00028 #include "kis_debug.h"
00029
00030 #include <kglobal.h>
00031 #include <kstandarddirs.h>
00032 #include <kcomponentdata.h>
00033
00034 Kis3DObjectModel::Kis3DObjectModel(const QString& model, const QString& material)
00035 {
00036 KGlobal::mainComponent().dirs()->addResourceType("kis_brushmodels", "data", "krita/brushmodels/");
00037 QString path = KGlobal::mainComponent().dirs()->findResource("kis_brushmodels", model);
00038
00039 m_cached = false;
00040
00041 parseMaterial(material);
00042
00043 QFile file(path);
00044 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
00045 kDebug() << "File " + model + " Not Found";
00046 return;
00047 }
00048
00049 QTextStream in(&file);
00050 QString key;
00051 QString edge;
00052 QStringList edgeList;
00053
00054 while (!in.atEnd()) {
00055
00056 QString line = in.readLine();
00057 if (line.isEmpty() || line[0] == '#') {
00058 continue;
00059 }
00060
00061 QTextStream ts(&line);
00062 QString id;
00063 ts >> id;
00064 if (id == "v") {
00065 KisVector3D vector;
00066 for (int i = 0; i < 3; i++) {
00067 ts >> vector[i];
00068 }
00069 m_vertex.append(vector);
00070 } else if (id == "vn") {
00071 KisVector3D normal;
00072 for (int i = 0; i < 3; i++) {
00073 ts >> normal[i];
00074
00075 }
00076 m_normal.append(normal);
00077 } else if (id == "usemtl") {
00078 ts >> key;
00079 } else if (id == "f") {
00080 if (key.isEmpty() || key.isNull()) {
00081
00082 qFatal("No material defined in model file!");
00083 }
00084
00085 for (int i = 0; i < 3; i++) {
00086 ts >> edge;
00087 edgeList = edge.split('/');
00088
00089
00090 m_vertexHash[ key ].append(edgeList.value(0).toInt() - 1);
00091 m_normalHash[ key ].append(edgeList.value(2).toInt() - 1);
00092 }
00093 }
00094 }
00095
00096
00097 #if 0
00098 kDebug() << "(v) vertex: " << m_vertex.size();
00099 kDebug() << "(vn) normals: " << m_normal.size();
00100 kDebug() << "(usemtl) keys (v): " << m_vertexHash.keys();
00101 kDebug() << "(usemtl) keys (vn): " << m_normalHash.keys();
00102
00103 int vSize = 0;
00104 int nSize = 0;
00105 QList<QString> keyList = m_vertexHash.keys();
00106 for (int i = 0; i < keyList.size(); i++) {
00107 vSize += m_vertexHash[ keyList[i] ].size();
00108 }
00109 keyList = m_normalHash.keys();
00110 for (int i = 0; i < keyList.size(); i++) {
00111 nSize += m_normalHash[ keyList[i] ].size();
00112 }
00113 kDebug() << "(f) faces-vertex: " << vSize;
00114 kDebug() << "(f) faces-normal: " << nSize;
00115 kDebug() << "(f) faces-vertex/3.0: " << vSize / 3.0;
00116 kDebug() << "(f) faces-normal/3.0: " << nSize / 3.0;
00117
00118 #endif
00119 }
00120
00121 #define MODEL_SCALE 30
00122 GLuint Kis3DObjectModel::displayList()
00123 {
00124 if (m_cached) {
00125 return m_displayList;
00126 }
00127
00128
00129 if (m_vertex.size() == 0) {
00130 return 0;
00131 }
00132
00133 KisVector3D vertex;
00134 KisVector3D normal;
00135 QList<QString> keyList = m_vertexHash.keys();
00136
00137 m_displayList = glGenLists(1);
00138
00139 glNewList(m_displayList, GL_COMPILE);
00140 glScalef(MODEL_SCALE, MODEL_SCALE, MODEL_SCALE);
00141 glBegin(GL_TRIANGLES);
00142 for (int k = 0; k < keyList.size(); k++) {
00143 m_vertexIndex = m_vertexHash.value(keyList[k]);
00144 m_normalIndex = m_normalHash.value(keyList[k]);
00145
00146 Material m = m_material.value(keyList[k]);
00147 glColor3f(m.Kd[0], m.Kd[1], m.Kd[2]);
00148 #if 0
00149 kDebug() << "Name: " << keyList[k];
00150 debug(m);
00151 #endif
00152
00153 for (int i = 0; i < m_vertexIndex.size(); i += 3) {
00154 for (int j = 0; j < 3; j++) {
00155 int vi = m_vertexIndex[i+j];
00156 int ni = m_normalIndex[i+j];
00157 vertex = m_vertex[ vi ];
00158 normal = m_normal[ ni ];
00159 glNormal3f(normal.x(), normal.y(), normal.z());
00160 glVertex3f(vertex.x(), vertex.y(), vertex.z());
00161 }
00162 }
00163
00164
00165 }
00166
00167
00168 glEnd();
00169 const GLfloat _1_MODEL_SCALE = GLfloat(1.0 / MODEL_SCALE);
00170 glScalef(_1_MODEL_SCALE, _1_MODEL_SCALE, _1_MODEL_SCALE);
00171 glEndList();
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185 m_cached = true;
00186 return m_displayList;
00187
00188 }
00189
00190
00191 void Kis3DObjectModel::parseMaterial(const QString& fileName)
00192 {
00193
00194 QString path = KGlobal::mainComponent().dirs()->findResource("kis_brushmodels", fileName);
00195
00196 QFile file(path);
00197 if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
00198 kDebug() << "File " + fileName + " Not Found";
00199 return;
00200 }
00201
00202 QTextStream in(&file);
00203
00204 QString key;
00205 while (!in.atEnd()) {
00206
00207 QString line = in.readLine();
00208 if (line.isEmpty() || line[0] == '#') {
00209 continue;
00210 }
00211
00212 QTextStream ts(&line);
00213 QString id;
00214 ts >> id;
00215 if (id == "Ka") {
00216 KisVector3D vector;
00217 for (int i = 0; i < 3; i++) {
00218 ts >> vector[i];
00219 }
00220 m_material[ key ].Ka = vector;
00221
00222 } else if (id == "Kd") {
00223
00224 KisVector3D vector;
00225 for (int i = 0; i < 3; i++) {
00226 ts >> vector[i];
00227 }
00228 m_material[ key ].Kd = vector;
00229
00230 } else if (id == "Ks") {
00231 KisVector3D vector;
00232 for (int i = 0; i < 3; i++) {
00233 ts >> vector[i];
00234 }
00235 m_material[ key ].Ks = vector;
00236 } else if (id == "d") {
00237 ts >> m_material[ key ].d;
00238 } else if (id == "Ns") {
00239 ts >> m_material[ key ].Ns;
00240 } else if (id == "Ni") {
00241 ts >> m_material[ key ].Ni;
00242 } else if (id == "newmtl") {
00243 ts >> key;
00244 }
00245
00246 }
00247
00248 #if 0
00249 QList<QString> list = m_material.keys();
00250 kDebug() << list;
00251 kDebug() << "----------------------------\n";
00252 for (int i = 0; i < list.size(); i++) {
00253 kDebug() << list[ i ];
00254 debug(m_material.value(list[ i ]));
00255 }
00256 kDebug() << "----------------------------\n";
00257 #endif
00258
00259 }
00260
00261
00262 void Kis3DObjectModel::debug(Material m)
00263 {
00264 kDebug() << "Ka:" << m.Ka[0] << " " << m.Ka[1] << " " << m.Ka[2];
00265 kDebug() << "Kd:" << m.Kd[0] << " " << m.Kd[1] << " " << m.Kd[2];
00266 kDebug() << "Ks:" << m.Ks[0] << " " << m.Ks[1] << " " << m.Ks[2];
00267 }
|