OSDN Git Service

テクスチャサンプリング形式指定機能の間違いを修正
[qtgeoviewer/QtGeoViewer.git] / Src / QtGeoViewer / FormMain.cpp
index b7aa9c4..c8ee49c 100644 (file)
@@ -31,6 +31,7 @@
 #include "EnvmapSelectDlg.h"
 #include "FileDlgUtil.h"
 #include "TreeUtil.h"
+#include "MaterialPresetDlg.h"
 
 
 
@@ -52,6 +53,7 @@ FormMain::FormMain(QWidget *parent)
        , m_EnvmapDlg(NULL)
        , m_CustomShaderDlg(NULL)
        , m_PyScriptDlg(NULL)
+       , m_MatPresetDlg(NULL)
 {
        ui.setupUi(this);
 
@@ -73,10 +75,14 @@ FormMain::FormMain(QWidget *parent)
        InitDataBinding();
 
        SyncViewSettingsFromGUI();
-       SyncUVViewSettingsFromGUI();
-       SyncSceneSettingsFromGUI();
+       m_Binder_Scene.UpdateAllData();
+       m_Binder_UVConfig.UpdateAllData();
+       m_Binder_TexConfig.UpdateAllData();
+       SyncTexConfigToData();
+
        ApplyGeomStateFromGUI();
        SyncShaderSettingsToGUI();
+       updateView_All();
 
        ui.toolBar_View->setVisible( ui.actionWindow_ToolBarView->isChecked() );
 
@@ -181,12 +187,18 @@ void FormMain::InitializeEventFilter(void)
        ui.editCurrentTexName->installEventFilter(this);
        ui.editCurrentMatNormalMap->installEventFilter(this);
        ui.editMatCapEachMaterial->installEventFilter(this);
+
+       ui.colorAmbient->installEventFilter(this);
+       ui.colorEmission->installEventFilter(this);
+       ui.colorDiffuse->installEventFilter(this);
+       ui.colorSpecular->installEventFilter(this);
 }
 
 void FormMain::InitDataBinding(void)
 {
        InitializeVisiblStateMenu();
        InitializeUVStateMenu();
+       InitializeTexStateMenu();
        InitializeSceneStateMenu();
        InitializeGeomStateMenu();
        InitializeCursorMenu();
@@ -198,56 +210,57 @@ void FormMain::InitializeVisiblStateMenu(void)
 
        View3DConfig& cfg_3d = m_View3d.m_Config;
 
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawBBox            , &cfg_3d.m_DrawBBox            ));
-       dbmap.AddBinder(new MenuBinder(ui.actionFaceVBO             , &cfg_3d.m_EnableFaceVBO       ));
-       dbmap.AddBinder(new MenuBinder(ui.actionVidTopMost          , &cfg_3d.m_ShowVidTopMost      ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawBBoxRange       , &cfg_3d.m_DrawBBoxRange       ));
-       dbmap.AddBinder(new MenuBinder(ui.actionWireDispList        , &cfg_3d.m_EnableWireDispList  ));
-       dbmap.AddBinder(new MenuBinder(ui.actionMultisample         , &cfg_3d.m_EnableMultisample   ));
-       dbmap.AddBinder(new MenuBinder(ui.actionCoverageTransparent , &cfg_3d.m_EnableCoverageTrans ));
-       dbmap.AddBinder(new MenuBinder(ui.actionSeparateSpecular    , &cfg_3d.m_SeparateSpecular    ));
-       dbmap.AddBinder(new MenuBinder(ui.actionShowSelVertCoord    , &cfg_3d.m_ShowSelVertCoord    ));
-       dbmap.AddBinder(new MenuBinder(ui.actionHighlightSelected   , &cfg_3d.m_HighlightSelected   ));
-       dbmap.AddBinder(new MenuBinder(ui.actionFixMaterialSilver   , &cfg_3d.m_UseFixMaterial      ));
-       dbmap.AddBinder(new MenuBinder(ui.actionShadowmapBuffer     , &cfg_3d.m_DrawShadowmapBuf    ));
-       dbmap.AddBinder(new MenuBinder(ui.actionEnableTexture3D     , &cfg_3d.m_EnableTexture       ));
-       dbmap.AddBinder(new MenuBinder(ui.actionEnableLighting      , &cfg_3d.m_EnableLighting      ));
-       dbmap.AddBinder(new MenuBinder(ui.actionEnableCulling       , &cfg_3d.m_EnableCullFace      ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawWire            , &cfg_3d.m_DrawWire            ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawVid             , &cfg_3d.m_DrawVid             ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawVertNormal      , &cfg_3d.m_DrawVertNormal      ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawVert            , &cfg_3d.m_DrawVert            ));
-       dbmap.AddBinder(new MenuBinder(ui.actionWireVBO             , &cfg_3d.m_EnableWireVBO       ));
-       dbmap.AddBinder(new MenuBinder(ui.actionIndexColorMode      , &cfg_3d.m_IndexMaterial       ));
-       dbmap.AddBinder(new MenuBinder(ui.actionFBMaterial          , &cfg_3d.m_FBMaterial          ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawMiniAxis        , &cfg_3d.m_DrawMiniAxis        ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawLookPos         , &cfg_3d.m_DrawLookPos         ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawLightPos        , &cfg_3d.m_DrawLightPosition   ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawGround          , &cfg_3d.m_DrawGround          ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawFid             , &cfg_3d.m_DrawFid             ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawFace            , &cfg_3d.m_DrawFace            ));
-       dbmap.AddBinder(new MenuBinder(ui.actionCameraRecords       , &cfg_3d.m_DrawCameraRecord    ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawAxis            , &cfg_3d.m_DrawAxis            ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDoubleSideShading   , &cfg_3d.m_DoubleSideShading   ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDirectionalLight    , &cfg_3d.m_LightIsDirectional  ));
-       dbmap.AddBinder(new MenuBinder(ui.actionCullFrontOrBack     , &cfg_3d.m_CullAngle_F         ));
-       dbmap.AddBinder(new MenuBinder(ui.actionHighlightMaterial   , &cfg_3d.m_HighlightMaterial   ));
-       dbmap.AddBinder(new MenuBinder(ui.actionCloseVert           , &cfg_3d.m_ShowCloseVertInfo   ));
-       dbmap.AddBinder(new MenuBinder(ui.actionCameraRange         , &cfg_3d.m_DrawRenderRange     ));
-       dbmap.AddBinder(new MenuBinder(ui.actionRenderTime          , &cfg_3d.m_ShowRenderTime      ));
-       dbmap.AddBinder(new MenuBinder(ui.actionUseFixTexture       , &cfg_3d.m_UseFixTexture       ));
-       dbmap.AddBinder(new MenuBinder(ui.actionShowSelVertIdx      , &cfg_3d.m_ShowSelVertIdx      ));
-       dbmap.AddBinder(new MenuBinder(ui.actionShowMeshBound       , &cfg_3d.m_ShowMeshBound       ));
-       dbmap.AddBinder(new MenuBinder(ui.actionPickTransparent     , &cfg_3d.m_PickTransparent     ));
-       dbmap.AddBinder(new MenuBinder(ui.actionFlatShading         , &cfg_3d.m_EnableFlatShade     ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawPolylineLenWhl  , &cfg_3d.m_DrawPolylineLenWhl  ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawPolylineLen     , &cfg_3d.m_DrawPolylineLen     ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawPolylineIdx     , &cfg_3d.m_DrawPolylineIdx     ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawPolyline        , &cfg_3d.m_DrawPolyline        ));
-       dbmap.AddBinder(new MenuBinder(ui.actionDrawBone            , &cfg_3d.m_DrawBone            ));
-       dbmap.AddBinder(new MenuBinder(ui.actionShowMeasure         , &cfg_3d.m_DrawCameraMeasure   ));
-       dbmap.AddBinder(new MenuBinder(ui.actionFlipMouseMR         , &cfg_3d.m_FlipMouseMR         ));
-       dbmap.AddBinder(new MenuBinder(ui.actionSyncLightToCamera   , &cfg_3d.m_SyncLightTocamera   ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawBBox              , &cfg_3d.m_DrawBBox              ));
+       dbmap.AddBinder(new MenuBinder(ui.actionFaceVBO               , &cfg_3d.m_EnableFaceVBO         ));
+       dbmap.AddBinder(new MenuBinder(ui.actionVidTopMost            , &cfg_3d.m_ShowVidTopMost        ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawBBoxRange         , &cfg_3d.m_DrawBBoxRange         ));
+       dbmap.AddBinder(new MenuBinder(ui.actionWireDispList          , &cfg_3d.m_EnableWireDispList    ));
+       dbmap.AddBinder(new MenuBinder(ui.actionMultisample           , &cfg_3d.m_EnableMultisample     ));
+       dbmap.AddBinder(new MenuBinder(ui.actionCoverageTransparent   , &cfg_3d.m_EnableCoverageTrans   ));
+       dbmap.AddBinder(new MenuBinder(ui.actionSeparateSpecular      , &cfg_3d.m_SeparateSpecular      ));
+       dbmap.AddBinder(new MenuBinder(ui.actionShowSelVertCoord      , &cfg_3d.m_ShowSelVertCoord      ));
+       dbmap.AddBinder(new MenuBinder(ui.actionHighlightSelected     , &cfg_3d.m_HighlightSelected     ));
+       dbmap.AddBinder(new MenuBinder(ui.actionHighlightSelectedWire , &cfg_3d.m_HighlightSelectedWire ));
+       dbmap.AddBinder(new MenuBinder(ui.actionFixMaterialSilver     , &cfg_3d.m_UseFixMaterial        ));
+       dbmap.AddBinder(new MenuBinder(ui.actionShadowmapBuffer       , &cfg_3d.m_DrawShadowmapBuf      ));
+       dbmap.AddBinder(new MenuBinder(ui.actionEnableTexture3D       , &cfg_3d.m_EnableTexture         ));
+       dbmap.AddBinder(new MenuBinder(ui.actionEnableLighting        , &cfg_3d.m_EnableLighting        ));
+       dbmap.AddBinder(new MenuBinder(ui.actionEnableCulling         , &cfg_3d.m_EnableCullFace        ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawWire              , &cfg_3d.m_DrawWire              ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawVid               , &cfg_3d.m_DrawVid               ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawVertNormal        , &cfg_3d.m_DrawVertNormal        ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawVert              , &cfg_3d.m_DrawVert              ));
+       dbmap.AddBinder(new MenuBinder(ui.actionWireVBO               , &cfg_3d.m_EnableWireVBO         ));
+       dbmap.AddBinder(new MenuBinder(ui.actionIndexColorMode        , &cfg_3d.m_IndexMaterial         ));
+       dbmap.AddBinder(new MenuBinder(ui.actionFBMaterial            , &cfg_3d.m_FBMaterial            ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawMiniAxis          , &cfg_3d.m_DrawMiniAxis          ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawLookPos           , &cfg_3d.m_DrawLookPos           ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawLightPos          , &cfg_3d.m_DrawLightPosition     ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawGround            , &cfg_3d.m_DrawGround            ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawFid               , &cfg_3d.m_DrawFid               ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawFace              , &cfg_3d.m_DrawFace              ));
+       dbmap.AddBinder(new MenuBinder(ui.actionCameraRecords         , &cfg_3d.m_DrawCameraRecord      ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawAxis              , &cfg_3d.m_DrawAxis              ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDoubleSideShading     , &cfg_3d.m_DoubleSideShading     ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDirectionalLight      , &cfg_3d.m_LightIsDirectional    ));
+       dbmap.AddBinder(new MenuBinder(ui.actionCullFrontOrBack       , &cfg_3d.m_CullAngle_F           ));
+       dbmap.AddBinder(new MenuBinder(ui.actionHighlightMaterial     , &cfg_3d.m_HighlightMaterial     ));
+       dbmap.AddBinder(new MenuBinder(ui.actionCloseVert             , &cfg_3d.m_ShowCloseVertInfo     ));
+       dbmap.AddBinder(new MenuBinder(ui.actionCameraRange           , &cfg_3d.m_DrawRenderRange       ));
+       dbmap.AddBinder(new MenuBinder(ui.actionRenderTime            , &cfg_3d.m_ShowRenderTime        ));
+       dbmap.AddBinder(new MenuBinder(ui.actionUseFixTexture         , &cfg_3d.m_UseFixTexture         ));
+       dbmap.AddBinder(new MenuBinder(ui.actionShowSelVertIdx        , &cfg_3d.m_ShowSelVertIdx        ));
+       dbmap.AddBinder(new MenuBinder(ui.actionShowMeshBound         , &cfg_3d.m_ShowMeshBound         ));
+       dbmap.AddBinder(new MenuBinder(ui.actionPickTransparent       , &cfg_3d.m_PickTransparent       ));
+       dbmap.AddBinder(new MenuBinder(ui.actionFlatShading           , &cfg_3d.m_EnableFlatShade       ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawPolylineLenWhl    , &cfg_3d.m_DrawPolylineLenWhl    ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawPolylineLen       , &cfg_3d.m_DrawPolylineLen       ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawPolylineIdx       , &cfg_3d.m_DrawPolylineIdx       ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawPolyline          , &cfg_3d.m_DrawPolyline          ));
+       dbmap.AddBinder(new MenuBinder(ui.actionDrawBone              , &cfg_3d.m_DrawBone              ));
+       dbmap.AddBinder(new MenuBinder(ui.actionShowMeasure           , &cfg_3d.m_DrawCameraMeasure     ));
+       dbmap.AddBinder(new MenuBinder(ui.actionFlipMouseMR           , &cfg_3d.m_FlipMouseMR           ));
+       dbmap.AddBinder(new MenuBinder(ui.actionSyncLightToCamera     , &cfg_3d.m_SyncLightTocamera     ));
 
        for (GuiBinder& binder : dbmap.m_BinderMap)
        {
@@ -272,9 +285,6 @@ void FormMain::InitializeUVStateMenu(void)
        dbmap.AddBinder(new MenuBinder(ui.actionUseFixTexture2D  , &m_View2d.m_UseFixTexute              ));
        dbmap.AddBinder(new MenuBinder(ui.actionShowVertex2d     , &m_View2d.m_DrawVerts                 ));
        dbmap.AddBinder(new MenuBinder(ui.actionShowImage2d      , &m_View2d.m_EnableTexture             ));
-       dbmap.AddBinder(new MenuBinder(ui.actionTextureMipmap    , &m_Scene.m_TexConfig.m_EnableMipmap   ));
-       dbmap.AddBinder(new MenuBinder(ui.actionTextureCompress  , &m_Scene.m_TexConfig.m_EnableCompress ));
-       dbmap.AddBinder(new MenuBinder(ui.actionUVFlipY          , &m_Scene.m_TextureTransform.m_FlipY   ));
 
        for (GuiBinder& binder : dbmap.m_BinderMap)
        {
@@ -291,6 +301,92 @@ void FormMain::InitializeUVStateMenu(void)
        }
 }
 
