code format
This commit is contained in:
180
glscene.cpp
180
glscene.cpp
@@ -1,25 +1,27 @@
|
||||
/*
|
||||
QGL Scene
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
QGL Scene
|
||||
Ivan Pelipenko peri4ko@yandex.ru
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Lesser General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "glscene.h"
|
||||
|
||||
#include "glcamera.h"
|
||||
#include "glmesh.h"
|
||||
#include "qglview.h"
|
||||
|
||||
#include <chunkstream.h>
|
||||
|
||||
|
||||
@@ -27,9 +29,9 @@ Scene::Scene() {
|
||||
root_ = new ObjectBase();
|
||||
root_->setScene(this);
|
||||
tree_changed = mat_changed = lights_changed = true;
|
||||
destroying = false;
|
||||
destroying = false;
|
||||
need_reload_materials = tree_struct_changed = true;
|
||||
sel_mode_ = smSingleSelection;
|
||||
sel_mode_ = smSingleSelection;
|
||||
}
|
||||
|
||||
|
||||
@@ -41,9 +43,9 @@ Scene::~Scene() {
|
||||
|
||||
|
||||
Scene * Scene::clone() {
|
||||
Scene * ret = new Scene();
|
||||
Scene * ret = new Scene();
|
||||
ObjectBase * o = root_->clone();
|
||||
foreach (ObjectBase * co, o->children())
|
||||
foreach(ObjectBase * co, o->children())
|
||||
ret->addObject(co);
|
||||
o->clearChildren();
|
||||
delete o;
|
||||
@@ -54,7 +56,7 @@ Scene * Scene::clone() {
|
||||
void Scene::addObject(ObjectBase * o) {
|
||||
ObjectBaseList aol = o->children(true);
|
||||
attachObject(o);
|
||||
foreach (ObjectBase * c, aol)
|
||||
foreach(ObjectBase * c, aol)
|
||||
attachObject(c);
|
||||
root_->addChild(o);
|
||||
tree_changed = tree_struct_changed = true;
|
||||
@@ -63,13 +65,13 @@ void Scene::addObject(ObjectBase * o) {
|
||||
|
||||
void Scene::addScene(const Scene * s) {
|
||||
if (!s) return;
|
||||
//qDebug() << "addScene clone ...";
|
||||
// qDebug() << "addScene clone ...";
|
||||
ObjectBase * o = s->root_->clone();
|
||||
o->setName(s->name());
|
||||
//qDebug() << "addScene clone ok" << o << o->children(true).size();
|
||||
// qDebug() << "addScene clone ok" << o << o->children(true).size();
|
||||
addObject(o);
|
||||
makeMaterialsUniqueNames();
|
||||
//qDebug() << "addScene add ok" << o;
|
||||
// qDebug() << "addScene add ok" << o;
|
||||
}
|
||||
|
||||
|
||||
@@ -77,16 +79,16 @@ void Scene::assignFrom(const Scene * s) {
|
||||
clear();
|
||||
if (!s) return;
|
||||
setName(s->name());
|
||||
foreach (Material * m, s->materials) {
|
||||
foreach(Material * m, s->materials) {
|
||||
Material * nm = new Material();
|
||||
*nm = *m;
|
||||
nm->_changed = true;
|
||||
*nm = *m;
|
||||
nm->_changed = true;
|
||||
nm->setMapsChanged();
|
||||
materials << nm;
|
||||
}
|
||||
for (int i = 0; i < s->root_->childCount(); ++i) {
|
||||
addObject(s->root_->child(i)->clone());
|
||||
//qDebug() << i << o->child(i)->pos();
|
||||
// qDebug() << i << o->child(i)->pos();
|
||||
}
|
||||
tree_changed = mat_changed = lights_changed = need_reload_materials = tree_struct_changed = true;
|
||||
}
|
||||
@@ -113,14 +115,14 @@ void Scene::reinitAll() {
|
||||
i->reinit();
|
||||
setTreeChanged();
|
||||
mat_changed = lights_changed = true;
|
||||
need_reload_materials = true;
|
||||
tree_struct_changed = true;
|
||||
need_reload_materials = true;
|
||||
tree_struct_changed = true;
|
||||
}
|
||||
|
||||
|
||||
void Scene::objectsCountInternal(int * cnt, ObjectBase * where) {
|
||||
++(*cnt);
|
||||
foreach (ObjectBase * i, where->children())
|
||||
foreach(ObjectBase * i, where->children())
|
||||
objectsCountInternal(cnt, i);
|
||||
}
|
||||
int Scene::objectsCount(bool all) {
|
||||
@@ -133,7 +135,7 @@ int Scene::objectsCount(bool all) {
|
||||
|
||||
void Scene::removeObjectInternal(ObjectBase * o, ObjectBase * where) {
|
||||
if (destroying) return;
|
||||
foreach (ObjectBase * i, where->children()) {
|
||||
foreach(ObjectBase * i, where->children()) {
|
||||
if (o == i) {
|
||||
where->removeChild(i);
|
||||
setObjectMeshChanged(i);
|
||||
@@ -145,30 +147,29 @@ void Scene::removeObjectInternal(ObjectBase * o, ObjectBase * where) {
|
||||
|
||||
void Scene::emitSelectionChanged() {
|
||||
selected_top.clear();
|
||||
foreach (ObjectBase * o, selected_) {
|
||||
foreach(ObjectBase * o, selected_) {
|
||||
ObjectBase * po = o->selectedParent();
|
||||
if (!po) po = o;
|
||||
if (!selected_top.contains(po))
|
||||
selected_top << po;
|
||||
if (!selected_top.contains(po)) selected_top << po;
|
||||
}
|
||||
foreach (Mesh * m, geometries)
|
||||
foreach(Mesh * m, geometries)
|
||||
m->setAllSelectionChanged(true);
|
||||
selectionChanged();
|
||||
}
|
||||
|
||||
|
||||
QString Scene::uniqueName(QString n, const QSet<QString> & names) {
|
||||
if (!names.contains(n))
|
||||
return n;
|
||||
if (!names.contains(n)) return n;
|
||||
QString num;
|
||||
while (!n.isEmpty()) {
|
||||
if (n.right(1)[0].isDigit()) {
|
||||
num.push_front(n.right(1));
|
||||
n.chop(1);
|
||||
} else break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (!n.endsWith('_')) n += '_';
|
||||
int in = num.toInt() + 1;
|
||||
int in = num.toInt() + 1;
|
||||
QString nn = n + QString::number(in).rightJustified(3, '0');
|
||||
while (names.contains(nn))
|
||||
nn = n + QString::number(++in).rightJustified(3, '0');
|
||||
@@ -176,7 +177,6 @@ QString Scene::uniqueName(QString n, const QSet<QString> & names) {
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Scene::removeObject(ObjectBase * o, bool inChildren) {
|
||||
if (destroying) return;
|
||||
o->setScene(nullptr);
|
||||
@@ -205,11 +205,13 @@ void Scene::clearObjects(bool deleteAll) {
|
||||
|
||||
|
||||
void Scene::selectObject(ObjectBase * o, bool add_to_selection) {
|
||||
//qDebug() << "selectObject" << o << add_to_selection;
|
||||
// qDebug() << "selectObject" << o << add_to_selection;
|
||||
if (!add_to_selection || (sel_mode_ == smSingleSelection)) clearSelection();
|
||||
if (o) {
|
||||
if (!add_to_selection) o->setSelected(true);
|
||||
else o->setSelected(!o->isSelected());
|
||||
if (!add_to_selection)
|
||||
o->setSelected(true);
|
||||
else
|
||||
o->setSelected(!o->isSelected());
|
||||
gatherSelection();
|
||||
}
|
||||
emitSelectionChanged();
|
||||
@@ -218,7 +220,7 @@ void Scene::selectObject(ObjectBase * o, bool add_to_selection) {
|
||||
|
||||
void Scene::selectObjects(ObjectBaseList ol, bool add_to_selection) {
|
||||
if (!add_to_selection || (sel_mode_ == smSingleSelection)) clearSelection();
|
||||
foreach (ObjectBase * o, ol) {
|
||||
foreach(ObjectBase * o, ol) {
|
||||
if (!o) continue;
|
||||
o->setSelected(true);
|
||||
}
|
||||
@@ -229,14 +231,12 @@ void Scene::selectObjects(ObjectBaseList ol, bool add_to_selection) {
|
||||
|
||||
void Scene::selectObjectsByMesh() {
|
||||
ObjectBaseList csl = selected_;
|
||||
QSet<Mesh*> sml;
|
||||
foreach (ObjectBase * o, csl)
|
||||
if (o->mesh())
|
||||
sml << o->mesh();
|
||||
QSet<Mesh *> sml;
|
||||
foreach(ObjectBase * o, csl)
|
||||
if (o->mesh()) sml << o->mesh();
|
||||
ObjectBaseList ol = root_->children(true);
|
||||
foreach (ObjectBase * o, ol) {
|
||||
if (sml.contains(o->mesh()))
|
||||
o->setSelected(true);
|
||||
foreach(ObjectBase * o, ol) {
|
||||
if (sml.contains(o->mesh())) o->setSelected(true);
|
||||
}
|
||||
gatherSelection();
|
||||
emitSelectionChanged();
|
||||
@@ -245,14 +245,12 @@ void Scene::selectObjectsByMesh() {
|
||||
|
||||
void Scene::selectObjectsByMaterial() {
|
||||
ObjectBaseList csl = selected_;
|
||||
QSet<Material*> sml;
|
||||
foreach (ObjectBase * o, csl)
|
||||
if (o->material())
|
||||
sml << o->material();
|
||||
QSet<Material *> sml;
|
||||
foreach(ObjectBase * o, csl)
|
||||
if (o->material()) sml << o->material();
|
||||
ObjectBaseList ol = root_->children(true);
|
||||
foreach (ObjectBase * o, ol) {
|
||||
if (sml.contains(o->material()))
|
||||
o->setSelected(true);
|
||||
foreach(ObjectBase * o, ol) {
|
||||
if (sml.contains(o->material())) o->setSelected(true);
|
||||
}
|
||||
gatherSelection();
|
||||
emitSelectionChanged();
|
||||
@@ -263,7 +261,7 @@ void Scene::clearSelection() {
|
||||
selected_.clear();
|
||||
selected_top.clear();
|
||||
ObjectBaseList ol = root_->children(true);
|
||||
foreach (ObjectBase * o, ol) {
|
||||
foreach(ObjectBase * o, ol) {
|
||||
o->setSelected(false);
|
||||
o->setAimSelected(false);
|
||||
}
|
||||
@@ -282,13 +280,13 @@ ObjectBase * Scene::selectedObject() const {
|
||||
}
|
||||
|
||||
|
||||
void gatherMeshes(ObjectBase * o, QSet<Mesh*> & ums) {
|
||||
void gatherMeshes(ObjectBase * o, QSet<Mesh *> & ums) {
|
||||
if (o->mesh()) ums << o->mesh();
|
||||
for (int i = 0; i < o->childCount(); ++i)
|
||||
gatherMeshes(o->child(i), ums);
|
||||
}
|
||||
void Scene::cleanUnused() {
|
||||
QSet<Mesh*> ums;
|
||||
QSet<Mesh *> ums;
|
||||
gatherMeshes(root_, ums);
|
||||
for (int i = 0; i < geometries.size(); ++i) {
|
||||
if (ums.contains(geometries[i])) continue;
|
||||
@@ -316,9 +314,8 @@ Material * Scene::newMaterial(const QString & name) {
|
||||
void Scene::removeMaterial(Material * m) {
|
||||
if (!m || !materials.contains(m)) return;
|
||||
ObjectBaseList ol = root_->children(true);
|
||||
foreach (ObjectBase * o, ol)
|
||||
if (o->material_ == m)
|
||||
o->setMaterial(0);
|
||||
foreach(ObjectBase * o, ol)
|
||||
if (o->material_ == m) o->setMaterial(0);
|
||||
materials.removeAll(m);
|
||||
changed_materials.removeAll(m);
|
||||
mat_changed = true;
|
||||
@@ -327,7 +324,7 @@ void Scene::removeMaterial(Material * m) {
|
||||
|
||||
void Scene::makeMaterialsUniqueNames() {
|
||||
QSet<QString> names;
|
||||
foreach (Material * m, materials) {
|
||||
foreach(Material * m, materials) {
|
||||
if (m->name.isEmpty()) m->name = "default_000";
|
||||
m->name = uniqueName(m->name, names);
|
||||
names << m->name;
|
||||
@@ -355,9 +352,8 @@ void Scene::dump() {
|
||||
void Scene::gatherSelection() {
|
||||
selected_.clear();
|
||||
ObjectBaseList ol = root_->children(true);
|
||||
foreach (ObjectBase * o, ol)
|
||||
if (o->isSelected())
|
||||
selected_ << o;
|
||||
foreach(ObjectBase * o, ol)
|
||||
if (o->isSelected()) selected_ << o;
|
||||
}
|
||||
|
||||
|
||||
@@ -369,9 +365,9 @@ void Scene::attachObject(ObjectBase * o) {
|
||||
setObjectMeshChanged(o);
|
||||
}
|
||||
if (o->material()) { // search suitable material in this scene
|
||||
uint ohash = o->material()->hash();
|
||||
uint ohash = o->material()->hash();
|
||||
bool need_new = true;
|
||||
foreach (Material * m, materials) {
|
||||
foreach(Material * m, materials) {
|
||||
if (m == o->material()) { // already exists by ptr
|
||||
need_new = false;
|
||||
break;
|
||||
@@ -384,7 +380,7 @@ void Scene::attachObject(ObjectBase * o) {
|
||||
}
|
||||
if (need_new) { // need to clone material and add to scene
|
||||
Material * nmat = new Material();
|
||||
*nmat = *(o->material());
|
||||
*nmat = *(o->material());
|
||||
nmat->setMapsChanged();
|
||||
o->setMaterial(nmat);
|
||||
materials << nmat;
|
||||
@@ -397,7 +393,7 @@ void Scene::attachObject(ObjectBase * o) {
|
||||
Mesh * Scene::attachMesh(Mesh * mesh) {
|
||||
if (!mesh) return 0;
|
||||
uint mhash = mesh->hash();
|
||||
foreach (Mesh * m, geometries) {
|
||||
foreach(Mesh * m, geometries) {
|
||||
if (m == mesh) { // already exists by ptr
|
||||
return m;
|
||||
}
|
||||
@@ -415,7 +411,7 @@ Mesh * Scene::attachMesh(Mesh * mesh) {
|
||||
void Scene::setTreeChanged() {
|
||||
if (destroying) return;
|
||||
tree_changed = true;
|
||||
foreach (Mesh * m, geometries) {
|
||||
foreach(Mesh * m, geometries) {
|
||||
m->setAllObjectsChanged(true);
|
||||
m->setAllSelectionChanged(true);
|
||||
}
|
||||
@@ -434,22 +430,20 @@ void Scene::setObjectMeshChanged(ObjectBase * o) {
|
||||
|
||||
|
||||
void Scene::prepareTree(ObjectBase * o) {
|
||||
foreach (ObjectBase * co, o->children_) {
|
||||
foreach(ObjectBase * co, o->children_) {
|
||||
if (co->isHidden()) continue;
|
||||
switch (co->type_) {
|
||||
case ObjectBase::glLight: {
|
||||
Light * l = globject_cast<Light * >(co);
|
||||
Light * l = globject_cast<Light *>(co);
|
||||
lights_used[l->light_type] << l;
|
||||
} break;
|
||||
} break;
|
||||
case ObjectBase::glMesh:
|
||||
if (co->mesh()) {
|
||||
geometries_used[co->pass()][co->mesh()] << co;
|
||||
co->setObjectsChanged();
|
||||
}
|
||||
break;
|
||||
case ObjectBase::glCamera:
|
||||
cameras_used << globject_cast<Camera * >(co);
|
||||
break;
|
||||
case ObjectBase::glCamera: cameras_used << globject_cast<Camera *>(co); break;
|
||||
default: break;
|
||||
}
|
||||
prepareTree(co);
|
||||
@@ -459,7 +453,7 @@ void Scene::prepareTree(ObjectBase * o) {
|
||||
|
||||
bool Scene::prepare() {
|
||||
changed_materials.clear();
|
||||
foreach (Material * m, materials) {
|
||||
foreach(Material * m, materials) {
|
||||
if (m->_changed) {
|
||||
need_reload_materials = tree_changed = true;
|
||||
changed_materials << m;
|
||||
@@ -470,7 +464,7 @@ bool Scene::prepare() {
|
||||
if (!tree_changed && !mat_changed) return false;
|
||||
aol = root_->children(true);
|
||||
if (tree_changed) {
|
||||
geometries_used[rpSolid ].clear();
|
||||
geometries_used[rpSolid].clear();
|
||||
geometries_used[rpTransparent].clear();
|
||||
lights_used.clear();
|
||||
cameras_used.clear();
|
||||
@@ -480,7 +474,7 @@ bool Scene::prepare() {
|
||||
cleanUnused();
|
||||
QMetaObject::invokeMethod(this, "treeChanged", Qt::QueuedConnection);
|
||||
}
|
||||
tree_changed = false;
|
||||
tree_changed = false;
|
||||
lights_changed = true;
|
||||
}
|
||||
mat_changed = false;
|
||||
@@ -489,36 +483,35 @@ bool Scene::prepare() {
|
||||
|
||||
|
||||
void Scene::destroy(QOpenGLExtraFunctions * f) {
|
||||
foreach (Mesh * g, geometries)
|
||||
foreach(Mesh * g, geometries)
|
||||
g->destroy(f);
|
||||
}
|
||||
|
||||
|
||||
void Scene::destroyUnused(QOpenGLExtraFunctions * f) {
|
||||
foreach (Mesh * i, td_geometries)
|
||||
foreach(Mesh * i, td_geometries)
|
||||
i->destroy(f);
|
||||
qDeleteAll(td_geometries);
|
||||
td_geometries.clear();
|
||||
}
|
||||
|
||||
|
||||
QDataStream & operator <<(QDataStream & s, const Scene * p) {
|
||||
QDataStream & operator<<(QDataStream & s, const Scene * p) {
|
||||
ChunkStream cs;
|
||||
//qDebug() << "place" << p->name() << "...";
|
||||
// qDebug() << "place" << p->name() << "...";
|
||||
QVector<short> geom_ind, mat_ind;
|
||||
ObjectBaseList cl = p->root_->children(true);
|
||||
geom_ind.reserve(cl.size());
|
||||
mat_ind.reserve(cl.size());
|
||||
foreach (ObjectBase * c, cl) {
|
||||
foreach(ObjectBase * c, cl) {
|
||||
geom_ind << p->geometries.indexOf(c->mesh());
|
||||
mat_ind << p->materials.indexOf(c->material());
|
||||
}
|
||||
cs.add(1, p->name_).add(10, p->geometries).add(11, p->materials)
|
||||
.add(20, p->root_).add(21, geom_ind).add(22, mat_ind);
|
||||
cs.add(1, p->name_).add(10, p->geometries).add(11, p->materials).add(20, p->root_).add(21, geom_ind).add(22, mat_ind);
|
||||
s << qCompress(cs.data());
|
||||
return s;
|
||||
}
|
||||
QDataStream & operator >>(QDataStream & s, Scene *& p) {
|
||||
QDataStream & operator>>(QDataStream & s, Scene *& p) {
|
||||
p = new Scene();
|
||||
QByteArray ba;
|
||||
s >> ba;
|
||||
@@ -527,21 +520,24 @@ QDataStream & operator >>(QDataStream & s, Scene *& p) {
|
||||
QVector<short> geom_ind, mat_ind;
|
||||
while (!cs.atEnd()) {
|
||||
switch (cs.read()) {
|
||||
case 1 : cs.get(p->name_); break;
|
||||
case 1: cs.get(p->name_); break;
|
||||
case 10: cs.get(p->geometries); break;
|
||||
case 11: cs.get(p->materials); break;
|
||||
case 20: cs.get(p->root_); p->root_->setScene(p); break;
|
||||
case 20:
|
||||
cs.get(p->root_);
|
||||
p->root_->setScene(p);
|
||||
break;
|
||||
case 21: cs.get(geom_ind); break;
|
||||
case 22: cs.get(mat_ind); break;
|
||||
}
|
||||
}
|
||||
p->makeMaterialsUniqueNames();
|
||||
ObjectBaseList cl = p->root_->children(true);
|
||||
int cnt = qMin(qMin(cl.size(), geom_ind.size()), mat_ind.size());
|
||||
int cnt = qMin(qMin(cl.size(), geom_ind.size()), mat_ind.size());
|
||||
for (int i = 0; i < cnt; ++i) {
|
||||
ObjectBase * c(cl[i]);
|
||||
if (geom_ind[i] >= 0) c->mesh_ = p->geometries[geom_ind[i]];
|
||||
if (mat_ind [i] >= 0) c->material_ = p->materials [mat_ind [i]];
|
||||
if (geom_ind[i] >= 0) c->mesh_ = p->geometries[geom_ind[i]];
|
||||
if (mat_ind[i] >= 0) c->material_ = p->materials[mat_ind[i]];
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user