00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include "optimize.h"
00013 #include "../../geometrynode.h"
00014 #include "algorithm"
00015
00016 using namespace VRUT;
00017
00018 void Optimize::parseMask(wxString mask, std::vector<wxString> &maskList)
00019 {
00020 while (!mask.IsEmpty())
00021 {
00022 int pos = mask.Find(wxT(','));
00023 if (pos != wxNOT_FOUND)
00024 {
00025 if (pos>0)
00026 maskList.push_back(mask.SubString(0,pos-1));
00027 mask.Remove(0, pos+1);
00028 }
00029 else
00030 {
00031 maskList.push_back(mask.SubString(0,pos-1));
00032 mask.Clear();
00033 }
00034 }
00035 }
00036
00037 bool Optimize::nameHasMask(wxString name, std::vector<wxString> &maskList)
00038 {
00039 for (std::vector<wxString>::iterator maskIt = maskList.begin(); maskIt != maskList.end(); maskIt++)
00040 {
00041 if (name.Matches(*maskIt))
00042 return true;
00043 }
00044 return false;
00045 }
00046
00047 void Optimize::deleteAction(SCENE_ID _sceneID, wxString mask)
00048 {
00049 Scene * scene = GetSceneMgr()->GetScene(_sceneID);
00050 if (!scene)
00051 return;
00052
00053 std::vector<wxString> maskList;
00054 parseMask(mask, maskList);
00055 long delCount=0;
00056
00057 std::vector<NODE_ID> nodes;
00058 scene->GetNodeIDs(&nodes);
00059
00060 for (std::vector<NODE_ID>::const_iterator nodeIt = nodes.begin();
00061 nodeIt != nodes.end(); nodeIt++)
00062 {
00063 const SceneNode * node = scene->GetNode(*nodeIt);
00064 if (nameHasMask(node->GetName(),maskList))
00065 {
00066
00067 wxCommandEvent evNodeRemove = Event::GET_EVT_SCENE_NODE_REMOVE(_sceneID, *nodeIt);
00068 PostToKernel(evNodeRemove);
00069 delCount++;
00070 }
00071 }
00072 LOG(wxString::Format(wxT("<Optimize>deleteAction removed %li nodes"), delCount));
00073 }
00074
00075 bool Optimize::simplifyStructureRecursion(Scene *scene, const SceneNode * node, std::vector<wxString> &maskList, long &delCount)
00076 {
00077 const SceneNode::NodeIDList *children = node->GetChildren();
00078 for (SceneNode::NodeIDList::const_iterator it = children->begin(); it != children->end();)
00079 {
00080 const SceneNode *child = scene->GetNode(*it);
00081 if ((child->IsOfType(SceneNode::ASSEMBLY))||(child->IsOfType(SceneNode::GEOMETRY)))
00082 {
00083 if (simplifyStructureRecursion(scene, child, maskList, delCount))
00084 it = children->begin();
00085 else
00086 it++;
00087 }
00088 else
00089 it++;
00090 }
00091
00092 if (node->GetID()==0)
00093 return false;
00094 if ((children->size()==0)&&(node->IsOfType(SceneNode::ASSEMBLY))&&(nameHasMask(node->GetName(), maskList)))
00095 {
00096 scene->Remove(node->GetID());
00097 delCount++;
00098 return true;
00099 }
00100 if (children->size()==1)
00101 {
00102 if (nameHasMask(node->GetName(), maskList))
00103 {
00104 NODE_ID childID = children->front();
00105 MATRIX transf((*node->GetLocalTransMatrix())*(*(scene->GetNode(childID)->GetLocalTransMatrix())));
00106 scene->Move(childID, node->GetParent());
00107 scene->SetTransformation(childID, transf);
00108 scene->Remove(node->GetID());
00109 delCount++;
00110 return true;
00111 } else if (nameHasMask(scene->GetNode(children->front())->GetName(), maskList))
00112 {
00113 NODE_ID childID = children->front();
00114 MATRIX transf((*node->GetLocalTransMatrix())*(*(scene->GetNode(childID)->GetLocalTransMatrix())));
00115 scene->Move(childID, node->GetParent());
00116 scene->SetTransformation(childID, transf);
00117 wxString name(node->GetName());
00118 scene->Remove(node->GetID());
00119 scene->SetName(childID, name);
00120 delCount++;
00121 return true;
00122 }
00123 }
00124 return false;
00125 }
00126
00127 void Optimize::simplifyStructureAction(SCENE_ID _sceneID, wxString mask)
00128 {
00129 Scene * scene = GetSceneMgr()->GetScene(_sceneID);
00130 if (!scene)
00131 return;
00132
00133 std::vector<wxString> maskList;
00134 parseMask(mask, maskList);
00135 long delCount = 0;
00136 simplifyStructureRecursion(scene, scene->GetNode(scene->GetRootID()), maskList, delCount);
00137 LOG(wxString::Format(wxT("<Optimize>simplifyStructureAction removed %li nodes"), delCount));
00138 }
00139
00140 void Optimize::removeUnusedMaterialsAction(SCENE_ID _sceneID)
00141 {
00142 Scene * scene = GetSceneMgr()->GetScene(_sceneID);
00143 if (!scene)
00144 return;
00145
00146 const Scene::MaterialList *materials = scene->GetMaterials();
00147 std::vector<bool> matUsed;
00148 matUsed.insert(matUsed.end(), materials->size(), false);
00149 std::vector<NODE_ID> nodes;
00150 scene->GetNodeIDs(&nodes);
00151 long delCount = 0;
00152 for (std::vector<NODE_ID>::const_iterator nodeIt = nodes.begin();
00153 nodeIt != nodes.end(); nodeIt++)
00154 {
00155 const SceneNode * node = scene->GetNode(*nodeIt);
00156 if (node && node->IsOfType(SceneNode::GEOMETRY))
00157 if (((GeometryNode*)node)->GetMaterialID()!=MATERIAL_ID_NONE)
00158 matUsed[((GeometryNode*)node)->GetMaterialID()]=true;
00159 }
00160 for (size_t i=0; i<matUsed.size(); i++)
00161 {
00162 if (!matUsed[i])
00163 {
00164 const Material *mat = scene->GetMaterial((MATERIAL_ID)i);
00165 if (mat)
00166 {
00167 LOG(wxString::Format(wxT("<Optimize>remove Material: %s"), mat->name.c_str()));
00168 scene->RemoveMaterial((MATERIAL_ID)i);
00169 delCount++;
00170 }
00171 }
00172 }
00173 LOG(wxString::Format(wxT("<Optimize>removeUnusedMaterialsAction removed %li materials"), delCount));
00174 }
00175
00176 void Optimize::unifyMaterialsAction(SCENE_ID _sceneID)
00177 {
00178 Scene * scene = GetSceneMgr()->GetScene(_sceneID);
00179 if (!scene)
00180 return;
00181
00182 long uniCount = 0;
00183 const Scene::MaterialList *materials = scene->GetMaterials();
00184 for (size_t i=0; i<materials->size(); i++)
00185 {
00186 const Material *firstMat = scene->GetMaterial((MATERIAL_ID)i);
00187 if (!firstMat)
00188 continue;
00189 for (size_t j=i+1; j<materials->size(); j++)
00190 {
00191 const Material *secMat = scene->GetMaterial((MATERIAL_ID)j);
00192 if (!secMat)
00193 continue;
00194 if (firstMat->IsSameAs(*secMat, 28))
00195 {
00196 uniCount++;
00197
00198 LOG(wxString::Format(wxT("<Optimize>unifyMaterialsAction: materials %s and %s are the same"), firstMat->name.c_str(), secMat->name.c_str()));
00199 std::vector<NODE_ID> nodes;
00200 scene->GetNodeIDs(&nodes);
00201 for (std::vector<NODE_ID>::const_iterator nodeIt = nodes.begin(); nodeIt != nodes.end(); nodeIt++)
00202 {
00203 const SceneNode * node = scene->GetNode(*nodeIt);
00204 if (node && node->IsOfType(SceneNode::GEOMETRY))
00205 {
00206 if ((((GeometryNode*)node)->GetMaterialID())==j)
00207 {
00208 scene->SetMaterial(*nodeIt, (MATERIAL_ID)i);
00209
00210
00211 }
00212 }
00213 }
00214 scene->RemoveMaterial((MATERIAL_ID)j);
00215 }
00216 }
00217 }
00218 LOG(wxString::Format(wxT("<Optimize>unifyMaterialsAction merged %li materials"), uniCount));
00219 }
00220
00221 struct VerticesVectorSort
00222 {
00223 std::vector<VECTOR3> * verts;
00224 VerticesVectorSort(std::vector<VECTOR3> * _verts): verts(_verts) {
00225 long uniCount = 0;
00226 }
00227 bool operator()(size_t rpStart, size_t rpEnd)
00228 {
00229 return verts->at(rpStart).x < verts->at(rpEnd).x;
00230 }
00231 };
00232 struct VerticesVectorSort2
00233 {
00234 std::vector<VECTOR3> *verts;
00235 std::vector<VECTOR3> *norms;
00236 std::vector<GeometryTriangles::TexCoord> *texs;
00237 VerticesVectorSort2(std::vector<VECTOR3> *_verts, std::vector<VECTOR3> *_norms, std::vector<GeometryTriangles::TexCoord> *_texs): verts(_verts), norms(_norms), texs(_texs) {}
00238 bool operator()(size_t rpStart, size_t rpEnd)
00239 {
00240 if (verts->at(rpStart) < verts->at(rpEnd))
00241 return true;
00242 else if (verts->at(rpStart) == verts->at(rpEnd))
00243 {
00244 if (norms->size() == verts->size())
00245 {
00246 if (norms->at(rpStart) < norms->at(rpEnd))
00247 return true;
00248 else if (norms->at(rpStart) == norms->at(rpEnd))
00249 {
00250 if (texs->size() == verts->size())
00251 if (texs->at(rpStart) < texs->at(rpEnd))
00252 return true;
00253 }
00254 }
00255 else if (texs->size() == verts->size())
00256 {
00257 if (texs->at(rpStart) < texs->at(rpEnd))
00258 return true;
00259 }
00260 }
00261 return false;
00262 }
00263 };
00264
00265
00266 void Optimize::unifyVerticesAction(SCENE_ID _sceneID)
00267 {
00268 Scene * scene = GetSceneMgr()->GetScene(_sceneID);
00269 if (!scene)
00270 return;
00271
00272 long uniCount = 0;
00273 std::vector<NODE_ID> nodes;
00274 scene->GetNodeIDs(&nodes);
00275 for (std::vector<NODE_ID>::const_iterator nodeIt = nodes.begin(); nodeIt != nodes.end(); nodeIt++)
00276 {
00277 const SceneNode * node = scene->GetNode(*nodeIt);
00278 if (node && node->IsOfType(SceneNode::GEOMETRY))
00279 {
00280 const Geometry *geom = scene->GetGeometry(((GeometryNode*)node)->GetGeometryID());
00281 if (geom && geom->type==Geometry::GEOMETRY_TRIANGLE)
00282 {
00283 GeometryTriangles *geoTri = (GeometryTriangles*)geom->Clone();
00284 std::vector<VECTOR3> * verts = &(geoTri->vertices);
00285 std::vector<VECTOR3> * norms = &(geoTri->normals);
00286 std::vector<GeometryTriangles::TexCoord> * texs = &(geoTri->texCoords);
00287 std::vector<GeometryTriangles::Indice> * inds = &(geoTri->indices);
00288
00289 std::vector<size_t> ind(verts->size());
00290 for (size_t i=0; i<ind.size(); i++)
00291 ind[i]=GeometryTriangles::Indice(i);
00292
00293 std::sort(ind.begin(), ind.end(), VerticesVectorSort2(verts, norms, texs));
00294
00295 bool geomChanged = false;
00296 std::vector<std::vector<size_t> > vertsref(verts->size());
00297 for (size_t i=0; i<inds->size(); i++)
00298 vertsref[inds->at(i)].push_back(i);
00299 size_t lastNotMerged = 0;
00300 for (size_t i=1; i<ind.size(); i++)
00301 {
00302 if (verts->at(ind[lastNotMerged])!=verts->at(ind[i]))
00303 {
00304 lastNotMerged = i;
00305 continue;
00306 }
00307 if (norms->size()==verts->size())
00308 if (norms->at(ind[lastNotMerged])!=norms->at(ind[i]))
00309 {
00310 lastNotMerged = i;
00311 continue;
00312 }
00313 if (texs->size()==verts->size())
00314 if (texs->at(ind[lastNotMerged])!=texs->at(ind[i]))
00315 {
00316 lastNotMerged = i;
00317 continue;
00318 }
00319
00320 while (vertsref[ind[i]].size())
00321 {
00322 inds->at(vertsref[ind[i]].back())=(GeometryTriangles::Indice)ind[lastNotMerged];
00323 vertsref[ind[lastNotMerged]].push_back(vertsref[ind[i]].back());
00324 vertsref[ind[i]].pop_back();
00325 }
00326 geomChanged = true;
00327 }
00328 if (!geomChanged)
00329 {
00330 for (size_t i=0; i<vertsref.size(); i++)
00331 {
00332 if (vertsref.at(i).size()==0)
00333 {
00334 geomChanged=true;
00335 break;
00336 }
00337 }
00338 }
00339 if (geomChanged)
00340 {
00341
00342 size_t lastUsed = vertsref.size()-1;
00343 for (size_t i=0; i<vertsref.size() && i<=lastUsed; i++)
00344 {
00345 if (!vertsref[i].size())
00346 {
00347 while (!vertsref[lastUsed].size())
00348 {
00349 lastUsed--;
00350 if (norms->size()==verts->size())
00351 norms->pop_back();
00352 if (texs->size()==verts->size())
00353 texs->pop_back();
00354 verts->pop_back();
00355 uniCount++;
00356 }
00357 if (i>=lastUsed)
00358 break;
00359 verts->at(i)=verts->at(lastUsed);
00360 if (norms->size()==verts->size())
00361 norms->at(i)=norms->at(lastUsed);
00362 if (texs->size()==verts->size())
00363 texs->at(i)=texs->at(lastUsed);
00364 while (vertsref[lastUsed].size())
00365 {
00366 inds->at(vertsref[lastUsed].back())=(GeometryTriangles::Indice)i;
00367 vertsref[i].push_back(vertsref[lastUsed].back());
00368 vertsref[lastUsed].pop_back();
00369 }
00370 }
00371 }
00372 scene->AddGeometry(geoTri);
00373 if (TestExit())
00374 return;
00375 }
00376 }
00377 }
00378 }
00379 LOG(wxString::Format(wxT("<Optimize>unifyVerticesAction merged %li vertices"), uniCount));
00380 }
00381
00382 void Optimize::removeUnusedGeometriesAction(SCENE_ID _sceneID)
00383 {
00384 Scene * scene = GetSceneMgr()->GetScene(_sceneID);
00385 if (!scene)
00386 return;
00387
00388 const Scene::GeometryList *geometries = scene->GetGeometries();
00389 std::vector<bool> geoUsed;
00390 geoUsed.insert(geoUsed.end(), geometries->size(), false);
00391 std::vector<NODE_ID> nodes;
00392 scene->GetNodeIDs(&nodes);
00393 long delCount = 0;
00394 for (std::vector<NODE_ID>::const_iterator nodeIt = nodes.begin();
00395 nodeIt != nodes.end(); nodeIt++)
00396 {
00397 const SceneNode * node = scene->GetNode(*nodeIt);
00398 if (node->IsOfType(SceneNode::GEOMETRY))
00399 if (((GeometryNode*)node)->GetGeometryID()!=GEOMETRY_ID_NONE)
00400 geoUsed[((GeometryNode*)node)->GetGeometryID()]=true;
00401 }
00402 for (size_t i=0; i<geoUsed.size(); i++)
00403 {
00404 if (!geoUsed[i])
00405 {
00406 const Geometry *geo = scene->GetGeometry((GEOMETRY_ID)i);
00407 if (geo)
00408 {
00409 LOG(wxString::Format(wxT("<Optimize>remove Geometry: %s"), geo->GetName().c_str()));
00410 scene->RemoveGeometry((GEOMETRY_ID)i);
00411 delCount++;
00412 }
00413 }
00414 }
00415 LOG(wxString::Format(wxT("<Optimize>removeUnusedGeometriesAction removed %li geometries"), delCount));
00416 }
00417
00418 void Optimize::mergePrimitive(std::vector<size_t> &canMerge, GeometryTriangles::PRIMITIVE_TYPE primType, GeometryTriangles::TriDescList &ntriD,
00419 GeometryTriangles::TriDescList *triDescList, std::vector<GeometryTriangles::Indice> &nind, std::vector<bool> &primUsed,
00420 std::vector<GeometryTriangles::Indice> * indices, long &delCount)
00421 {
00422 if (canMerge.size()>1)
00423 {
00424 ntriD.push_back(triDescList->at(canMerge[0]));
00425 ntriD.back().first=(GeometryTriangles::Indice)nind.size();
00426 ntriD.back().second=primType;
00427 for (size_t j=0; j<canMerge.size(); j++)
00428 {
00429 primUsed[canMerge[j]]=true;
00430 size_t last = (canMerge[j]+1<triDescList->size())?triDescList->at(canMerge[j]+1).first:indices->size();
00431 for (size_t k=triDescList->at(canMerge[j]).first; k<last; k++)
00432 nind.push_back(indices->at(k));
00433 }
00434 delCount+=long(canMerge.size()-1);
00435 }
00436 }
00437
00438 void Optimize::mergePrimitivesAction(SCENE_ID _sceneID)
00439 {
00440 Scene * scene = GetSceneMgr()->GetScene(_sceneID);
00441 if (!scene)
00442 return;
00443
00444 long delCount = 0;
00445 const Scene::GeometryList *geometries = scene->GetGeometries();
00446 for (size_t i=0; i<geometries->size(); i++)
00447 {
00448 if (!geometries->at(i))
00449 continue;
00450 if (geometries->at(i)->type==Geometry::GEOMETRY_TRIANGLE)
00451 {
00452 GeometryTriangles *geoTri = (GeometryTriangles*)geometries->at(i)->Clone();
00453 std::vector<GeometryTriangles::Indice> * indices = &(geoTri->indices);
00454 GeometryTriangles::TriDescList *triDescList = &(geoTri->triDescList);
00455 std::vector<size_t> canTriangles, canLines, canPoints, canQuads;
00456 for (size_t j=0; j<geoTri->triDescList.size(); j++)
00457 {
00458 long count = long(((j+1<triDescList->size())?triDescList->at(j+1).first:indices->size()) - triDescList->at(j).first);
00459 switch (triDescList->at(j).second)
00460 {
00461 case GeometryTriangles::TRI_STRIP:
00462 if (count==4)
00463 {
00465
00466
00467
00468
00469
00470
00471
00472 break;
00473 }
00474 case GeometryTriangles::TRI_FAN:
00475 case GeometryTriangles::POLYGON:
00476 if (count==3)
00477 canTriangles.push_back(j);
00478 else if (count==4)
00479 canQuads.push_back(j);
00480 break;
00481 case GeometryTriangles::TRI_LIST:
00482 canTriangles.push_back(j);
00483 break;
00484 case GeometryTriangles::LINE_STRIP:
00485 if (count!=2)
00486 break;
00487 case GeometryTriangles::LINES:
00488 canLines.push_back(j);
00489 break;
00490 case GeometryTriangles::POINTS:
00491 canPoints.push_back(j);
00492 break;
00493 case GeometryTriangles::QUADS:
00494 canQuads.push_back(j);
00495 break;
00496 }
00497 }
00498
00499 std::vector<GeometryTriangles::Indice> nind;
00500 GeometryTriangles::TriDescList ntriD;
00501 std::vector<bool> primUsed;
00502 primUsed.insert(primUsed.end(), triDescList->size(), false);
00503 mergePrimitive(canTriangles, GeometryTriangles::TRI_LIST, ntriD, triDescList, nind, primUsed, indices, delCount);
00504 mergePrimitive(canLines, GeometryTriangles::LINES, ntriD, triDescList, nind, primUsed, indices, delCount);
00505 mergePrimitive(canPoints, GeometryTriangles::POINTS, ntriD, triDescList, nind, primUsed, indices, delCount);
00506 mergePrimitive(canQuads, GeometryTriangles::QUADS, ntriD, triDescList, nind, primUsed, indices, delCount);
00507 if (ntriD.size()>0)
00508 {
00509 for (size_t j=0; j<triDescList->size(); j++)
00510 {
00511 if (primUsed[j])
00512 continue;
00513 ntriD.push_back(triDescList->at(j));
00514 ntriD.back().first=(GeometryTriangles::Indice)nind.size();
00515 size_t last = (j+1<triDescList->size())?triDescList->at(j+1).first:indices->size();
00516 for (size_t k=triDescList->at(j).first; k<last; k++)
00517 nind.push_back(indices->at(k));
00518 }
00519 indices->assign(nind.begin(), nind.end());
00520 triDescList->assign(ntriD.begin(), ntriD.end());
00521 scene->AddGeometry(geoTri);
00522 if (TestExit())
00523 return;
00524 }
00525 }
00526 }
00527 LOG(wxString::Format(wxT("<Optimize>mergePrimitivesAction merged %li primitives"), delCount));
00528 }
00529
00530 void Optimize::deleteNormalsAction(SCENE_ID _sceneID, wxString mask)
00531 {
00532 Scene * scene = GetSceneMgr()->GetScene(_sceneID);
00533 if (!scene)
00534 return;
00535
00536 std::vector<wxString> maskList;
00537 parseMask(mask, maskList);
00538 long delCount=0;
00539
00540 std::vector<NODE_ID> nodes;
00541 scene->GetNodeIDs(&nodes);
00542
00543 for (std::vector<NODE_ID>::const_iterator nodeIt = nodes.begin(); nodeIt != nodes.end(); nodeIt++)
00544 {
00545 const SceneNode * node = scene->GetNode(*nodeIt);
00546 if (node->IsOfType(SceneNode::GEOMETRY) && nameHasMask(node->GetName(),maskList))
00547 {
00548 const Geometry *geom = scene->GetGeometry(((GeometryNode*)node)->GetGeometryID());
00549 if (geom->type==Geometry::GEOMETRY_TRIANGLE)
00550 {
00551 GeometryTriangles *geoTri = (GeometryTriangles*)geom->Clone();
00552 if (geoTri->normals.size()>0)
00553 {
00554 geoTri->normals.clear();
00555 delCount++;
00556 scene->AddGeometry(geoTri);
00557 }
00558 }
00559 }
00560 }
00561 LOG(wxString::Format(wxT("<Optimize>deleteNormalsAction removed normals from %li nodes"), delCount));
00562 }
00563
00564 void Optimize::deleteTexCoordsAction(SCENE_ID _sceneID, wxString mask)
00565 {
00566 Scene * scene = GetSceneMgr()->GetScene(_sceneID);
00567 if (!scene)
00568 return;
00569
00570 std::vector<wxString> maskList;
00571 parseMask(mask, maskList);
00572 long delCount=0;
00573
00574 std::vector<NODE_ID> nodes;
00575 scene->GetNodeIDs(&nodes);
00576
00577 for (std::vector<NODE_ID>::const_iterator nodeIt = nodes.begin(); nodeIt != nodes.end(); nodeIt++)
00578 {
00579 const SceneNode * node = scene->GetNode(*nodeIt);
00580 if (node->IsOfType(SceneNode::GEOMETRY) && nameHasMask(node->GetName(),maskList))
00581 {
00582 const Geometry *geom = scene->GetGeometry(((GeometryNode*)node)->GetGeometryID());
00583 if (geom->type==Geometry::GEOMETRY_TRIANGLE)
00584 {
00585 GeometryTriangles *geoTri = (GeometryTriangles*)geom->Clone();
00586 if (geoTri->texCoords.size()>0)
00587 {
00588 geoTri->texCoords.clear();
00589 delCount++;
00590 scene->AddGeometry(geoTri);
00591 }
00592 }
00593 }
00594 }
00595 LOG(wxString::Format(wxT("<Optimize>deleteTexCoordsAction removed texture coordinates from %li nodes"), delCount));
00596 }
00597
00598 void Optimize::statisticsAction(SCENE_ID _sceneID)
00599 {
00600 Scene * scene = GetSceneMgr()->GetScene(_sceneID);
00601 if (!scene)
00602 return;
00603
00604 std::vector<NODE_ID> nodes;
00605 scene->GetNodeIDs(&nodes);
00606
00607 long ass = 0, geo = 0, lig = 0, cam = 0;
00608 for (std::vector<NODE_ID>::const_iterator nodeIt = nodes.begin(); nodeIt != nodes.end(); nodeIt++)
00609 {
00610 switch (scene->GetNode(*nodeIt)->GetType())
00611 {
00612 case SceneNode::ASSEMBLY:
00613 ass++;
00614 break;
00615 case SceneNode::GEOMETRY:
00616 geo++;
00617 break;
00618 case SceneNode::CAMERA:
00619 cam++;
00620 break;
00621 case SceneNode::LIGHT:
00622 lig++;
00623 break;
00624 }
00625 }
00626
00627 long geos = 0, ver = 0, nor = 0, tco = 0, ind = 0, fac = 0;
00628 long tri = 0, fan = 0, str = 0, pol = 0, lin = 0, lli = 0, poi = 0, qua = 0;
00629 long tris = 0;
00630 const Scene::GeometryList *geometries = scene->GetGeometries();
00631 for (size_t i=0; i<geometries->size(); i++)
00632 {
00633 if (geometries->at(i))
00634 geos++;
00635 else
00636 continue;
00637 if (geometries->at(i)->type==Geometry::GEOMETRY_TRIANGLE)
00638 {
00639 GeometryTriangles *geoTri = (GeometryTriangles*)geometries->at(i);
00640 ver+=long(geoTri->vertices.size());
00641 nor+=long(geoTri->normals.size());
00642 tco+=long(geoTri->texCoords.size());
00643 ind+=long(geoTri->indices.size());
00644 fac+=long(geoTri->triDescList.size());
00645 for (size_t j=0; j<geoTri->triDescList.size(); j++)
00646 {
00647 long count = long(((j+1<geoTri->triDescList.size())?geoTri->triDescList.at(j+1).first:geoTri->indices.size()) - geoTri->triDescList.at(j).first);
00648 switch (geoTri->triDescList.at(j).second)
00649 {
00650 case GeometryTriangles::TRI_LIST:
00651 tri++;
00652 tris+=count/3;
00653 break;
00654 case GeometryTriangles::TRI_FAN:
00655 tris+=count-2;
00656 fan++;
00657 break;
00658 case GeometryTriangles::TRI_STRIP:
00659 tris+=count-2;
00660 str++;
00661 break;
00662 case GeometryTriangles::POLYGON:
00663 tris+=count-2;
00664 pol++;
00665 break;
00666 case GeometryTriangles::LINES:
00667 lin++;
00668 break;
00669 case GeometryTriangles::LINE_STRIP:
00670 lli++;
00671 break;
00672 case GeometryTriangles::POINTS:
00673 poi++;
00674 break;
00675 case GeometryTriangles::QUADS:
00676 tris+=count/2;
00677 qua++;
00678 break;
00679 }
00680 }
00681 }
00682 }
00683 long mat = 0, sha = 0, tex = 0;
00684 const Scene::MaterialList *materials = scene->GetMaterials();
00685 for (size_t i=0; i<materials->size(); i++)
00686 {
00687 if (scene->GetMaterial((MATERIAL_ID)i))
00688 {
00689 mat++;
00690 if (scene->GetMaterial((MATERIAL_ID)i)->shader)
00691 sha++;
00692 if (!scene->GetMaterial((MATERIAL_ID)i)->imageName.IsEmpty())
00693 tex++;
00694 }
00695 }
00696 wxString result(wxString::Format(wxT("<Optimize>statistics, scene=%i ("), _sceneID));
00697 result+=scene->GetName()+wxT(")\n");
00698 result+=wxString::Format(wxT("Nodes=%li, ASSEMBLY=%li, GEOMETRY=%li, CAMERA=%li, LIGHT=%li\n"), nodes.size(), ass, geo, cam, lig);
00699 result+=wxString::Format(wxT("Geometries=%li, Vertices=%li, Normals=%li, TexCoords=%li, Indices=%li, Faces=%li\n"),geos, ver, nor, tco, ind, fac);
00700 result+=wxString::Format(wxT("Materials=%li, Shaders=%li, Textures=%li, Triangles=%li\n"), mat, sha, tex, tris);
00701 result+=wxString::Format(wxT("TRI_LIST=%li, TRI_FAN=%li, TRI_STRIP=%li, POLYGON=%li, LINES=%li, LINE_STRIP=%li, POINTS=%li, QUADS=%li\n"), tri, fan, str, pol, lin, lli, poi, qua);
00702 LOG(result);
00703 }
00704