+void FormMain::InitializeTexStateMenu(void)
+{
+       DataBinderMap& dbmap = m_Binder_TexConfig;
+
+       static bool t = false;
+
+       dbmap.AddBinder(new MenuBinder(ui.actionUVFlipY         , &m_Scene.m_TextureTransform.m_FlipY   ));
+       dbmap.AddBinder(new MenuBinder(ui.actionTextureCompress , &m_Scene.m_TexConfig.m_EnableCompress ));
+
+       for (GuiBinder& binder : dbmap.m_BinderMap)
+       {
+               MenuBinder* mb = dynamic_cast<MenuBinder*>(&binder);
+               if (mb != NULL)
+               {
+                       QAction* a = mb->GetMenu();
+                       connect(
+                               a,
+                               SIGNAL(triggered(bool)),
+                               this,
+                               SLOT(actionVisibleStatesTex_Triggered(bool)));
+               }
+       }
+}
+
+void FormMain::on_actionTextureMipmap_toggled(bool b)
+{
+       m_Scene.m_TexConfig.m_SampleMode = gl::TexSampleMode::Mipmap;
+       updateView_All();
+}
+
+void FormMain::on_actionTextureLinear_toggled(bool b)
+{
+       m_Scene.m_TexConfig.m_SampleMode = gl::TexSampleMode::Linear;
+       updateView_All();
+}
+
+void FormMain::on_actionTextureNearest_toggled(bool b)
+{
+       m_Scene.m_TexConfig.m_SampleMode = gl::TexSampleMode::Nearest;
+       updateView_All();
+}
+
+void FormMain::SyncTexConfigToGUI(bool silent)
+{
+       gl::TexSampleMode mode = m_Scene.m_TexConfig.m_SampleMode;
+
+       if (silent)
+       {
+               SetActioncheck(ui.actionTextureMipmap, true, false);
+               SetActioncheck(ui.actionTextureLinear, true, false);
+               SetActioncheck(ui.actionTextureNearest, true, false);
+       }
+
+       QAction* a = NULL;
+       if (mode == gl::TexSampleMode::Mipmap)
+               a = ui.actionTextureMipmap;
+       else if (mode == gl::TexSampleMode::Linear)
+               a = ui.actionTextureLinear;
+       else if (mode == gl::TexSampleMode::Nearest)
+               a = ui.actionTextureNearest;
+
+       SetActioncheck(a, silent, true);
+}
+
+void FormMain::SetActioncheck(QAction* a, bool silent, bool check)
+{
+       assert(a != NULL);
+       if (silent)
+               a->blockSignals(true);
+
+       a->setChecked(check);
+
+       if (silent)
+               a->blockSignals(false);
+}
+
+void FormMain::SyncTexConfigToData(void)
+{
+       if (ui.actionTextureMipmap->isChecked())
+               m_Scene.m_TexConfig.m_SampleMode = gl::TexSampleMode::Mipmap;
+       else if (ui.actionTextureLinear->isChecked())
+               m_Scene.m_TexConfig.m_SampleMode = gl::TexSampleMode::Linear;
+       else if (ui.actionTextureNearest->isChecked())
+               m_Scene.m_TexConfig.m_SampleMode = gl::TexSampleMode::Nearest;
+}
+
 void FormMain::InitializeSceneStateMenu(void)
 {
        DataBinderMap& dbmap = m_Binder_Scene;
@@ -320,15 +416,18 @@ void FormMain::InitializeCursorMenu(void)
        DataBinderMap& dbmap = m_Binder_Cursor;
 
        Cursor3D& cursor = m_Scene.m_Cursor3d;
-       dbmap.AddBinder(new MenuBinder( ui.actionShowCursor     , &cursor.ShowCursor     ));
-       dbmap.AddBinder(new MenuBinder( ui.actionCursorToDepth  , &cursor.CursorDepth    ));
-       dbmap.AddBinder(new MenuBinder( ui.actionCursorCoord    , &cursor.ShowCoord      ));
-       dbmap.AddBinder(new MenuBinder( ui.actionCheckBaryCoord , &cursor.CheckBaryCoord ));
-       dbmap.AddBinder(new MenuBinder( ui.actionSelectCloseMat , &cursor.SelCloseVert   ));
-       dbmap.AddBinder(new MenuBinder( ui.actionCursorAxis     , &cursor.ShowAxis       ));
-       dbmap.AddBinder(new MenuBinder( ui.actionMeasure        , &cursor.ShowMeasure    ));
-       dbmap.AddBinder(new MenuBinder( ui.actionMeasureLen     , &cursor.ShowMeasureLen ));
-       dbmap.AddBinder(new MenuBinder( ui.actionMeasureXYZ     , &cursor.ShowMeasureXYZ ));
+       dbmap.AddBinder(new MenuBinder( ui.actionShowCursor        , &cursor.ShowCursor     ));
+       dbmap.AddBinder(new MenuBinder( ui.actionCursorToDepth     , &cursor.CursorDepth    ));
+       dbmap.AddBinder(new MenuBinder( ui.actionCursorCoord       , &cursor.ShowCoord      ));
+       dbmap.AddBinder(new MenuBinder( ui.actionCheckBaryCoord    , &cursor.CheckBaryCoord ));
+       dbmap.AddBinder(new MenuBinder( ui.actionSelectCloseMat    , &cursor.SelCloseMat    ));
+       dbmap.AddBinder(new MenuBinder( ui.actionCursorAxis        , &cursor.ShowAxis       ));
+       dbmap.AddBinder(new MenuBinder( ui.actionMeasure           , &cursor.ShowMeasure    ));
+       dbmap.AddBinder(new MenuBinder( ui.actionMeasureLen        , &cursor.ShowMeasureLen ));
+       dbmap.AddBinder(new MenuBinder( ui.actionMeasureXYZ        , &cursor.ShowMeasureXYZ ));
+       dbmap.AddBinder(new MenuBinder( ui.actionRecordStroke      , &cursor.RecordStroke   ));
+       dbmap.AddBinder(new MenuBinder( ui.actionShowStrokeLength  , &cursor.ShowStrokeLen  ));
+       dbmap.AddBinder(new MenuBinder( ui.actionTransparentStroke , &cursor.TranspStorke   ));
 
        for (GuiBinder& binder : dbmap.m_BinderMap)
        {
@@ -409,6 +508,10 @@ void FormMain::InitializeGLView(void)
                &m_View3d,
                SIGNAL(SequenceStepped(int)),
                SLOT(View3D_SequenceStepped(int)));
+       connect(
+               &m_View3d,
+               SIGNAL(CursorMoved()),
+               SLOT(View3D_CursorMoved()));
 }
 
 // OpenGL\82Ì\83\8a\83X\83g\82Ì\8b¤\97L\89»
