OSDN Git Service

アニメーション逆再生機能追加
[qtgeoviewer/QtGeoViewer.git] / Src / QtGeoViewer / FormMain.cpp
1 #include "stdafx.h"
2 #include "FormMain.h"
3
4 #include <QFileInfo>
5 #include <fstream>
6 #include <sstream>
7
8 #include <cassert>
9 #include <QSettings>
10
11 #include "FormVertexBuilder.h"
12 #include "FullScreenPanel.h"
13
14 #include <Qt5Utility/QGui.h>
15
16 #include <QMessageBox>
17 #include <QFileDialog>
18 #include <QPrintDialog>
19 #include <QPrintPreviewDialog>
20
21 #include "BuildInfo.h"
22 #include "PathInfo.h"
23 #include "PostprocLibrary.h"
24 #include "SampleShapeBuilder.h"
25 #include "ShaderLibrary.h"
26 #include "QGVAboutDlg.h"
27
28 #include "FormCustomShader.h"
29 #include "FormPyScript.h"
30 #include "MatcapSelectDlg.h"
31 #include "EnvmapSelectDlg.h"
32 #include "FileDlgUtil.h"
33 #include "TreeUtil.h"
34
35
36
37 QColor ToQColor(const lib_graph::color4f& c)
38 {
39         int r = lm::clamp(0, (int)(c.r() * 255.0f), 255);
40         int g = lm::clamp(0, (int)(c.g() * 255.0f), 255);
41         int b = lm::clamp(0, (int)(c.b() * 255.0f), 255);
42         int a = lm::clamp(0, (int)(c.a() * 255.0f), 255);
43
44         return QColor(r, g, b, a);
45 }
46
47
48
49 FormMain::FormMain(QWidget *parent)
50         : QMainWindow(parent)
51         , m_MatcapDlg(NULL)
52         , m_EnvmapDlg(NULL)
53         , m_CustomShaderDlg(NULL)
54         , m_PyScriptDlg(NULL)
55 {
56         ui.setupUi(this);
57
58         m_EnableAllFeatures = false;
59         m_LastFocusedDockDlg = NULL;
60
61         setAcceptDrops(true);
62
63         setWindowTitle("QtGeoViewer");
64
65         InitializeGLView();
66         InitializeStatusBar();
67         InitializeMenu();
68         InitializeCoordinateCombobox();
69         Initialize2DViewSrcCombobox();
70         InitializeEventFilter();
71         InitContextMenu();
72
73         InitDataBinding();
74
75         SyncViewSettingsFromGUI();
76         SyncUVViewSettingsFromGUI();
77         SyncSceneSettingsFromGUI();
78         ApplyGeomStateFromGUI();
79         SyncShaderSettingsToGUI();
80
81         ui.toolBar_View->setVisible( ui.actionWindow_ToolBarView->isChecked() );
82
83         UpdateViewTypeFromMenu();
84
85         CenteringSplitter();
86
87         RebuildObjectList();
88
89         InitializeSubDlg();
90
91         InitializeAnimation();
92
93         InitializeFromConfigFiles();
94
95         HideFeatures();
96
97         ResetHoleRange();
98
99         this->show();
100
101         m_InitRect = rect();
102         m_InitRect.translate(pos());
103
104         LoadLastWinPos();
105
106         ProcArguments();
107 }
108
109 FormMain::~FormMain()
110 {
111 }
112
113
114 void FormMain::LoadLastWinPos(void)
115 {
116         QString file = PathInfo::GetPosConfigFilePath();
117         QSettings conf(file, QSettings::IniFormat);
118
119         QVariant v;
120         v = conf.value("main/WindowPos");
121         if (v.isValid())
122         {
123                 QRect r = v.toRect();
124                 int dl = r.left();
125                 int dt = r.top();
126                 int dw = r.width();
127                 int dh = r.height();
128
129                 resize(dw, dh);
130
131                 move(QPoint(dl, dt));
132         }
133
134         v = conf.value("main/WinState");
135         if (v.isValid())
136         {
137                 if (v.toBool())
138                         setWindowState(Qt::WindowMaximized);
139         }
140 }
141
142 void FormMain::SaveWinPos(void)
143 {
144         QString file = PathInfo::GetPosConfigFilePath();
145         QSettings conf(file, QSettings::IniFormat);
146
147         conf.setValue("main/WinState", isMaximized());
148
149         if (isMaximized() || isMinimized())
150         {
151                 setWindowState(Qt::WindowNoState);
152                 QApplication::processEvents(QEventLoop::ExcludeUserInputEvents);
153         }
154
155         QRect r = rect();
156         r.translate(pos());
157
158         conf.setValue("main/WindowPos", r);
159 }
160
161 void FormMain::HideFeatures(void)
162 {
163         bool b = m_EnableAllFeatures;
164
165         ui.actionVertexBuilder->setVisible(b);
166         ui.menuPrintRoot->menuAction()->setVisible(b);
167         ui.actionShadowmap->setVisible(b);
168         ui.actionEnvmap->setVisible(b);
169         ui.actionShaderCustom->setVisible(b);
170         ui.actionWindowCustomShader->setVisible(b);
171         ui.actionPyScript->setVisible(b);
172         ui.actionConsole->setVisible(b);
173         ui.actionReleaseShader->setVisible(b);
174 }
175
176 void FormMain::InitializeEventFilter(void)
177 {
178         ui.editEnvMap->installEventFilter(this);
179         ui.editMatcap->installEventFilter(this);
180
181         ui.editCurrentTexName->installEventFilter(this);
182         ui.editCurrentMatNormalMap->installEventFilter(this);
183         ui.editMatCapEachMaterial->installEventFilter(this);
184 }
185
186 void FormMain::InitDataBinding(void)
187 {
188         InitializeVisiblStateMenu();
189         InitializeUVStateMenu();
190         InitializeSceneStateMenu();
191         InitializeGeomStateMenu();
192         InitializeCursorMenu();
193 }
194
195 void FormMain::InitializeVisiblStateMenu(void)
196 {
197         DataBinderMap& dbmap = m_Binder_ViewConfig;
198
199         View3DConfig& cfg_3d = m_View3d.m_Config;
200
201         dbmap.AddBinder(new MenuBinder(ui.actionDrawBBox            , &cfg_3d.m_DrawBBox            ));
202         dbmap.AddBinder(new MenuBinder(ui.actionFaceVBO             , &cfg_3d.m_EnableFaceVBO       ));
203         dbmap.AddBinder(new MenuBinder(ui.actionVidTopMost          , &cfg_3d.m_ShowVidTopMost      ));
204         dbmap.AddBinder(new MenuBinder(ui.actionDrawBBoxRange       , &cfg_3d.m_DrawBBoxRange       ));
205         dbmap.AddBinder(new MenuBinder(ui.actionWireDispList        , &cfg_3d.m_EnableWireDispList  ));
206         dbmap.AddBinder(new MenuBinder(ui.actionMultisample         , &cfg_3d.m_EnableMultisample   ));
207         dbmap.AddBinder(new MenuBinder(ui.actionCoverageTransparent , &cfg_3d.m_EnableCoverageTrans ));
208         dbmap.AddBinder(new MenuBinder(ui.actionSeparateSpecular    , &cfg_3d.m_SeparateSpecular    ));
209         dbmap.AddBinder(new MenuBinder(ui.actionShowSelVertCoord    , &cfg_3d.m_ShowSelVertCoord    ));
210         dbmap.AddBinder(new MenuBinder(ui.actionHighlightSelected   , &cfg_3d.m_HighlightSelected   ));
211         dbmap.AddBinder(new MenuBinder(ui.actionFixMaterialSilver   , &cfg_3d.m_UseFixMaterial      ));
212         dbmap.AddBinder(new MenuBinder(ui.actionShadowmapBuffer     , &cfg_3d.m_DrawShadowmapBuf    ));
213         dbmap.AddBinder(new MenuBinder(ui.actionEnableTexture3D     , &cfg_3d.m_EnableTexture       ));
214         dbmap.AddBinder(new MenuBinder(ui.actionEnableLighting      , &cfg_3d.m_EnableLighting      ));
215         dbmap.AddBinder(new MenuBinder(ui.actionEnableCulling       , &cfg_3d.m_EnableCullFace      ));
216         dbmap.AddBinder(new MenuBinder(ui.actionDrawWire            , &cfg_3d.m_DrawWire            ));
217         dbmap.AddBinder(new MenuBinder(ui.actionDrawVid             , &cfg_3d.m_DrawVid             ));
218         dbmap.AddBinder(new MenuBinder(ui.actionDrawVertNormal      , &cfg_3d.m_DrawVertNormal      ));
219         dbmap.AddBinder(new MenuBinder(ui.actionDrawVert            , &cfg_3d.m_DrawVert            ));
220         dbmap.AddBinder(new MenuBinder(ui.actionWireVBO             , &cfg_3d.m_EnableWireVBO       ));
221         dbmap.AddBinder(new MenuBinder(ui.actionIndexColorMode      , &cfg_3d.m_IndexMaterial       ));
222         dbmap.AddBinder(new MenuBinder(ui.actionFBMaterial          , &cfg_3d.m_FBMaterial          ));
223         dbmap.AddBinder(new MenuBinder(ui.actionDrawMiniAxis        , &cfg_3d.m_DrawMiniAxis        ));
224         dbmap.AddBinder(new MenuBinder(ui.actionDrawLookPos         , &cfg_3d.m_DrawLookPos         ));
225         dbmap.AddBinder(new MenuBinder(ui.actionDrawLightPos        , &cfg_3d.m_DrawLightPosition   ));
226         dbmap.AddBinder(new MenuBinder(ui.actionDrawGround          , &cfg_3d.m_DrawGround          ));
227         dbmap.AddBinder(new MenuBinder(ui.actionDrawFid             , &cfg_3d.m_DrawFid             ));
228         dbmap.AddBinder(new MenuBinder(ui.actionDrawFace            , &cfg_3d.m_DrawFace            ));
229         dbmap.AddBinder(new MenuBinder(ui.actionCameraRecords       , &cfg_3d.m_DrawCameraRecord    ));
230         dbmap.AddBinder(new MenuBinder(ui.actionDrawAxis            , &cfg_3d.m_DrawAxis            ));
231         dbmap.AddBinder(new MenuBinder(ui.actionDoubleSideShading   , &cfg_3d.m_DoubleSideShading   ));
232         dbmap.AddBinder(new MenuBinder(ui.actionDirectionalLight    , &cfg_3d.m_LightIsDirectional  ));
233         dbmap.AddBinder(new MenuBinder(ui.actionCullFrontOrBack     , &cfg_3d.m_CullAngle_F         ));
234         dbmap.AddBinder(new MenuBinder(ui.actionHighlightMaterial   , &cfg_3d.m_HighlightMaterial   ));
235         dbmap.AddBinder(new MenuBinder(ui.actionCloseVert           , &cfg_3d.m_ShowCloseVertInfo   ));
236         dbmap.AddBinder(new MenuBinder(ui.actionCameraRange         , &cfg_3d.m_DrawRenderRange     ));
237         dbmap.AddBinder(new MenuBinder(ui.actionRenderTime          , &cfg_3d.m_ShowRenderTime      ));
238         dbmap.AddBinder(new MenuBinder(ui.actionUseFixTexture       , &cfg_3d.m_UseFixTexture       ));
239         dbmap.AddBinder(new MenuBinder(ui.actionShowSelVertIdx      , &cfg_3d.m_ShowSelVertIdx      ));
240         dbmap.AddBinder(new MenuBinder(ui.actionShowMeshBound       , &cfg_3d.m_ShowMeshBound       ));
241         dbmap.AddBinder(new MenuBinder(ui.actionPickTransparent     , &cfg_3d.m_PickTransparent     ));
242         dbmap.AddBinder(new MenuBinder(ui.actionFlatShading         , &cfg_3d.m_EnableFlatShade     ));
243         dbmap.AddBinder(new MenuBinder(ui.actionDrawPolylineLenWhl  , &cfg_3d.m_DrawPolylineLenWhl  ));
244         dbmap.AddBinder(new MenuBinder(ui.actionDrawPolylineLen     , &cfg_3d.m_DrawPolylineLen     ));
245         dbmap.AddBinder(new MenuBinder(ui.actionDrawPolylineIdx     , &cfg_3d.m_DrawPolylineIdx     ));
246         dbmap.AddBinder(new MenuBinder(ui.actionDrawPolyline        , &cfg_3d.m_DrawPolyline        ));
247         dbmap.AddBinder(new MenuBinder(ui.actionDrawBone            , &cfg_3d.m_DrawBone            ));
248         dbmap.AddBinder(new MenuBinder(ui.actionShowMeasure         , &cfg_3d.m_DrawCameraMeasure   ));
249         dbmap.AddBinder(new MenuBinder(ui.actionFlipMouseMR         , &cfg_3d.m_FlipMouseMR         ));
250         dbmap.AddBinder(new MenuBinder(ui.actionSyncLightToCamera   , &cfg_3d.m_SyncLightTocamera   ));
251
252         for (GuiBinder& binder : dbmap.m_BinderMap)
253         {
254                 MenuBinder* mb = dynamic_cast<MenuBinder*>(&binder);
255                 if (mb != NULL)
256                 {
257                         QAction* a = mb->GetMenu();
258                         connect(
259                                 a,
260                                 SIGNAL(triggered(bool)),
261                                 this,
262                                 SLOT(actionVisibleStates_Triggered(bool)));
263                 }
264         }
265 }
266
267 void FormMain::InitializeUVStateMenu(void)
268 {
269         DataBinderMap& dbmap = m_Binder_UVConfig;
270
271         dbmap.AddBinder(new MenuBinder(ui.actionUVRepeat         , &m_View2d.m_RepeatTexture             ));
272         dbmap.AddBinder(new MenuBinder(ui.actionUseFixTexture2D  , &m_View2d.m_UseFixTexute              ));
273         dbmap.AddBinder(new MenuBinder(ui.actionShowVertex2d     , &m_View2d.m_DrawVerts                 ));
274         dbmap.AddBinder(new MenuBinder(ui.actionShowImage2d      , &m_View2d.m_EnableTexture             ));
275         dbmap.AddBinder(new MenuBinder(ui.actionTextureMipmap    , &m_Scene.m_TexConfig.m_EnableMipmap   ));
276         dbmap.AddBinder(new MenuBinder(ui.actionTextureCompress  , &m_Scene.m_TexConfig.m_EnableCompress ));
277         dbmap.AddBinder(new MenuBinder(ui.actionUVFlipY          , &m_Scene.m_TextureTransform.m_FlipY   ));
278
279         for (GuiBinder& binder : dbmap.m_BinderMap)
280         {
281                 MenuBinder* mb = dynamic_cast<MenuBinder*>(&binder);
282                 if (mb != NULL)
283                 {
284                         QAction* a = mb->GetMenu();
285                         connect(
286                                 a,
287                                 SIGNAL(triggered(bool)),
288                                 this,
289                                 SLOT(actionVisibleStatesUV_Triggered(bool)));
290                 }
291         }
292 }
293
294 void FormMain::InitializeSceneStateMenu(void)
295 {
296         DataBinderMap& dbmap = m_Binder_Scene;
297
298         dbmap.AddBinder(new CheckboxBinder( ui.checkEnvMap         , &m_Scene.m_EnvImg.m_VisibleEnvSphere       ));
299         dbmap.AddBinder(new CheckboxBinder( ui.checkEnvReflection  , &m_Scene.m_EnvImg.m_IsEnableReflection     ));
300         dbmap.AddBinder(new CheckboxBinder( ui.checkShadowEnabled  , &m_Scene.m_ShadowConfig.m_EnableShadow     ));
301         dbmap.AddBinder(new CheckboxBinder( ui.checkSoftShadow     , &m_Scene.m_ShadowConfig.m_EnableSoftShadow ));
302
303         for (GuiBinder& binder : dbmap.m_BinderMap)
304         {
305                 CheckboxBinder* mb = dynamic_cast<CheckboxBinder*>(&binder);
306                 if (mb != NULL)
307                 {
308                         QCheckBox* c = mb->GetCheckBox();
309                         connect(
310                                 c,
311                                 SIGNAL(toggled(bool)),
312                                 this,
313                                 SLOT(actionSceneStates_Toggled(bool)));
314                 }
315         }
316 }
317
318 void FormMain::InitializeCursorMenu(void)
319 {
320         DataBinderMap& dbmap = m_Binder_Cursor;
321
322         Cursor3D& cursor = m_Scene.m_Cursor3d;
323         dbmap.AddBinder(new MenuBinder( ui.actionShowCursor        , &cursor.ShowCursor     ));
324         dbmap.AddBinder(new MenuBinder( ui.actionCursorToDepth     , &cursor.CursorDepth    ));
325         dbmap.AddBinder(new MenuBinder( ui.actionCursorCoord       , &cursor.ShowCoord      ));
326         dbmap.AddBinder(new MenuBinder( ui.actionCheckBaryCoord    , &cursor.CheckBaryCoord ));
327         dbmap.AddBinder(new MenuBinder( ui.actionSelectCloseMat    , &cursor.SelCloseVert   ));
328         dbmap.AddBinder(new MenuBinder( ui.actionCursorAxis        , &cursor.ShowAxis       ));
329         dbmap.AddBinder(new MenuBinder( ui.actionMeasure           , &cursor.ShowMeasure    ));
330         dbmap.AddBinder(new MenuBinder( ui.actionMeasureLen        , &cursor.ShowMeasureLen ));
331         dbmap.AddBinder(new MenuBinder( ui.actionMeasureXYZ        , &cursor.ShowMeasureXYZ ));
332         dbmap.AddBinder(new MenuBinder( ui.actionRecordStroke      , &cursor.RecordStroke   ));
333         dbmap.AddBinder(new MenuBinder( ui.actionShowStrokeLength  , &cursor.ShowStrokeLen  ));
334         dbmap.AddBinder(new MenuBinder( ui.actionTransparentStroke , &cursor.TranspStorke   ));
335
336         for (GuiBinder& binder : dbmap.m_BinderMap)
337         {
338                 MenuBinder* mb = dynamic_cast<MenuBinder*>(&binder);
339                 if (mb != NULL)
340                 {
341                         QAction* a = mb->GetMenu();
342                         connect(
343                                 a,
344                                 SIGNAL(triggered(bool)),
345                                 this,
346                                 SLOT(actionCursorMenuStates_Toggled(bool)));
347                 }
348         }
349 }
350
351
352 void FormMain::InitializeGeomStateMenu(void)
353 {
354         AddGeomStateAction( ui.actionCentering  );
355         AddGeomStateAction( ui.actionAutoResize );
356 }
357
358 void FormMain::AddGeomStateAction(const QAction* action)
359 {
360         connect(
361                 action,
362                 SIGNAL(triggered(bool)),
363                 this,
364                 SLOT(actionGeomStates_Triggered(bool)));
365 }
366
367
368 void FormMain::InitializeGLView(void)
369 {
370         ui.GLWidgetMain->setMouseTracking(true);
371         ui.GLWidgetUV->setMouseTracking(true);
372
373         ui.GLWidgetMain->SetViewer(&m_View3d);
374         m_View3d.m_Widgets = &m_Widgets;
375         m_View3d.RegisterScene(&m_Scene);
376         m_View3d.InitializeView(ui.GLWidgetMain);
377
378         ui.GLWidgetUV->SetViewer(&m_View2d);
379         m_View2d.m_Widgets = &m_Widgets;
380         m_View2d.RegisterScene(&m_Scene);
381         m_View2d.InitializeView(ui.GLWidgetUV);
382
383         m_Widgets.AddWidget(ui.GLWidgetMain);
384         m_Widgets.AddWidget(ui.GLWidgetUV);
385
386         // OpenGL\82Ì\83\8a\83X\83g\82Ì\8b¤\97L\89»
387         SetContextShare();
388
389         m_ContextShare.BeginDrawTop();
390
391         m_Scene.Initialize();
392
393         m_ContextShare.EndDrawTop();
394
395         connect(
396                 &m_View3d,
397                 SIGNAL(SelectedObjectChanged(int, int)),
398                 SLOT(View3D_SelectedObjectChanged(int, int)));
399         connect(
400                 &m_View3d,
401                 SIGNAL(SelectedMatChanged(int)),
402                 SLOT(View3D_SelectedMatChanged(int)));
403         connect(
404                 &m_View3d,
405                 SIGNAL(CameraMoved(void)),
406                 SLOT(View3D_CameraMoved(void)));
407         connect(
408                 &m_View3d,
409                 SIGNAL(StatusTipChanged(QString)),
410                 SLOT(View3D_StatusTipChanged(QString)));
411         connect(
412                 &m_View3d,
413                 SIGNAL(SequenceStepped(int)),
414                 SLOT(View3D_SequenceStepped(int)));
415         connect(
416                 &m_View3d,
417                 SIGNAL(CursorMoved()),
418                 SLOT(View3D_CursorMoved()));
419 }
420
421 // OpenGL\82Ì\83\8a\83X\83g\82Ì\8b¤\97L\89»
422 void FormMain::SetContextShare(void)
423 {
424         ui.GLWidgetUV->makeCurrent();
425         m_ContextShare.AddContext( GetDC((HWND)ui.GLWidgetUV->winId()) , wglGetCurrentContext() );
426         ui.GLWidgetUV->doneCurrent();
427
428         ui.GLWidgetMain->makeCurrent();
429         m_ContextShare.AddContext( GetDC((HWND)ui.GLWidgetUV->winId()) , wglGetCurrentContext() );
430         ui.GLWidgetMain->doneCurrent();
431
432         m_ContextShare.MakeShare();
433 }
434
435 void FormMain::InitializeCoordinateCombobox(void)
436 {
437         ui.comboCoordinate->blockSignals(true);
438         ui.comboCoordinate->addItem("Yup RH"); // RUF
439         ui.comboCoordinate->addItem("Zup RH"); // FRU
440         ui.comboCoordinate->addItem("Xup RH"); // UFR
441         ui.comboCoordinate->addItem("Yup LH"); // RUB
442         ui.comboCoordinate->addItem("Zup LH"); // BRU
443         ui.comboCoordinate->addItem("Xup LH"); // UBR
444         ui.comboCoordinate->blockSignals(false);
445 }
446
447 void FormMain::Initialize2DViewSrcCombobox(void)
448 {
449         ui.combo2DViewSrcType->blockSignals(true);
450         ui.combo2DViewSrcType->addItem("Color");
451         ui.combo2DViewSrcType->addItem("Normal");
452         ui.combo2DViewSrcType->blockSignals(false);
453 }
454
455 void FormMain::InitializeStatusBar(void)
456 {
457         m_StatusBar0 = new QLabel(this);
458         m_StatusBar1 = new QLabel(this);
459         ui.statusBar->addWidget(m_StatusBar0, 1);
460         ui.statusBar->addWidget(m_StatusBar1, 0);
461
462         m_StatusBar0->setText("");
463
464         m_StatusBar1->setMinimumWidth(290);
465         m_StatusBar1->setText("");
466 }
467
468 void FormMain::InitializeFromConfigFiles(void)
469 {
470         if (!InitializeConfig(PathInfo::GetGuiConfigFilePath()))
471         {
472                 InitializeConfig(PathInfo::GetDefaultGuiConfigFilePath());
473         }
474
475         OpenCameraFile(PathInfo::GetCameraLogFilePath());
476
477         LoadWindowLayout(PathInfo::GetWindowLayoutConfigFilePath());
478
479         if (!QGui::LoadGUIState(this, PathInfo::GetLayoutConfigFilePath()))
480         {
481                 QGui::LoadGUIState(this, PathInfo::GetDefaultLayoutConfigFilePath());
482         }
483 }
484
485 void FormMain::LoadDefaultConfig(void)
486 {
487         InitializeConfig(PathInfo::GetDefaultGuiConfigFilePath());
488         QGui::LoadGUIState(this, PathInfo::GetDefaultLayoutConfigFilePath());
489 }
490
491 void FormMain::SaveConfig(void)
492 {
493         PathInfo::CreateConfiDirIfNotExist();
494
495         SaveConfigFile(PathInfo::GetGuiConfigFilePath());
496
497         m_View3d.m_CameraRecord.SaveCamera(PathInfo::GetCameraLogFilePath().toLocal8Bit().data());
498
499         QGui::SaveGUIState(this, PathInfo::GetLayoutConfigFilePath());
500
501         SaveWindowLayout(PathInfo::GetWindowLayoutConfigFilePath());
502 }
503
504 bool FormMain::InitializeConfig(QString path)
505 {
506         View3DConfig& config_3d = m_View3d.m_Config;
507
508         GuiConfig cfg;
509         cfg.m_Config3D = &config_3d;
510         cfg.m_Scene    = &m_Scene;
511
512         if (!cfg.LoadConfigT(path.toLocal8Bit().data()))
513                 return false;
514
515         ui.actionUVAutoFit->setChecked(cfg.m_AutFitUVView);
516
517         ui.comboCoordinate->setCurrentIndex(cfg.m_CoordType);
518
519         CreateRecentFilesMenu(cfg.m_RecentFiles);
520
521         m_Binder_ViewConfig.UpdateAllGUI(true);
522         m_Binder_UVConfig.UpdateAllGUI(true);
523         m_Binder_Scene.UpdateAllGUI(true);
524         m_Binder_Cursor.UpdateAllGUI(true);
525
526         ApplyGeomStateDataoToGUI();
527
528         SyncViewSettingsFromGUI();
529         SyncUVViewSettingsFromGUI();
530         SyncShaderSettingsToGUI();
531
532         m_EnableAllFeatures = cfg.m_EnableAllFeatures;
533
534         return true;
535 }
536
537 void FormMain::SaveConfigFile(QString path)
538 {
539         GuiConfig cfg;
540         cfg.m_Config3D = &m_View3d.m_Config;
541         cfg.m_Scene    = &m_Scene;
542
543         cfg.m_EnableAllFeatures = m_EnableAllFeatures;
544
545         cfg.m_AutFitUVView = ui.actionUVAutoFit ->isChecked();
546
547         cfg.m_CoordType = ui.comboCoordinate->currentIndex();
548
549         CreateRecentFilesFromMenu(cfg.m_RecentFiles);
550
551         cfg.SaveConfigT(path.toLocal8Bit().data());
552 }
553
554
555 void FormMain::InitializeSubDlg(void)
556 {
557         connect(
558                 &m_WireColorSelDlg,
559                 SIGNAL(currentColorChanged(const QColor &)),
560                 this,
561                 SLOT(WireOverlayColorChanged(const QColor &)));
562         connect(
563                 &m_DiffuseColorSelDlg,
564                 SIGNAL(currentColorChanged(const QColor &)),
565                 this,
566                 SLOT(FaceDiffuseColorChanged(const QColor &)));
567         connect(
568                 &m_BGColorSelDlg,
569                 SIGNAL(currentColorChanged(const QColor &)),
570                 this,
571                 SLOT(BGColorChanged(const QColor &)));
572         connect(
573                 &m_SelMatColorSelDlg,
574                 SIGNAL(currentColorChanged(const QColor &)),
575                 this,
576                 SLOT(SelMatColorChanged(const QColor &)));
577
578         m_SelMatColorWidget = NULL;
579
580         m_ViewConfigDlg.InitializeConfigDlg(&m_View3d.m_Config);
581         connect(
582                 &m_ViewConfigDlg,
583                 SIGNAL(ConfigChanged()),
584                 this,
585                 SLOT(ConfigChangedDlg_ConfigChanged()));
586
587         m_CrossSectionDlg.InitializeConfigDlg(&m_View3d);
588         connect(
589                 &m_CrossSectionDlg,
590                 SIGNAL(ConfigChanged()),
591                 this,
592                 SLOT(CrossSectionDlg_ConfigChanged()));
593 }
594
595 void FormMain::InitializeAnimation(void)
596 {
597         connect(
598                 &m_AnimationTimer,
599                 SIGNAL(timeout()),
600                 this,
601                 SLOT(OnAnimationTimerUpdated()));
602         m_AnimationTimer.setInterval(20);
603 }
604
605 void FormMain::InitializeMenu(void)
606 {
607         m_AGroup_Window = new QActionGroup(this);
608         m_AGroup_Window->setExclusive(true);
609         m_AGroup_Window->addAction( ui.actionWindow_3DView    );
610         m_AGroup_Window->addAction( ui.actionWindow_UVView    );
611         m_AGroup_Window->addAction( ui.actionWindows_DualView );
612
613         m_AGroup_Shader = new QActionGroup(this);
614         m_AGroup_Shader->setExclusive(true);
615         m_AGroup_Shader->addAction( ui.actionShaderDefault   );
616         m_AGroup_Shader->addAction( ui.actionShaderPhong     );
617         m_AGroup_Shader->addAction( ui.actionShaderCustom    );
618         m_AGroup_Shader->addAction( ui.actionNormalColor     );
619         m_AGroup_Shader->addAction( ui.actionDepthColor      );
620         m_AGroup_Shader->addAction( ui.actionShadowmap       );
621         m_AGroup_Shader->addAction( ui.actionEnvmap          );
622         m_AGroup_Shader->addAction( ui.actionIntegrateShader );
623         m_AGroup_Shader->addAction( ui.actionMatcapShader    );
624
625         m_AGroup_PProc = new QActionGroup(this);
626         m_AGroup_PProc->addAction( ui.actionPostProcNone            );
627         m_AGroup_PProc->addAction( ui.actionPostProcAntialias       );
628         m_AGroup_PProc->addAction( ui.actionPostProcBorder          );
629         m_AGroup_PProc->addAction( ui.actionPostProcDepthLayerColor );
630         m_AGroup_PProc->addAction( ui.actionPostProcDepthColor      );
631         m_AGroup_PProc->addAction( ui.actionPostProcDepthOfField    );
632 }
633
634 void FormMain::InitContextMenu(void)
635 {
636         QList<QAction*> actions;
637         actions
638                 << ui.actionSelObjectVisible
639                 << ui.actionSelObjectVertexOnlyMode
640                 << ui.actionSelObjectDelete
641                 << ui.actionSelObjectReload
642                 << ui.actionSelObjectFlipFace
643                 << ui.actionSelObjectFlipNormal
644                 << ui.actionSelObjectOpenDir
645                 << ui.actionActionSelObjectShowOnlyOnce
646                 << ui.actionSelObjectTriangulate
647                 << ui.actionTreeCollapseAll
648                 << ui.actionTreeExpandAll;
649
650         QTreeWidget* obj_tree = ui.treeObjects;
651
652         obj_tree->setContextMenuPolicy(Qt::ActionsContextMenu);
653         obj_tree->addActions(actions);
654 }
655
656 void FormMain::ProcArguments(void)
657 {
658         QStringList args = QApplication::arguments();
659         for (int i = 1; i < args.size(); ++i)
660         {
661                 QString s = args[i];
662                 OpenGeomFile(s);
663         }
664 }
665
666 void FormMain::closeEvent(QCloseEvent *e)
667 {
668         SaveWinPos();
669
670         SaveConfig();
671
672         e->accept();
673
674         m_ViewConfigDlg.close();
675         m_CrossSectionDlg.close();
676         m_FullscreenPanel.close();
677
678         if (m_CustomShaderDlg != NULL)
679                 m_CustomShaderDlg->close();
680         if (m_PyScriptDlg != NULL)
681                 m_PyScriptDlg->close();
682
683         if (m_MatcapDlg != NULL)
684                 m_MatcapDlg->close();
685         if (m_EnvmapDlg != NULL)
686                 m_EnvmapDlg->close();
687
688         m_ContextShare.BeginDrawTop();
689         m_Scene.FinalizeScene();
690         m_ContextShare.EndDrawTop();
691 }
692
693
694 bool FormMain::eventFilter(QObject * filterobj, QEvent * filterevt)
695 {
696         if (filterobj == ui.editEnvMap)
697         {
698                 if (filterevt->type() == QEvent::DragEnter)
699                         return AcceptDropFilterIfUrl(filterevt);
700
701                 if (filterevt->type() == QEvent::Drop)
702                         return OnDropFile_editEnvMap(filterevt);
703         }
704         else if (filterobj == ui.editMatcap)
705         {
706                 if (filterevt->type() == QEvent::DragEnter)
707                         return AcceptDropFilterIfUrl(filterevt);
708
709                 if (filterevt->type() == QEvent::Drop)
710                         return OnDropFile_editMatcap(filterevt);
711         }
712         else if (filterobj == ui.editMatCapEachMaterial)
713         {
714                 if (filterevt->type() == QEvent::DragEnter)
715                         return AcceptDropFilterIfUrl(filterevt);
716
717                 if (filterevt->type() == QEvent::Drop)
718                         return OnDropFile_editMatcapEachMat(filterevt);
719         }
720         else if (filterobj == ui.editCurrentTexName)
721         {
722                 if (filterevt->type() == QEvent::DragEnter)
723                         return AcceptDropFilterIfUrl(filterevt);
724
725                 if (filterevt->type() == QEvent::Drop)
726                         return OnDropFile_editCurrentTexName(filterevt);
727         }
728         else if (filterobj == ui.editCurrentMatNormalMap)
729         {
730                 if (filterevt->type() == QEvent::DragEnter)
731                         return AcceptDropFilterIfUrl(filterevt);
732
733                 if (filterevt->type() == QEvent::Drop)
734                         return OnDropFile_editCurrentMatNormalMap(filterevt);
735         }
736
737         return QMainWindow::eventFilter(filterobj, filterevt);
738 }
739
740 bool FormMain::OnDropFile_editEnvMap(QEvent * filterevt)
741 {
742         QString path = GetFirstLoadableImagePathFromDragEvent(filterevt);
743         if (!path.isEmpty())
744                 LoadEnvMap(path);
745
746         return true;
747 }
748
749 bool FormMain::OnDropFile_editMatcap(QEvent * filterevt)
750 {
751         QString path = GetFirstLoadableImagePathFromDragEvent(filterevt);
752         if (!path.isEmpty())
753                 LoadMatcapImage(path);
754
755         return true;
756 }
757
758 bool FormMain::OnDropFile_editMatcapEachMat(QEvent * filterevt)
759 {
760         QString path = GetFirstLoadableImagePathFromDragEvent(filterevt);
761         if (!path.isEmpty())
762                 LoadMatcapImageForCurrentMat(path);
763
764         return true;
765 }
766
767 bool FormMain::OnDropFile_editCurrentTexName(QEvent * filterevt)
768 {
769         QString path = GetFirstLoadableImagePathFromDragEvent(filterevt);
770         if (!path.isEmpty())
771                 LoadCurSelMatTexture(TextureType::Color, path);
772
773         return true;
774 }
775
776 bool FormMain::OnDropFile_editCurrentMatNormalMap(QEvent * filterevt)
777 {
778         QString path = GetFirstLoadableImagePathFromDragEvent(filterevt);
779         if (!path.isEmpty())
780                 LoadCurSelMatTexture(TextureType::Normal, path);
781
782         return true;
783 }
784
785 bool FormMain::AcceptDropFilterIfUrl(QEvent * filterevt)
786 {
787         QDragEnterEvent* e = dynamic_cast<QDragEnterEvent*>(filterevt);
788         if (e == NULL)
789                 return false;
790
791         if (e->mimeData()->hasUrls())
792                 e->acceptProposedAction();
793
794         return true;
795 }
796
797 QString FormMain::GetFirstLoadableImagePathFromDragEvent(QEvent* filterevt)
798 {
799         QDropEvent* e = dynamic_cast<QDropEvent*>(filterevt);
800         if (e == NULL)
801                 return false;
802
803         if (!e->mimeData()->hasUrls())
804                 return false;
805
806         QList<QUrl> urls = e->mimeData()->urls();
807         for (int i = 0; i < urls.size(); ++i)
808         {
809                 QString path = urls[i].toLocalFile();
810                 if (IsSupportedTextureExt(path))
811                         return path;
812         }
813
814         return QString();
815 }
816
817
818 void FormMain::CenteringSplitter(void)
819 {
820         int w = ui.splitter->width();
821         QList<int> s;
822         s.append(w / 2);
823         s.append(w / 2);
824         ui.splitter->setSizes(s);
825 }
826
827 void FormMain::updateView_All(void)
828 {
829         updateView_3D();
830         updateView_2D();
831 }
832
833 void FormMain::updateView_2D(void)
834 {
835         ui.GLWidgetUV->update();
836 }
837
838 void FormMain::updateView_3D(void)
839 {
840         ui.GLWidgetMain->update();
841 }
842
843 void FormMain::on_actionOpen_triggered()
844 {
845         FileDlgFilterList exts;
846         exts.Add( "Wavefront"   , "obj" );
847         exts.Add( "STL"         , "stl" );
848         exts.Add( "PLY"         , "ply" );
849         exts.Add( "Metasequoia" , "mqo" );
850         exts.Add( "Pmd"         , "pmd" );
851         exts.Add( "Collada"     , "dae" );
852         exts.Add( "DirectX"     , "x"   );
853
854         QString filter = FileDlgUtil::ExtListToDlgFilter("Geometry", exts);
855         QString title = "Open file";
856         QString fileName = GetFilePathFromOpenDlg(title, filter);
857
858         if (fileName.isEmpty())
859                 return;
860
861         if (IsResetSceneOnBeforeLoadFile())
862                 ClearAllObjects();
863
864         if (OpenGeomFile(fileName))
865                 return;
866 }
867
868 void FormMain::on_actionExit_triggered()
869 {
870         close();
871 }
872
873 void FormMain::actionVisibleStates_Triggered(bool checked)
874 {
875         QAction* a = dynamic_cast<QAction*>(QObject::sender());
876         if (checked)
877         {
878                 if (a == ui.actionIndexColorMode)
879                 {
880                         ui.actionFixMaterialSilver->setChecked(false);
881                         ui.actionFBMaterial->setChecked(false);
882                 }
883                 else if (a == ui.actionFixMaterialSilver)
884                 {
885                         ui.actionIndexColorMode->setChecked(false);
886                         ui.actionFBMaterial->setChecked(false);
887                 }
888                 else if (a == ui.actionFBMaterial)
889                 {
890                         ui.actionFixMaterialSilver->setChecked(false);
891                         ui.actionIndexColorMode->setChecked(false);
892                 }
893         }
894
895         SyncViewSettingsFromGUI();
896         updateView_All();
897 }
898
899 void FormMain::SyncViewSettingsFromGUI(void)
900 {
901         m_Binder_ViewConfig.UpdateAllData();
902
903         QAction* menu = GetMenuFromShader(m_View3d.m_Config.m_ShaderMode);
904         if (menu != NULL)
905                 menu->setChecked(true);
906 }
907
908 QAction* FormMain::GetMenuFromShader(ShaderType type)
909 {
910         switch(m_View3d.m_Config.m_ShaderMode)
911         {
912         case ShaderType::Phong      : return ui.actionShaderPhong;
913         case ShaderType::Custom     : return ui.actionShaderCustom;
914         case ShaderType::NormalColor: return ui.actionNormalColor;
915         case ShaderType::DepthColor : return ui.actionDepthColor;
916         case ShaderType::Shadowmap  : return ui.actionShadowmap;
917         case ShaderType::Envmap     : return ui.actionEnvmap;
918         case ShaderType::Integrate  : return ui.actionIntegrateShader;
919         case ShaderType::Matcap     : return ui.actionMatcapShader;
920         case ShaderType::Default    : return ui.actionShaderDefault;
921
922         default:
923                 assert(false);
924                 return NULL;
925         };
926 }
927
928 bool FormMain::SaveWindowLayout(const QString& filepath)
929 {
930         WindowConfig config;
931
932         config.m_MainWinLeft   = geometry().x();
933         config.m_MainWinTop    = geometry().y();
934         config.m_MainWinWidth  = geometry().width();
935         config.m_MainWinHeight = geometry().height();
936         config.m_IsMaximized   = isMaximized();
937
938         return config.SaveConfig(filepath.toLocal8Bit().data());
939 }
940
941 bool FormMain::LoadWindowLayout(const QString& filepath)
942 {
943         WindowConfig config;
944         if (!config.LoadConfig(filepath.toLocal8Bit().data()))
945                 return false;
946
947         if (config.m_IsMaximized)
948                 showMaximized();
949
950         int l = config.m_MainWinLeft;
951         int t = config.m_MainWinTop;
952         int w = config.m_MainWinWidth;
953         int h = config.m_MainWinHeight;
954         setGeometry(l, t, w, h);
955
956         return true;
957 }
958
959 void FormMain::actionVisibleStatesUV_Triggered(bool)
960 {
961         SyncUVViewSettingsFromGUI();
962 }
963
964 void FormMain::SyncUVViewSettingsFromGUI(void)
965 {
966         m_Binder_UVConfig.UpdateAllData();
967         updateView_All();
968 }
969
970 void FormMain::actionSceneStates_Toggled(bool)
971 {
972         SyncSceneSettingsFromGUI();
973 }
974
975 void FormMain::SyncSceneSettingsFromGUI(void)
976 {
977         m_Binder_Scene.UpdateAllData();
978         updateView_All();
979 }
980
981 void FormMain::on_actionWindow_ToolBarView_triggered(bool checked)
982 {
983         ui.toolBar_View->setVisible( ui.actionWindow_ToolBarView->isChecked() );
984 }
985
986 void FormMain::on_actionToolBar_Options_toggled(bool checked)
987 {
988         ui.toolBar_Option->setVisible(checked);
989 }
990
991 void FormMain::on_actionToolBar_Operation_toggled(bool checked)
992 {
993         ui.toolBar_Operation->setVisible(checked);
994 }
995
996 void FormMain::on_actionCameraDist_triggered()
997 {
998         m_View3d.AdjustCameraDistAuto();
999 }
1000
1001 void FormMain::on_actionCameraFront_triggered()
1002 {
1003         m_View3d.MoveCaemraTo(ViewPoint::Front);
1004 }
1005
1006 void FormMain::on_actionCameraBack_triggered()
1007 {
1008         m_View3d.MoveCaemraTo(ViewPoint::Back);
1009 }
1010
1011 void FormMain::on_actionCameraLeft_triggered()
1012 {
1013         m_View3d.MoveCaemraTo(ViewPoint::Left);
1014 }
1015
1016 void FormMain::on_actionCameraRight_triggered()
1017 {
1018         m_View3d.MoveCaemraTo(ViewPoint::Right);
1019 }
1020
1021 void FormMain::on_actionCameraTop_triggered()
1022 {
1023         m_View3d.MoveCaemraTo(ViewPoint::Top);
1024 }
1025
1026 void FormMain::on_actionCameraBottom_triggered()
1027 {
1028         m_View3d.MoveCaemraTo(ViewPoint::Bottom);
1029 }
1030
1031 void FormMain::on_actionCameraPers_triggered()
1032 {
1033         m_View3d.MoveCaemraTo(ViewPoint::Perse);
1034 }
1035
1036 void FormMain::on_actionCameraLookOrigin_triggered()
1037 {
1038         m_View3d.MoveLookPosToOrigin();
1039 }
1040
1041 void FormMain::on_actionCameraLookCenter_triggered()
1042 {
1043         m_View3d.MoveLookPosToCenter();
1044 }
1045
1046 void FormMain::on_actionWindow_3DView_triggered(bool checked)
1047 {
1048         UpdateViewTypeFromMenu();
1049 }
1050
1051 void FormMain::on_actionWindows_DualView_triggered(bool checked)
1052 {
1053         UpdateViewTypeFromMenu();
1054 }
1055
1056 void FormMain::on_actionWindow_UVView_triggered(bool checked)
1057 {
1058         UpdateViewTypeFromMenu();
1059 }
1060
1061 void FormMain::UpdateViewTypeFromMenu(void)
1062 {
1063         if (ui.actionWindows_DualView->isChecked())
1064         {
1065                 ui.frameView3D->setVisible(true);
1066                 ui.frameView2D->setVisible(true);
1067
1068                 // TODO: \89¼. \8bN\93®\8e\9e\82É\83r\83\85\81[\82ð1:1\82É\90Ý\92è\82Å\82«\82È\82¢\96â\91è\82Ì\89¼\91Î\89\9e.
1069                 static bool firsttime = true;
1070                 if (firsttime)
1071                 {
1072                         firsttime = false;
1073                         CenteringSplitter();
1074                 }
1075         }
1076         if (ui.actionWindow_3DView->isChecked())
1077         {
1078                 ui.frameView3D->setVisible(true);
1079                 ui.frameView2D->setVisible(false);
1080         }
1081         if (ui.actionWindow_UVView->isChecked())
1082         {
1083                 ui.frameView3D->setVisible(false);
1084                 ui.frameView2D->setVisible(true);
1085         }
1086 }
1087
1088 void FormMain::on_actionWindowMaterialList_triggered()
1089 {
1090         ShowAndActivateAndRaise(ui.dockMaterial);
1091         ui.listMaterial->setFocus();
1092 }
1093
1094 void FormMain::on_actionWindowObjectList_triggered()
1095 {
1096         ShowAndActivateAndRaise(ui.dockObject);
1097         ui.treeObjects->setFocus();
1098 }
1099
1100 void FormMain::on_actionWindowCameraList_triggered()
1101 {
1102         ShowAndActivateAndRaise(ui.dockCamera);
1103         ui.listCamera->setFocus();
1104 }
1105
1106 void FormMain::on_actionWindowScenePanel_triggered()
1107 {
1108         ShowAndActivateAndRaise(ui.dockScene);
1109 }
1110
1111 void FormMain::on_actionCursorPanel_triggered()
1112 {
1113         ShowAndActivateAndRaise(ui.dockCursor);
1114 }
1115
1116 void FormMain::on_listMaterial_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
1117 {
1118         m_Scene.m_Sels.SetSelMat(ui.listMaterial->currentRow());
1119         OnChangedSelectedMaterial();
1120         updateView_All();
1121 }
1122
1123 void FormMain::ShowAndActivateAndRaise(QDockWidget* widget)
1124 {
1125         widget->setVisible(true);
1126         widget->activateWindow();
1127         widget->raise();
1128 }
1129
1130 void FormMain::on_treeObjects_currentItemChanged(QTreeWidgetItem * current, QTreeWidgetItem * previous)
1131 {
1132         RefreshObjectSelectState();
1133 }
1134
1135 void FormMain::RefreshObjectSelectState(void)
1136 {
1137         SetPrimayrSelectObjectToScene();
1138
1139         QListWidget* list_mat = ui.listMaterial;
1140         list_mat->clear();
1141
1142         const MeshBuf* mbuf = m_Scene.GetPrimaryMeshbuf();
1143         if (mbuf != NULL)
1144         {
1145                 const lib_geo::BaseMesh& mesh = mbuf->m_Mesh;
1146                 for (const lib_geo::BaseMaterial& mat : mesh.m_Materials)
1147                 {
1148                         const std::string& name = mat.m_Name;
1149
1150                         if (name.empty())
1151                                 list_mat->addItem("--");
1152                         else
1153                                 list_mat->addItem(QString::fromLocal8Bit(name.c_str()));
1154                 }
1155         }
1156
1157         const GeomObject* obj = m_Scene.GetPrimaryObject();
1158         if (mbuf != NULL)
1159         {
1160                 ui.actionSelObjectVisible->setChecked(mbuf->IsVisible());
1161         }
1162         else if (obj != NULL)
1163         {
1164                 ui.actionSelObjectVisible->setChecked(obj->m_Visible);
1165         }
1166         
1167         if (obj != NULL)
1168                 ui.actionSelObjectVertexOnlyMode->setChecked(obj->m_VertexOnlyMode);
1169
1170         if (list_mat->count() > 0 && list_mat->currentRow() < 0)
1171         {
1172                 list_mat->setCurrentRow(0);
1173                 m_Scene.m_Sels.SetSelMat(0);
1174                 OnChangedSelectedMaterial();
1175         }
1176
1177         updateView_All();
1178 }
1179
1180 void FormMain::OnChangedSelectedMaterial(void)
1181 {
1182         if (IsAutUVFit())
1183         {
1184                 m_View2d.FitView();
1185         }
1186
1187         ui.editCurrentTexName->clear();
1188
1189         GeomTextureSet* ts = m_Scene.GetSelectedTexture();
1190         if (ts == NULL)
1191         {
1192                 ui.editCurrentTexName->setText("");
1193                 ui.editMatCapEachMaterial->setText("");
1194         }
1195         else
1196         {
1197                 QString name_c, name_n;
1198
1199                 gl::GlTexture* tex_c = ts->GetTexColor();
1200                 if (tex_c != NULL)
1201                         name_c = QString::fromLocal8Bit(tex_c->GetName().c_str());
1202
1203                 gl::GlTexture* tex_n = ts->GetTexNormal();
1204                 if (tex_n != NULL)
1205                         name_n = QString::fromLocal8Bit(tex_n->GetName().c_str());
1206
1207                 ui.editCurrentTexName->setText(name_c);
1208                 ui.editCurrentMatNormalMap->setText(name_n);
1209
1210                 MatcapImage& matcap = ts->TexMatcap;
1211                 ui.editMatCapEachMaterial->setText(matcap.GetName());
1212         }
1213
1214         lib_geo::BaseMaterial* mat = m_Scene.GetSelectedMaterial();
1215         if (mat != NULL)
1216         {
1217                 SetWidgetColor(ui.colorAmbient  , ToQColor(mat->m_Ambient));
1218                 SetWidgetColor(ui.colorEmission , ToQColor(mat->m_Emission));
1219                 SetWidgetColor(ui.colorDiffuse  , ToQColor(mat->m_Diffuse));
1220                 SetWidgetColor(ui.colorSpecular , ToQColor(mat->m_Specular));
1221
1222                 int val_max = ui.sliderShininess->maximum();
1223                 int slider_pos = (int)(mat->m_Shininess * (float)val_max / 200.0f);
1224                 slider_pos = (lm::min)(val_max, slider_pos);
1225                 ui.sliderShininess->blockSignals(true);
1226                 ui.sliderShininess->setValue(slider_pos);
1227                 ui.sliderShininess->blockSignals(false);
1228                 ui.labelShininessVal->setText(QString::number(mat->m_Shininess, 'f', 2));
1229         }
1230
1231         updateView_All();
1232 }
1233
1234 void FormMain::keyPressEvent(QKeyEvent *e)
1235 {
1236         Modifier m(e);
1237         if (m.Flag_C() && e->key() == Qt::Key_Tab)
1238         {
1239                 FocusNextSubDlg();
1240         }
1241 }
1242
1243 void FormMain::FocusNextSubDlg(void)
1244 {
1245         std::vector<QDockWidget*> widgets;
1246
1247         if (ui.dockObject   ->isVisible()) widgets.push_back( ui.dockObject   );
1248         if (ui.dockCamera   ->isVisible()) widgets.push_back( ui.dockCamera   );
1249         if (ui.dockScene    ->isVisible()) widgets.push_back( ui.dockScene    );
1250         if (ui.dockMaterial ->isVisible()) widgets.push_back( ui.dockMaterial );
1251
1252         if (widgets.empty())
1253                 return;
1254
1255         QDockWidget* next_widget = NULL;
1256
1257         for (size_t i = 0; i < widgets.size(); ++i)
1258         {
1259                 if (widgets[i] == m_LastFocusedDockDlg)
1260                 {
1261                         next_widget = widgets[(i + 1) % widgets.size()];
1262                         break;
1263                 }
1264         }
1265
1266         if (next_widget == NULL)
1267                 next_widget = widgets.front();
1268
1269         m_LastFocusedDockDlg = next_widget;
1270
1271         next_widget->activateWindow();
1272         next_widget->raise();
1273         next_widget->setFocus();
1274 }
1275
1276 void FormMain::dragEnterEvent(QDragEnterEvent* e)
1277 {
1278         if (e->mimeData()->hasUrls())
1279                 e->acceptProposedAction();
1280 }
1281
1282 void FormMain::dropEvent(QDropEvent* e)
1283 {
1284         if (e->mimeData()->hasUrls())
1285         {
1286                 QList<QUrl> urls = e->mimeData()->urls();
1287
1288                 std::vector<QString> geom_files;
1289
1290                 for (int i = 0; i < urls.size(); ++i)
1291                 {
1292                         QString path = urls[i].toLocalFile();
1293                         if (FormatType::IsGeomFileExt(path))
1294                                 geom_files.push_back(path);
1295                 }
1296
1297                 if (!geom_files.empty())
1298                 {
1299                         if (IsResetSceneOnBeforeLoadFile())
1300                                 ClearAllObjects();
1301
1302                         for (size_t i = 0; i < geom_files.size(); ++i)
1303                         {
1304                                 if (OpenGeomFile(geom_files[i]))
1305                                         continue;
1306                         }
1307                 }
1308
1309                 for (int i = 0; i < urls.size(); ++i)
1310                 {
1311                         QString path = urls[i].toLocalFile();
1312
1313                         if (IsSupportedTextureExt(path))
1314                         {
1315                                 OpenFixTextureFile(path);
1316                                 continue;
1317                         }
1318
1319                         if (IsCameraFile(path))
1320                         {
1321                                 OpenCameraFile(path);
1322                                 continue;
1323                         }
1324                 }
1325         }
1326 }
1327
1328 bool FormMain::IsResetSceneOnBeforeLoadFile(void) const
1329 {
1330         if (QApplication::keyboardModifiers() & Qt::ShiftModifier)
1331                 return true;
1332
1333         return false;
1334 }
1335
1336 //! \83I\83u\83W\83F\83N\83g\82Ì\83}\83e\83\8a\83A\83\8b\82É\90Ý\92è\82³\82ê\82½\82à\82Ì\82Æ\82Í\95Ê\82Ì\83e\83N\83X\83`\83\83\82ð\8ew\92è\82·\82é.
1337 void FormMain::OpenFixTextureFile(const QString& path)
1338 {
1339         std::string fname = path.toLocal8Bit().data();
1340
1341         m_ContextShare.BeginDrawTop();
1342         m_Scene.LoadDefaultMatTexture(fname);
1343         m_ContextShare.EndDrawTop();
1344
1345         updateView_All();
1346 }
1347
1348 bool FormMain::OpenGeomFile(const QString& path)
1349 {
1350         m_Scene.m_ObjSplit = ui.checkSplitOBJ->isChecked();
1351
1352         m_ContextShare.BeginDrawTop();
1353
1354         bool suc = true;
1355         try
1356         {
1357                 m_Scene.ImportFileAutoFmt(path);
1358         }
1359         catch(const FileLoadErrorException& ex)
1360         {
1361                 QString msg;
1362                 msg += "Failed Load ";
1363                 msg += path + "\n\n";
1364                 msg += QString::fromLocal8Bit(ex.what());
1365
1366                 QMessageBox::warning(this, "", msg);
1367                 suc = false;
1368         }
1369
1370         m_ContextShare.EndDrawTop();
1371
1372         RebuildObjectList();
1373
1374         ResetSequenceSliderRange();
1375
1376         updateView_All();
1377
1378         if (!suc)
1379                 return false;
1380
1381         AddRecentFile(path);
1382
1383         return true;
1384 }
1385
1386 void FormMain::ClearAllObjects(void)
1387 {
1388         m_ContextShare.BeginDrawTop();
1389
1390         m_Scene.ClearObjects();
1391
1392         m_ContextShare.EndDrawTop();
1393
1394         m_View3d.ClearRenderMap();
1395
1396         RebuildObjectList();
1397         RefreshObjectSelectState();
1398
1399         updateView_All();
1400 }
1401
1402 void FormMain::RebuildObjectList(void)
1403 {
1404         QTreeWidget* obj_tree = ui.treeObjects;
1405
1406         obj_tree->setCurrentItem(NULL);
1407         obj_tree->blockSignals(true);
1408
1409         obj_tree->clear();
1410
1411         obj_tree->setSelectionBehavior(QAbstractItemView::SelectRows);
1412         obj_tree->setSelectionMode(QAbstractItemView::SingleSelection);
1413         obj_tree->setEditTriggers(QAbstractItemView::NoEditTriggers);
1414
1415         obj_tree->setColumnCount(4);
1416
1417         InitObjectListHeader();
1418
1419         for (const geom::GeomObject& obj : m_Scene.m_Objects)
1420         {
1421                 QTreeWidgetItem* n = CreateObjectTreeNode(obj);
1422                 PushbackTreeNode(ui.treeObjects, n);
1423                 n->setExpanded(true);
1424         }
1425
1426         SetPrimayrSelectObjectFromScene();
1427
1428         obj_tree->blockSignals(false);
1429
1430         if (obj_tree->currentItem() == NULL)
1431         {
1432                 if (!m_Scene.m_Objects.empty())
1433                 {
1434                         QTreeWidgetItem* ti = obj_tree->topLevelItem(0);
1435                         obj_tree->setCurrentItem(ti);
1436
1437                         if (IsAutUVFit())
1438                                 m_View2d.FitView();
1439                 }
1440         }
1441
1442         ResizeTreeColumns(obj_tree, 4);
1443 }
1444
1445
1446 bool FormMain::IsCameraFile(const QString& path) const
1447 {
1448         QFileInfo fInfo( path );
1449         QString ext = fInfo.suffix().toLower();
1450         return (ext == "camera");
1451 }
1452
1453 bool FormMain::OpenCameraFile(const QString& path)
1454 {
1455         std::string fname = path.toLocal8Bit().data();
1456
1457         if(!m_View3d.m_CameraRecord.LoadCamera(fname.c_str()))
1458                 return false;
1459
1460         ui.listCamera->blockSignals(true);
1461         ui.listCamera->clear();
1462         for (size_t i = 0; i < m_View3d.m_CameraRecord.m_Records.size(); ++i)
1463         {
1464                 ui.listCamera->addItem( QString::number(i) );
1465         }
1466         ui.listCamera->blockSignals(false);
1467
1468         return true;
1469 }
1470
1471
1472 void FormMain::actionGeomStates_Triggered(bool)
1473 {
1474         ApplyGeomStateFromGUI();
1475
1476         m_Scene.UpdateTransform();
1477
1478         updateView_All();
1479 }
1480
1481 void FormMain::ApplyGeomStateFromGUI(void)
1482 {
1483         m_Scene.m_Config.m_EnableAutoCentering = ui.actionCentering->isChecked();
1484         m_Scene.m_Config.m_EnableAutoReisze    = ui.actionAutoResize->isChecked();
1485 }
1486
1487 void FormMain::ApplyGeomStateDataoToGUI(void)
1488 {
1489         ui.actionAutoResize ->setChecked( m_Scene.m_Config.m_EnableAutoReisze    );
1490         ui.actionCentering  ->setChecked( m_Scene.m_Config.m_EnableAutoCentering );
1491
1492         ui.checkShowOnlySelect->setChecked(m_View3d.m_Config.m_ShowOnlySelect);
1493 }
1494
1495 void FormMain::on_actionGeomClear_triggered()
1496 {
1497         ClearAllObjects();
1498 }
1499
1500
1501 void FormMain::on_actionUVFitView_triggered()
1502 {
1503         m_View2d.FitView();
1504         updateView_All();
1505 }
1506
1507 void FormMain::on_actionSelObjectDelete_triggered()
1508 {
1509         DeleteSelectedObject();
1510 }
1511
1512 void FormMain::on_actionSelObjectReload_triggered()
1513 {
1514         GeomObject* obj = m_Scene.GetPrimaryObject();
1515         if (obj == NULL)
1516                 return;
1517
1518         if (!obj->IsFileObject())
1519         {
1520                 QMessageBox::information(this, "", "IsNotFileObject");
1521                 return;
1522         }
1523
1524         m_Scene.ReloadObject(obj);
1525
1526         RebuildObjectList();
1527
1528         m_View3d.ClearRenderMap();
1529         updateView_All();
1530 }
1531
1532 void FormMain::on_actionSelObjectVisible_triggered()
1533 {
1534         FlipVisibleSelectedObject();
1535 }
1536
1537 void FormMain::on_actionSelObjectVertexOnlyMode_triggered()
1538 {
1539         GeomObject* obj = m_Scene.GetPrimaryObject();
1540         if (obj == NULL)
1541                 return;
1542
1543         obj->m_VertexOnlyMode = !obj->m_VertexOnlyMode;
1544
1545         ui.actionSelObjectVertexOnlyMode->setChecked(obj->m_VertexOnlyMode);
1546
1547         updateView_All();
1548 }
1549
1550 void FormMain::on_actionSelObjectFlipFace_triggered()
1551 {
1552         m_Scene.FlipCurselFace(false);
1553
1554         ui.GLWidgetMain->makeCurrent();
1555         std::vector<MeshBuf*> mv = m_Scene.GetCurSelMeshes();
1556         for (MeshBuf* m : mv)
1557         {
1558                 m_View3d.ReleaseRenderbuffer(m);
1559         }
1560         ui.GLWidgetMain->doneCurrent();
1561
1562         updateView_All();
1563 }
1564
1565 void FormMain::on_actionSelObjectFlipNormal_triggered()
1566 {
1567         m_Scene.FlipCurselFace(true);
1568
1569         ui.GLWidgetMain->makeCurrent();
1570         std::vector<MeshBuf*> mv = m_Scene.GetCurSelMeshes();
1571         for (MeshBuf* m : mv)
1572         {
1573                 m_View3d.ReleaseRenderbuffer(m);
1574         }
1575         ui.GLWidgetMain->doneCurrent();
1576
1577         updateView_All();
1578 }
1579
1580 void FormMain::on_actionSelObjectOpenDir_triggered()
1581 {
1582         GeomObject* obj = m_Scene.GetPrimaryObject();
1583         if (obj == NULL)
1584                 return;
1585
1586         if (!obj->IsFileObject())
1587                 return;
1588
1589         QString path = QString::fromLocal8Bit(obj->m_FilePath.c_str());
1590         QString p2 = QDir::toNativeSeparators(path);
1591         QGui::ShowExplorerFileSel(p2);
1592 }
1593
1594 void FormMain::on_actionShowOnlySelected_triggered()
1595 {
1596         ShowObjectOnlySelected();
1597 }
1598
1599 void FormMain::on_actionSelObjectTriangulate_triggered()
1600 {
1601         MeshBuf* mbuf = m_Scene.GetPrimaryMeshbuf();
1602         if (mbuf == NULL)
1603                 return;
1604
1605         mbuf->Triangulate();
1606
1607         m_View3d.ReleaseAllRenderBuffer();
1608
1609         RebuildObjectList();
1610         updateView_All();
1611 }
1612
1613 void FormMain::on_actionTreeCollapseAll_triggered()
1614 {
1615         TreeUtil::SetAllTopExpand(ui.treeObjects, false);
1616 }
1617
1618 void FormMain::on_actionTreeExpandAll_triggered()
1619 {
1620         TreeUtil::SetAllTopExpand(ui.treeObjects, true);
1621 }
1622
1623
1624 void FormMain::on_actionAddSample_triggered()
1625 {
1626         SampleShapeBuilder::CreateSphere(m_Scene);
1627         OnDoneAddGeom();
1628 }
1629
1630 void FormMain::on_actionAddGroundPlane_triggered()
1631 {
1632         SampleShapeBuilder::CreateGroundPlane(m_Scene);
1633         OnDoneAddGeom();
1634 }
1635
1636 void FormMain::OnDoneAddGeom(void)
1637 {
1638         QTreeWidget* obj_tree = ui.treeObjects;
1639
1640         const GeomObject& obj = m_Scene.m_Objects.back();
1641
1642         obj_tree->setCurrentItem(NULL);
1643         obj_tree->blockSignals(true);
1644
1645         QTreeWidgetItem* n = CreateObjectTreeNode(obj);
1646         PushbackTreeNode(obj_tree, n);
1647         n->setExpanded(true);
1648
1649         SetPrimayrSelectObjectFromScene();
1650
1651         obj_tree->blockSignals(false);
1652
1653         if (obj_tree->currentItem() == NULL)
1654         {
1655                 if (!m_Scene.m_Objects.empty())
1656                 {
1657                         QTreeWidgetItem * j = obj_tree->topLevelItem(0);
1658                         obj_tree->setCurrentItem(j);
1659
1660                         if (IsAutUVFit())
1661                                 m_View2d.FitView();
1662                 }
1663         }
1664
1665         ResizeTreeColumns(obj_tree, 4);
1666
1667         ResetSequenceSliderRange();
1668
1669         updateView_All();
1670 }
1671
1672
1673 void FormMain::on_actionShaderDefault_triggered(bool)
1674 {
1675         ChangeShaderMenuMain(ShaderType::Default);
1676 }
1677
1678 void FormMain::on_actionShaderPhong_triggered(bool)
1679 {
1680         ChangeShaderMenuMain(ShaderType::Phong);
1681 }
1682
1683 void FormMain::on_actionShaderCustom_triggered(bool)
1684 {
1685         ChangeShaderMenuMain(ShaderType::Custom);
1686 }
1687
1688 void FormMain::on_actionNormalColor_triggered(bool)
1689 {
1690         ChangeShaderMenuMain(ShaderType::NormalColor);
1691 }
1692
1693 void FormMain::on_actionDepthColor_triggered(bool)
1694 {
1695         ChangeShaderMenuMain(ShaderType::DepthColor);
1696 }
1697
1698 void FormMain::on_actionShadowmap_triggered(bool)
1699 {
1700         ChangeShaderMenuMain(ShaderType::Shadowmap);
1701 }
1702
1703 void FormMain::on_actionEnvmap_triggered(bool)
1704 {
1705         ChangeShaderMenuMain(ShaderType::Envmap);
1706 }
1707
1708 void FormMain::on_actionIntegrateShader_triggered(bool)
1709 {
1710         ChangeShaderMenuMain(ShaderType::Integrate);
1711 }
1712
1713 void FormMain::on_actionMatcapShader_triggered(bool)
1714 {
1715         ChangeShaderMenuMain(ShaderType::Matcap);
1716 }
1717
1718 void FormMain::SyncShaderSettingsToGUI(void)
1719 {
1720         ChangeShaderMenuMain(m_View3d.m_Config.m_ShaderMode);
1721 }
1722
1723 void FormMain::ChangeShaderMenuMain(ShaderType type)
1724 {
1725         m_View3d.m_Config.m_ShaderMode = type;
1726         updateView_All();
1727 }
1728
1729
1730 void FormMain::on_actionCreate_Check_triggered()
1731 {
1732         CreateSampleTextureMain(SampleTextureBuilder::TEX_CHECKER);
1733 }
1734
1735 void FormMain::on_actionCreate_Stripe_V_triggered()
1736 {
1737         CreateSampleTextureMain(SampleTextureBuilder::TEX_STRIPE_V);
1738 }
1739
1740 void FormMain::on_actionCreate_Stripe_H_triggered()
1741 {
1742         CreateSampleTextureMain(SampleTextureBuilder::TEX_STRIPE_H);
1743 }
1744
1745 void FormMain::CreateSampleTextureMain(SampleTextureBuilder::TextureType tex_type)
1746 {
1747         m_ContextShare.BeginDrawTop();
1748         m_Scene.CreateSampleTexture(tex_type);
1749         m_ContextShare.EndDrawTop();
1750
1751         updateView_All();
1752 }
1753
1754 bool FormMain::IsAutUVFit(void) const
1755 {
1756         return ui.actionUVAutoFit->isChecked();
1757 }
1758
1759
1760 void FormMain::on_pushDeleteSelectedObject_clicked()
1761 {
1762         DeleteSelectedObject();
1763 }
1764
1765 void FormMain::on_treeObjects_itemChanged(QTreeWidgetItem * item, int column)
1766 {
1767         QTreeWidget* obj_tree = ui.treeObjects;
1768
1769         if (column == 1)
1770         {
1771                 QTreeWidgetItem* t = item->parent();
1772                 bool checked = (item->checkState(1) == Qt::Checked);
1773                 if (t == NULL)
1774                 {
1775                         int sel_idx = obj_tree->indexOfTopLevelItem(item);
1776                         GeomObject& obj = m_Scene.m_Objects[sel_idx];
1777                         obj.m_Visible = checked;
1778                 }
1779                 else
1780                 {
1781                         int sel_idx = obj_tree->indexOfTopLevelItem(t);
1782                         int midx = t->indexOfChild(item);
1783
1784                         GeomObject& obj = m_Scene.m_Objects[sel_idx];
1785                         MeshBuf& mb = obj.m_MeshAry[midx];
1786                         mb.m_Visible = checked;
1787                 }
1788
1789                 updateView_All();
1790         }
1791 }
1792
1793
1794 void FormMain::DeleteSelectedObject()
1795 {
1796         QTreeWidget* obj_tree = ui.treeObjects;
1797         QTreeWidgetItem* ti = obj_tree->currentItem();
1798         if (ti == NULL)
1799                 return;
1800
1801         QTreeWidgetItem* pn = ti->parent();
1802
1803         int sel_idx;
1804         if (pn == NULL)
1805                 sel_idx = obj_tree->indexOfTopLevelItem(ti);
1806         else
1807                 sel_idx = obj_tree->indexOfTopLevelItem(pn);
1808
1809         if (sel_idx < 0)
1810                 return;
1811
1812         m_ContextShare.BeginDrawTop();
1813
1814         m_Scene.RemoveItem(sel_idx);
1815
1816         m_ContextShare.EndDrawTop();
1817
1818         m_View3d.ClearRenderMap();
1819
1820         obj_tree->setCurrentItem(NULL);
1821         obj_tree->takeTopLevelItem(sel_idx);
1822
1823         ResizeTreeColumns(obj_tree, 4);
1824
1825         ti = obj_tree->currentItem();
1826         sel_idx = obj_tree->indexOfTopLevelItem(ti);
1827         m_Scene.m_Sels.SelectObject(sel_idx);
1828
1829         m_Scene.UpdateTransform();
1830
1831         RefreshObjectSelectState();
1832
1833         ResetSequenceSliderRange();
1834
1835         updateView_All();
1836 }
1837
1838 void FormMain::FlipVisibleSelectedObject()
1839 {
1840         QTreeWidget* obj_tree = ui.treeObjects;
1841         QTreeWidgetItem * item = obj_tree->currentItem();
1842         if (item == NULL)
1843                 return;
1844
1845         item->setCheckState(1, FilpState(item->checkState(1)));
1846 }
1847
1848 Qt::CheckState FormMain::FilpState(Qt::CheckState state) const
1849 {
1850         if(state == Qt::Checked)
1851                 return Qt::Unchecked;
1852         else
1853                 return Qt::Checked;
1854 }
1855
1856 void FormMain::ShowObjectOnlySelected(void)
1857 {
1858         GeomObject* sel_obj = m_Scene.GetPrimaryObject();
1859         if (sel_obj == NULL)
1860                 return;
1861
1862         for (GeomObject& o : m_Scene.m_Objects)
1863         {
1864                 o.m_Visible = (sel_obj == &o);
1865         }
1866
1867         RebuildObjectList();
1868         updateView_All();
1869 }
1870
1871 void FormMain::ShowAllObject(void)
1872 {
1873         m_Scene.ShowAllObject();
1874
1875         RebuildObjectList();
1876         updateView_All();
1877 }
1878
1879 void FormMain::HideAllObject(void)
1880 {
1881         m_Scene.HideAllObject();
1882
1883         RebuildObjectList();
1884         updateView_All();
1885 }
1886
1887 void FormMain::on_actionUVResetView_triggered()
1888 {
1889         m_View2d.ResetView();
1890
1891         updateView_All();
1892 }
1893
1894
1895 //! \83\8f\83C\83\84\81[\83I\81[\83o\81[\83\8c\83C\95\\8e¦\8e\9e\82Ì\90F\90Ý\92è
1896 void FormMain::on_actionWireColor_triggered()
1897 {
1898         m_WireColorSelDlg.exec();
1899 }
1900
1901 //! \83f\83t\83H\83\8b\83g\83}\83e\83\8a\83A\83\8b\82Ì\90F\90Ý\92è
1902 void FormMain::on_actionFaceColor_triggered()
1903 {
1904         const lib_graph::color4f& c = m_Scene.m_DefaultMaterial.m_Diffuse;
1905
1906         m_DiffuseColorSelDlg.setOption(QColorDialog::ShowAlphaChannel);
1907         m_DiffuseColorSelDlg.setCurrentColor(ToQColor(c));
1908         m_DiffuseColorSelDlg.exec();
1909 }
1910
1911 //! \94w\8ci\90F\82Ì\90Ý\92è
1912 void FormMain::on_actionBackGroundColor_triggered()
1913 {
1914         const lib_graph::color4f& c = m_View3d.m_BGColor;
1915
1916         m_BGColorSelDlg.setCurrentColor(ToQColor(c));
1917         m_BGColorSelDlg.exec();
1918 }
1919
1920 void FormMain::WireOverlayColorChanged(const QColor & color)
1921 {
1922         lib_graph::color3b& c = m_View3d.m_Config.m_WireColor;
1923         c.set(color.red(), color.green(), color.blue());
1924
1925         m_View3d.ReleaseAllRenderBuffer();
1926
1927         updateView_All();
1928 }
1929
1930 void FormMain::CopyRGB(lib_graph::color4f& c, const QColor & color)
1931 {
1932         c.r() = (float)color.red()   / 255.0f;
1933         c.g() = (float)color.green() / 255.0f;
1934         c.b() = (float)color.blue()  / 255.0f;
1935 }
1936
1937 void FormMain::CopyRGBA(lib_graph::color4f& c, const QColor & color)
1938 {
1939         c.r() = (float)color.red()   / 255.0f;
1940         c.g() = (float)color.green() / 255.0f;
1941         c.b() = (float)color.blue()  / 255.0f;
1942         c.a() = (float)color.alpha() / 255.0f;
1943 }
1944
1945 void FormMain::FaceDiffuseColorChanged(const QColor & color)
1946 {
1947         lib_graph::color4f& c = m_Scene.m_DefaultMaterial.m_Diffuse;
1948         CopyRGB(c, color);
1949
1950         m_View3d.ReleaseAllRenderBuffer();
1951         updateView_All();
1952 }
1953
1954 void FormMain::BGColorChanged(const QColor & color)
1955 {
1956         lib_graph::color4f& c = m_View3d.m_BGColor;
1957         CopyRGB(c, color);
1958
1959         updateView_All();
1960 }
1961
1962 void FormMain::SetSelectedMaterialColor(QColor col)
1963 {
1964         lib_geo::BaseMaterial* mat = m_Scene.GetSelectedMaterial();
1965         if (mat == NULL)
1966                 return;
1967
1968         if (m_SelMatColorWidget == ui.colorAmbient  ) CopyRGBA(mat->m_Ambient  , col);
1969         if (m_SelMatColorWidget == ui.colorEmission ) CopyRGBA(mat->m_Emission , col);
1970         if (m_SelMatColorWidget == ui.colorDiffuse  ) CopyRGBA(mat->m_Diffuse  , col);
1971         if (m_SelMatColorWidget == ui.colorSpecular ) CopyRGBA(mat->m_Specular , col);
1972
1973         SetWidgetColor(m_SelMatColorWidget, col);
1974 }
1975
1976 void FormMain::SelMatColorChanged(const QColor & color)
1977 {
1978         SetSelectedMaterialColor(color);
1979         m_View3d.ResetPrimaryObjectLists();
1980         updateView_All();
1981 }
1982
1983
1984 void FormMain::on_actionWindowOptions_triggered()
1985 {
1986         m_ViewConfigDlg.showNormal();
1987         m_ViewConfigDlg.show();
1988         m_ViewConfigDlg.activateWindow();
1989 }
1990
1991 void FormMain::on_actionWindowCustomShader_triggered()
1992 {
1993         if (m_CustomShaderDlg == NULL)
1994         {
1995                 m_CustomShaderDlg = new FormCustomShader(this);
1996                 m_CustomShaderDlg->SetShaderLibrary(&m_View3d.m_ShaderLib);
1997                 m_CustomShaderDlg->SetParentWidget(ui.GLWidgetMain);
1998                 m_CustomShaderDlg->LoadOrSetDefaultCode();
1999                 connect(
2000                         m_CustomShaderDlg,
2001                         SIGNAL(ShaderBuild()),
2002                         this,
2003                         SLOT(CustomShaderDlg_ShaderBuild()));
2004         }
2005
2006         m_CustomShaderDlg->showNormal();
2007         m_CustomShaderDlg->show();
2008         m_CustomShaderDlg->activateWindow();
2009 }
2010
2011
2012 void FormMain::ConfigChangedDlg_ConfigChanged()
2013 {
2014         m_View3d.ReleaseAllRenderBuffer();
2015         updateView_All();
2016 }
2017
2018 void FormMain::CrossSectionDlg_ConfigChanged()
2019 {
2020         updateView_All();
2021 }
2022
2023
2024 void FormMain::OnPaintImage(QPrinter *printer)
2025 {
2026         QPainter painter(printer);
2027
2028         QRect rect = painter.viewport();
2029         QSize size = this->size();
2030         size.scale(rect.size(), Qt::KeepAspectRatio);//\8fc\89¡\94ä\88Û\8e\9d
2031
2032         painter.setViewport(rect.x(), rect.y(), size.width(), size.height());
2033         painter.setWindow(this->rect());
2034
2035         this->render(&painter);
2036 }
2037
2038 void FormMain::on_actionPrint_triggered()
2039 {
2040         PrintImage(false);
2041 }
2042
2043 void FormMain::on_actionPrintPreview_triggered()
2044 {
2045         PrintImage(true);
2046 }
2047
2048 void FormMain::PrintImage(bool WithPreview)
2049 {
2050         //QPrinter printer(QPrinter::ScreenResolution);
2051         QPrinter printer(QPrinter::ScreenResolution);
2052
2053         if(WithPreview)
2054         {
2055                 QPrintPreviewDialog preview(&printer, this);
2056                 preview.setWindowFlags( Qt::Window );
2057                 connect(
2058                         &preview,
2059                         SIGNAL(paintRequested(QPrinter *)),
2060                         SLOT(OnPaintImage(QPrinter *)));
2061
2062                 preview.showMaximized();
2063                 preview.exec();
2064         }
2065         else
2066         {
2067                 QPrintDialog printDialog(&printer, this);
2068                 if(printDialog.exec() == QDialog::Accepted)
2069                         OnPaintImage(&printer);
2070         }
2071 }
2072
2073
2074 void FormMain::on_pushButtonAddCameraRecord_clicked()
2075 {
2076         m_View3d.RecordCamera();
2077
2078         ui.listCamera->addItem( QString::number(ui.listCamera->count()) );
2079
2080         updateView_3D();
2081 }
2082
2083 void FormMain::on_pushButtonDeleteCameraRecord_clicked()
2084 {
2085         int idx = ui.listCamera->currentRow();
2086         if(idx < 0)
2087                 return;
2088
2089         m_View3d.RemoveRecordedCamera(idx);
2090
2091         for (int i = idx+1; i < ui.listCamera->count(); ++i)
2092         {
2093                 ui.listCamera->item(i)->setText(QString::number(i - 1));
2094         }
2095
2096         ui.listCamera->takeItem(idx);
2097
2098         updateView_3D();
2099 }
2100
2101 void FormMain::on_pushCameraRecordClear_clicked()
2102 {
2103         m_View3d.ClearRecordedCamera();
2104
2105         ui.listCamera->clear();
2106
2107         updateView_3D();
2108 }
2109
2110 void FormMain::on_listCamera_itemDoubleClicked(QListWidgetItem *item)
2111 {
2112         int idx = ui.listCamera->currentRow();
2113         if (idx < 0)
2114                 return;
2115
2116         m_View3d.MoveToRecordedCamera(idx, ui.checkCameraAnimation->isChecked());
2117 }
2118
2119 void FormMain::on_actionSaveCamera_triggered()
2120 {
2121         QString title = "camera";
2122         QString filter = "Camera File(*.camera)";
2123         QString fileName = GetFilePathFromSaveDlg(title, filter);
2124         if (fileName.isEmpty())
2125                 return;
2126
2127         m_View3d.m_CameraRecord.SaveCamera(fileName.toLocal8Bit().data());
2128 }
2129
2130 void FormMain::on_actionProjectionOrtho_triggered()
2131 {
2132         ui.actionProjectionOrtho->setChecked(true);
2133         ui.actionProjectionPers->setChecked(false);
2134
2135         m_View3d.m_Camera.m_ProjMode = gl::Camera::PROJ_ORTHO;
2136
2137         updateView_All();
2138 }
2139
2140 void FormMain::on_actionProjectionPers_triggered()
2141 {
2142         ui.actionProjectionPers->setChecked(true);
2143         ui.actionProjectionOrtho->setChecked(false);
2144
2145         m_View3d.m_Camera.m_ProjMode = gl::Camera::PROJ_PERS;
2146
2147         updateView_All();
2148 }
2149
2150
2151 void FormMain::CustomShaderDlg_ShaderBuild()
2152 {
2153         updateView_All();
2154 }
2155
2156 void FormMain::OnAnimationTimerUpdated()
2157 {
2158         static const float rot_speed = 0.005f;
2159
2160         if (ui.actionRotateCamera->isChecked())
2161         {
2162                 m_View3d.m_Camera.m_Manip.Tumble(rot_speed, 0.0f);
2163                 UpdateCameraStatus();
2164         }
2165
2166         if (ui.actionRotateLight->isChecked())
2167                 m_View3d.m_ControlLight.m_Position.rotate_y(rot_speed);
2168
2169         if (ui.actionAnimation->isChecked())
2170         {
2171                 StepSequence(1);
2172                 if (IsLastSequence())
2173                         ui.actionAnimation->setChecked(false);
2174         }
2175         else if (ui.actionAnimationRev->isChecked())
2176         {
2177                 StepSequence(-1);
2178                 if (IsTopSequence())
2179                         ui.actionAnimationRev->setChecked(false);
2180         }
2181
2182         updateView_3D();
2183 }
2184
2185 void FormMain::on_actionRotateCamera_toggled(bool checked)
2186 {
2187         UpdateAnimState();
2188 }
2189
2190 void FormMain::on_actionRotateLight_toggled(bool checked)
2191 {
2192         UpdateAnimState();
2193 }
2194
2195 void FormMain::on_actionAnimation_toggled(bool checked)
2196 {
2197         if (checked)
2198         {
2199                 ui.actionAnimationRev->setChecked(false);
2200                 if (IsLastSequence())
2201                 {
2202                         QSlider* s = ui.sliderSequence;
2203                         s->setValue(0);
2204                 }
2205         }
2206
2207         UpdateAnimState();
2208 }
2209
2210 void FormMain::on_actionAnimationRev_toggled(bool checked)
2211 {
2212         if (checked)
2213         {
2214                 ui.actionAnimation->setChecked(false);
2215                 if (IsTopSequence())
2216                 {
2217                         QSlider* s = ui.sliderSequence;
2218                         s->setValue(s->maximum());
2219                 }
2220         }
2221
2222         UpdateAnimState();
2223 }
2224
2225 void FormMain::UpdateAnimState(void)
2226 {
2227         if (IsEnableAnimation())
2228                 m_AnimationTimer.start();
2229         else
2230                 m_AnimationTimer.stop();
2231 }
2232
2233 bool FormMain::IsEnableAnimation(void)
2234 {
2235         if (ui.actionRotateCamera->isChecked())
2236                 return true;
2237         if (ui.actionRotateLight->isChecked())
2238                 return true;
2239         if (ui.actionAnimation->isChecked())
2240                 return true;
2241         if (ui.actionAnimationRev->isChecked())
2242                 return true;
2243
2244         return false;
2245 }
2246
2247 void FormMain::on_actionCrossSectionDlg_triggered()
2248 {
2249         m_CrossSectionDlg.showNormal();
2250         m_CrossSectionDlg.show();
2251         m_CrossSectionDlg.activateWindow();
2252 }
2253
2254 void FormMain::on_actionSelectNext_triggered()
2255 {
2256         AddSelectObjectIdx(1);
2257 }
2258
2259 void FormMain::on_actionSelectPrev_triggered()
2260 {
2261         AddSelectObjectIdx(-1);
2262 }
2263
2264 void FormMain::AddSelectObjectIdx(int step)
2265 {
2266         QTreeWidget* obj_tree = ui.treeObjects;
2267
2268         int num_obj = obj_tree->topLevelItemCount();
2269         if (num_obj == 0)
2270                 return;
2271
2272         QTreeWidgetItem * i = obj_tree->currentItem();
2273         int idx = obj_tree->indexOfTopLevelItem(i);
2274         idx += step;
2275
2276         if (0 > idx)
2277                 idx = num_obj - 1;
2278         else if (idx >= num_obj)
2279                 idx = 0;
2280
2281         QTreeWidgetItem * j = obj_tree->topLevelItem(idx);
2282         obj_tree->setCurrentItem(j);
2283 }
2284
2285 void FormMain::on_actionSwitchVisible_triggered()
2286 {
2287         FlipVisibleSelectedObject();
2288 }
2289
2290 void FormMain::on_actionActionSelObjectShowOnlyOnce_triggered()
2291 {
2292         ShowObjectOnlySelected();
2293 }
2294
2295 void FormMain::on_actionHideAll_triggered()
2296 {
2297         HideAllObject();
2298 }
2299
2300 void FormMain::on_actionShowAll_triggered()
2301 {
2302         ShowAllObject();
2303 }
2304
2305 void FormMain::on_actionVertexBuilder_triggered()
2306 {
2307         FormVertexBuilder builder;
2308         builder.CreateVertex(m_Scene);
2309
2310         RebuildObjectList();
2311         updateView_All();
2312 }
2313
2314 void FormMain::on_actionFullScreen_triggered()
2315 {
2316         m_FullscreenPanel.ShowWidgetAsFullscreen(ui.splitter, ui.gridLayout_4);
2317 }
2318
2319 void FormMain::on_actionResetConfig_triggered()
2320 {
2321         QString msg = QString::fromLocal8Bit("\90Ý\92è\82ð\83\8a\83Z\83b\83g\82µ\82Ü\82·");
2322         if (QMessageBox::question(this, "", msg, QMessageBox::Ok|QMessageBox::Cancel) != QMessageBox::Ok)
2323                 return;
2324
2325         setGeometry(m_InitRect);
2326
2327         LoadDefaultConfig();
2328
2329         SyncViewSettingsFromGUI();
2330         SyncUVViewSettingsFromGUI();
2331         ApplyGeomStateFromGUI();
2332         SyncShaderSettingsToGUI();
2333 }
2334
2335 QString FormMain::GetFilePathFromOpenDlg(const QString& title, const QString& filter)
2336 {
2337         QString default_path = GetNextDefaultPathForFileDlg();
2338         QString s = QFileDialog::getOpenFileName(this, title, default_path, filter);
2339
2340         if (!s.isEmpty())
2341                 m_LastFileDialogDir = QFileInfo(s).absolutePath();
2342
2343         return s;
2344 }
2345
2346 QString FormMain::GetFilePathFromSaveDlg(const QString& title, const QString& filter)
2347 {
2348         QString default_path = GetNextDefaultPathForFileDlg();
2349         QString s = QFileDialog::getSaveFileName(this, title, default_path, filter);
2350
2351         if (!s.isEmpty())
2352                 m_LastFileDialogDir = QFileInfo(s).absolutePath();
2353
2354         return s;
2355 }
2356
2357 bool FormMain::IsSupportedTextureExt(const QString& path) const
2358 {
2359         QString ext = QFileInfo(path).suffix().toLower();
2360
2361         std::map<QString, bool> types;
2362         types[ "png"  ] = true;
2363         types[ "jpg"  ] = true;
2364         types[ "jepg" ] = true;
2365         types[ "bmp"  ] = true;
2366         types[ "tif"  ] = true;
2367         types[ "tiff" ] = true;
2368
2369         return types[ext];
2370 }
2371
2372 QString FormMain::GetSupportedImageFilePathFromDlg(const QString& title)
2373 {
2374         FileDlgFilterList exts;
2375         exts.Add( "Png" , "png"  );
2376         exts.Add( "Jpg" , "jpg"  );
2377         exts.Add( "Jpg" , "jpeg" );
2378         exts.Add( "Bmp" , "bmp"  );
2379         exts.Add( "Tif" , "tif"  );
2380         exts.Add( "Tif" , "tiff" );
2381
2382         QString filter = FileDlgUtil::ExtListToDlgFilter("Image", exts);
2383         return GetFilePathFromOpenDlg(title, filter);
2384 }
2385
2386
2387 QString FormMain::GetNextDefaultPathForFileDlg(void)
2388 {
2389         if (m_LastFileDialogDir.isEmpty())
2390                 return PathInfo::GetMyDocDirPath();
2391
2392         return m_LastFileDialogDir;
2393 }
2394
2395
2396 void FormMain::on_toolLoadEnvMap_clicked()
2397 {
2398         QString fileName = GetSupportedImageFilePathFromDlg("Open envmap");
2399         if (fileName.isEmpty())
2400                 return;
2401
2402         LoadEnvMap(fileName);
2403 }
2404
2405 void FormMain::LoadEnvMap(QString& path)
2406 {
2407         m_ContextShare.BeginDrawTop();
2408         m_Scene.m_EnvImg.LoadTexture(path.toLocal8Bit().data());
2409         m_ContextShare.EndDrawTop();
2410
2411         QString title = QFileInfo(path).fileName();
2412         ui.editEnvMap->setText(title);
2413
2414         updateView_All();
2415 }
2416
2417 void FormMain::on_buttonReleaseEnvImg_clicked()
2418 {
2419         m_ContextShare.BeginDrawTop();
2420         m_Scene.m_EnvImg.ClearEnv();
2421         m_ContextShare.EndDrawTop();
2422
2423         ui.editEnvMap->clear();
2424
2425         updateView_All();
2426 }
2427
2428 void FormMain::on_buttonPresetEnvMap_clicked()
2429 {
2430         if (m_EnvmapDlg == NULL)
2431         {
2432                 m_EnvmapDlg = new EnvmapSelectDlg(this);
2433                 connect(
2434                         m_EnvmapDlg,
2435                         SIGNAL(ListSelectChanged()),
2436                         this,
2437                         SLOT(EnvmapDlg_ListSelectChanged()));
2438         }
2439
2440         m_EnvmapDlg->show();
2441 }
2442
2443 void FormMain::EnvmapDlg_ListSelectChanged()
2444 {
2445         QString p = m_EnvmapDlg->GetSelectedItemPath();
2446         if (p.isEmpty())
2447                 return;
2448
2449         LoadEnvMap(p);
2450 }
2451
2452 void FormMain::on_toolLoadMatcap_clicked()
2453 {
2454         QString fileName = GetSupportedImageFilePathFromDlg("Open matcap");
2455         if (fileName.isEmpty())
2456                 return;
2457
2458         LoadMatcapImage(fileName);
2459 }
2460
2461 void FormMain::on_buttonReleaseMatcap_clicked()
2462 {
2463         m_ContextShare.BeginDrawTop();
2464         m_Scene.m_MatcapImg.ClearEnv();
2465         m_ContextShare.EndDrawTop();
2466
2467         ui.editMatcap->clear();
2468
2469         updateView_All();
2470 }
2471
2472 void FormMain::on_buttonLoadMatcapPreset_clicked()
2473 {
2474         if (m_MatcapDlg == NULL)
2475         {
2476                 m_MatcapDlg = new MatcapSelectDlg(this);
2477                 connect(
2478                         m_MatcapDlg,
2479                         SIGNAL(ListSelectChanged()),
2480                         this,
2481                         SLOT(MatcapDlg_ListSelectChanged()));
2482         }
2483
2484         m_MatcapDlg->show();
2485 }
2486
2487 void FormMain::MatcapDlg_ListSelectChanged()
2488 {
2489         QString p = m_MatcapDlg->GetSelectedItemPath();
2490         if (p.isEmpty())
2491                 return;
2492
2493         LoadMatcapImage(p);
2494 }
2495
2496 void FormMain::on_sliderEnvReflection_valueChanged(int value)
2497 {
2498         float r = GetSliderNormalizedPos(ui.sliderEnvReflection);
2499         m_Scene.m_EnvImg.m_EnvReflection = r;
2500
2501         updateView_All();
2502 }
2503
2504
2505 void FormMain::on_comboCoordinate_currentIndexChanged(int index)
2506 {
2507         SceneTransform& transform = m_Scene.m_WorldTransform;
2508
2509         int idx = ui.comboCoordinate->currentIndex();
2510         switch (idx)
2511         {
2512         case 0: transform.SetCoordType(geom::SceneTransform::COORD_RUF); break;
2513         case 1: transform.SetCoordType(geom::SceneTransform::COORD_FRU); break;
2514         case 2: transform.SetCoordType(geom::SceneTransform::COORD_UFR); break;
2515         case 3: transform.SetCoordType(geom::SceneTransform::COORD_RUB); break;
2516         case 4: transform.SetCoordType(geom::SceneTransform::COORD_BRU); break;
2517         case 5: transform.SetCoordType(geom::SceneTransform::COORD_UBR); break;
2518         default:
2519                 break;
2520         }
2521
2522         updateView_All();
2523 }
2524
2525 void FormMain::on_sliderShadowDarkness_valueChanged(int value)
2526 {
2527         int b = ui.sliderShadowDarkness->minimum();
2528         int t = ui.sliderShadowDarkness->maximum();
2529
2530         float r = (float)(value - b) / (float)(t - b);
2531         m_Scene.m_ShadowConfig.m_ShadowDarkness = r;
2532
2533         updateView_All();
2534 }
2535
2536 void FormMain::on_buttonClearAllGeoms_clicked()
2537 {
2538         ClearAllObjects();
2539 }
2540
2541 //! \83J\83\81\83\89\88Ê\92u\95\9c\8c³\8b@\94\\8eg\97p\8e\9e\82Ì\83A\83j\83\81\81[\83V\83\87\83\93\97L\96³
2542 void FormMain::on_checkCameraAnimation_toggled(bool checked)
2543 {
2544 }
2545
2546
2547 void FormMain::on_actionOpenAppdir_triggered()
2548 {
2549         PathInfo::OpenAppDir();
2550 }
2551
2552 void FormMain::on_actionOpenConfigDir_triggered()
2553 {
2554         PathInfo::OpenConfigDir();
2555 }
2556
2557 void FormMain::on_buttonDecGridAxis_clicked()
2558 {
2559         m_View3d.m_GridAxisScale /= 10.0f;
2560         updateView_3D();
2561 }
2562
2563 void FormMain::on_buttonIncGridAxis_clicked()
2564 {
2565         m_View3d.m_GridAxisScale *= 10.0f;
2566         updateView_3D();
2567 }
2568
2569 void FormMain::on_buttonResetGridAxis_clicked()
2570 {
2571         m_View3d.m_GridAxisScale = 1.0f;
2572         updateView_3D();
2573 }
2574
2575
2576 void FormMain::View3D_SelectedObjectChanged(int sel_obj, int sel_mesh)
2577 {
2578         QTreeWidgetItem* on = ui.treeObjects->topLevelItem(sel_obj);
2579
2580         if (sel_mesh == -1)
2581         {
2582                 ui.treeObjects->setCurrentItem(on);
2583         }
2584         else
2585         {
2586                 QTreeWidgetItem* mn = on->child(sel_mesh);
2587                 ui.treeObjects->setCurrentItem(mn);
2588         }
2589 }
2590
2591 void FormMain::View3D_SelectedMatChanged(int sel_idx)
2592 {
2593         ui.listMaterial->setCurrentRow(sel_idx);
2594 }
2595
2596 void FormMain::View3D_CameraMoved(void)
2597 {
2598         UpdateCameraStatus();
2599 }
2600
2601 void FormMain::View3D_StatusTipChanged(QString msg)
2602 {
2603         //ui.statusBar->showMessage(msg, 1500);
2604 }
2605
2606 void FormMain::View3D_SequenceStepped(int step)
2607 {
2608         StepSequence(step);
2609 }
2610
2611 void FormMain::View3D_CursorMoved()
2612 {
2613         Cursor3D& c = m_Scene.m_Cursor3d;
2614         QString x = QString::number(c.CursorPos.x, 'f', 4);
2615         QString y = QString::number(c.CursorPos.y, 'f', 4);
2616         QString z = QString::number(c.CursorPos.z, 'f', 4);
2617         QString s;
2618         if (x.at(0) != '-')
2619                 s += " ";
2620         s += x;
2621         if (y.at(0) != '-')
2622                 s += " ";
2623         s += " ";
2624         s += y;
2625         if (z.at(0) != '-')
2626                 s += " ";
2627         s += " ";
2628         s += z;
2629
2630         ui.editCursorPos->setText(s);
2631 }
2632
2633 void FormMain::StepSequence(int step)
2634 {
2635         QSlider* s = ui.sliderSequence;
2636         s->setValue(s->value() + step);
2637 }
2638
2639 bool FormMain::IsLastSequence(void)
2640 {
2641         QSlider* s = ui.sliderSequence;
2642         return s->value() == s->maximum();
2643 }
2644
2645 bool FormMain::IsTopSequence(void)
2646 {
2647         QSlider* s = ui.sliderSequence;
2648         return s->value() == 0;
2649 }
2650
2651 void FormMain::UpdateCameraStatus(void)
2652 {
2653         const Camera& camera = m_View3d.m_Camera;
2654         const lib_gl::CameraManipulator& manip = camera.m_Manip;
2655         const lm::vec3f& vp = manip.m_ViewPos;
2656
2657         float a, b;
2658         manip.GetViewAngles(a, b);
2659         a = a * 180.0f / M_PI;
2660         b = b * 180.0f / M_PI;
2661
2662         QString msg;
2663         msg += "(";
2664         msg += QString::number(vp.x, 'f', 2) + " ";
2665         msg += QString::number(vp.y, 'f', 2) + " ";
2666         msg += QString::number(vp.z, 'f', 2);
2667         msg += ")";
2668
2669         msg += "(";
2670         msg += QString::number(a, 'f', 2) + " ";
2671         msg += QString::number(b, 'f', 2);
2672         msg += ")";
2673
2674         msg += "(";
2675         msg += QString::number(camera.m_Projection.m_Near, 'f', 2) + " ";
2676         msg += QString::number(camera.m_Projection.m_Far, 'f', 2);
2677         msg += ")";
2678
2679         m_StatusBar1->setText(msg);
2680 }
2681
2682 void FormMain::on_actionCameraFPSMode_toggled(bool arg1)
2683 {
2684         m_View3d.m_FpsMode = arg1;
2685 }
2686
2687
2688 void FormMain::actionCursorMenuStates_Toggled(bool)
2689 {
2690         m_Binder_Cursor.UpdateAllData();
2691
2692         if (QObject::sender() == ui.actionRecordStroke)
2693         {
2694                 m_Scene.m_Cursor3d.CutStroke();
2695         }
2696
2697         updateView_3D();
2698 }
2699
2700 void FormMain::on_actionResetCursor_triggered()
2701 {
2702         m_Scene.m_Cursor3d.ResetCursorPos();
2703         m_Scene.m_Cursor3d.UpdateNormal(m_View3d.m_Camera.m_Manip.GetFront());
2704         updateView_3D();
2705 }
2706
2707 void FormMain::on_actionResetMeasure_triggered()
2708 {
2709         m_View3d.ResetCursorMeasure();
2710         updateView_3D();
2711 }
2712
2713
2714 void FormMain::on_actionPyScript_triggered()
2715 {
2716         if (m_PyScriptDlg == NULL)
2717         {
2718                 m_PyScriptDlg = new FormPyScript(this);
2719                 m_PyScriptDlg->m_Scene = &m_Scene;
2720                 m_PyScriptDlg->m_View3d = &m_View3d;
2721                 m_PyScriptDlg->m_View2d = &m_View2d;
2722         }
2723
2724         m_PyScriptDlg->showNormal();
2725         m_PyScriptDlg->show();
2726         m_PyScriptDlg->activateWindow();
2727 }
2728
2729 void FormMain::on_actionConsole_triggered()
2730 {
2731         ::AllocConsole();
2732         freopen( "CON", "r", stdin  );
2733         freopen( "CON", "w", stdout );
2734 }
2735
2736
2737 void FormMain::on_actionClearVertSelect_triggered()
2738 {
2739         m_Scene.ClearAllVertSelect();
2740         updateView_All();
2741 }
2742
2743
2744 void FormMain::on_action_About_triggered()
2745 {
2746         QGVAboutDlg dlg;
2747         dlg.exec();
2748 }
2749
2750 void FormMain::on_action_Association_triggered()
2751 {
2752         m_AssociationDlg.exec();
2753 }
2754
2755 void FormMain::on_actionLookDepth_triggered()
2756 {
2757         m_View3d.LookDepth();
2758 }
2759
2760 void FormMain::on_actionLook3DCursor_triggered()
2761 {
2762         m_View3d.Look3DCursor();
2763 }
2764
2765 void FormMain::on_sliderLightPower_valueChanged(int value)
2766 {
2767         float val = (float)ui.sliderLightPower->value();
2768         float val_max = (float)ui.sliderLightPower->maximum();
2769         float n = 2.0f * val / val_max;
2770         
2771         m_View3d.SetLightStrengthByStdRatio(n);
2772
2773         ui.labelLightPower->setText(QString("LightPower ") + QString::number(n, 'f', 2));
2774
2775         updateView_All();
2776 }
2777
2778 void FormMain::on_buttonResetLightPower_clicked()
2779 {
2780         ui.sliderLightPower->setValue(1000);
2781 }
2782
2783 void FormMain::on_checkHoleAroundCursor_clicked(bool checked)
2784 {
2785         if (checked)
2786                 ui.checkShowOnlyAroundCursor->setChecked(false);
2787
2788         if (checked)
2789                 m_Scene.m_Cursor3d.CircleClip = Cursor3DCircleClip::Hole;
2790         else
2791                 m_Scene.m_Cursor3d.CircleClip = Cursor3DCircleClip::None;
2792
2793         updateView_All();
2794 }
2795
2796 void FormMain::on_checkShowOnlyAroundCursor_toggled(bool checked)
2797 {
2798         if (checked)
2799                 ui.checkHoleAroundCursor->setChecked(false);
2800
2801         if (checked)
2802                 m_Scene.m_Cursor3d.CircleClip = Cursor3DCircleClip::ShowAround;
2803         else
2804                 m_Scene.m_Cursor3d.CircleClip = Cursor3DCircleClip::None;
2805
2806         updateView_All();
2807 }
2808
2809 void FormMain::on_sliderCursorHoleRange_valueChanged(int value)
2810 {
2811         float val = (float)ui.sliderCursorHoleRange->value();
2812         float maxval = (float)ui.sliderCursorHoleRange->maximum();
2813         float n = val / maxval;
2814
2815         m_Scene.m_Cursor3d.HoleRangeRatio = n;
2816         updateView_All();
2817 }
2818
2819 void FormMain::on_buttonResetCursorHoleRange_clicked()
2820 {
2821         ResetHoleRange();
2822 }
2823
2824 void FormMain::ResetHoleRange(void)
2825 {
2826         ui.sliderCursorHoleRange->setValue(500);
2827 }
2828
2829 void FormMain::on_actionSaveImageToMydoc_triggered()
2830 {
2831         QString path = PathInfo::GetMyDocDirPath();
2832         QString basename = path + "/" + "qgv_snap_";
2833
2834         QDateTime dt = QDateTime::currentDateTime();
2835
2836         QString dst;
2837         for(;;)
2838         {
2839                 QString tp = dt.toString("yyyyMMdd_hhmmss_zzz");
2840                 dst = basename + tp + ".png";
2841                 if (!QFile(dst).exists())
2842                         break;
2843         }
2844
2845         ui.GLWidgetMain->grabFrameBuffer().save(dst);
2846 }
2847
2848 void FormMain::on_actionPostProcNone_triggered()
2849 {
2850         ChangePostprocMode(PostProcType::None);
2851 }
2852
2853 void FormMain::on_actionPostProcAntialias_triggered()
2854 {
2855         ChangePostprocMode(PostProcType::Antialias);
2856 }
2857
2858 void FormMain::on_actionPostProcBorder_triggered()
2859 {
2860         ChangePostprocMode(PostProcType::Border);
2861 }
2862
2863 void FormMain::on_actionPostProcDepthLayerColor_triggered()
2864 {
2865         ChangePostprocMode(PostProcType::DepthLayerColor);
2866 }
2867
2868 void FormMain::on_actionPostProcDepthColor_triggered()
2869 {
2870         ChangePostprocMode(PostProcType::DepthColor);
2871 }
2872
2873 void FormMain::on_actionPostProcDepthOfField_triggered()
2874 {
2875         ChangePostprocMode(PostProcType::DepthOfField);
2876 }
2877
2878 void FormMain::ChangePostprocMode(PostProcType type)
2879 {
2880         m_View3d.m_Config.m_PPMode = type;
2881         updateView_3D();
2882 }
2883
2884 void FormMain::on_sliderDOFPint_valueChanged(int value)
2885 {
2886         float n = GetSliderNormalizedPos(ui.sliderDOFPint);
2887         m_View3d.m_PPContext.m_DOFPintPos = n;
2888
2889         updateView_3D();
2890 }
2891
2892 void FormMain::on_sliderDOFRange_valueChanged(int value)
2893 {
2894         float n = GetSliderNormalizedPos(ui.sliderDOFRange);
2895         m_View3d.m_PPContext.m_DOFRange = 10.0f * n;
2896
2897         updateView_3D();
2898 }
2899
2900 float FormMain::GetSliderNormalizedPos(const QSlider* slider) const
2901 {
2902         float t = (float)slider->maximum();
2903         float b = (float)slider->minimum();
2904         float v = (float)slider->value();
2905
2906         return (v - b) / (t - b);
2907 }
2908
2909 void FormMain::on_buttonResetDOFPint_clicked()
2910 {
2911         ui.sliderDOFPint->setValue(1000);
2912 }
2913
2914 void FormMain::on_buttonResetDOFRange_clicked()
2915 {
2916         ui.sliderDOFRange->setValue(1000);
2917 }
2918
2919 void FormMain::on_actionAddCrossSectionRecord_triggered()
2920 {
2921         m_Scene.AddCrossSectionRecord();
2922         updateView_All();
2923 }
2924
2925 void FormMain::on_actionClearCrossSectionRecord_triggered()
2926 {
2927         m_Scene.ClearCrossSectionRecord();
2928         updateView_All();
2929 }
2930
2931 void FormMain::LoadCurSelMatTexture(TextureType type)
2932 {
2933         QString path = GetSupportedImageFilePathFromDlg("Load Texture");
2934         if (path.isEmpty())
2935                 return;
2936
2937         LoadCurSelMatTexture(type, path);
2938 }
2939
2940 void FormMain::LoadCurSelMatTexture(TextureType type, QString filepath)
2941 {
2942         GeomTextureSet* ts = m_Scene.GetSelectedTexture();
2943         if (ts == NULL)
2944                 return;
2945
2946         MeshBuf* mbuf = ts->GetParent();
2947         std::string fp = filepath.toLocal8Bit().data();
2948
2949         QString name_qs = QFileInfo(filepath).fileName();
2950         std::string name = name_qs.toLocal8Bit().data();
2951
2952         m_ContextShare.BeginDrawTop();
2953
2954         mbuf->ReleaseTextureUnit(ts, type);
2955         gl::GlTexture* tex = mbuf->GetInitTexture(fp, name, m_Scene.m_TexConfig);
2956         ts->SetTextureUnit(type, tex);
2957
2958         if (type == TextureType::Normal)
2959                 m_View3d.ReleaseAllRenderBuffer();
2960
2961         m_ContextShare.EndDrawTop();
2962
2963         OnChangedSelectedMaterial();
2964         updateView_All();
2965 }
2966
2967 void FormMain::ReleaseCurSelTexture(TextureType type)
2968 {
2969         MeshBuf* mbuf = m_Scene.GetPrimaryMeshbuf();
2970         if (mbuf == NULL)
2971                 return;
2972
2973         int mat_idx = m_Scene.m_Sels.GetSelMat();
2974
2975         m_ContextShare.BeginDrawTop();
2976         mbuf->ReleaseTextureUnit(mat_idx, type);
2977         m_ContextShare.EndDrawTop();
2978
2979         OnChangedSelectedMaterial();
2980         updateView_All();
2981 }
2982
2983 void FormMain::LoadMatcapImageForCurrentMat(QString& path)
2984 {
2985         GeomTextureSet* ts = m_Scene.GetSelectedTexture();
2986
2987         QString title = QFileInfo(path).fileName();
2988
2989         m_ContextShare.BeginDrawTop();
2990         ts->TexMatcap.LoadTexture(path.toLocal8Bit().data());
2991         ts->TexMatcap.SetName(title);
2992         m_ContextShare.EndDrawTop();
2993
2994         OnChangedSelectedMaterial();
2995         updateView_All();
2996 }
2997
2998 void FormMain::LoadMatcapImage(QString& path)
2999 {
3000         MatcapImage& mc = m_Scene.m_MatcapImg;
3001
3002         QString title = QFileInfo(path).fileName();
3003
3004         m_ContextShare.BeginDrawTop();
3005         mc.LoadTexture(path.toLocal8Bit().data());
3006         mc.SetName(title);
3007         m_ContextShare.EndDrawTop();
3008
3009         ui.editMatcap->setText(mc.GetName());
3010
3011         updateView_All();
3012 }
3013
3014 void FormMain::on_buttonOpenMatCapEachMaterial_clicked()
3015 {
3016         QString path = GetSupportedImageFilePathFromDlg("Load Texture");
3017         if (path.isEmpty())
3018                 return;
3019
3020         LoadMatcapImage(path);
3021 }
3022
3023 void FormMain::on_buttonClearMatCapEachMaterial_clicked()
3024 {
3025         geom::GeomTextureSet* tex = m_Scene.GetSelectedTexture();
3026         if (tex == NULL)
3027                 return;
3028
3029         m_ContextShare.BeginDrawTop();
3030         tex->TexMatcap.ClearEnv();
3031         m_ContextShare.EndDrawTop();
3032
3033         ui.editMatCapEachMaterial->clear();
3034
3035         updateView_All();
3036 }
3037
3038 void FormMain::on_buttonOpenCurrentMatColorMap_clicked()
3039 {
3040         LoadCurSelMatTexture(TextureType::Color);
3041 }
3042
3043 void FormMain::on_buttonClearCurrentMatColorMap_clicked()
3044 {
3045         ReleaseCurSelTexture(TextureType::Color);
3046 }
3047
3048 void FormMain::on_buttonOpenCurrentMatNormalMap_clicked()
3049 {
3050         LoadCurSelMatTexture(TextureType::Normal);
3051 }
3052
3053 void FormMain::on_buttonClearCurrentMatNormalMap_clicked()
3054 {
3055         ReleaseCurSelTexture(TextureType::Normal);
3056 }
3057
3058 void FormMain::ChangeMatlemColor(QWidget* col_widget)
3059 {
3060         lib_geo::BaseMaterial* mat = m_Scene.GetSelectedMaterial();
3061         if (mat == NULL)
3062                 return;
3063
3064         lib_graph::color4f* col;
3065
3066         if (col_widget == ui.colorAmbient  ) col = &mat->m_Ambient  ;
3067         if (col_widget == ui.colorEmission ) col = &mat->m_Emission ;
3068         if (col_widget == ui.colorDiffuse  ) col = &mat->m_Diffuse  ;
3069         if (col_widget == ui.colorSpecular ) col = &mat->m_Specular ;
3070
3071         lib_graph::color4f src = *col;
3072
3073         QColor dc = ToQColor(*col);
3074
3075         m_SelMatColorWidget = col_widget;
3076
3077         m_SelMatColorSelDlg.setOption(QColorDialog::ShowAlphaChannel);
3078         m_SelMatColorSelDlg.setCurrentColor(dc);
3079         if (m_SelMatColorSelDlg.exec() == QDialog::Rejected)
3080         {
3081                 *col = src;
3082                 SetWidgetColor(col_widget, dc);
3083         }
3084 }
3085
3086 void FormMain::on_buttonDiffuse_clicked()
3087 {
3088         ChangeMatlemColor(ui.colorDiffuse);
3089 }
3090
3091 void FormMain::on_buttonAmbient_clicked()
3092 {
3093         ChangeMatlemColor(ui.colorAmbient);
3094 }
3095
3096 void FormMain::on_buttonEmission_clicked()
3097 {
3098         ChangeMatlemColor(ui.colorEmission);
3099 }
3100
3101 void FormMain::on_buttonSpecular_clicked()
3102 {
3103         ChangeMatlemColor(ui.colorSpecular);
3104 }
3105
3106 void FormMain::SetWidgetColor(QWidget* w, QColor col)
3107 {
3108         QString ss = QString("background-color: %1").arg(col.name());
3109         w->setStyleSheet(ss);
3110 }
3111
3112 void FormMain::on_sliderShininess_valueChanged(int value)
3113 {
3114         lib_geo::BaseMaterial* mat = m_Scene.GetSelectedMaterial();
3115         if (mat == NULL)
3116                 return;
3117
3118         float val = (float)ui.sliderShininess->value();
3119         float val_max = (float)ui.sliderShininess->maximum();
3120
3121         float real_val = 200.0f * val / val_max;
3122
3123         mat->m_Shininess = real_val;
3124
3125         ui.labelShininessVal->setText(QString::number(real_val, 'f', 2));
3126
3127         updateView_All();
3128 }
3129
3130 void FormMain::CreateRecentFilesMenu(const std::vector<QString>& path)
3131 {
3132         QMenu* recents = ui.menuOpenRecent;
3133         recents->actions().clear();
3134
3135         for (size_t i = 0; i < path.size(); ++i)
3136         {
3137                 AddRecentFile(path[path.size() - i - 1]);
3138         }
3139 }
3140
3141 void FormMain::CreateRecentFilesFromMenu(std::vector<QString>& path)
3142 {
3143         QMenu* recents = ui.menuOpenRecent;
3144         for (int i = 0; i < recents->actions().size(); ++i)
3145         {
3146                 QAction* a = recents->actions().at(i);
3147                 path.push_back(a->text());
3148         }
3149 }
3150
3151 void FormMain::AddRecentFile(const QString& path)
3152 {
3153         QString path_local = QDir::toNativeSeparators(path);
3154
3155         static const int max_files = 10;
3156
3157         QMenu* recents = ui.menuOpenRecent;
3158
3159         for (int i = 0; i < recents->actions().size(); ++i)
3160         {
3161                 QAction* a = recents->actions().at(i);
3162                 if (a->text() == path_local)
3163                 {
3164                         recents->removeAction(a);
3165                         break;
3166                 }
3167         }
3168
3169         QAction* new_path = new QAction(path_local, this);
3170         connect(
3171                 new_path,
3172                 SIGNAL(triggered()),
3173                 this,
3174                 SLOT(OnOpenRecent()));
3175
3176         if (recents->actions().empty())
3177                 recents->addAction(new_path);
3178         else
3179                 recents->insertAction(recents->actions().front(), new_path);
3180
3181         if (recents->actions().size() > max_files)
3182         {
3183                 QAction* a = recents->actions().back();
3184                 recents->removeAction(a);
3185         }
3186 }
3187
3188 void FormMain::OnOpenRecent()
3189 {
3190         QAction* a = dynamic_cast<QAction*>(QObject::sender());
3191         assert(a != NULL);
3192         if (a == NULL)
3193                 return;
3194
3195         QString path = a->text();
3196
3197         if (IsResetSceneOnBeforeLoadFile())
3198                 ClearAllObjects();
3199
3200         if (OpenGeomFile(path))
3201                 return;
3202 }
3203
3204 void FormMain::on_checkShowOnlySelect_toggled(bool checked)
3205 {
3206         m_View3d.m_Config.m_ShowOnlySelect = checked;
3207         updateView_All();
3208 }
3209
3210 void FormMain::ResizeTreeColumns(QTreeWidget* t, int num_col)
3211 {
3212         t->setVisible(false);
3213         t->resizeColumnToContents(0);
3214         t->resizeColumnToContents(1);
3215         t->resizeColumnToContents(2);
3216         t->resizeColumnToContents(3);
3217         t->setVisible(true);
3218 }
3219
3220 void FormMain::PushbackTreeNode(QTreeWidget* tree, QTreeWidgetItem *node)
3221 {
3222         int next_idx = tree->topLevelItemCount();
3223         tree->insertTopLevelItem(next_idx, node);
3224 }
3225
3226 QTreeWidgetItem* FormMain::CreateObjectTreeNode(const geom::GeomObject& obj) const
3227 {
3228         QTreeWidgetItem* n = new QTreeWidgetItem;
3229
3230         n->setText(0, QString::fromLocal8Bit(obj.m_Name.c_str()));
3231         n->setCheckState(1, obj.m_Visible ? Qt::Checked : Qt::Unchecked);
3232         n->setText(2, QString::number(obj.GetNumTotalVerts()));
3233         n->setText(3, QString::number(obj.GetNumTotalFaces()));
3234
3235         int idx = 0;
3236         for (const MeshBuf& mbuf : obj.m_MeshAry)
3237         {
3238                 n->addChild(CreateMeshBufNode(obj, mbuf, idx++));
3239         }
3240
3241         n->setExpanded(true);
3242
3243         return n;
3244 }
3245
3246 QTreeWidgetItem* FormMain::CreateMeshBufNode(const geom::GeomObject& obj, const MeshBuf& mbuf, int idx) const
3247 {
3248         QTreeWidgetItem* n = new QTreeWidgetItem;
3249
3250         QString name;
3251         if (mbuf.m_Name.empty())
3252                 name = QString::fromLocal8Bit(obj.m_Name.c_str()) + QString::number(idx);
3253         else
3254                 name = QString::fromLocal8Bit(mbuf.m_Name.c_str());
3255
3256         n->setText(0, name);
3257         n->setCheckState(1, mbuf.m_Visible ? Qt::Checked : Qt::Unchecked);
3258         n->setText(2, QString::number(mbuf.GetNumVerts()));
3259         n->setText(3, QString::number(mbuf.GetNumFaces()));
3260
3261         return n;
3262 }
3263
3264 void FormMain::InitObjectListHeader(void)
3265 {
3266         QStringList qs;
3267         qs << "Name" << "Visible" << "Verts" << "Faces";
3268         ui.treeObjects->setHeaderLabels(qs);
3269 }
3270
3271 void FormMain::SetPrimayrSelectObjectFromScene(void)
3272 {
3273         QTreeWidget* obj_tree = ui.treeObjects;
3274
3275         Selection3D& sels = m_Scene.m_Sels;
3276         if (!sels.IsObjectSelected())
3277                 return;
3278
3279         int sel_idx = sels.GetSelObjectIdx();
3280
3281         QTreeWidgetItem* on = obj_tree->topLevelItem(sel_idx);
3282         if (on == NULL)
3283                 return;
3284
3285         if (sels.IsMBufSelected())
3286         {
3287                 QTreeWidgetItem* mn = on->child(sels.GetMBufIdx());
3288                 obj_tree->setCurrentItem(mn);
3289         }
3290         else
3291         {
3292                 obj_tree->setCurrentItem(on);
3293         }
3294 }
3295
3296 void FormMain::SetPrimayrSelectObjectToScene(void)
3297 {
3298         Selection3D& sels = m_Scene.m_Sels;
3299
3300         QTreeWidget* tree = ui.treeObjects;
3301
3302         QTreeWidgetItem* sel_node = tree->currentItem();
3303         if (sel_node == NULL)
3304                 return;
3305
3306         QTreeWidgetItem* on = sel_node->parent();
3307         if (on == NULL)
3308         {
3309                 int obj_idx = tree->indexOfTopLevelItem(sel_node);
3310                 sels.SelectObject(obj_idx);
3311         }
3312         else
3313         {
3314                 int obj_idx = tree->indexOfTopLevelItem(on);
3315                 int mb_idx = on->indexOfChild(sel_node);
3316                 sels.SelectMBuf(obj_idx, mb_idx);
3317         }
3318 }
3319
3320 void FormMain::on_actionReleaseShader_triggered()
3321 {
3322         m_ContextShare.BeginDrawTop();
3323
3324         m_View3d.m_ShaderLib.ReleaseAllShaders();
3325
3326         m_ContextShare.EndDrawTop();
3327 }
3328
3329 void FormMain::on_combo2DViewSrcType_currentIndexChanged(int index)
3330 {
3331         switch (index)
3332         {
3333         case 0 : return m_View2d.ChangeTextureSource(View2DTexSrc::Color);
3334         case 1 : return m_View2d.ChangeTextureSource(View2DTexSrc::Normal);
3335         default:
3336                 assert(false);
3337                 break;
3338         }
3339 }
3340
3341 void FormMain::on_sliderSequence_valueChanged(int value)
3342 {
3343         UpdateSequence();
3344 }
3345
3346 void FormMain::ResetSequenceSliderRange(void)
3347 {
3348         int m = m_Scene.GetKeyframeMax();
3349         ui.sliderSequence->setMaximum(m);
3350         UpdateSequence();
3351 }
3352
3353 void FormMain::UpdateSequence(void)
3354 {
3355         int v = ui.sliderSequence->value();
3356         int m = ui.sliderSequence->maximum();
3357
3358         QString s = QString("%1 / %2").arg(v).arg(m);
3359         ui.labelSequencePos->setText(s);
3360
3361         m_Scene.SetFrame(v);
3362
3363         m_View3d.ReleaseAllRenderBuffer();
3364         updateView_All();
3365 }
3366
3367 void FormMain::on_actionNewStroke_triggered()
3368 {
3369         m_Scene.m_Cursor3d.CutStroke();
3370         updateView_All();
3371 }
3372
3373 void FormMain::on_actionClearStroke_triggered()
3374 {
3375         m_Scene.m_Cursor3d.ClearStroke();
3376         updateView_All();
3377 }