From 580b35c8ea59187d5197e712022b706df3655f86 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Mon, 1 Apr 2019 20:22:25 +0300 Subject: SL-307 Display in-viewer all warning messages logged by the mesh uploader --- indra/llprimitive/llmodelloader.cpp | 4 + indra/llprimitive/llmodelloader.h | 5 + indra/llui/lltabcontainer.cpp | 4 + indra/llui/lltabcontainer.h | 6 + indra/llui/lltextbase.cpp | 12 ++ indra/llui/lltextbase.h | 2 + indra/newview/llfloatermodelpreview.cpp | 126 ++++++++++++++++++--- indra/newview/llfloatermodelpreview.h | 9 +- .../skins/default/xui/en/floater_model_preview.xml | 39 ++++++- 9 files changed, 191 insertions(+), 16 deletions(-) (limited to 'indra') diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index 4e468ff45f..c8da68afc8 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -146,6 +146,7 @@ LLModelLoader::~LLModelLoader() void LLModelLoader::run() { + mWarningStream.clear(); doLoadModel(); doOnIdleOneTime(boost::bind(&LLModelLoader::loadModelCallback,this)); } @@ -426,6 +427,7 @@ bool LLModelLoader::isRigLegacy( const std::vector &jointListFromAs { LL_WARNS() << "Rigged to " << jointListFromAsset.size() << " joints, max is " << mMaxJointsPerMesh << LL_ENDL; LL_WARNS() << "Skinning disabled due to too many joints" << LL_ENDL; + mWarningStream << "Skinning disabled due to too many joints, maximum amount per mesh: " << mMaxJointsPerMesh << "\n"; return false; } @@ -437,12 +439,14 @@ bool LLModelLoader::isRigLegacy( const std::vector &jointListFromAs if (mJointMap.find(*it)==mJointMap.end()) { LL_WARNS() << "Rigged to unrecognized joint name " << *it << LL_ENDL; + mWarningStream << "Rigged to unrecognized joint name " << *it << "\n"; unknown_joint_count++; } } if (unknown_joint_count>0) { LL_WARNS() << "Skinning disabled due to unknown joints" << LL_ENDL; + mWarningStream << "Skinning disabled due to unknown joints\n"; return false; } diff --git a/indra/llprimitive/llmodelloader.h b/indra/llprimitive/llmodelloader.h index 643c45a6d8..8dde176b54 100644 --- a/indra/llprimitive/llmodelloader.h +++ b/indra/llprimitive/llmodelloader.h @@ -185,6 +185,9 @@ public: return name != NULL && mJointMap.find(name) != mJointMap.end(); } + std::string logOut() { return mWarningStream.str(); } + void clearLog() { mWarningStream.clear(); } + protected: LLModelLoader::load_callback_t mLoadCallback; @@ -201,6 +204,8 @@ protected: JointTransformMap mJointTransformMap; + std::ostringstream mWarningStream; // preview floater will pull logs from here + static std::list sActiveLoaderList; static bool isAlive(LLModelLoader* loader) ; }; diff --git a/indra/llui/lltabcontainer.cpp b/indra/llui/lltabcontainer.cpp index 1b2f09cff5..0af97bfab2 100644 --- a/indra/llui/lltabcontainer.cpp +++ b/indra/llui/lltabcontainer.cpp @@ -217,6 +217,7 @@ LLTabContainer::Params::Params() last_tab("last_tab"), use_custom_icon_ctrl("use_custom_icon_ctrl", false), open_tabs_on_drag_and_drop("open_tabs_on_drag_and_drop", false), + enable_tabs_flashing("enable_tabs_flashing", false), tab_icon_ctrl_pad("tab_icon_ctrl_pad", 0), use_ellipses("use_ellipses"), font_halign("halign") @@ -1090,6 +1091,9 @@ void LLTabContainer::addTabPanel(const TabPanelParams& panel) p.pad_left( mLabelPadLeft ); p.pad_right(2); } + + // inits flash timer + p.button_flash_enable = mEnableTabsFlashing; // *TODO : It seems wrong not to use p in both cases considering the way p is initialized if (mCustomIconCtrlUsed) diff --git a/indra/llui/lltabcontainer.h b/indra/llui/lltabcontainer.h index 4a5f08f5d3..a8cf380333 100644 --- a/indra/llui/lltabcontainer.h +++ b/indra/llui/lltabcontainer.h @@ -109,6 +109,11 @@ public: * Open tabs on hover in drag and drop situations */ Optional open_tabs_on_drag_and_drop; + + /** + * Open tabs on hover in drag and drop situations + */ + Optional enable_tabs_flashing; /** * Paddings for LLIconCtrl in case of LLCustomButtonIconCtrl usage(use_custom_icon_ctrl = true) @@ -308,6 +313,7 @@ private: bool mCustomIconCtrlUsed; bool mOpenTabsOnDragAndDrop; + bool mEnableTabsFlashing; S32 mTabIconCtrlPad; bool mUseTabEllipses; }; diff --git a/indra/llui/lltextbase.cpp b/indra/llui/lltextbase.cpp index c570285856..f4713e19ba 100644 --- a/indra/llui/lltextbase.cpp +++ b/indra/llui/lltextbase.cpp @@ -2215,6 +2215,18 @@ void LLTextBase::needsReflow(S32 index) mReflowIndex = llmin(mReflowIndex, index); } +S32 LLTextBase::removeFirstLine() +{ + if (!mLineInfoList.empty()) + { + S32 length = getLineEnd(0); + deselect(); + removeStringNoUndo(0, length); + return length; + } + return 0; +} + void LLTextBase::appendLineBreakSegment(const LLStyle::Params& style_params) { segment_vec_t segments; diff --git a/indra/llui/lltextbase.h b/indra/llui/lltextbase.h index 5fdde445ef..6913374bac 100644 --- a/indra/llui/lltextbase.h +++ b/indra/llui/lltextbase.h @@ -401,6 +401,7 @@ public: virtual void setText(const LLStringExplicit &utf8str , const LLStyle::Params& input_params = LLStyle::Params()); // uses default style virtual std::string getText() const; void setMaxTextLength(S32 length) { mMaxTextByteLength = length; } + S32 getMaxTextLength() { return mMaxTextByteLength; } // wide-char versions void setWText(const LLWString& text); @@ -429,6 +430,7 @@ public: S32 getLength() const { return getWText().length(); } S32 getLineCount() const { return mLineInfoList.size(); } + S32 removeFirstLine(); // returns removed length void addDocumentChild(LLView* view); void removeDocumentChild(LLView* view); diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 8be405df9e..6387dfee55 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -76,6 +76,7 @@ #include "llsdserialize.h" #include "llsliderctrl.h" #include "llspinctrl.h" +#include "lltabcontainer.h" #include "lltoggleablemenu.h" #include "lltrans.h" #include "llvfile.h" @@ -83,6 +84,7 @@ #include "llcallbacklist.h" #include "llviewerobjectlist.h" #include "llanimationstates.h" +#include "llviewertexteditor.h" #include "llviewernetwork.h" #include "llviewershadermgr.h" @@ -263,7 +265,9 @@ void FindModel(LLModelLoader::scene& scene, const std::string& name_to_match, LL LLFloaterModelPreview::LLFloaterModelPreview(const LLSD& key) : LLFloaterModelUploadBase(key), mUploadBtn(NULL), -mCalculateBtn(NULL) +mCalculateBtn(NULL), +mUploadLogText(NULL), +mTabContainer(NULL) { sInstance = this; mLastMouseX = 0; @@ -392,6 +396,13 @@ BOOL LLFloaterModelPreview::postBuild() mUploadBtn = getChild("ok_btn"); mCalculateBtn = getChild("calculate_btn"); + mUploadLogText = getChild("log_text"); + mTabContainer = getChild("import_tab"); + + // Disable Logs tab untill it has something to show + LLPanel* panel = mTabContainer->getPanelByName("logs_panel"); + S32 index = mTabContainer->getIndexForPanel(panel); + mTabContainer->enableTabButton(index, false); if (LLConvexDecomposition::getInstance() != NULL) { @@ -1280,6 +1291,64 @@ void LLFloaterModelPreview::onMouseCaptureLostModelPreview(LLMouseHandler* handl gViewerWindow->showCursor(); } +//----------------------------------------------------------------------------- +// addStringToLog() +//----------------------------------------------------------------------------- +// static +void LLFloaterModelPreview::addStringToLog(const std::string& str, bool flash) +{ + if (sInstance) + { + sInstance->addStringToLogTab(str, flash); + } +} + +// static +void LLFloaterModelPreview::addStringToLog(const std::ostringstream& strm, bool flash) +{ + if (sInstance) + { + sInstance->addStringToLogTab(strm.str(), flash); + } +} + +//----------------------------------------------------------------------------- +// addStringToLogTab() +//----------------------------------------------------------------------------- +void LLFloaterModelPreview::addStringToLogTab(const std::string& str, bool flash) +{ + if (str.empty()) + { + return; + } + + LLWString text = utf8str_to_wstring(str); + S32 add_text_len = text.length() + 1; // newline + S32 editor_max_len = mUploadLogText->getMaxTextLength(); + if (add_text_len > editor_max_len) + { + return; + } + + LLPanel* panel = mTabContainer->getPanelByName("logs_panel"); + S32 index = mTabContainer->getIndexForPanel(panel); + mTabContainer->enableTabButton(index, true); + + // Make sure we have space for new string + S32 editor_text_len = mUploadLogText->getLength(); + while (editor_max_len < (editor_text_len + add_text_len)) + { + editor_text_len -= mUploadLogText->removeFirstLine(); + } + + mUploadLogText->appendText(str, true); + + if (flash && mTabContainer->getCurrentPanel() != panel) + { + mTabContainer->setTabPanelFlashing(panel, true); + } +} + //----------------------------------------------------------------------------- // LLModelPreview //----------------------------------------------------------------------------- @@ -1710,8 +1779,14 @@ void LLModelPreview::rebuildUploadData() LLQuaternion identity; if (!bind_rot.isEqualEps(identity,0.01)) { - LL_WARNS() << "non-identity bind shape rot. mat is " << high_lod_model->mSkinInfo.mBindShapeMatrix - << " bind_rot " << bind_rot << LL_ENDL; + std::ostringstream out; + out << "non-identity bind shape rot. mat is "; + out << high_lod_model->mSkinInfo.mBindShapeMatrix; + out << " bind_rot "; + out << bind_rot; + LL_WARNS() << out.str() << LL_ENDL; + + LLFloaterModelPreview::addStringToLog(out, false); setLoadState( LLModelLoader::WARNING_BIND_SHAPE_ORIENTATION ); } } @@ -1882,7 +1957,11 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable if (lod < LLModel::LOD_IMPOSTOR || lod > LLModel::NUM_LODS - 1) { - LL_WARNS() << "Invalid level of detail: " << lod << LL_ENDL; + std::ostringstream out; + out << "Invalid level of detail: "; + out << lod; + LL_WARNS() << out.str() << LL_ENDL; + LLFloaterModelPreview::addStringToLog(out, true); assert(lod >= LLModel::LOD_IMPOSTOR && lod < LLModel::NUM_LODS); return; } @@ -2259,7 +2338,12 @@ void LLModelPreview::loadModelCallback(S32 loaded_lod) if (importerDebug) { - LL_WARNS() << "Loded model name " << mModel[loaded_lod][idx]->mLabel << " for LOD " << loaded_lod << " doesn't match the base model. Renaming to " << name << LL_ENDL; + std::ostringstream out; + out << "Loded model name " << mModel[loaded_lod][idx]->mLabel; + out << " for LOD " << loaded_lod; + out << " doesn't match the base model. Renaming to " << name; + LL_WARNS() << out.str() << LL_ENDL; + LLFloaterModelPreview::addStringToLog(out, false); } mModel[loaded_lod][idx]->mLabel = name; @@ -2417,7 +2501,10 @@ void LLModelPreview::genLODs(S32 which_lod, U32 decimation, bool enforce_tri_lim // Allow LoD from -1 to LLModel::LOD_PHYSICS if (which_lod < -1 || which_lod > LLModel::NUM_LODS - 1) { - LL_WARNS() << "Invalid level of detail: " << which_lod << LL_ENDL; + std::ostringstream out; + out << "Invalid level of detail: " << which_lod; + LL_WARNS() << out.str() << LL_ENDL; + LLFloaterModelPreview::addStringToLog(out, false); assert(which_lod >= -1 && which_lod < LLModel::NUM_LODS); return; } @@ -3288,7 +3375,10 @@ void LLModelPreview::updateLodControls(S32 lod) { if (lod < LLModel::LOD_IMPOSTOR || lod > LLModel::LOD_HIGH) { - LL_WARNS() << "Invalid level of detail: " << lod << LL_ENDL; + std::ostringstream out; + out << "Invalid level of detail: " << lod; + LL_WARNS() << out.str() << LL_ENDL; + LLFloaterModelPreview::addStringToLog(out, false); assert(lod >= LLModel::LOD_IMPOSTOR && lod <= LLModel::LOD_HIGH); return; } @@ -3484,9 +3574,12 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) if (!vb->allocateBuffer(num_vertices, num_indices, TRUE)) { // We are likely to crash due this failure, if this happens, find a way to gracefully stop preview - LL_WARNS() << "Failed to allocate Vertex Buffer for model preview " - << num_vertices << " vertices and " - << num_indices << " indices" << LL_ENDL; + std::ostringstream out; + out << "Failed to allocate Vertex Buffer for model preview "; + out << num_vertices << " vertices and "; + out << num_indices << " indices"; + LL_WARNS() << out.str() << LL_ENDL; + LLFloaterModelPreview::addStringToLog(out, true); } LLStrider vertex_strider; @@ -3634,8 +3727,11 @@ void LLModelPreview::loadedCallback( LLModelPreview* pPreview = static_cast< LLModelPreview* >(opaque); if (pPreview && !LLModelPreview::sIgnoreLoadedCallback) { - pPreview->loadModelCallback(lod); - } + LLFloaterModelPreview::addStringToLog(pPreview->mModelLoader->logOut(), true); + pPreview->mModelLoader->clearLog(); + pPreview->loadModelCallback(lod); // removes mModelLoader in some cases + } + } void LLModelPreview::stateChangedCallback(U32 state,void* opaque) @@ -4688,7 +4784,11 @@ void LLFloaterModelPreview::handleModelPhysicsFeeReceived() void LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(S32 status, const std::string& reason) { - LL_WARNS() << "LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(" << status << " : " << reason << ")" << LL_ENDL; + std::ostringstream out; + out << "LLFloaterModelPreview::setModelPhysicsFeeErrorStatus(" << status; + out << " : " << reason << ")"; + LL_WARNS() << out.str() << LL_ENDL; + LLFloaterModelPreview::addStringToLog(out, false); doOnIdleOneTime(boost::bind(&LLFloaterModelPreview::toggleCalculateButton, this, true)); } diff --git a/indra/newview/llfloatermodelpreview.h b/indra/newview/llfloatermodelpreview.h index 096544cdbf..c459b9296b 100644 --- a/indra/newview/llfloatermodelpreview.h +++ b/indra/newview/llfloatermodelpreview.h @@ -57,7 +57,9 @@ class domController; class domSkin; class domMesh; class LLMenuButton; +class LLTabContainer; class LLToggleableMenu; +class LLViewerTextEditor; class LLFloaterModelPreview : public LLFloaterModelUploadBase { @@ -93,6 +95,8 @@ public: static void onMouseCaptureLostModelPreview(LLMouseHandler*); static void setUploadAmount(S32 amount) { sUploadAmount = amount; } + static void addStringToLog(const std::string& str, bool flash); + static void addStringToLog(const std::ostringstream& strm, bool flash); void setDetails(F32 x, F32 y, F32 z, F32 streaming_cost, F32 physics_cost); void setPreviewLOD(S32 lod); @@ -176,7 +180,8 @@ protected: // FIXME - this function and mStatusMessage have no visible effect, and the // actual status messages are managed by directly manipulation of // the UI element. - void setStatusMessage(const std::string& msg); + void setStatusMessage(const std::string& msg); + void addStringToLogTab(const std::string& str, bool flash); LLModelPreview* mModelPreview; @@ -221,6 +226,8 @@ private: LLButton* mUploadBtn; LLButton* mCalculateBtn; + LLViewerTextEditor* mUploadLogText; + LLTabContainer* mTabContainer; }; class LLMeshFilePicker : public LLFilePickerThread diff --git a/indra/newview/skins/default/xui/en/floater_model_preview.xml b/indra/newview/skins/default/xui/en/floater_model_preview.xml index 274e6e6c7a..cbc5aeb37d 100644 --- a/indra/newview/skins/default/xui/en/floater_model_preview.xml +++ b/indra/newview/skins/default/xui/en/floater_model_preview.xml @@ -82,7 +82,8 @@ height="300" width="635" name="import_tab" - tab_position="top"> + tab_position="top" + enable_tabs_flashing="true"> + width="619" /> + + + + +