@@ -467,7 +570,10 @@ void FormMain::InitializeFromConfigFiles(void)
 
        OpenCameraFile(PathInfo::GetCameraLogFilePath());
 
-       LoadWindowLayout(PathInfo::GetWindowLayoutConfigFilePath());
+       if (!LoadWindowLayout(PathInfo::GetWindowLayoutConfigFilePath()))
+       {
+               LoadWindowLayout(PathInfo::GetDefaultWindowLayoutConfigFilePath());
+       }
 
        if (!QGui::LoadGUIState(this, PathInfo::GetLayoutConfigFilePath()))
        {
@@ -479,6 +585,7 @@ void FormMain::LoadDefaultConfig(void)
 {
        InitializeConfig(PathInfo::GetDefaultGuiConfigFilePath());
        QGui::LoadGUIState(this, PathInfo::GetDefaultLayoutConfigFilePath());
+       LoadWindowLayout(PathInfo::GetDefaultWindowLayoutConfigFilePath());
 }
 
 void FormMain::SaveConfig(void)
@@ -515,13 +622,19 @@ bool FormMain::InitializeConfig(QString path)
        m_Binder_UVConfig.UpdateAllGUI(true);
        m_Binder_Scene.UpdateAllGUI(true);
        m_Binder_Cursor.UpdateAllGUI(true);
+       m_Binder_TexConfig.UpdateAllGUI(true);
+       SyncTexConfigToGUI(true);
 
        ApplyGeomStateDataoToGUI();
 
        SyncViewSettingsFromGUI();
-       SyncUVViewSettingsFromGUI();
+       m_Binder_UVConfig.UpdateAllData();
+       m_Binder_TexConfig.UpdateAllData();
+       SyncTexConfigToData();
        SyncShaderSettingsToGUI();
 
+       updateView_All();
+
        m_EnableAllFeatures = cfg.m_EnableAllFeatures;
 
        return true;
@@ -622,6 +735,11 @@ void FormMain::InitializeMenu(void)
        m_AGroup_PProc->addAction( ui.actionPostProcDepthLayerColor );
        m_AGroup_PProc->addAction( ui.actionPostProcDepthColor      );
        m_AGroup_PProc->addAction( ui.actionPostProcDepthOfField    );
+
+       m_AGroup_Texture = new QActionGroup(this);
+       m_AGroup_Texture->addAction( ui.actionTextureMipmap  );
+       m_AGroup_Texture->addAction( ui.actionTextureNearest );
+       m_AGroup_Texture->addAction( ui.actionTextureLinear  );
 }
 
 void FormMain::InitContextMenu(void)
@@ -634,6 +752,7 @@ void FormMain::InitContextMenu(void)
                << ui.actionSelObjectReload
                << ui.actionSelObjectFlipFace
                << ui.actionSelObjectFlipNormal
+               << ui.actionSelObjectResetNormal
                << ui.actionSelObjectOpenDir
                << ui.actionActionSelObjectShowOnlyOnce
                << ui.actionSelObjectTriangulate
@@ -677,6 +796,8 @@ void FormMain::closeEvent(QCloseEvent *e)
                m_MatcapDlg->close();
        if (m_EnvmapDlg != NULL)
                m_EnvmapDlg->close();
+       if (m_MatPresetDlg != NULL)
+               m_MatPresetDlg->close();
 
        m_ContextShare.BeginDrawTop();
        m_Scene.FinalizeScene();
@@ -726,6 +847,26 @@ bool FormMain::eventFilter(QObject * filterobj, QEvent * filterevt)
                if (filterevt->type() == QEvent::Drop)
                        return OnDropFile_editCurrentMatNormalMap(filterevt);
        }
+       else if (filterobj == ui.colorAmbient)
+       {
+               if (filterevt->type() == QEvent::MouseButtonPress)
+                       return colorAmbient_OnButtonDown(filterevt);
+       }
+       else if (filterobj == ui.colorEmission)
+       {
+               if (filterevt->type() == QEvent::MouseButtonPress)
+                       return colorEmission_OnButtonDown(filterevt);
+       }
+       else if (filterobj == ui.colorDiffuse)
+       {
+               if (filterevt->type() == QEvent::MouseButtonPress)
+                       return colorDiffuse_OnButtonDown(filterevt);
+       }
+       else if (filterobj == ui.colorSpecular)
+       {
+               if (filterevt->type() == QEvent::MouseButtonPress)
+                       return colorSpecular_OnButtonDown(filterevt);
+       }
 
        return QMainWindow::eventFilter(filterobj, filterevt);
 }
@@ -797,9 +938,9 @@ QString FormMain::GetFirstLoadableImagePathFromDragEvent(QEvent* filterevt)
                return false;
 
        QList<QUrl> urls = e->mimeData()->urls();
-       for (int i = 0; i < urls.size(); ++i)
+       for (QUrl& url : urls)
        {
-               QString path = urls[i].toLocalFile();
+               QString path = url.toLocalFile();
                if (IsSupportedTextureExt(path))
                        return path;
        }
@@ -807,6 +948,65 @@ QString FormMain::GetFirstLoadableImagePathFromDragEvent(QEvent* filterevt)
        return QString();
 }
 
+bool FormMain::colorAmbient_OnButtonDown(QEvent * filterevt)
+{
+       QMouseEvent * e = dynamic_cast<QMouseEvent *>(filterevt);
+       if (e->buttons() == Qt::LeftButton)
+               ChangeMatlemColor(ui.colorAmbient);
+       return true;
+}
+
+bool FormMain::colorEmission_OnButtonDown(QEvent * filterevt)
+{
+       QMouseEvent * e = dynamic_cast<QMouseEvent *>(filterevt);
+       if (e->buttons() == Qt::LeftButton)
+               ChangeMatlemColor(ui.colorEmission);
+       return true;
+}
+
+bool FormMain::colorDiffuse_OnButtonDown(QEvent * filterevt)
+{
+       QMouseEvent * e = dynamic_cast<QMouseEvent *>(filterevt);
+       if (e->buttons() == Qt::LeftButton)
+               ChangeMatlemColor(ui.colorDiffuse);
+       return true;
+}
+
+bool FormMain::colorSpecular_OnButtonDown(QEvent * filterevt)
+{
+       QMouseEvent * e = dynamic_cast<QMouseEvent *>(filterevt);
+       if (e->buttons() == Qt::LeftButton)
+               ChangeMatlemColor(ui.colorSpecular);
+       return true;
+}
+
+void FormMain::ChangeMatlemColor(QWidget* col_widget)
+{
+       lib_geo::BaseMaterial* mat = m_Scene.GetSelectedMaterial();
+       if (mat == NULL)
+               return;
+
+       lib_graph::color4f* col = NULL;
+       if (col_widget == ui.colorAmbient  ) col = &mat->m_Ambient  ;
+       if (col_widget == ui.colorEmission ) col = &mat->m_Emission ;
+       if (col_widget == ui.colorDiffuse  ) col = &mat->m_Diffuse  ;
+       if (col_widget == ui.colorSpecular ) col = &mat->m_Specular ;
+
+       lib_graph::color4f src = *col;
+
+       QColor dc = ToQColor(*col);
+
+       m_SelMatColorWidget = col_widget;
+
+       m_SelMatColorSelDlg.setOption(QColorDialog::ShowAlphaChannel);
+       m_SelMatColorSelDlg.setCurrentColor(dc);
+       if (m_SelMatColorSelDlg.exec() == QDialog::Rejected)
+       {
+               *col = src;
+               SetColorPalleteBG(col_widget, dc);
+       }
+}
+
 
 void FormMain::CenteringSplitter(void)
 {
@@ -951,21 +1151,17 @@ bool FormMain::LoadWindowLayout(const QString& filepath)
 
 void FormMain::actionVisibleStatesUV_Triggered(bool)
 {
-       SyncUVViewSettingsFromGUI();
-}
-
-void FormMain::SyncUVViewSettingsFromGUI(void)
-{
        m_Binder_UVConfig.UpdateAllData();
        updateView_All();
 }
 
-void FormMain::actionSceneStates_Toggled(bool)
+void FormMain::actionVisibleStatesTex_Triggered(bool)
 {
-       SyncSceneSettingsFromGUI();
+       m_Binder_TexConfig.UpdateAllData();
+       updateView_All();
 }
 
-void FormMain::SyncSceneSettingsFromGUI(void)
+void FormMain::actionSceneStates_Toggled(bool)
 {
        m_Binder_Scene.UpdateAllData();
        updateView_All();
@@ -1101,9 +1297,24 @@ void FormMain::on_actionWindowScenePanel_triggered()
        ShowAndActivateAndRaise(ui.dockScene);
 }
 
+void FormMain::on_actionCursorPanel_triggered()
+{
+       ShowAndActivateAndRaise(ui.dockCursor);
+}
+
+void FormMain::on_actionIOOptionPanel_triggered()
+{
+       ShowAndActivateAndRaise(ui.dockIOOption);
+}
+
 void FormMain::on_listMaterial_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
 {
-       m_Scene.m_Sels.SetSelMat(ui.listMaterial->currentRow());
+       MeshBuf* mbuf = m_Scene.GetSelOrFirstMeshbuf();
+       if (mbuf == NULL)
+               return;
+
+       int idx = ui.listMaterial->currentRow();
+       mbuf->SetSelMatIdx(idx);
        OnChangedSelectedMaterial();
        updateView_All();
 }
@@ -1115,56 +1326,6 @@ void FormMain::ShowAndActivateAndRaise(QDockWidget* widget)
        widget->raise();
 }
 
