OSDN Git Service

obj読み込み時のグループ分割形式の自動認識機能を追加
[qtgeoviewer/QtGeoViewer.git] / Src / LibQtGeoViewerCore / SceneMain.cpp
1 #include "StdAfx.h"
2 #include "SceneMain.h"
3
4 #include <LibGeo/Path.h>
5
6 #include <C2/graph/MaterialSamples.h>
7 #include <C2/gl/GlApiExt.h>
8
9 #include <C2/util/string_util.h>
10
11 #include <QFileInfo>
12
13 #include <sstream>
14 #include <map>
15
16 #include <boost/algorithm/string.hpp>
17
18 #include "Format/GeomReaderBuilder.h"
19
20
21
22 SceneMain::SceneMain(void)
23 {
24         m_ConstantColorStrength = 1.0f;
25 }
26
27 void SceneMain::Initialize(void)
28 {
29         m_DefaultMaterial = lib_graph::MaterialSamples::GetSilver();
30
31         m_DefaultAlphaMaterial = m_DefaultMaterial;
32         m_DefaultAlphaMaterial.SetAlphaAll( 0.75f );
33
34         m_DefaultTexture.InitializeTexture();
35
36         ClearObjects();
37
38         m_EnvImg.InitEnvMap();
39 }
40
41 void SceneMain::FinalizeScene(void)
42 {
43         m_DefaultTexture.FinalizeTexture();
44
45         m_Observers.clear();
46
47         m_EnvImg.ClearEnv();
48 }
49
50 void SceneMain::ClearObjects(void)
51 {
52         for (GeomObject& obj : m_Objects)
53         {
54                 obj.ClearObject();
55         }
56
57         m_Objects.clear();
58         m_Cursor3d.ResetCloseFace();
59
60         ReportDoneEditGeometry();
61 }
62
63
64 void SceneMain::ImportFileAutoFmt(const QString& path)
65 {
66         geom::GeomFileFormat fmt = FormatType::GetGeomFileTypeFromPath(path);
67         if (fmt == GeomFileFormat::None)
68                 throw FileLoadErrorException("Unknown format");
69
70         if (!ImportFile(path.toLocal8Bit().data(), fmt))
71                 throw FileLoadErrorException("Failed Load Geometry");
72 }
73
74 bool SceneMain::ImportFile(const std::string& filename, geom::GeomFileFormat fmt)
75 {
76         std::auto_ptr<GeomFileReader> reader;
77         reader.reset(GeomReaderBuilder::Create(fmt));
78         if (reader.get() == NULL)
79         {
80                 assert(false);
81                 return false;
82         }
83
84         RefreshObjectIndex();
85
86         return reader->Load(*this, filename);
87 }
88
89 GeomObject* SceneMain::CreateNewGeometry(void)
90 {
91         GeomObject* geom = new GeomObject();
92         m_Objects.push_back(geom);
93         RefreshObjectIndex();
94
95         return geom;
96 }
97
98
99 void AppendWeight(std::vector<float>& vw, std::vector<lm::vec3f>& vp, lm::matrix4f& mat_parent, GeomObject& g, Bone* b, int frame)
100 {
101         lm::matrix4f md;
102         if(frame == -1)
103                 md = b->m_NodeTrans;
104         else
105                 md = b->GetFrameMatrix(frame);
106
107         md = md * mat_parent;
108
109         for(size_t j = 0; j < b->m_Weights.size(); ++j)
110         {
111                 int vid = b->m_Weights[j].m_Vid;
112                 float weight = b->m_Weights[j].m_Weight;
113
114                 lm::vec3f v = g.m_BoneAnimation.m_SrcVertPos[vid];
115
116                 v = v * b->m_Offset * md;
117                 vw[vid] += weight;
118                 vp[vid] += v * weight;
119         }
120
121         for(size_t i = 0; i < b->m_Children.size(); ++i)
122         {
123                 AppendWeight(vw, vp, md, g, b->m_Children[i], frame);
124         }
125 }
126
127 void SceneMain::SetFrame(int frame)
128 {
129         GeomObject& g = m_Objects[0];
130         lib_geo::BaseMesh& m = g.m_MeshAry[0].m_Mesh;
131
132         m.m_Verts = g.m_BoneAnimation.m_SrcVertPos;
133
134         std::vector<float> vw(m.m_Verts.size(), 0.0f);
135         std::vector<lm::vec3f> vp(m.m_Verts.size());
136
137         for (BoneRoot& br : g.m_BoneAnimation.m_RootNodes)
138         {
139                 lm::matrix4f mi = br.m_Transform;
140                 AppendWeight(vw, vp, mi, g, br.m_Bone, frame);
141         }
142
143         for (size_t i = 0; i < m.m_Verts.size(); ++i)
144         {
145                 if(vw[i] > 0.0f)
146                         m.m_Verts[i] = vp[i] / vw[i];
147         }
148
149         m.UpdateNormal();
150 }
151
152 int SceneMain::GetMaxFrame(void) const
153 {
154         size_t max_frame = 0;
155         for (const GeomObject& g : m_Objects)
156         {
157                 for (const Bone& b : g.m_BoneAnimation.m_Bones)
158                 {
159                         max_frame = (std::max)(max_frame, b.m_Translate.size());
160                         max_frame = (std::max)(max_frame, b.m_Scale.size());
161                         max_frame = (std::max)(max_frame, b.m_Rotate.size());
162                 }
163         }
164
165         return max_frame;
166 }
167
168
169 void SceneMain::UpdateTransform(void)
170 {
171         SceneTransform& t = m_WorldTransform;
172
173         t.SetScale(1.0);
174         t.m_Translate.set_zero();
175
176         lm::range3f r = GetSceneBBox();
177         if (!r.is_valid())
178                 return;
179
180         if( m_Config.m_EnableAutoCentering )
181         {
182                 t.m_Translate = -r.mid_point();
183         }
184
185         if( m_Config.m_EnableAutoReisze )
186         {
187                 t.SetScale(1.0f / r.max_length());
188         }
189 }
190
191
192 void SceneMain::LoadDefaultMatTexture(const std::string& filename)
193 {
194         m_DefaultTexture.LoadTextureFromFile(filename.c_str(), true);
195         m_DefaultTexture.SetTextureGLAndReleaseImage(m_TexConfig);
196 }
197
198
199 //! \83I\83u\83T\81[\83o\82ð\83Z\83b\83g.
200 //! \8f\8a\97L\8c \82Í\8e\9d\82½\82È\82¢.
201 void SceneMain::AddObserver(SceneObserver* observer)
202 {
203         m_Observers.push_back( observer );
204 }
205
206 bool SceneMain::RemoveObserver(size_t idx)
207 {
208         assert( idx < m_Observers.size() );
209         if( idx < m_Observers.size() )
210                 return false;
211
212         std::vector<SceneObserver*>::iterator i = m_Observers.begin();
213         std::advance( i , idx );
214         m_Observers.erase( i );
215
216         return true;
217 }
218
219 bool SceneMain::RemoveObserver(SceneObserver* registered_observer)
220 {
221         for( size_t i = 0 ; i < m_Observers.size() ; ++i )
222         {
223                 if( m_Observers[i] == registered_observer )
224                         return RemoveObserver( i );
225         }
226
227         assert(false);
228         return false;
229 }
230
231
232 void SceneMain::ReportDoneEditGeometry(void)
233 {
234         for( size_t i = 0 ; i < m_Observers.size() ; ++i )
235         {
236                 m_Observers[i]->OnGeometryBuild(*this);
237         }
238 }
239
240 lm::range3f SceneMain::GetSceneBBox(void) const
241 {
242         lm::range3f bbox;
243         bbox.clear();
244
245         for (const GeomObject& obj : m_Objects)
246         {
247                 bbox.expand(obj.GetBBox());
248         }
249
250         return bbox;
251 }
252
253 lm::range3f SceneMain::GetSceneTransformedBBox(void) const
254 {
255         lm::range3f bbox = GetSceneBBox();
256
257         lm::range3f tbb;
258         tbb.clear();
259         tbb.expand(m_WorldTransform.TransformVec(bbox.min_point()));
260         tbb.expand(m_WorldTransform.TransformVec(bbox.max_point()));
261
262         return tbb;
263 }
264
265
266 GeomObject* SceneMain::GetPrimaryObject(void)
267 {
268         if (!m_Sels.IsObjectSelected())
269                 return NULL;
270
271         if (m_Objects.empty())
272                 return NULL;
273
274         return &m_Objects[m_Sels.GetSelObjectIdx()];
275 }
276
277 const GeomObject* SceneMain::GetPrimaryObject(void) const
278 {
279         if (!m_Sels.IsObjectSelected())
280                 return NULL;
281
282         if (m_Objects.empty())
283                 return NULL;
284
285         return &m_Objects[m_Sels.GetSelObjectIdx()];
286 }
287
288
289 void SceneMain::GetSelectedMeshes(std::vector<MeshBuf*>& meshes)
290 {
291         GeomObject* obj = GetPrimaryObject();
292         if (obj == NULL)
293                 return;
294
295         if (m_Sels.IsMBufSelected())
296         {
297                 meshes.resize(1, &obj->m_MeshAry[m_Sels.GetMBufIdx()]);
298         }
299         else
300         {
301                 meshes.reserve(obj->m_MeshAry.size());
302                 for (MeshBuf& m : obj->m_MeshAry)
303                 {
304                         meshes.push_back(&m);
305                 }
306         }
307 }
308
309 MeshBuf* SceneMain::GetPrimaryMeshbuf(void)
310 {
311         GeomObject* obj = GetPrimaryObject();
312         if (obj == NULL)
313                 return NULL;
314
315         if (!m_Sels.IsMBufSelected())
316                 return NULL;
317
318         return &obj->m_MeshAry[m_Sels.GetMBufIdx()];
319 }
320
321 const MeshBuf* SceneMain::GetPrimaryMeshbuf(void) const
322 {
323         const GeomObject* obj = GetPrimaryObject();
324         if (obj == NULL)
325                 return NULL;
326
327         if (!m_Sels.IsMBufSelected())
328                 return NULL;
329
330         return &obj->m_MeshAry[m_Sels.GetMBufIdx()];
331 }
332
333 GeomTextureSet* SceneMain::GetSelectedTexture(void)
334 {
335         int idx = GetSelectedMatIdx();
336         if (idx == -1)
337                 return NULL;
338
339         return GetPrimaryMeshbuf()->GetTexture(idx);
340 }
341
342 lib_geo::BaseMaterial* SceneMain::GetSelectedMaterial(void)
343 {
344         int idx = GetSelectedMatIdx();
345         if (idx == -1)
346                 return NULL;
347
348         return GetPrimaryMeshbuf()->GetMaterial(idx);
349 }
350
351 int SceneMain::GetSelectedMatIdx(void)
352 {
353         MeshBuf* mbuf = GetPrimaryMeshbuf();
354         if (mbuf == NULL)
355                 return -1;
356
357         int idx = m_Sels.GetSelMat();
358         if (!mbuf->IsValidMaterialIdx(idx))
359                 return -1;
360
361         return idx;
362 }
363
364
365 void SceneMain::RemoveItem(int sel_idx)
366 {
367         boost::ptr_vector<GeomObject>::iterator i;
368         i = m_Objects.begin();
369         i += sel_idx;
370
371         if (i->IsInChild(m_Cursor3d.CloseFaceMBuf))
372                 m_Cursor3d.ResetCloseFace();
373
374         m_Objects.erase(i);
375
376         m_Sels.ClearSelect();
377
378         RefreshObjectIndex();
379 }
380
381
382 void SceneMain::CreateSampleTexture(SampleTextureBuilder::TextureType tex_type)
383 {
384         SDL_Surface* tex = SampleTextureBuilder::CreateTexture(tex_type, 256);
385         if(tex == NULL)
386                 return;
387
388         m_DefaultTexture.SetFromSDLSurface( tex );
389         m_DefaultTexture.SetTextureGLAndReleaseImage(m_TexConfig);
390 }
391
392
393 void SceneMain::RefreshObjectIndex(void)
394 {
395         for (size_t i = 0; i < m_Objects.size(); ++i)
396         {
397                 GeomObject& o = m_Objects[i];
398                 o.m_ObjectIndex = (int)i;
399                 for (size_t j = 0; j < o.m_MeshAry.size(); ++j)
400                 {
401                         MeshBuf& m = o.m_MeshAry[j];
402                         m.m_MBufIdx = (int)j;
403                 }
404         }
405 }
406
407
408 bool SceneMain::ReloadObject(GeomObject* obj)
409 {
410         if(!obj->IsFileObject())
411                 return false;
412
413         int idx = FindObjectIdx(obj);
414         if (idx == -1)
415         {
416                 assert(false);
417                 return false;
418         }
419
420         geom::GeomFileFormat fmt = obj->m_FileFormat;
421         const std::string filename = obj->m_FilePath;
422
423         RemoveItem(idx);
424
425         return ImportFile(filename, fmt);
426 }
427
428 int SceneMain::FindObjectIdx(const GeomObject* obj) const
429 {
430         for (const GeomObject& o : m_Objects)
431         {
432                 if(&o == obj)
433                         return o.GetObjectIndex();
434         }
435
436         return -1;
437 }
438
439
440 void SceneMain::ShowAllObject(void)
441 {
442         for (GeomObject& o : m_Objects)
443         {
444                 o.m_Visible = true;
445                 for (MeshBuf& m : o.m_MeshAry)
446                         m.m_Visible = true;
447         }
448 }
449
450 void SceneMain::HideAllObject(void)
451 {
452         for (GeomObject& o : m_Objects)
453         {
454                 o.m_Visible = false;
455                 for (MeshBuf& m : o.m_MeshAry)
456                         m.m_Visible = false;
457         }
458 }
459
460 void SceneMain::ClearAllVertSelect(void)
461 {
462         for (GeomObject& obj : m_Objects)
463         {
464                 for (MeshBuf& mbuf : obj.m_MeshAry)
465                 {
466                         mbuf.ClearSelect();
467                 }
468         }
469 }
470
471
472 void SceneMain::AddCrossSectionRecord()
473 {
474         UpdateCrossSectionIfRequire(true);
475
476         for (GeomObject& obj : m_Objects)
477         {
478                 for (MeshBuf& mbuf : obj.m_MeshAry)
479                 {
480                         mbuf.m_CrossSectionLog.push_back(lib_geo::CrossSection());
481                         std::swap(mbuf.m_CrossSectionLog.back(), mbuf.m_CrossSection);
482                 }
483         }
484 }
485
486 void SceneMain::ClearCrossSectionRecord()
487 {
488         for (GeomObject& obj : m_Objects)
489         {
490                 for (MeshBuf& mbuf : obj.m_MeshAry)
491                 {
492                         mbuf.m_CrossSectionLog.clear();
493                 }
494         }
495 }
496
497 void SceneMain::GetFreeCutParam(lm::vec3f& p, lm::vec3f& n)
498 {
499         Cursor3D& c = m_Cursor3d;
500         p = c.CursorPos;
501         n = c.MeasureNorm;
502 }
503
504 void SceneMain::UpdateCrossSectionIfRequire(bool force_update)
505 {
506         const CrossSectionConfig& conf = m_CrossSectionConfig;
507
508         if (!force_update)
509         {
510                 if (!conf.IsRequireUpdateCS())
511                         return;
512         }
513
514         lib_geo::Plane cutplane;
515
516         if (conf.IsFreeCut())
517                 GetFreeCutParam(cutplane.origin, cutplane.normal);
518         else
519                 conf.GetCutPlane(GetSceneBBox(), cutplane);
520
521         bool cs_group = conf.m_EnableCrossSectionGroup;
522
523         for (GeomObject& obj : m_Objects)
524         {
525                 for (MeshBuf& mbuf : obj.m_MeshAry)
526                 {
527                         mbuf.UpdateCrossSection(cs_group, cutplane);
528                 }
529         }
530 }