-void FormMain::on_treeObjects_currentItemChanged(QTreeWidgetItem * current, QTreeWidgetItem * previous)
-{
-       RefreshObjectSelectState();
-}
-
-void FormMain::RefreshObjectSelectState(void)
-{
-       SetPrimayrSelectObjectToScene();
-
-       QListWidget* list_mat = ui.listMaterial;
-       list_mat->clear();
-
-       const MeshBuf* mbuf = m_Scene.GetPrimaryMeshbuf();
-       if (mbuf != NULL)
-       {
-               const lib_geo::BaseMesh& mesh = mbuf->m_Mesh;
-               for (const lib_geo::BaseMaterial& mat : mesh.m_Materials)
-               {
-                       const std::string& name = mat.m_Name;
-
-                       if (name.empty())
-                               list_mat->addItem("--");
-                       else
-                               list_mat->addItem(QString::fromLocal8Bit(name.c_str()));
-               }
-       }
-
-       const GeomObject* obj = m_Scene.GetPrimaryObject();
-       if (mbuf != NULL)
-       {
-               ui.actionSelObjectVisible->setChecked(mbuf->IsVisible());
-       }
-       else if (obj != NULL)
-       {
-               ui.actionSelObjectVisible->setChecked(obj->m_Visible);
-       }
-       
-       if (obj != NULL)
-               ui.actionSelObjectVertexOnlyMode->setChecked(obj->m_VertexOnlyMode);
-
-       if (list_mat->count() > 0 && list_mat->currentRow() < 0)
-       {
-               list_mat->setCurrentRow(0);
-               m_Scene.m_Sels.SetSelMat(0);
-               OnChangedSelectedMaterial();
-       }
-
-       updateView_All();
-}
-
 void FormMain::OnChangedSelectedMaterial(void)
 {
        if (IsAutUVFit())
@@ -1202,23 +1363,36 @@ void FormMain::OnChangedSelectedMaterial(void)
        lib_geo::BaseMaterial* mat = m_Scene.GetSelectedMaterial();
        if (mat != NULL)
        {
-               SetWidgetColor(ui.colorAmbient  , ToQColor(mat->m_Ambient));
-               SetWidgetColor(ui.colorEmission , ToQColor(mat->m_Emission));
-               SetWidgetColor(ui.colorDiffuse  , ToQColor(mat->m_Diffuse));
-               SetWidgetColor(ui.colorSpecular , ToQColor(mat->m_Specular));
-
-               int val_max = ui.sliderShininess->maximum();
-               int slider_pos = (int)(mat->m_Shininess * (float)val_max / 200.0f);
-               slider_pos = (lm::min)(val_max, slider_pos);
-               ui.sliderShininess->blockSignals(true);
-               ui.sliderShininess->setValue(slider_pos);
-               ui.sliderShininess->blockSignals(false);
-               ui.labelShininessVal->setText(QString::number(mat->m_Shininess, 'f', 2));
+               SetColorPalleteBG(ui.colorAmbient  , ToQColor(mat->m_Ambient));
+               SetColorPalleteBG(ui.colorEmission , ToQColor(mat->m_Emission));
+               SetColorPalleteBG(ui.colorDiffuse  , ToQColor(mat->m_Diffuse));
+               SetColorPalleteBG(ui.colorSpecular , ToQColor(mat->m_Specular));
+               SetMatShininessSliderPos(mat->m_Shininess);
+       }
+       else
+       {
+               QColor w(255, 255, 255);
+               SetColorPalleteBG( ui.colorAmbient  , w );
+               SetColorPalleteBG( ui.colorEmission , w );
+               SetColorPalleteBG( ui.colorDiffuse  , w );
+               SetColorPalleteBG( ui.colorSpecular , w );
+               SetMatShininessSliderPos(0);
        }
 
        updateView_All();
 }
 
+void FormMain::SetMatShininessSliderPos(float shininess)
+{
+       int val_max = ui.sliderShininess->maximum();
+       int slider_pos = (int)(shininess * (float)val_max / 200.0f);
+       slider_pos = (lm::min)(val_max, slider_pos);
+       ui.sliderShininess->blockSignals(true);
+       ui.sliderShininess->setValue(slider_pos);
+       ui.sliderShininess->blockSignals(false);
+       ui.labelShininessVal->setText(QString::number(shininess, 'f', 2));
+}
+
 void FormMain::keyPressEvent(QKeyEvent *e)
 {
        Modifier m(e);
@@ -1275,9 +1449,9 @@ void FormMain::dropEvent(QDropEvent* e)
 
                std::vector<QString> geom_files;
 
-               for (int i = 0; i < urls.size(); ++i)
+               for (QUrl& url : urls)
                {
-                       QString path = urls[i].toLocalFile();
+                       QString path = url.toLocalFile();
                        if (FormatType::IsGeomFileExt(path))
                                geom_files.push_back(path);
                }
@@ -1287,20 +1461,20 @@ void FormMain::dropEvent(QDropEvent* e)
                        if (IsResetSceneOnBeforeLoadFile())
                                ClearAllObjects();
 
-                       for (size_t i = 0; i < geom_files.size(); ++i)
+                       for (QString& f : geom_files)
                        {
-                               if (OpenGeomFile(geom_files[i]))
+                               if (OpenGeomFile(f))
                                        continue;
                        }
                }
 
-               for (int i = 0; i < urls.size(); ++i)
+               for (QUrl& url : urls)
                {
-                       QString path = urls[i].toLocalFile();
+                       QString path = url.toLocalFile();
 
                        if (IsSupportedTextureExt(path))
                        {
-                               OpenFixTextureFile(path);
+                               DropTextureFile(path, e->pos());
                                continue;
                        }
 
@@ -1321,21 +1495,54 @@ bool FormMain::IsResetSceneOnBeforeLoadFile(void) const
        return false;
 }
 
-//! \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é.
-void FormMain::OpenFixTextureFile(const QString& path)
+//! \83I\83u\83W\83F\83N\83g\82É\89æ\91\9c\82ð\83h\83\8d\83b\83v\82³\82ê\82½\8fê\8d\87\82Í\82»\82Ì\83}\83e\83\8a\83A\83\8b\82Ì\83J\83\89\81[\83e\83N\83X\83`\83\83\82ð\83Z\83b\83g
+//! \89½\82à\96³\82¢\8fê\8f\8a\82É\83h\83\8d\83b\83v\82³\82ê\82é\82Æ\83f\83t\83H\83\8b\83g\83e\83N\83X\83`\83\83\82ð\83Z\83b\83g
+void FormMain::DropTextureFile(const QString& path, const QPoint& pos)
 {
        std::string fname = path.toLocal8Bit().data();
 
-       m_ContextShare.BeginDrawTop();
-       m_Scene.LoadDefaultMatTexture(fname);
-       m_ContextShare.EndDrawTop();
+       QPoint pl = ui.GLWidgetMain->mapFrom(this, pos);
+
+       PickedMeshSubface picked;
+       m_View3d.BeginRender();
+       bool suc = m_View3d.PickFace2D(picked, pl.x(), pl.y());
+       m_View3d.EndRender();
+
+       if (suc)
+       {
+               m_View3d.BeginRender();
+               MeshBuf* mbuf = picked.mbuf;
+               lib_geo::BaseFace& f = mbuf->m_Mesh.m_Faces[picked.subf.fid];
+               GeomTextureSet* ts = mbuf->GetTexture(f.m_MatIdx);
+               if (ts != NULL)
+               {
+                       std::string fp = path.toLocal8Bit().data();
+
+                       QString name_qs = QFileInfo(path).fileName();
+                       std::string name = name_qs.toLocal8Bit().data();
+
+                       mbuf->ReleaseTextureUnit(ts, TextureType::Color);
+                       gl::GlTexture* tex = mbuf->GetInitTexture(fp, name, m_Scene.m_TexConfig);
+                       ts->SetTextureUnit(TextureType::Color, tex);
+               }
+               m_View3d.EndRender();
+       }
+       else
+       {
+               m_ContextShare.BeginDrawTop();
+               m_Scene.LoadDefaultMatTexture(fname);
+               m_ContextShare.EndDrawTop();
+       }
 
        updateView_All();
 }
 
 bool FormMain::OpenGeomFile(const QString& path)
 {
-       m_Scene.m_ObjSplit = ui.checkSplitOBJ->isChecked();
+       IOConfig& conf = m_Scene.m_IOConfig;
+       conf.ObjSplit = ui.checkSplitOBJ->isChecked();
+       conf.ObjMergeLine = ui.checkMergeObjLine->isChecked();
+       conf.InterpolateAnimation = ui.checkInterpolateAnimation->isChecked();
 
        m_ContextShare.BeginDrawTop();
 
@@ -1400,14 +1607,12 @@ void FormMain::RebuildObjectList(void)
        obj_tree->setSelectionMode(QAbstractItemView::SingleSelection);
        obj_tree->setEditTriggers(QAbstractItemView::NoEditTriggers);
 
-       obj_tree->setColumnCount(4);
-
        InitObjectListHeader();
 
        for (const geom::GeomObject& obj : m_Scene.m_Objects)
        {
                QTreeWidgetItem* n = CreateObjectTreeNode(obj);
-               PushbackTreeNode(ui.treeObjects, n);
+               PushbackTreeNode(obj_tree, n);
                n->setExpanded(true);
        }
 
@@ -1421,13 +1626,36 @@ void FormMain::RebuildObjectList(void)
                {
                        QTreeWidgetItem* ti = obj_tree->topLevelItem(0);
                        obj_tree->setCurrentItem(ti);
-
                        if (IsAutUVFit())
                                m_View2d.FitView();
                }
        }
 
-       ResizeTreeColumns(obj_tree, 4);
+       ResizeObjectTreeColumns();
+}
+
+void FormMain::ResizeObjectTreeColumns(void)
+{
+       QTreeWidget* t = ui.treeObjects;
+
+       t->setVisible(false);
+       t->resizeColumnToContents(0);
+       t->resizeColumnToContents(1);
+       t->resizeColumnToContents(2);
+       t->resizeColumnToContents(3);
+       t->setVisible(true);
+}
+
+void FormMain::InitObjectListHeader(void)
+{
+       QTreeWidget* obj_tree = ui.treeObjects;
+
+       QStringList qs;
+       qs << "Name" << "Visible" << "Verts" << "Faces";
+       
+       obj_tree->setColumnCount(4);
+
+       obj_tree->setHeaderLabels(qs);
 }
 
 
@@ -1513,6 +1741,7 @@ void FormMain::on_actionSelObjectReload_triggered()
 
        RebuildObjectList();
 
+       m_View3d.ClearRenderMap();
        updateView_All();
 }
 
@@ -1538,21 +1767,25 @@ void FormMain::on_actionSelObjectFlipFace_triggered()
 {
        m_Scene.FlipCurselFace(false);
 
-       ui.GLWidgetMain->makeCurrent();
-       std::vector<MeshBuf*> mv = m_Scene.GetCurSelMeshes();
-       for (MeshBuf* m : mv)
-       {
-               m_View3d.ReleaseRenderbuffer(m);
-       }
-       ui.GLWidgetMain->doneCurrent();
-
-       updateView_All();
+       RebuildAllGLBuf();
 }
 
 void FormMain::on_actionSelObjectFlipNormal_triggered()
 {
        m_Scene.FlipCurselFace(true);
 
+       RebuildAllGLBuf();
+}
+
+void FormMain::on_actionSelObjectResetNormal_triggered()
+{
+       m_Scene.RebuildCurselNormal();
+
+       RebuildAllGLBuf();
+}
+
+void FormMain::RebuildAllGLBuf(void)
+{
        ui.GLWidgetMain->makeCurrent();
        std::vector<MeshBuf*> mv = m_Scene.GetCurSelMeshes();
        for (MeshBuf* m : mv)
@@ -1643,13 +1876,12 @@ void FormMain::OnDoneAddGeom(void)
                {
                        QTreeWidgetItem * j = obj_tree->topLevelItem(0);
                        obj_tree->setCurrentItem(j);
-
                        if (IsAutUVFit())
                                m_View2d.FitView();
                }
        }
 
-       ResizeTreeColumns(obj_tree, 4);
+       ResizeObjectTreeColumns();
 
        ResetSequenceSliderRange();
 
@@ -1657,47 +1889,47 @@ void FormMain::OnDoneAddGeom(void)
 }
 
 
-void FormMain::on_actionShaderDefault_triggered(bool checked)
+void FormMain::on_actionShaderDefault_triggered(bool)
 {
        ChangeShaderMenuMain(ShaderType::Default);
 }
 
-void FormMain::on_actionShaderPhong_triggered(bool checked)
+void FormMain::on_actionShaderPhong_triggered(bool)
 {
        ChangeShaderMenuMain(ShaderType::Phong);
 }
 
-void FormMain::on_actionShaderCustom_triggered(bool checked)
+void FormMain::on_actionShaderCustom_triggered(bool)
 {
        ChangeShaderMenuMain(ShaderType::Custom);
 }
 
-void FormMain::on_actionNormalColor_triggered(bool checked)
+void FormMain::on_actionNormalColor_triggered(bool)
 {
        ChangeShaderMenuMain(ShaderType::NormalColor);
 }
 
-void FormMain::on_actionDepthColor_triggered(bool checked)
+void FormMain::on_actionDepthColor_triggered(bool)
 {
        ChangeShaderMenuMain(ShaderType::DepthColor);
 }
 
-void FormMain::on_actionShadowmap_triggered(bool checked)
+void FormMain::on_actionShadowmap_triggered(bool)
 {
        ChangeShaderMenuMain(ShaderType::Shadowmap);
 }
 
-void FormMain::on_actionEnvmap_triggered(bool checked)
+void FormMain::on_actionEnvmap_triggered(bool)
 {
        ChangeShaderMenuMain(ShaderType::Envmap);
 }
 
-void FormMain::on_actionIntegrateShader_triggered(bool checked)
+void FormMain::on_actionIntegrateShader_triggered(bool)
 {
        ChangeShaderMenuMain(ShaderType::Integrate);
 }
 
-void FormMain::on_actionMatcapShader_triggered(bool checked)
+void FormMain::on_actionMatcapShader_triggered(bool)
 {
        ChangeShaderMenuMain(ShaderType::Matcap);
 }
@@ -1713,22 +1945,6 @@ void FormMain::ChangeShaderMenuMain(ShaderType type)
        updateView_All();
 }
 
-
-void FormMain::on_actionCreate_Check_triggered()
-{
-       CreateSampleTextureMain(SampleTextureBuilder::TEX_CHECKER);
-}
-
-void FormMain::on_actionCreate_Stripe_V_triggered()
-{
-       CreateSampleTextureMain(SampleTextureBuilder::TEX_STRIPE_V);
-}
-
-void FormMain::on_actionCreate_Stripe_H_triggered()
-{
-       CreateSampleTextureMain(SampleTextureBuilder::TEX_STRIPE_H);
-}
-
 void FormMain::CreateSampleTextureMain(SampleTextureBuilder::TextureType tex_type)
 {
        m_ContextShare.BeginDrawTop();
@@ -1749,31 +1965,126 @@ void FormMain::on_pushDeleteSelectedObject_clicked()
        DeleteSelectedObject();
 }
 
+void FormMain::on_treeObjects_currentItemChanged(QTreeWidgetItem * current, QTreeWidgetItem * previous)
+{
+       RefreshObjectSelectState();
+}
+
 void FormMain::on_treeObjects_itemChanged(QTreeWidgetItem * item, int column)
 {
+       if (column != 1)
+               return;
+
        QTreeWidget* obj_tree = ui.treeObjects;
 
-       if (column == 1)
+       QTreeWidgetItem* t = item->parent();
+       bool checked = (item->checkState(1) == Qt::Checked);
+       if (t == NULL)
        {
-               QTreeWidgetItem* t = item->parent();
-               bool checked = (item->checkState(1) == Qt::Checked);
-               if (t == NULL)
-               {
-                       int sel_idx = obj_tree->indexOfTopLevelItem(item);
-                       GeomObject& obj = m_Scene.m_Objects[sel_idx];
-                       obj.m_Visible = checked;
-               }
-               else
-               {
-                       int sel_idx = obj_tree->indexOfTopLevelItem(t);
-                       int midx = t->indexOfChild(item);
+               int sel_idx = obj_tree->indexOfTopLevelItem(item);
+               GeomObject& obj = m_Scene.m_Objects[sel_idx];
+               obj.m_Visible = checked;
+       }
+       else
+       {
+               int sel_idx = obj_tree->indexOfTopLevelItem(t);
+               int midx = t->indexOfChild(item);
 
-                       GeomObject& obj = m_Scene.m_Objects[sel_idx];
-                       MeshBuf& mb = obj.m_MeshAry[midx];
-                       mb.m_Visible = checked;
-               }
+               GeomObject& obj = m_Scene.m_Objects[sel_idx];
+               MeshBuf& mb = obj.m_MeshAry[midx];
+               mb.m_Visible = checked;
+       }
 
-               updateView_All();
+       updateView_All();
+}
+
+void FormMain::RefreshObjectSelectState(void)
+{
+       SetPrimayrSelectObjectToScene();
+
+       RebuildMatList();
+       UpdateContextmenuState();
+
+       updateView_All();
+}
+
+void FormMain::RebuildMatList(void)
+{
+       MeshBuf* mbuf = m_Scene.GetSelOrFirstMeshbuf();
+
+       QListWidget* list_mat = ui.listMaterial;
+
+       list_mat->blockSignals(true);
+       list_mat->clear();
+
+       if (mbuf != NULL)
+       {
+               const lib_geo::BaseMesh& mesh = mbuf->m_Mesh;
+               for (const lib_geo::BaseMaterial& mat : mesh.m_Materials)
+               {
+                       const std::string& name = mat.m_Name;
+
+                       if (name.empty())
+                               list_mat->addItem("--");
+                       else
+                               list_mat->addItem(QString::fromLocal8Bit(name.c_str()));
+               }
+       }
+
+       list_mat->blockSignals(false);
+
+       if (mbuf != NULL)
+       {
+               mbuf->SelectMatAuto();
+               list_mat->setCurrentRow(mbuf->GetSelMatIdx());
+       }
+       else
+       {
+               list_mat->setCurrentRow(-1);
+       }
+
+       OnChangedSelectedMaterial();
+}
+
+void FormMain::UpdateContextmenuState(void)
+{
+       GeomObject* obj = m_Scene.GetPrimaryObject();
+       MeshBuf* mbuf = m_Scene.GetPrimaryMeshbuf();
+
+       if (mbuf != NULL)
+       {
+               ui.actionSelObjectVisible->setChecked(mbuf->IsVisible());
+       }
+       else if (obj != NULL)
+       {
+               ui.actionSelObjectVisible->setChecked(obj->m_Visible);
+       }
+
+       if (obj != NULL)
+               ui.actionSelObjectVertexOnlyMode->setChecked(obj->m_VertexOnlyMode);
+}
+
+void FormMain::SetPrimayrSelectObjectToScene(void)
+{
+       Selection3D& sels = m_Scene.m_Sels;
+
+       QTreeWidget* tree = ui.treeObjects;
+
+       QTreeWidgetItem* sel_node = tree->currentItem();
+       if (sel_node == NULL)
+               return;
+
+       QTreeWidgetItem* on = sel_node->parent();
+       if (on == NULL)
+       {
+               int obj_idx = tree->indexOfTopLevelItem(sel_node);
+               sels.SelectObject(obj_idx);
+       }
+       else
+       {
+               int obj_idx = tree->indexOfTopLevelItem(on);
+               int mb_idx = on->indexOfChild(sel_node);
+               sels.SelectMBuf(obj_idx, mb_idx);
        }
 }
 
@@ -1807,7 +2118,7 @@ void FormMain::DeleteSelectedObject()
        obj_tree->setCurrentItem(NULL);
        obj_tree->takeTopLevelItem(sel_idx);
 
-       ResizeTreeColumns(obj_tree, 4);
+       ResizeObjectTreeColumns();
 
        ti = obj_tree->currentItem();
        sel_idx = obj_tree->indexOfTopLevelItem(ti);
@@ -1855,22 +2166,6 @@ void FormMain::ShowObjectOnlySelected(void)
        updateView_All();
 }
 
-void FormMain::ShowAllObject(void)
-{
-       m_Scene.ShowAllObject();
-
-       RebuildObjectList();
-       updateView_All();
-}
-
-void FormMain::HideAllObject(void)
-{
-       m_Scene.HideAllObject();
-
-       RebuildObjectList();
-       updateView_All();
-}
-
 void FormMain::on_actionUVResetView_triggered()
 {
        m_View2d.ResetView();
@@ -1957,7 +2252,7 @@ void FormMain::SetSelectedMaterialColor(QColor col)
        if (m_SelMatColorWidget == ui.colorDiffuse  ) CopyRGBA(mat->m_Diffuse  , col);
        if (m_SelMatColorWidget == ui.colorSpecular ) CopyRGBA(mat->m_Specular , col);
 
-       SetWidgetColor(m_SelMatColorWidget, col);
+       SetColorPalleteBG(m_SelMatColorWidget, col);
 }
 
 void FormMain::SelMatColorChanged(const QColor & color)
@@ -2052,7 +2347,7 @@ void FormMain::PrintImage(bool WithPreview)
        else
        {
                QPrintDialog printDialog(&printer, this);
-               if(printDialog.exec() == QDialog::Accepted)
+               if (printDialog.exec() == QDialog::Accepted)
                        OnPaintImage(&printer);
        }
 }
@@ -2119,7 +2414,7 @@ void FormMain::on_actionProjectionOrtho_triggered()
        ui.actionProjectionOrtho->setChecked(true);
        ui.actionProjectionPers->setChecked(false);
 
-       m_View3d.m_Camera.m_ProjMode = gl::Camera::PROJ_ORTHO;
+       m_Scene.m_Camera.m_ProjMode = gl::Camera::PROJ_ORTHO;
 
        updateView_All();
 }
@@ -2129,7 +2424,7 @@ void FormMain::on_actionProjectionPers_triggered()
        ui.actionProjectionPers->setChecked(true);
        ui.actionProjectionOrtho->setChecked(false);
 
-       m_View3d.m_Camera.m_ProjMode = gl::Camera::PROJ_PERS;
+       m_Scene.m_Camera.m_ProjMode = gl::Camera::PROJ_PERS;
 
        updateView_All();
 }
@@ -2146,7 +2441,7 @@ void FormMain::OnAnimationTimerUpdated()
 
        if (ui.actionRotateCamera->isChecked())
        {
-               m_View3d.m_Camera.m_Manip.Tumble(rot_speed, 0.0f);
+               m_Scene.m_Camera.m_Manip.Tumble(rot_speed, 0.0f);
                UpdateCameraStatus();
        }
 
@@ -2159,6 +2454,12 @@ void FormMain::OnAnimationTimerUpdated()
                if (IsLastSequence())
                        ui.actionAnimation->setChecked(false);
        }
+       else if (ui.actionAnimationRev->isChecked())
+       {
+               StepSequence(-1);
+               if (IsTopSequence())
+                       ui.actionAnimationRev->setChecked(false);
+       }
 
        updateView_3D();
 }
@@ -2177,6 +2478,7 @@ void FormMain::on_actionAnimation_toggled(bool checked)
 {
        if (checked)
        {
+               ui.actionAnimationRev->setChecked(false);
                if (IsLastSequence())
                {
                        QSlider* s = ui.sliderSequence;
@@ -2184,9 +2486,42 @@ void FormMain::on_actionAnimation_toggled(bool checked)
                }
        }
 
+       ui.butonAnimationFwd->blockSignals(true);
+       ui.butonAnimationFwd->setChecked(checked);
+       ui.butonAnimationFwd->blockSignals(false);
+
+       UpdateAnimState();
+}
+
+void FormMain::on_actionAnimationRev_toggled(bool checked)
+{
+       if (checked)
+       {
+               ui.actionAnimation->setChecked(false);
+               if (IsTopSequence())
+               {
+                       QSlider* s = ui.sliderSequence;
+                       s->setValue(s->maximum());
+               }
+       }
+
+       ui.butonAnimationRev->blockSignals(true);
+       ui.butonAnimationRev->setChecked(checked);
+       ui.butonAnimationRev->blockSignals(false);
+
        UpdateAnimState();
 }
 
+void FormMain::on_butonAnimationFwd_toggled(bool checked)
+{
+       ui.actionAnimation->setChecked(checked);
+}
+
+void FormMain::on_butonAnimationRev_toggled(bool checked)
+{
+       ui.actionAnimationRev->setChecked(checked);
+}
+
 void FormMain::UpdateAnimState(void)
 {
        if (IsEnableAnimation())
@@ -2203,6 +2538,8 @@ bool FormMain::IsEnableAnimation(void)
                return true;
        if (ui.actionAnimation->isChecked())
                return true;
+       if (ui.actionAnimationRev->isChecked())
+               return true;
 
        return false;
 }
@@ -2257,12 +2594,18 @@ void FormMain::on_actionActionSelObjectShowOnlyOnce_triggered()
 
 void FormMain::on_actionHideAll_triggered()
 {
-       HideAllObject();
+       m_Scene.HideAllObject();
+
+       RebuildObjectList();
+       updateView_All();
 }
 
 void FormMain::on_actionShowAll_triggered()
 {
-       ShowAllObject();
+       m_Scene.ShowAllObject();
+
+       RebuildObjectList();
+       updateView_All();
 }
 
 void FormMain::on_actionVertexBuilder_triggered()
@@ -2290,9 +2633,13 @@ void FormMain::on_actionResetConfig_triggered()
        LoadDefaultConfig();
 
        SyncViewSettingsFromGUI();
-       SyncUVViewSettingsFromGUI();
+       m_Binder_UVConfig.UpdateAllData();
+       m_Binder_TexConfig.UpdateAllData();
+       SyncTexConfigToData();
        ApplyGeomStateFromGUI();
        SyncShaderSettingsToGUI();
+
+       updateView_All();
 }
 
 QString FormMain::GetFilePathFromOpenDlg(const QString& title, const QString& filter)
@@ -2328,6 +2675,7 @@ bool FormMain::IsSupportedTextureExt(const QString& path) const
        types[ "bmp"  ] = true;
        types[ "tif"  ] = true;
        types[ "tiff" ] = true;
+       types[ "spa"  ] = true;
 
        return types[ext];
 }
@@ -2461,6 +2809,17 @@ void FormMain::on_sliderEnvReflection_valueChanged(int value)
        float r = GetSliderNormalizedPos(ui.sliderEnvReflection);
        m_Scene.m_EnvImg.m_EnvReflection = r;
 
+       ui.labelEnvReflection->setText(QString::number(r, 'f', 2));
+
+       updateView_All();
+}
+
+void FormMain::on_sliderEnvRefract_valueChanged(int value)
+{
+       float r = ui.sliderEnvRefract->value() / 1000.0;
+       m_Scene.m_EnvImg.m_EnvRefract = r;
+
+       ui.labelEnvRefract->setText(QString::number(r, 'f', 2));
        updateView_All();
 }
 
@@ -2571,6 +2930,28 @@ void FormMain::View3D_SequenceStepped(int step)
        StepSequence(step);
 }
 
+void FormMain::View3D_CursorMoved()
+{
+       Cursor3D& c = m_Scene.m_Cursor3d;
+       QString x = QString::number(c.CursorPos.x, 'f', 4);
+       QString y = QString::number(c.CursorPos.y, 'f', 4);
+       QString z = QString::number(c.CursorPos.z, 'f', 4);
+       QString s;
+       if (x.at(0) != '-')
+               s += " ";
+       s += x;
+       if (y.at(0) != '-')
+               s += " ";
+       s += " ";
+       s += y;
+       if (z.at(0) != '-')
+               s += " ";
+       s += " ";
+       s += z;
+
+       ui.editCursorPos->setText(s);
+}
+
 void FormMain::StepSequence(int step)
 {
        QSlider* s = ui.sliderSequence;
@@ -2583,9 +2964,15 @@ bool FormMain::IsLastSequence(void)
        return s->value() == s->maximum();
 }
 
+bool FormMain::IsTopSequence(void)
+{
+       QSlider* s = ui.sliderSequence;
+       return s->value() == 0;
+}
+
 void FormMain::UpdateCameraStatus(void)
 {
-       const Camera& camera = m_View3d.m_Camera;
+       const Camera& camera = m_Scene.m_Camera;
        const lib_gl::CameraManipulator& manip = camera.m_Manip;
        const lm::vec3f& vp = manip.m_ViewPos;
 
@@ -2623,13 +3010,18 @@ void FormMain::on_actionCameraFPSMode_toggled(bool arg1)
 void FormMain::actionCursorMenuStates_Toggled(bool)
 {
        m_Binder_Cursor.UpdateAllData();
+
+       if (QObject::sender() == ui.actionRecordStroke)
+       {
+               m_Scene.m_Cursor3d.CutStroke();
+       }
+
        updateView_3D();
 }
 
 void FormMain::on_actionResetCursor_triggered()
 {
        m_Scene.m_Cursor3d.ResetCursorPos();
-       m_Scene.m_Cursor3d.UpdateNormal(m_View3d.m_Camera.m_Manip.GetFront());
        updateView_3D();
 }
 
@@ -2691,22 +3083,46 @@ void FormMain::on_actionLook3DCursor_triggered()
        m_View3d.Look3DCursor();
 }
 
-void FormMain::on_sliderLightPower_valueChanged(int value)
+void FormMain::on_sliderLightPowerDS_valueChanged(int value)
 {
-       float val = (float)ui.sliderLightPower->value();
-       float val_max = (float)ui.sliderLightPower->maximum();
-       float n = 2.0f * val / val_max;
-       
-       m_View3d.SetLightStrengthByStdRatio(n);
+       float n = 2.0f * GetSliderNormalizedPos(ui.sliderLightPowerDS);
+       m_View3d.SetDfSpLightPower(n);
+
+       UpdateLightPowerText();
+
+       updateView_All();
+}
 
-       ui.labelLightPower->setText(QString("LightPower ") + QString::number(n, 'f', 2));
+void FormMain::on_buttonResetLightPowerDS_clicked()
+{
+       ui.sliderLightPowerDS->setValue(1000);
+}
+
+void FormMain::on_sliderLightPowerA_valueChanged(int value)
+{
+       float n = 2.0f * GetSliderNormalizedPos(ui.sliderLightPowerA);
+       m_View3d.SetAmbientLightPower(n);
+
+       UpdateLightPowerText();
 
        updateView_All();
 }
 
-void FormMain::on_buttonResetLightPower_clicked()
+void FormMain::on_buttonResetLightPowerA_clicked()
+{
+       ui.sliderLightPowerA->setValue(1000);
+}
+
+void FormMain::UpdateLightPowerText(void)
 {
-       ui.sliderLightPower->setValue(1000);
+       float ld = 2.0f * GetSliderNormalizedPos(ui.sliderLightPowerDS);
+       float la = 2.0f * GetSliderNormalizedPos(ui.sliderLightPowerA);
+
+       QString s = "";
+       s += QString("Light");
+       s += QString(" DS=") + QString::number(ld, 'f', 2);
+       s += QString(" A=") + QString::number(la, 'f', 2);
+       ui.labelLightPower->setText(s);
 }
 
 void FormMain::on_checkHoleAroundCursor_clicked(bool checked)
@@ -2715,9 +3131,9 @@ void FormMain::on_checkHoleAroundCursor_clicked(bool checked)
                ui.checkShowOnlyAroundCursor->setChecked(false);
 
        if (checked)
-               m_Scene.m_Cursor3d.CircleClip = Cursor3DCircleClip::Hole;
+               m_Scene.m_Cursor3d.SphereClip = SphereClipType::Hole;
        else
-               m_Scene.m_Cursor3d.CircleClip = Cursor3DCircleClip::None;
+               m_Scene.m_Cursor3d.SphereClip = SphereClipType::None;
 
        updateView_All();
 }
@@ -2728,9 +3144,9 @@ void FormMain::on_checkShowOnlyAroundCursor_toggled(bool checked)
                ui.checkHoleAroundCursor->setChecked(false);
 
        if (checked)
-               m_Scene.m_Cursor3d.CircleClip = Cursor3DCircleClip::ShowAround;
+               m_Scene.m_Cursor3d.SphereClip = SphereClipType::ShowAround;
        else
-               m_Scene.m_Cursor3d.CircleClip = Cursor3DCircleClip::None;
+               m_Scene.m_Cursor3d.SphereClip = SphereClipType::None;
 
        updateView_All();
 }
@@ -2895,11 +3311,12 @@ void FormMain::LoadCurSelMatTexture(TextureType type, QString filepath)
 
 void FormMain::ReleaseCurSelTexture(TextureType type)
 {
-       MeshBuf* mbuf = m_Scene.GetPrimaryMeshbuf();
-       if (mbuf == NULL)
+       GeomTextureSet* ts = m_Scene.GetSelectedTexture();
+       if (ts == NULL)
                return;
 
-       int mat_idx = m_Scene.m_Sels.GetSelMat();
+       MeshBuf* mbuf = ts->GetParent();
+       int mat_idx = mbuf->GetSelMatIdx();
 
        m_ContextShare.BeginDrawTop();
        mbuf->ReleaseTextureUnit(mat_idx, type);
@@ -2912,6 +3329,8 @@ void FormMain::ReleaseCurSelTexture(TextureType type)
 void FormMain::LoadMatcapImageForCurrentMat(QString& path)
 {
        GeomTextureSet* ts = m_Scene.GetSelectedTexture();
+       if (ts == NULL)
+               return;
 
        QString title = QFileInfo(path).fileName();
 
@@ -2930,13 +3349,13 @@ void FormMain::LoadMatcapImage(QString& path)
 
        QString title = QFileInfo(path).fileName();
 
-       ui.editMatcap->setText(mc.GetName());
-
        m_ContextShare.BeginDrawTop();
        mc.LoadTexture(path.toLocal8Bit().data());
        mc.SetName(title);
        m_ContextShare.EndDrawTop();
 
+       ui.editMatcap->setText(mc.GetName());
+
        updateView_All();
 }
 
@@ -2984,57 +3403,23 @@ void FormMain::on_buttonClearCurrentMatNormalMap_clicked()
        ReleaseCurSelTexture(TextureType::Normal);
 }
 
-void FormMain::ChangeMatlemColor(QWidget* col_widget)
-{
-       lib_geo::BaseMaterial* mat = m_Scene.GetSelectedMaterial();
-       if (mat == NULL)
-               return;
-
-       lib_graph::color4f* col;
-
-       if (col_widget == ui.colorAmbient  ) col = &mat->m_Ambient  ;
-       if (col_widget == ui.colorEmission ) col = &mat->m_Emission ;
-       if (col_widget == ui.colorDiffuse  ) col = &mat->m_Diffuse  ;
-       if (col_widget == ui.colorSpecular ) col = &mat->m_Specular ;
-
-       lib_graph::color4f src = *col;
-
-       QColor dc = ToQColor(*col);
-
-       m_SelMatColorWidget = col_widget;
-
-       m_SelMatColorSelDlg.setOption(QColorDialog::ShowAlphaChannel);
-       m_SelMatColorSelDlg.setCurrentColor(dc);
-       if (m_SelMatColorSelDlg.exec() == QDialog::Rejected)
-       {
-               *col = src;
-               SetWidgetColor(col_widget, dc);
-       }
-}
-
-void FormMain::on_buttonDiffuse_clicked()
-{
-       ChangeMatlemColor(ui.colorDiffuse);
-}
-
-void FormMain::on_buttonAmbient_clicked()
+void FormMain::SetColorPalleteBG(QWidget* w, QColor col)
 {
-       ChangeMatlemColor(ui.colorAmbient);
+       QColor border(0, 0, 0);
+       SetWidgetColor(w, col, border);
 }
 
-void FormMain::on_buttonEmission_clicked()
+void FormMain::SetWidgetColor(QWidget* w, QColor col)
 {
-       ChangeMatlemColor(ui.colorEmission);
+       QString ss = QString("background-color: %1").arg(col.name());
+       w->setStyleSheet(ss);
 }
 
-void FormMain::on_buttonSpecular_clicked()
+void FormMain::SetWidgetColor(QWidget* w, QColor col, QColor col_border)
 {
-       ChangeMatlemColor(ui.colorSpecular);
-}
-
-void FormMain::SetWidgetColor(QWidget* w, QColor col)
-{
-       QString ss = QString("background-color: %1").arg(col.name());
+       QString ss;
+       ss += QString("background-color: %1;").arg(col.name());
+       ss += QString("border: 1px solid %1;").arg(col_border.name());
        w->setStyleSheet(ss);
 }
 
@@ -3070,9 +3455,8 @@ void FormMain::CreateRecentFilesMenu(const std::vector<QString>& path)
 void FormMain::CreateRecentFilesFromMenu(std::vector<QString>& path)
 {
        QMenu* recents = ui.menuOpenRecent;
-       for (int i = 0; i < recents->actions().size(); ++i)
+       for (QAction* a : recents->actions())
        {
-               QAction* a = recents->actions().at(i);
                path.push_back(a->text());
        }
 }
@@ -3085,9 +3469,8 @@ void FormMain::AddRecentFile(const QString& path)
 
        QMenu* recents = ui.menuOpenRecent;
 
-       for (int i = 0; i < recents->actions().size(); ++i)
+       for (QAction* a : recents->actions())
        {
-               QAction* a = recents->actions().at(i);
                if (a->text() == path_local)
                {
                        recents->removeAction(a);
@@ -3136,16 +3519,6 @@ void FormMain::on_checkShowOnlySelect_toggled(bool checked)
        updateView_All();
 }
 
-void FormMain::ResizeTreeColumns(QTreeWidget* t, int num_col)
-{
-       t->setVisible(false);
-       t->resizeColumnToContents(0);
-       t->resizeColumnToContents(1);
-       t->resizeColumnToContents(2);
-       t->resizeColumnToContents(3);
-       t->setVisible(true);
-}
-
 void FormMain::PushbackTreeNode(QTreeWidget* tree, QTreeWidgetItem *node)
 {
        int next_idx = tree->topLevelItemCount();
@@ -3190,13 +3563,6 @@ QTreeWidgetItem* FormMain::CreateMeshBufNode(const geom::GeomObject& obj, const
        return n;
 }
 
-void FormMain::InitObjectListHeader(void)
-{
-       QStringList qs;
-       qs << "Name" << "Visible" << "Verts" << "Faces";
-       ui.treeObjects->setHeaderLabels(qs);
-}
-
 void FormMain::SetPrimayrSelectObjectFromScene(void)
 {
        QTreeWidget* obj_tree = ui.treeObjects;
@@ -3222,30 +3588,6 @@ void FormMain::SetPrimayrSelectObjectFromScene(void)
        }
 }
 
-void FormMain::SetPrimayrSelectObjectToScene(void)
-{
-       Selection3D& sels = m_Scene.m_Sels;
-
-       QTreeWidget* tree = ui.treeObjects;
-
-       QTreeWidgetItem* sel_node = tree->currentItem();
-       if (sel_node == NULL)
-               return;
-
-       QTreeWidgetItem* on = sel_node->parent();
-       if (on == NULL)
-       {
-               int obj_idx = tree->indexOfTopLevelItem(sel_node);
-               sels.SelectObject(obj_idx);
-       }
-       else
-       {
-               int obj_idx = tree->indexOfTopLevelItem(on);
-               int mb_idx = on->indexOfChild(sel_node);
-               sels.SelectMBuf(obj_idx, mb_idx);
-       }
-}
-
 void FormMain::on_actionReleaseShader_triggered()
 {
        m_ContextShare.BeginDrawTop();
@@ -3253,6 +3595,8 @@ void FormMain::on_actionReleaseShader_triggered()
        m_View3d.m_ShaderLib.ReleaseAllShaders();
 
        m_ContextShare.EndDrawTop();
+
+       updateView_All();
 }
 
 void FormMain::on_combo2DViewSrcType_currentIndexChanged(int index)
@@ -3292,3 +3636,231 @@ void FormMain::UpdateSequence(void)
        m_View3d.ReleaseAllRenderBuffer();
        updateView_All();
 }
+
+void FormMain::on_actionNewStroke_triggered()
+{
+       m_Scene.m_Cursor3d.CutStroke();
+       updateView_All();
+}
+
+void FormMain::on_actionClearStroke_triggered()
+{
+       m_Scene.m_Cursor3d.ClearStroke();
+       updateView_All();
+}
+
+void FormMain::on_buttonMatPreset_clicked()
+{
+       lib_geo::BaseMaterial* mat = m_Scene.GetSelectedMaterial();
+       if (mat == NULL)
+               return;
+
+       lib_geo::BaseMaterial mat_backup = (*mat);
+
+       if (m_MatPresetDlg == NULL)
+       {
+               m_MatPresetDlg = new MaterialPresetDlg(this);
+               connect(
+                       m_MatPresetDlg,
+                       SIGNAL(OnMatChanged()),
+                       this,
+                       SLOT(MatPresetDlg_OnMatChanged()));
+       }
+
+       MatPresetDlg_OnMatChanged();
+
+       if (m_MatPresetDlg->exec() != QDialog::Accepted)
+       {
+               (*mat) = mat_backup;
+               OnChangedSelectedMaterial();
+               updateView_All();
+               return;
+       }
+
+       lib_graph::MaterialSamples::MaterialSampleType t = m_MatPresetDlg->GetSelectedType();
+
+       if (t != lib_graph::MaterialSamples::MAT_NONE)
+               (*mat) = lib_graph::MaterialSamples::GetMaterial(t);
+       else
+               (*mat) = mat_backup;
+
+       OnChangedSelectedMaterial();
+       updateView_All();
+}
+
+void FormMain::MatPresetDlg_OnMatChanged()
+{
+       lib_geo::BaseMaterial* mat = m_Scene.GetSelectedMaterial();
+       if (mat == NULL)
+               return;
+
+       lib_graph::MaterialSamples::MaterialSampleType t = m_MatPresetDlg->GetSelectedType();
+       if (t == lib_graph::MaterialSamples::MAT_NONE)
+               return;
+
+       (*mat) = lib_graph::MaterialSamples::GetMaterial(t);
+
+       OnChangedSelectedMaterial();
+       updateView_All();
+}
+
+void FormMain::on_buttonLoadCameraSeq_clicked()
+{
+       FileDlgFilterList exts;
+       exts.Add("Collada", "dae");
+
+       QString filter = FileDlgUtil::ExtListToDlgFilter("Geometry", exts);
+       QString title = "Open Camera seq by collada";
+       QString path = GetFilePathFromOpenDlg("", filter);
+
+       if (path.isEmpty())
+               return;
+
+       m_Scene.LoadCameraSeq(path.toLocal8Bit().data());
+
+       ResetSequenceSliderRange();
+
+       updateView_All();
+}
+
+void FormMain::on_buttonClearCameraSeq_clicked()
+{
+       m_Scene.m_Camera.m_SeqTrans.Clear();
+       ResetSequenceSliderRange();
+}
+
+void FormMain::on_checkEnableCamerSeq_toggled(bool checked)
+{
+       m_Scene.m_Camera.m_EnableSeqence = checked;
+}
+
+void FormMain::on_checkEnableIndexRange_toggled(bool checked)
+{
+       IndexRangeConfig& ir = m_Scene.m_IndexVisrange;
+       ir.enableRange = checked;
+
+       m_View3d.ReleaseAllIndexList();
+       updateView_All();
+}
+
+void FormMain::on_editIndexLimitOffset_textChanged(const QString &arg1)
+{
+       IndexRangeConfig& ir = m_Scene.m_IndexVisrange;
+
+       bool b;
+       int i = arg1.toInt(&b);
+       if (!b)
+               return;
+
+       ir.beginIdx = i;
+
+       if (ir.enableRange)
+       {
+               m_View3d.ReleaseAllIndexList();
+               updateView_All();
+       }
+}
+
+void FormMain::on_editIndexLimitLen_textChanged(const QString &arg1)
+{
+       IndexRangeConfig& ir = m_Scene.m_IndexVisrange;
+
+       bool b;
+       int i = arg1.toInt(&b);
+       if (!b)
+               return;
+
+       ir.idxLen = i;
+
+       if (ir.enableRange)
+       {
+               m_View3d.ReleaseAllIndexList();
+               updateView_All();
+       }
+}
+
+void FormMain::on_fscrollIndexLimitOffset_onScroll(int step)
+{
+       IndexRangeConfig& ir = m_Scene.m_IndexVisrange;
+
+       int n = ir.beginIdx + step;
+       n = (std::max)(n, 0);
+       ui.editIndexLimitOffset->setText(QString::number(n));
+}
+
+void FormMain::on_fscrollIndexLimitOffset_onReset()
+{
+       ui.editIndexLimitOffset->setText("0");
+}
+
+void FormMain::on_fscrollIndexLimitLen_onScroll(int step)
+{
+       IndexRangeConfig& ir = m_Scene.m_IndexVisrange;
+
+       int n = ir.idxLen + step;
+       n = (std::max)(n, 1);
+       ui.editIndexLimitLen->setText(QString::number(n));
+}
+
+void FormMain::on_fscrollIndexLimitLen_onReset()
+{
+       ui.editIndexLimitLen->setText("1");
+}
+
+void FormMain::on_buttonTextureScaleDiv10_clicked()
+{
+       MulTexScaleMain(1.0 / 10.0);
+}
+
+void FormMain::on_buttonTextureScaleMul10_clicked()
+{
+       MulTexScaleMain(10.0);
+}
+
+void FormMain::on_fscrollTextureScale_onScroll(int step)
+{
+       double s = pow(2.0, (double)step / 100.0);
+       MulTexScaleMain(s);
+}
+
+void FormMain::MulTexScaleMain(double s)
+{
+       m_Scene.m_TextureTransform.m_TexScale *= s;
+       float ts = m_Scene.m_TextureTransform.m_TexScale;
+       SetTextSilent(ui.editTextureScale, QString::number(ts));
+       updateView_All();
+}
+
+void FormMain::on_fscrollTextureScale_onReset()
+{
+       ui.editTextureScale->setText("1.0");
+}
+
+void FormMain::on_editTextureScale_textChanged(const QString &arg1)
+{
+       bool b;
+       double d = arg1.toDouble(&b);
+       if (!b)
+               return;
+
+       m_Scene.m_TextureTransform.m_TexScale = d;
+
+       updateView_All();
+}
+
+void FormMain::SetTextSilent(QLineEdit* edit, const QString& text)
+{
+       edit->blockSignals(true);
+       edit->setText(text);
+       edit->blockSignals(false);
+}
+
+void FormMain::on_sliderMatcapRate_valueChanged(int value)
+{
+       float r = GetSliderNormalizedPos(ui.sliderMatcapRate);
+       m_Scene.m_MatcapImg.m_BlendRate = r;
+
+       ui.labelMatcapRate->setText(QString::number(r, 'f', 2));
+
+       updateView_All();
+}