From 1e1707d532560583744bb877adfed11864f2db31 Mon Sep 17 00:00:00 2001 From: Kadah_Coba Date: Mon, 14 Oct 2019 20:35:44 -0700 Subject: [Project Copy/Paste] Texture support --- indra/newview/llpanelface.cpp | 482 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 478 insertions(+), 4 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 5e6a44c09d..29994253c4 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -38,6 +38,7 @@ #include "llfontgl.h" // project includes +#include "llagent.h" // gAgent #include "llagentdata.h" #include "llbutton.h" #include "llcheckboxctrl.h" @@ -45,10 +46,14 @@ #include "llcombobox.h" #include "lldrawpoolbump.h" #include "llface.h" +#include "llinventoryfunctions.h" +#include "llinventorymodel.h" // gInventory #include "lllineeditor.h" #include "llmaterialmgr.h" #include "llmediaentry.h" +#include "llmenubutton.h" #include "llnotificationsutil.h" +#include "llpanelobject.h" // LLPanelObject::canCopyTexture #include "llradiogroup.h" #include "llresmgr.h" #include "llselectmgr.h" @@ -295,7 +300,18 @@ BOOL LLPanelFace::postBuild() { mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this); } - + + mBtnCopyFaces = getChild("copy_face_btn"); + if(mBtnCopyFaces) + { + BtnCopyFaces->setCommitCallback(boost::bind(&LLPanelFace::onCopyFaces, this)); + } + mBtnPasteFaces = getChild("paste_face_btn"); + if (mBtnPasteFaces) + { + mBtnPasteFaces->setCommitCallback(boost::bind(&LLPanelFace::onPasteFaces, this)); + } + mBtnPasteMenu = getChild("paste_face_gear_btn"); clearCtrls(); @@ -304,9 +320,21 @@ BOOL LLPanelFace::postBuild() LLPanelFace::LLPanelFace() : LLPanel(), - mIsAlpha(false) + mIsAlpha(false), + mPasteColor(TRUE), + mPasteAlpha(TRUE), + mPasteGlow(TRUE), + mPasteDiffuse(TRUE), + mPasteNormal(TRUE), + mPasteSpecular(TRUE), + mPasteMapping(TRUE), + mPasteMedia(TRUE) { USE_TEXTURE = LLTrans::getString("use_texture"); + + mEnableCallbackRegistrar.add("BuildFace.PasteCheckItem", boost::bind(&LLPanelFace::pasteCheckMenuItem, this, _2)); + mCommitCallbackRegistrar.add("BuildFace.PasteDoToSelected", boost::bind(&LLPanelFace::pasteDoMenuItem, this, _2)); + mEnableCallbackRegistrar.add("BuildFace.PasteEnable", boost::bind(&LLPanelFace::pasteEnabletMenuItem, this, _2)); } @@ -1407,6 +1435,12 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } } + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + BOOL single_volume = (selected_count == 1); + mBtnCopyFaces->setEnabled(editable && single_volume); + mBtnPasteFaces->setEnabled(editable && (mClipboard.size() > 0)); + mBtnPasteMenu->setEnabled(editable); + // Set variable values for numeric expressions LLCalc* calcp = LLCalc::getInstance(); calcp->setVar(LLCalc::TEX_U_SCALE, childGetValue("TexScaleU").asReal()); @@ -1602,8 +1636,6 @@ void LLPanelFace::updateVisibility() getChildView("bumpyRot")->setVisible(show_bumpiness); getChildView("bumpyOffsetU")->setVisible(show_bumpiness); getChildView("bumpyOffsetV")->setVisible(show_bumpiness); - - } // static @@ -2681,3 +2713,445 @@ void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identic } max_diff_repeats_func; identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats ); } + +static LLSD texture_clipboard; + +void LLPanelFace::onCopyFaces() +{ + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + if( !objectp || !node + || objectp->getPCode() != LL_PCODE_VOLUME + || !objectp->permModify() + || objectp->isPermanentEnforced() + || selected_count > 1) + { + return; + } + + mClipboard.clear(); + + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + LLTextureEntry* tep = objectp->getTE(te); + if (tep) + { + LLSD te_data; + + te_data["te"] = tep->asLLSD(); + te_data["te"]["glow"] = tep->getGlow(); + te_data["te"]["shiny"] = tep->getShiny(); + + if (te_data["te"].has("imageid")) + { + LLUUID id = te_data["te"]["imageid"].asUUID(); + if (id.isNull() || !LLPanelObject::canCopyTexture(id)) + { + te_data["te"].erase("imageid"); + te_data["te"]["imageid"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); + } + // else + // { + // te_data["te"]["imageid"] = canCopyTexture(te_data["te"]["imageid"].asUUID()); + // } + } + + LLMaterialPtr material_ptr = tep->getMaterialParams(); + if (!material_ptr.isNull()) + { + LLSD mat_data; + + mat_data["NormMap"] = material_ptr->getNormalID(); + mat_data["SpecMap"] = material_ptr->getSpecularID(); + + mat_data["NormRepX"] = material_ptr->getNormalRepeatX(); + mat_data["NormRepY"] = material_ptr->getNormalRepeatY(); + mat_data["NormOffX"] = material_ptr->getNormalOffsetX(); + mat_data["NormOffY"] = material_ptr->getNormalOffsetY(); + mat_data["NormRot"] = material_ptr->getNormalRotation(); + + mat_data["SpecRepX"] = material_ptr->getSpecularRepeatX(); + mat_data["SpecRepY"] = material_ptr->getSpecularRepeatY(); + mat_data["SpecOffX"] = material_ptr->getSpecularOffsetX(); + mat_data["SpecOffY"] = material_ptr->getSpecularOffsetY(); + mat_data["SpecRot"] = material_ptr->getSpecularRotation(); + + mat_data["SpecColor"] = material_ptr->getSpecularLightColor().getValue(); + mat_data["SpecExp"] = material_ptr->getSpecularLightExponent(); + mat_data["EnvIntensity"] = material_ptr->getEnvironmentIntensity(); + mat_data["AlphaMaskCutoff"] = material_ptr->getAlphaMaskCutoff(); + mat_data["DiffuseAlphaMode"] = material_ptr->getDiffuseAlphaMode(); + + // Replace no-copy textures, destination texture will get used instead if available + if (mat_data.has("NormMap")) + { + LLUUID id = te_data["material"]["NormMap"].asUUID(); + if (id.notNull() && !LLPanelObject::canCopyTexture(id)) + { + mat_data["NormMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); + mat_data["NormMapNoCopy"] = true; + } + + } + if (mat_data.has("SpecMap")) + { + LLUUID id = te_data["material"]["SpecMap"].asUUID(); + if (id.notNull() && !LLPanelObject::canCopyTexture(id)) + { + mat_data["SpecMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); + mat_data["SpecMapNoCopy"] = true; + } + + } + + te_data["material"] = mat_data; + } + + //*TODO: Media + + mClipboard.append(te_data); + } + } + } +} + +void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) +{ + LLSD te_data; + if (mClipboard.size() == 1) + { + te_data = *(mClipboard.beginArray()); + } + else if (mClipboard[te]) + { + te_data = mClipboard[te]; + } + else + { + return; + } + + LLTextureEntry* tep = objectp->getTE(te); + if (tep) + { + if (te_data.has("te")) + { + // Texture + if (mPasteDiffuse) + { + // Replace no-copy texture with target's + if (!te_data["te"].has("imageid")) + { + te_data["te"]["imageid"] = tep->getID(); + } + const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); + LLViewerInventoryItem* item = gInventory.getItem(imageid); + if (item) + { + if (te == -1) // all faces + { + LLToolDragAndDrop::dropTextureAllFaces(objectp, + item, + LLToolDragAndDrop::SOURCE_AGENT, + LLUUID::null); + } + else // one face + { + LLToolDragAndDrop::dropTextureOneFace(objectp, + te, + item, + LLToolDragAndDrop::SOURCE_AGENT, + LLUUID::null); + } + } + else // not an inventory item + { + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + objectp->setTEImage(U8(te), image); + } + } + + // Color / Alpha + if ((mPasteColor || mPasteAlpha) && te_data.has("colors")) + { + LLColor4 color = objectp->getTE(te)->getColor(); + + LLColor4 clip_color; + clip_color.setValue(te_data["colors"]); + + // Color + if (mPasteColor) + { + color.mV[VRED] = clip_color.mV[VRED]; + color.mV[VGREEN] = clip_color.mV[VGREEN]; + color.mV[VBLUE] = clip_color.mV[VBLUE]; + } + + // Alpha + if (mPasteAlpha) + { + color.mV[VALPHA] = clip_color.mV[VALPHA]; + } + + objectp->setTEColor(te, color); + } + + // Glow + if (mPasteGlow && te_data.has("glow")) + { + objectp->setTEGlow(te, (F32)te_data["glow"].asReal()); + } + + // Texture map + if (mPasteMapping) + { + if (te_data.has("scales") && te_data.has("scalet")) + { + objectp->setTEScale(te, (F32)te_data["scales"].asReal(), (F32)te_data["scalet"].asReal()); + } + if (te_data.has("offsets") && te_data.has("offsett")) + { + objectp->setTEOffset(te, (F32)te_data["offsets"].asReal(), (F32)te_data["offsett"].asReal()); + } + if (te_data.has("imagerot")) + { + objectp->setTERotation(te, (F32)te_data["imagerot"].asReal()); + } + } + + // Media + if (mPasteMedia && te_data.has("media")) + { + //*TODO + } + else + { + // // Keep media flags on destination unchanged + // // Media is handled later + // if (te_data["te"].has("media_flags")) + // { + // te_data["te"]["media_flags"] = tep->getMediaTexGen(); + // } + } + } + + if (te_data.has("material")) + { + LLUUID object_id = objectp->getID(); + + LLSelectedTEMaterial::setAlphaMaskCutoff(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id); + + if (mPasteNormal) + { + // Replace placeholders with target's + if (te_data["material"].has("NormMapNoCopy")) + { + LLMaterialPtr material = tep->getMaterialParams(); + if (material.notNull()) + { + LLUUID id = material->getNormalID(); + if (id.notNull()) + { + te_data["material"]["NormMap"] = id; + } + } + } + LLSelectedTEMaterial::setNormalID(this, te_data["material"]["NormMap"].asUUID(), te, object_id); + LLSelectedTEMaterial::setNormalRepeatX(this, (F32)te_data["material"]["NormRepX"].asReal(), te, object_id); + LLSelectedTEMaterial::setNormalRepeatY(this, (F32)te_data["material"]["NormRepY"].asReal(), te, object_id); + LLSelectedTEMaterial::setNormalOffsetX(this, (F32)te_data["material"]["NormOffX"].asReal(), te, object_id); + LLSelectedTEMaterial::setNormalOffsetY(this, (F32)te_data["material"]["NormOffY"].asReal(), te, object_id); + LLSelectedTEMaterial::setNormalRotation(this, (F32)te_data["material"]["NormRot"].asReal(), te, object_id); + } + + if (mPasteSpecular) + { + // Replace placeholders with target's + if (te_data["material"].has("SpecMapNoCopy")) + { + LLMaterialPtr material = tep->getMaterialParams(); + if (material.notNull()) + { + LLUUID id = material->getSpecularID(); + if (id.notNull()) + { + te_data["material"]["SpecMap"] = id; + } + } + } + LLSelectedTEMaterial::setSpecularID(this, te_data["material"]["SpecMap"].asUUID(), te, object_id); + LLSelectedTEMaterial::setSpecularRepeatX(this, (F32)te_data["material"]["SpecRepX"].asReal(), te, object_id); + LLSelectedTEMaterial::setSpecularRepeatY(this, (F32)te_data["material"]["SpecRepY"].asReal(), te, object_id); + LLSelectedTEMaterial::setSpecularOffsetX(this, (F32)te_data["material"]["SpecOffX"].asReal(), te, object_id); + LLSelectedTEMaterial::setSpecularOffsetY(this, (F32)te_data["material"]["SpecOffY"].asReal(), te, object_id); + LLSelectedTEMaterial::setSpecularRotation(this, (F32)te_data["material"]["SpecRot"].asReal(), te, object_id); + LLColor4 spec_color(te_data["material"]["SpecColor"]); + LLSelectedTEMaterial::setSpecularLightColor(this, spec_color, te); + LLSelectedTEMaterial::setSpecularLightExponent(this, (U8)te_data["material"]["SpecExp"].asInteger(), te, object_id); + LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te), object_id; + LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id); + if (te_data.has("shiny")) + { + objectp->setTEShiny(te, (U8)te_data["shiny"].asInteger()); + } + } + } + } +} + +struct LLPanelFacePasteTexFunctor : public LLSelectedTEFunctor +{ + LLPanelFacePasteTexFunctor(LLPanelFace* panel) : + mPanelFace(panel){} + + virtual bool apply(LLViewerObject* objectp, S32 te) + { + mPanelFace->pasteFace(objectp, te); + return true; + } +private: + LLPanelFace *mPanelFace; +}; + +void LLPanelFace::onPasteFaces() +{ + LLPanelFacePasteTexFunctor paste_func(this); + LLSelectMgr::getInstance()->getSelection()->applyToTEs(&paste_func); + + LLPanelFaceSendFunctor sendfunc; + LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); +} + +bool LLPanelFace::pasteCheckMenuItem(const LLSD& userdata) +{ + std::string command = userdata.asString(); + + if ("Color" == command) + { + return mPasteColor; + } + if ("Transparency" == command) + { + return mPasteAlpha; + } + if ("Glow" == command) + { + return mPasteGlow; + } + if ("Diffuse" == command) + { + return mPasteDiffuse; + } + if ("Normal" == command) + { + return mPasteNormal; + } + if ("Specular" == command) + { + return mPasteSpecular; + } + if ("Mapping" == command) + { + return mPasteMapping; + } + if ("Media" == command) + { + return mPasteMedia; + } + + return false; +} + +void LLPanelFace::pasteDoMenuItem(const LLSD& userdata) +{ + std::string command = userdata.asString(); + + if ("Color" == command) + { + mPasteColor = !mPasteColor; + } + if ("Transparency" == command) + { + mPasteAlpha = !mPasteAlpha; + } + if ("Glow" == command) + { + mPasteGlow = !mPasteGlow; + } + if ("Diffuse" == command) + { + mPasteDiffuse = !mPasteDiffuse; + } + if ("Normal" == command) + { + mPasteNormal = !mPasteNormal; + } + if ("Specular" == command) + { + mPasteSpecular = !mPasteSpecular; + } + if ("Mapping" == command) + { + mPasteMapping = !mPasteMapping; + } + if ("Media" == command) + { + mPasteMedia = !mPasteMedia; + } +} + +bool LLPanelFace::pasteEnabletMenuItem(const LLSD& userdata) +{ + std::string command = userdata.asString(); + + // Keep at least one option enabled + S32 num_enabled = mPasteColor + + mPasteAlpha + + mPasteGlow + + mPasteDiffuse + + mPasteNormal + + mPasteSpecular + + mPasteMapping + + mPasteMedia; + if ( num_enabled == 1) + { + if ("Color" == command && mPasteColor) + { + return false; + } + if ("Transparency" == command && mPasteAlpha) + { + return false; + } + if ("Glow" == command && mPasteGlow) + { + return false; + } + if ("Diffuse" == command && mPasteDiffuse) + { + return false; + } + if ("Normal" == command && mPasteNormal) + { + return false; + } + if ("Specular" == command && mPasteSpecular) + { + return false; + } + if ("Mapping" == command && mPasteMapping) + { + return false; + } + if ("Media" == command && mPasteMedia) + { + return false; + } + } + + return true; +} -- cgit v1.3 From be7d81626e512019b46a8ed301b4a1825e129aa5 Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Tue, 15 Oct 2019 19:20:36 +0300 Subject: Buildfix (typo) --- indra/newview/llpanelface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 1e0b1874f7..fb99ffef09 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -307,7 +307,7 @@ BOOL LLPanelFace::postBuild() mBtnCopyFaces = getChild("copy_face_btn"); if(mBtnCopyFaces) { - BtnCopyFaces->setCommitCallback(boost::bind(&LLPanelFace::onCopyFaces, this)); + mBtnCopyFaces->setCommitCallback(boost::bind(&LLPanelFace::onCopyFaces, this)); } mBtnPasteFaces = getChild("paste_face_btn"); if (mBtnPasteFaces) -- cgit v1.3 From a09f68a809d8537041ea91c0768ba503f107f26b Mon Sep 17 00:00:00 2001 From: AndreyL ProductEngine Date: Thu, 17 Oct 2019 02:46:09 +0300 Subject: Buildfix (typo) --- indra/newview/llpanelface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index fb99ffef09..8f8f1b4763 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -3161,7 +3161,7 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) LLColor4 spec_color(te_data["material"]["SpecColor"]); LLSelectedTEMaterial::setSpecularLightColor(this, spec_color, te); LLSelectedTEMaterial::setSpecularLightExponent(this, (U8)te_data["material"]["SpecExp"].asInteger(), te, object_id); - LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te), object_id; + LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te, object_id); LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id); if (te_data.has("shiny")) { -- cgit v1.3 From 448eff8307324d12c86185f81c9d3896aec153fb Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Mon, 4 Nov 2019 17:00:21 +0200 Subject: SL-12212 Unable to copy-paste Color, Transparency and Glow settings --- indra/newview/llpanelface.cpp | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 8f8f1b4763..4e2fa5c95c 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -3045,12 +3045,12 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) } // Color / Alpha - if ((mPasteColor || mPasteAlpha) && te_data.has("colors")) + if ((mPasteColor || mPasteAlpha) && te_data["te"].has("colors")) { LLColor4 color = objectp->getTE(te)->getColor(); LLColor4 clip_color; - clip_color.setValue(te_data["colors"]); + clip_color.setValue(te_data["te"]["colors"]); // Color if (mPasteColor) @@ -3068,32 +3068,38 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) objectp->setTEColor(te, color); } - + + if (mPasteColor && te_data["te"].has("fullbright")) + { + objectp->setTEFullbright(te, te_data["te"]["fullbright"].asInteger()); + } + + // Glow - if (mPasteGlow && te_data.has("glow")) + if (mPasteGlow && te_data["te"].has("glow")) { - objectp->setTEGlow(te, (F32)te_data["glow"].asReal()); + objectp->setTEGlow(te, (F32)te_data["te"]["glow"].asReal()); } // Texture map if (mPasteMapping) { - if (te_data.has("scales") && te_data.has("scalet")) + if (te_data["te"].has("scales") && te_data["te"].has("scalet")) { - objectp->setTEScale(te, (F32)te_data["scales"].asReal(), (F32)te_data["scalet"].asReal()); + objectp->setTEScale(te, (F32)te_data["te"]["scales"].asReal(), (F32)te_data["te"]["scalet"].asReal()); } - if (te_data.has("offsets") && te_data.has("offsett")) + if (te_data["te"].has("offsets") && te_data["te"].has("offsett")) { - objectp->setTEOffset(te, (F32)te_data["offsets"].asReal(), (F32)te_data["offsett"].asReal()); + objectp->setTEOffset(te, (F32)te_data["te"]["offsets"].asReal(), (F32)te_data["te"]["offsett"].asReal()); } - if (te_data.has("imagerot")) + if (te_data["te"].has("imagerot")) { - objectp->setTERotation(te, (F32)te_data["imagerot"].asReal()); + objectp->setTERotation(te, (F32)te_data["te"]["imagerot"].asReal()); } } // Media - if (mPasteMedia && te_data.has("media")) + if (mPasteMedia && te_data.has("media")) //te_data["te"]? { //*TODO } @@ -3163,9 +3169,9 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) LLSelectedTEMaterial::setSpecularLightExponent(this, (U8)te_data["material"]["SpecExp"].asInteger(), te, object_id); LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te, object_id); LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id); - if (te_data.has("shiny")) + if (te_data.has("te") && te_data["te"].has("shiny")) { - objectp->setTEShiny(te, (U8)te_data["shiny"].asInteger()); + objectp->setTEShiny(te, (U8)te_data["te"]["shiny"].asInteger()); } } } -- cgit v1.3 From c17a08721bd6a767c722100e44f904b95e12bf58 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Mon, 11 Nov 2019 17:21:33 +0200 Subject: SL-12244 Copying a no transfer texture does not set target object to no transfer --- indra/newview/llpanelface.cpp | 101 +++++++++++++++++++++++++++++++++++------- 1 file changed, 85 insertions(+), 16 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 4e2fa5c95c..2ed6ec0b0d 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -48,6 +48,7 @@ #include "llface.h" #include "llinventoryfunctions.h" #include "llinventorymodel.h" // gInventory +#include "llinventorymodelbackgroundfetch.h" #include "lllineeditor.h" #include "llmaterialmgr.h" #include "llmediaentry.h" @@ -2918,15 +2919,36 @@ void LLPanelFace::onCopyFaces() if (te_data["te"].has("imageid")) { LLUUID id = te_data["te"]["imageid"].asUUID(); + // Doesn't support local images! if (id.isNull() || !LLPanelObject::canCopyTexture(id)) { te_data["te"].erase("imageid"); te_data["te"]["imageid"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); + te_data["te"]["itemfullperm"] = true; + } + else + { + te_data["te"]["itemfullperm"] = false; // if item is not in inventory, we won't get here + LLTextureCtrl* texture_ctrl = getChild("texture control"); + LLUUID item_id = texture_ctrl->getImageItemID(); + if (item_id.notNull()) + { + // Texture control should have the id (otherwise canCopyTexture == false), + // use it for consistency. + te_data["te"]["imageitemid"] = item_id; + + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (itemp) + { + te_data["te"]["itemfullperm"] = itemp->getIsFullPerm(); + if (!itemp->isFinished()) + { + // needed for dropTextureAllFaces + LLInventoryModelBackgroundFetch::instance().start(item_id, false); + } + } + } } - // else - // { - // te_data["te"]["imageid"] = canCopyTexture(te_data["te"]["imageid"].asUUID()); - // } } LLMaterialPtr material_ptr = tep->getMaterialParams(); @@ -3010,21 +3032,63 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) if (te_data.has("te")) { // Texture - if (mPasteDiffuse) + if (mPasteDiffuse && te_data["te"].has("imageid")) { - // Replace no-copy texture with target's - if (!te_data["te"].has("imageid")) + const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); //texture or asset id + LLViewerInventoryItem* itemp_res = NULL; + + if (te_data["te"].has("imageitemid")) { - te_data["te"]["imageid"] = tep->getID(); + LLUUID item_id = te_data["te"]["imageitemid"].asUUID(); + if (item_id.notNull()) + { + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (itemp && itemp->isFinished()) + { + // dropTextureAllFaces will fail if incomplete + itemp_res = itemp; + } + } } - const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); - LLViewerInventoryItem* item = gInventory.getItem(imageid); - if (item) + + // for case when item got removed from inventory after we pressed 'copy' + if (!itemp_res) + { + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLAssetIDMatches asset_id_matches(imageid); + gInventory.collectDescendentsIf(LLUUID::null, + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + asset_id_matches); + + // Extremely unreliable and perfomance unfriendly. + // But we need this to check permissions and it is how texture control finds items + for (S32 i = 0; i < items.size(); i++) + { + LLViewerInventoryItem* itemp = items[i]; + if (itemp && itemp->isFinished()) + { + // dropTextureAllFaces will fail if incomplete + LLPermissions item_permissions = itemp->getPermissions(); + if (item_permissions.allowOperationBy(PERM_COPY, + gAgent.getID(), + gAgent.getGroupID())) + { + itemp_res = itemp; + break; // first match + } + } + } + } + + if (itemp_res) { if (te == -1) // all faces { LLToolDragAndDrop::dropTextureAllFaces(objectp, - item, + itemp_res, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null); } @@ -3032,15 +3096,20 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) { LLToolDragAndDrop::dropTextureOneFace(objectp, te, - item, + itemp_res, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null); } } - else // not an inventory item + // not an inventory item or no complete items + else if (te_data["te"].has("itemfullperm")) { - LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - objectp->setTEImage(U8(te), image); + if (te_data["te"]["itemfullperm"].asBoolean()) + { + // when user clicked copy, item existed in inventory as fullperm (also can be used for local images) + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + objectp->setTEImage(U8(te), image); + } } } -- cgit v1.3 From 87fd7cbea501ba9cd9211ee0cc90e9e8c9421ec2 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 14 Nov 2019 21:22:10 +0200 Subject: SL-12289 'Copy media face' support --- indra/newview/llpanelface.cpp | 83 +++++++++++++++++++++++++++++++++++-------- 1 file changed, 68 insertions(+), 15 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 9c80d582d5..9eb491ef3a 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2912,6 +2912,7 @@ void LLPanelFace::onCopyFaces() { LLSD te_data; + // asLLSD() includes media te_data["te"] = tep->asLLSD(); te_data["te"]["glow"] = tep->getGlow(); te_data["te"]["shiny"] = tep->getShiny(); @@ -3002,8 +3003,6 @@ void LLPanelFace::onCopyFaces() te_data["material"] = mat_data; } - //*TODO: Media - mClipboard.append(te_data); } } @@ -3116,7 +3115,7 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) // Color / Alpha if ((mPasteColor || mPasteAlpha) && te_data["te"].has("colors")) { - LLColor4 color = objectp->getTE(te)->getColor(); + LLColor4 color = tep->getColor(); LLColor4 clip_color; clip_color.setValue(te_data["te"]["colors"]); @@ -3167,19 +3166,20 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) } } - // Media - if (mPasteMedia && te_data.has("media")) //te_data["te"]? + // Media + if (mPasteMedia && te_data["te"].has("media_flags")) { - //*TODO + U8 media_flags = te_data["te"]["media_flags"].asInteger(); + objectp->setTEMediaFlags(te, media_flags); + LLVOVolume *vo = dynamic_cast(objectp); + if (vo && te_data["te"].has(LLTextureEntry::TEXTURE_MEDIA_DATA_KEY)) + { + vo->syncMediaData(te, te_data["te"][LLTextureEntry::TEXTURE_MEDIA_DATA_KEY], true/*merge*/, true/*ignore_agent*/); + } } else { - // // Keep media flags on destination unchanged - // // Media is handled later - // if (te_data["te"].has("media_flags")) - // { - // te_data["te"]["media_flags"] = tep->getMediaTexGen(); - // } + // Keep media flags on destination unchanged } } @@ -3261,13 +3261,66 @@ private: LLPanelFace *mPanelFace; }; +struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor +{ + LLPanelFaceUpdateFunctor(bool update_media) : mUpdateMedia(update_media) {} + virtual bool apply(LLViewerObject* object) + { + object->sendTEUpdate(); + if (mUpdateMedia) + { + LLVOVolume *vo = dynamic_cast(object); + if (vo && vo->hasMedia()) + { + vo->sendMediaDataUpdate(); + } + } + return true; + } +private: + bool mUpdateMedia; +}; + +struct LLPanelFaceNavigateHomeFunctor : public LLSelectedTEFunctor +{ + virtual bool apply(LLViewerObject* objectp, S32 te) + { + if (objectp && objectp->getTE(te)) + { + LLTextureEntry* tep = objectp->getTE(te); + const LLMediaEntry *media_data = tep->getMediaData(); + if (media_data) + { + if (media_data->getCurrentURL().empty() && media_data->getAutoPlay()) + { + viewer_media_t media_impl = + LLViewerMedia::getMediaImplFromTextureID(tep->getMediaData()->getMediaID()); + if (media_impl) + { + media_impl->navigateHome(); + } + } + } + } + return true; + } +}; + void LLPanelFace::onPasteFaces() { + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + LLPanelFacePasteTexFunctor paste_func(this); - LLSelectMgr::getInstance()->getSelection()->applyToTEs(&paste_func); + selected_objects->applyToTEs(&paste_func); + + LLPanelFaceUpdateFunctor sendfunc(mPasteMedia); + selected_objects->applyToObjects(&sendfunc); - LLPanelFaceSendFunctor sendfunc; - LLSelectMgr::getInstance()->getSelection()->applyToObjects(&sendfunc); + if (mPasteMedia) + { + LLPanelFaceNavigateHomeFunctor navigate_home_func; + selected_objects->applyToTEs(&navigate_home_func); + } } bool LLPanelFace::pasteCheckMenuItem(const LLSD& userdata) -- cgit v1.3 From 0afe586856765b9e3f8a39dd9b5b18bd0b02283d Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Fri, 15 Nov 2019 15:40:09 +0200 Subject: SL-12289 Build fix --- indra/newview/llpanelface.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 9eb491ef3a..e19e3f13ee 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -3294,7 +3294,7 @@ struct LLPanelFaceNavigateHomeFunctor : public LLSelectedTEFunctor if (media_data->getCurrentURL().empty() && media_data->getAutoPlay()) { viewer_media_t media_impl = - LLViewerMedia::getMediaImplFromTextureID(tep->getMediaData()->getMediaID()); + LLViewerMedia::getInstance()->getMediaImplFromTextureID(tep->getMediaData()->getMediaID()); if (media_impl) { media_impl->navigateHome(); -- cgit v1.3 From 4fcf31e20319fbbfdd76240b351753e5de726eb5 Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Fri, 15 Nov 2019 17:58:32 +0200 Subject: SL-12287 FIXED [Project Copy/Paste] Unable to paste texture from "local" storage --- indra/newview/lllocalbitmaps.cpp | 14 ++++++++++++++ indra/newview/lllocalbitmaps.h | 2 ++ indra/newview/llpanelface.cpp | 11 +++++++++-- 3 files changed, 25 insertions(+), 2 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index b8bde39bd1..5d301748c7 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -1038,6 +1038,20 @@ LLUUID LLLocalBitmapMgr::getWorldID(LLUUID tracking_id) return world_id; } +bool LLLocalBitmapMgr::isLocalBitmap(LLUUID texture_id) +{ + for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++) + { + LLLocalBitmap* unit = *iter; + if (unit->getWorldID() == texture_id) + { + return true; + } + } + + return false; +} + std::string LLLocalBitmapMgr::getFilename(LLUUID tracking_id) { std::string filename = ""; diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index f6cc1e919e..c15ba9caa4 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -122,6 +122,8 @@ public: LLUUID getWorldID(LLUUID tracking_id); std::string getFilename(LLUUID tracking_id); + bool isLocalBitmap(LLUUID texture_id); + void feedScrollList(LLScrollListCtrl* ctrl); void doUpdates(); void setNeedsRebake(); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index e19e3f13ee..da471b0b62 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2923,8 +2923,15 @@ void LLPanelFace::onCopyFaces() // Doesn't support local images! if (id.isNull() || !LLPanelObject::canCopyTexture(id)) { - te_data["te"].erase("imageid"); - te_data["te"]["imageid"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); + if (LLLocalBitmapMgr::getInstance()->isLocalBitmap(id)) + { + te_data["te"]["imageid"] = id; + } + else + { + te_data["te"].erase("imageid"); + te_data["te"]["imageid"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); + } te_data["te"]["itemfullperm"] = true; } else -- cgit v1.3 From 0a411b0b1a89001afbe009c17b5aac70748289c6 Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Tue, 3 Dec 2019 17:31:46 +0200 Subject: SL-12374 FIXED [Project Copy/Paste] Normal & specular texture UUIDs are copied to clipboard from no-copy or no-transfer objects --- indra/newview/llpanelface.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index da471b0b62..2aba115e3f 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2988,7 +2988,7 @@ void LLPanelFace::onCopyFaces() // Replace no-copy textures, destination texture will get used instead if available if (mat_data.has("NormMap")) { - LLUUID id = te_data["material"]["NormMap"].asUUID(); + LLUUID id = mat_data["NormMap"].asUUID(); if (id.notNull() && !LLPanelObject::canCopyTexture(id)) { mat_data["NormMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); @@ -2998,7 +2998,7 @@ void LLPanelFace::onCopyFaces() } if (mat_data.has("SpecMap")) { - LLUUID id = te_data["material"]["SpecMap"].asUUID(); + LLUUID id = mat_data["SpecMap"].asUUID(); if (id.notNull() && !LLPanelObject::canCopyTexture(id)) { mat_data["SpecMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); -- cgit v1.3 From b3d57f93b6c445578ea3f4caf596472f4ee6fa43 Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Mon, 9 Dec 2019 17:26:16 +0200 Subject: SL-12413 FIXED [Project Copy/Paste] Bumpiness/Shininess parameters are not pasted from the clipboard --- indra/newview/llpanelface.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 2aba115e3f..3a48db0a1a 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2916,6 +2916,9 @@ void LLPanelFace::onCopyFaces() te_data["te"] = tep->asLLSD(); te_data["te"]["glow"] = tep->getGlow(); te_data["te"]["shiny"] = tep->getShiny(); + te_data["te"]["bumpmap"] = tep->getBumpmap(); + te_data["te"]["bumpshiny"] = tep->getBumpShiny(); + te_data["te"]["bumpfullbright"] = tep->getBumpShinyFullbright(); if (te_data["te"].has("imageid")) { @@ -3156,6 +3159,19 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) objectp->setTEGlow(te, (F32)te_data["te"]["glow"].asReal()); } + if (mPasteNormal && te_data["te"].has("bumpmap")) + { + objectp->setTEBumpmap(te, (U8)te_data["te"]["bumpmap"].asInteger()); + } + if (mPasteSpecular && te_data["te"].has("bumpshiny")) + { + objectp->setTEBumpShiny(te, (U8)te_data["te"]["bumpshiny"].asInteger()); + } + if (mPasteSpecular && te_data["te"].has("bumpfullbright")) + { + objectp->setTEBumpShinyFullbright(te, (U8)te_data["te"]["bumpfullbright"].asInteger()); + } + // Texture map if (mPasteMapping) { -- cgit v1.3 From eaa4e977d687abbfb28687c66cb0b92e66deb484 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Wed, 11 Dec 2019 22:48:46 +0200 Subject: SL-12334 [Copypaste] Texture is not copied to clipboard from a full-perms object --- indra/newview/llpanelface.cpp | 69 +++++++++++++++++++++++++---------------- indra/newview/llpanelobject.cpp | 42 +++++++++++++++---------- indra/newview/llpanelobject.h | 6 ++++ 3 files changed, 73 insertions(+), 44 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 3a48db0a1a..914863ccc0 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2922,15 +2922,24 @@ void LLPanelFace::onCopyFaces() if (te_data["te"].has("imageid")) { + LLUUID item_id; LLUUID id = te_data["te"]["imageid"].asUUID(); - // Doesn't support local images! - if (id.isNull() || !LLPanelObject::canCopyTexture(id)) + bool full_perm = LLPanelObject::isLibraryTexture(id) || (objectp->permCopy() && objectp->permTransfer() && objectp->permModify()); + + // todo: fix this, we are often searching same tuxture multiple times (equal to number of faces) + if (id.notNull() && !full_perm) { - if (LLLocalBitmapMgr::getInstance()->isLocalBitmap(id)) - { - te_data["te"]["imageid"] = id; - } - else + // What this does is simply searches inventory for item with same asset id, + // as result it is Hightly unreliable, leaves little control to user, borderline hack + // but there are little options to preserve permissions - multiple inventory + // items might reference same asset and inventory search is expensive. + item_id = LLPanelObject::getCopyPermInventoryTextureId(id); + } + + if (id.isNull() + || (!full_perm && item_id.isNull())) + { + if (!LLLocalBitmapMgr::getInstance()->isLocalBitmap(id)) { te_data["te"].erase("imageid"); te_data["te"]["imageid"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); @@ -2939,23 +2948,30 @@ void LLPanelFace::onCopyFaces() } else { - te_data["te"]["itemfullperm"] = false; // if item is not in inventory, we won't get here - LLTextureCtrl* texture_ctrl = getChild("texture control"); - LLUUID item_id = texture_ctrl->getImageItemID(); - if (item_id.notNull()) + te_data["te"]["itemfullperm"] = full_perm; + // If full permission object, texture is free to copy, + // but otherwise we need to check inventory and extract permissions + // + // Normally we care only about restrictions for current user and objects + // don't inherit any 'next owner' permissions from texture, so there is + // no need to record item id if full_perm==true + if (!full_perm && item_id.notNull()) { - // Texture control should have the id (otherwise canCopyTexture == false), - // use it for consistency. - te_data["te"]["imageitemid"] = item_id; - LLViewerInventoryItem* itemp = gInventory.getItem(item_id); if (itemp) { - te_data["te"]["itemfullperm"] = itemp->getIsFullPerm(); - if (!itemp->isFinished()) + LLPermissions item_permissions = itemp->getPermissions(); + if (item_permissions.allowOperationBy(PERM_COPY, + gAgent.getID(), + gAgent.getGroupID())) { - // needed for dropTextureAllFaces - LLInventoryModelBackgroundFetch::instance().start(item_id, false); + te_data["te"]["imageitemid"] = item_id; + te_data["te"]["itemfullperm"] = itemp->getIsFullPerm(); + if (!itemp->isFinished()) + { + // needed for dropTextureAllFaces + LLInventoryModelBackgroundFetch::instance().start(item_id, false); + } } } } @@ -3041,6 +3057,7 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) if (te_data.has("te")) { // Texture + bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean(); if (mPasteDiffuse && te_data["te"].has("imageid")) { const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); //texture or asset id @@ -3061,8 +3078,9 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) } // for case when item got removed from inventory after we pressed 'copy' - if (!itemp_res) + if (!itemp_res && !full_perm) { + // todo: fix this, we are often searching same tuxter multiple times (equal to number of faces) LLViewerInventoryCategory::cat_array_t cats; LLViewerInventoryItem::item_array_t items; LLAssetIDMatches asset_id_matches(imageid); @@ -3111,14 +3129,11 @@ void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) } } // not an inventory item or no complete items - else if (te_data["te"].has("itemfullperm")) + else if (full_perm) { - if (te_data["te"]["itemfullperm"].asBoolean()) - { - // when user clicked copy, item existed in inventory as fullperm (also can be used for local images) - LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - objectp->setTEImage(U8(te), image); - } + // Either library, local or existed as fullperm when user made a copy + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + objectp->setTEImage(U8(te), image); } } diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index b99c77fb79..b179b1be53 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -2503,32 +2503,31 @@ bool LLPanelObject::pasteEnabletMenuItem(const LLSD& userdata) return true; } -// Static -bool LLPanelObject::canCopyTexture(LLUUID image_id) +//static +bool LLPanelObject::isLibraryTexture(LLUUID image_id) { - // User is allowed to copy a texture if: - // library asset or default texture, - // or copy perm asset exists in user's inventory - - // Library asset or default texture if (gInventory.isObjectDescendentOf(image_id, gInventory.getLibraryRootFolderID()) - || image_id == LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )) - || image_id == LLUUID(gSavedSettings.getString( "UIImgWhiteUUID" )) - || image_id == LLUUID(gSavedSettings.getString( "UIImgInvisibleUUID" )) + || image_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture")) + || image_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID")) + || image_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")) || image_id == LLUUID(SCULPT_DEFAULT_TEXTURE)) { return true; } + return false; +} - // Search for a copy perm asset +//static +LLUUID LLPanelObject::getCopyPermInventoryTextureId(LLUUID image_id) +{ LLViewerInventoryCategory::cat_array_t cats; LLViewerInventoryItem::item_array_t items; LLAssetIDMatches asset_id_matches(image_id); gInventory.collectDescendentsIf(LLUUID::null, - cats, - items, - LLInventoryModel::INCLUDE_TRASH, - asset_id_matches); + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + asset_id_matches); if (items.size()) { for (S32 i = 0; i < items.size(); i++) @@ -2541,11 +2540,20 @@ bool LLPanelObject::canCopyTexture(LLUUID image_id) gAgent.getID(), gAgent.getGroupID())) { - return true; + return itemp->getUUID(); } } } } + return LLUUID::null; +} - return false; +// Static +bool LLPanelObject::canCopyTexture(LLUUID image_id) +{ + // User is allowed to copy a texture if: + // library asset or default texture, + // or copy perm asset exists in user's inventory + + return isLibraryTexture(image_id) || getCopyPermInventoryTextureId(image_id).notNull(); } diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h index 0c37e837ad..65f46a8ed3 100644 --- a/indra/newview/llpanelobject.h +++ b/indra/newview/llpanelobject.h @@ -88,6 +88,12 @@ public: bool pasteCheckMenuItem(const LLSD& userdata); void pasteDoMenuItem(const LLSD& userdata); bool pasteEnabletMenuItem(const LLSD& userdata); + static bool isLibraryTexture(LLUUID image_id); + + // Finds copy-enabled texture with specified asset from inventory + // This can be performance unfriendly and doesn't warranty that + // the texture is original source of asset + static LLUUID getCopyPermInventoryTextureId(LLUUID image_id); static bool canCopyTexture(LLUUID image_id); protected: -- cgit v1.3 From ee3ae8cb4abcb8e738d434fe15b97c628d6ca815 Mon Sep 17 00:00:00 2001 From: andreykproductengine Date: Thu, 12 Dec 2019 15:05:14 +0200 Subject: SL-12334 Reduce inventory use --- indra/newview/llpanelface.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 914863ccc0..f8199090dc 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2901,6 +2901,7 @@ void LLPanelFace::onCopyFaces() } mClipboard.clear(); + std::map asset_item_map; S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); for (S32 te = 0; te < num_tes; ++te) @@ -2926,14 +2927,23 @@ void LLPanelFace::onCopyFaces() LLUUID id = te_data["te"]["imageid"].asUUID(); bool full_perm = LLPanelObject::isLibraryTexture(id) || (objectp->permCopy() && objectp->permTransfer() && objectp->permModify()); - // todo: fix this, we are often searching same tuxture multiple times (equal to number of faces) if (id.notNull() && !full_perm) { - // What this does is simply searches inventory for item with same asset id, - // as result it is Hightly unreliable, leaves little control to user, borderline hack - // but there are little options to preserve permissions - multiple inventory - // items might reference same asset and inventory search is expensive. - item_id = LLPanelObject::getCopyPermInventoryTextureId(id); + std::map::iterator iter = asset_item_map.find(id); + if (iter != asset_item_map.end()) + { + item_id = iter->second; + } + else + { + // What this does is simply searches inventory for item with same asset id, + // as result it is Hightly unreliable, leaves little control to user, borderline hack + // but there are little options to preserve permissions - multiple inventory + // items might reference same asset and inventory search is expensive. + item_id = LLPanelObject::getCopyPermInventoryTextureId(id); + // record value to avoid repeating inventory search when possible + asset_item_map[id] = item_id; + } } if (id.isNull() -- cgit v1.3 From c34f9c28b08a3dba50b831cde9a884f831366bee Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Wed, 19 Feb 2020 17:15:20 +0200 Subject: SL-12473 FIXED Copied texture params get duplicated when pasting to objects that use different face counts. --- indra/newview/llpanelface.cpp | 8 ++++++-- indra/newview/llpanelface.h | 2 ++ 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index f8199090dc..810c18de40 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -63,6 +63,8 @@ #include "lltexturectrl.h" #include "lltextureentry.h" #include "lltooldraganddrop.h" +#include "lltoolface.h" +#include "lltoolmgr.h" #include "lltrans.h" #include "llui.h" #include "llviewercontrol.h" @@ -332,7 +334,8 @@ LLPanelFace::LLPanelFace() mPasteNormal(TRUE), mPasteSpecular(TRUE), mPasteMapping(TRUE), - mPasteMedia(TRUE) + mPasteMedia(TRUE), + mPopulateAllTEs(TRUE) { USE_TEXTURE = LLTrans::getString("use_texture"); @@ -2904,6 +2907,7 @@ void LLPanelFace::onCopyFaces() std::map asset_item_map; S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + mPopulateAllTEs = (num_tes != 1) || (LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()); for (S32 te = 0; te < num_tes; ++te) { if (node->isTESelected(te)) @@ -3048,7 +3052,7 @@ void LLPanelFace::onCopyFaces() void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) { LLSD te_data; - if (mClipboard.size() == 1) + if ((mClipboard.size() == 1) && mPopulateAllTEs) { te_data = *(mClipboard.beginArray()); } diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 76673c6444..770f10e2ee 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -255,6 +255,8 @@ private: BOOL mPasteMapping; BOOL mPasteMedia; + BOOL mPopulateAllTEs; + // Update visibility of controls to match current UI mode // (e.g. materials vs media editing) // -- cgit v1.3 From f4c7c8aff55d0cd8f044d5b7c8cddb2be750dde5 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Sun, 26 Apr 2020 21:15:54 +0300 Subject: Post-merge build fixes --- indra/newview/lllocalbitmaps.h | 4 +--- indra/newview/llpanelface.cpp | 2 +- indra/newview/llpanelobject.cpp | 4 ++-- 3 files changed, 4 insertions(+), 6 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index 8dba73f001..def5a6bd6e 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -122,9 +122,7 @@ public: LLUUID getWorldID(LLUUID tracking_id); bool isLocal(LLUUID world_id); std::string getFilename(LLUUID tracking_id); - - bool isLocalBitmap(LLUUID texture_id); - + void feedScrollList(LLScrollListCtrl* ctrl); void doUpdates(); void setNeedsRebake(); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 810c18de40..13d0e377d7 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2953,7 +2953,7 @@ void LLPanelFace::onCopyFaces() if (id.isNull() || (!full_perm && item_id.isNull())) { - if (!LLLocalBitmapMgr::getInstance()->isLocalBitmap(id)) + if (!LLLocalBitmapMgr::getInstance()->isLocal(id)) { te_data["te"].erase("imageid"); te_data["te"]["imageid"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 8c5afb914a..ac0122237f 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -2215,7 +2215,7 @@ void LLPanelObject::onCopyParams() mParamsClipboard["light"]["intensity"] = volobjp->getLightIntensity(); mParamsClipboard["light"]["radius"] = volobjp->getLightRadius(); mParamsClipboard["light"]["falloff"] = volobjp->getLightFalloff(); - LLColor3 color = volobjp->getLightColor(); + LLColor3 color = volobjp->getLightSRGBColor(); mParamsClipboard["light"]["r"] = color.mV[0]; mParamsClipboard["light"]["g"] = color.mV[1]; mParamsClipboard["light"]["b"] = color.mV[2]; @@ -2288,7 +2288,7 @@ void LLPanelObject::onPasteParams() F32 r = (F32)mParamsClipboard["light"]["r"].asReal(); F32 g = (F32)mParamsClipboard["light"]["g"].asReal(); F32 b = (F32)mParamsClipboard["light"]["b"].asReal(); - volobjp->setLightColor(LLColor3(r,g,b)); + volobjp->setLightSRGBColor(LLColor3(r, g, b)); } else { -- cgit v1.3 From 090bb3e6de6d5cb70ed372748a76e391f61cb32e Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 2 Jun 2020 15:27:34 +0300 Subject: SL-13359 #1 Revert floater_tools and object panel changes --- indra/newview/llpanelface.cpp | 63 ++- indra/newview/llpanelface.h | 7 + indra/newview/llpanelobject.cpp | 479 +-------------------- indra/newview/llpanelobject.h | 34 -- .../newview/skins/default/textures/icons/Paste.png | Bin 530 -> 0 bytes indra/newview/skins/default/textures/textures.xml | 1 - .../newview/skins/default/xui/en/floater_tools.xml | 176 +------- .../skins/default/xui/en/menu_build_paste.xml | 38 -- 8 files changed, 87 insertions(+), 711 deletions(-) delete mode 100644 indra/newview/skins/default/textures/icons/Paste.png delete mode 100644 indra/newview/skins/default/xui/en/menu_build_paste.xml (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 13d0e377d7..369861fa25 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2929,7 +2929,7 @@ void LLPanelFace::onCopyFaces() { LLUUID item_id; LLUUID id = te_data["te"]["imageid"].asUUID(); - bool full_perm = LLPanelObject::isLibraryTexture(id) || (objectp->permCopy() && objectp->permTransfer() && objectp->permModify()); + bool full_perm = LLPanelFace::isLibraryTexture(id) || (objectp->permCopy() && objectp->permTransfer() && objectp->permModify()); if (id.notNull() && !full_perm) { @@ -2944,7 +2944,7 @@ void LLPanelFace::onCopyFaces() // as result it is Hightly unreliable, leaves little control to user, borderline hack // but there are little options to preserve permissions - multiple inventory // items might reference same asset and inventory search is expensive. - item_id = LLPanelObject::getCopyPermInventoryTextureId(id); + item_id = LLPanelFace::getCopyPermInventoryTextureId(id); // record value to avoid repeating inventory search when possible asset_item_map[id] = item_id; } @@ -3022,7 +3022,7 @@ void LLPanelFace::onCopyFaces() if (mat_data.has("NormMap")) { LLUUID id = mat_data["NormMap"].asUUID(); - if (id.notNull() && !LLPanelObject::canCopyTexture(id)) + if (id.notNull() && !LLPanelFace::canCopyTexture(id)) { mat_data["NormMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); mat_data["NormMapNoCopy"] = true; @@ -3032,7 +3032,7 @@ void LLPanelFace::onCopyFaces() if (mat_data.has("SpecMap")) { LLUUID id = mat_data["SpecMap"].asUUID(); - if (id.notNull() && !LLPanelObject::canCopyTexture(id)) + if (id.notNull() && !LLPanelFace::canCopyTexture(id)) { mat_data["SpecMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); mat_data["SpecMapNoCopy"] = true; @@ -3504,3 +3504,58 @@ bool LLPanelFace::pasteEnabletMenuItem(const LLSD& userdata) return true; } + +//static +bool LLPanelFace::isLibraryTexture(LLUUID image_id) +{ + if (gInventory.isObjectDescendentOf(image_id, gInventory.getLibraryRootFolderID()) + || image_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture")) + || image_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID")) + || image_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")) + || image_id == LLUUID(SCULPT_DEFAULT_TEXTURE)) + { + return true; + } + return false; +} + +//static +LLUUID LLPanelFace::getCopyPermInventoryTextureId(LLUUID image_id) +{ + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLAssetIDMatches asset_id_matches(image_id); + gInventory.collectDescendentsIf(LLUUID::null, + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + asset_id_matches); + if (items.size()) + { + for (S32 i = 0; i < items.size(); i++) + { + LLViewerInventoryItem* itemp = items[i]; + if (itemp) + { + LLPermissions item_permissions = itemp->getPermissions(); + if (item_permissions.allowOperationBy(PERM_COPY, + gAgent.getID(), + gAgent.getGroupID())) + { + return itemp->getUUID(); + } + } + } + } + return LLUUID::null; +} + +// Static +bool LLPanelFace::canCopyTexture(LLUUID image_id) +{ + // User is allowed to copy a texture if: + // library asset or default texture, + // or copy perm asset exists in user's inventory + + return isLibraryTexture(image_id) || getCopyPermInventoryTextureId(image_id).notNull(); +} diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 770f10e2ee..dbf3531332 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -115,6 +115,13 @@ public: LLRender::eTexIndex getTextureChannelToEdit(); void pasteFace(LLViewerObject* object, S32 te); + static bool isLibraryTexture(LLUUID image_id); + + // Finds copy-enabled texture with specified asset from inventory + // This can be performance unfriendly and doesn't warranty that + // the texture is original source of asset + static LLUUID getCopyPermInventoryTextureId(LLUUID image_id); + static bool canCopyTexture(LLUUID image_id); protected: void getState(); diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index ac0122237f..5fd9655201 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -32,7 +32,6 @@ // linden library includes #include "llerror.h" #include "llfontgl.h" -#include "material_codes.h" // LL_MCODE_MASK #include "llpermissionsflags.h" #include "llstring.h" #include "llvolume.h" @@ -46,8 +45,6 @@ #include "llcolorswatch.h" #include "llcombobox.h" #include "llfocusmgr.h" -#include "llinventoryfunctions.h" -#include "llinventorymodel.h" #include "llmanipscale.h" #include "llmenubutton.h" #include "llpreviewscript.h" @@ -153,31 +150,6 @@ BOOL LLPanelObject::postBuild() mCtrlRotZ = getChild("Rot Z"); childSetCommitCallback("Rot Z",onCommitRotation,this); - // Copy/paste pos - mBtnCopyPos = getChild("copy_pos_btn"); - mBtnCopyPos->setCommitCallback(boost::bind(&LLPanelObject::onCopyPos, this)); - mBtnPastePos = getChild("paste_pos_btn"); - mBtnPastePos->setCommitCallback(boost::bind(&LLPanelObject::onPastePos, this)); - - // Copy/paste size - mBtnCopySize = getChild("copy_size_btn"); - mBtnCopySize->setCommitCallback(boost::bind(&LLPanelObject::onCopySize, this)); - mBtnPasteSize = getChild("paste_size_btn"); - mBtnPasteSize->setCommitCallback(boost::bind(&LLPanelObject::onPasteSize, this)); - - // Copy/paste rot - mBtnCopyRot = getChild("copy_rot_btn"); - mBtnCopyRot->setCommitCallback(boost::bind(&LLPanelObject::onCopyRot, this)); - mBtnPasteRot = getChild("paste_rot_btn"); - mBtnPasteRot->setCommitCallback(boost::bind(&LLPanelObject::onPasteRot, this));; - - // Copy/paste obj prams - mBtnCopyParams = getChild("copy_params_btn"); - mBtnCopyParams->setCommitCallback(boost::bind(&LLPanelObject::onCopyParams, this)); - mBtnPasteParams = getChild("paste_params_btn"); - mBtnPasteParams->setCommitCallback(boost::bind(&LLPanelObject::onPasteParams, this)); - mBtnPasteMenu = getChild("paste_gear_btn"); - //-------------------------------------------------------- // Base Type @@ -314,19 +286,11 @@ LLPanelObject::LLPanelObject() mSelectedType(MI_BOX), mSculptTextureRevert(LLUUID::null), mSculptTypeRevert(0), - mSizeChanged(FALSE), - mHasParamsClipboard(FALSE), mHasPosClipboard(FALSE), mHasSizeClipboard(FALSE), mHasRotClipboard(FALSE), - mPasteParametric(TRUE), - mPasteFlexible(TRUE), - mPastePhysics(TRUE), - mPasteLight(TRUE) + mSizeChanged(FALSE) { - mEnableCallbackRegistrar.add("BuildObject.PasteCheckItem", boost::bind(&LLPanelObject::pasteCheckMenuItem, this, _2)); - mCommitCallbackRegistrar.add("BuildObject.PasteDoToSelected", boost::bind(&LLPanelObject::pasteDoMenuItem, this, _2)); - mEnableCallbackRegistrar.add("BuildObject.PasteEnable", boost::bind(&LLPanelObject::pasteEnabletMenuItem, this, _2)); } @@ -418,8 +382,6 @@ void LLPanelObject::getState( ) mCtrlPosX->setEnabled(enable_move); mCtrlPosY->setEnabled(enable_move); mCtrlPosZ->setEnabled(enable_move); - mBtnCopyPos->setEnabled(enable_move); - mBtnPastePos->setEnabled(enable_move && mHasPosClipboard); if (enable_scale) { @@ -445,8 +407,6 @@ void LLPanelObject::getState( ) mCtrlScaleX->setEnabled( enable_scale ); mCtrlScaleY->setEnabled( enable_scale ); mCtrlScaleZ->setEnabled( enable_scale ); - mBtnCopySize->setEnabled( enable_scale ); - mBtnPasteSize->setEnabled( enable_scale && mHasSizeClipboard ); LLQuaternion object_rot = objectp->getRotationEdit(); object_rot.getEulerAngles(&(mCurEulerDegrees.mV[VX]), &(mCurEulerDegrees.mV[VY]), &(mCurEulerDegrees.mV[VZ])); @@ -478,12 +438,6 @@ void LLPanelObject::getState( ) mCtrlRotX->setEnabled( enable_rotate ); mCtrlRotY->setEnabled( enable_rotate ); mCtrlRotZ->setEnabled( enable_rotate ); - mBtnCopyRot->setEnabled( enable_rotate ); - mBtnPasteRot->setEnabled( enable_rotate && mHasRotClipboard ); - - mBtnCopyParams->setEnabled( single_volume && enable_modify ); - mBtnPasteParams->setEnabled( single_volume && enable_modify && mHasParamsClipboard ); - mBtnPasteMenu->setEnabled( single_volume && enable_modify ); LLUUID owner_id; std::string owner_name; @@ -2058,12 +2012,6 @@ void LLPanelObject::onCopyPos() std::string stringVec = llformat("<%g, %g, %g>", mClipboardPos.mV[VX], mClipboardPos.mV[VY], mClipboardPos.mV[VZ]); LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec)); - LLStringUtil::format_map_t args; - args["VALUE"] = stringVec; - mBtnPastePos->setToolTip(getString("paste_position", args)); - - mBtnPastePos->setEnabled(TRUE); - mHasPosClipboard = TRUE; } @@ -2074,12 +2022,6 @@ void LLPanelObject::onCopySize() std::string stringVec = llformat("<%g, %g, %g>", mClipboardSize.mV[VX], mClipboardSize.mV[VY], mClipboardSize.mV[VZ]); LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec)); - LLStringUtil::format_map_t args; - args["VALUE"] = stringVec; - mBtnPasteSize->setToolTip(getString("paste_size", args)); - - mBtnPasteSize->setEnabled(TRUE); - mHasSizeClipboard = TRUE; } @@ -2090,12 +2032,6 @@ void LLPanelObject::onCopyRot() std::string stringVec = llformat("<%g, %g, %g>", mClipboardRot.mV[VX], mClipboardRot.mV[VY], mClipboardRot.mV[VZ]); LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec)); - LLStringUtil::format_map_t args; - args["VALUE"] = stringVec; - mBtnPasteRot->setToolTip(getString("paste_rotation", args)); - - mBtnPasteRot->setEnabled(TRUE); - mHasRotClipboard = TRUE; } @@ -2143,416 +2079,3 @@ void LLPanelObject::onPasteRot() sendRotation(FALSE); } - -void LLPanelObject::onCopyParams() -{ - LLViewerObject* objectp = mObject; - if (!objectp) - { - return; - } - - mParamsClipboard.clear(); - - mParamsClipboard["is_phantom"] = objectp->flagPhantom(); - mParamsClipboard["is_physical"] = objectp->flagUsePhysics(); - - // Parametrics - if (!objectp->isMesh()) - { - getVolumeParams(mClipboardVolumeParams); - } - - LLVOVolume *volobjp = NULL; - if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) - { - volobjp = (LLVOVolume *)objectp; - } - - // Flexi Prim - if (volobjp && volobjp->isFlexible()) - { - LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); - if (attributes) - { - mParamsClipboard["flex"]["lod"] = attributes->getSimulateLOD(); - mParamsClipboard["flex"]["gav"] = attributes->getGravity(); - mParamsClipboard["flex"]["ten"] = attributes->getTension(); - mParamsClipboard["flex"]["fri"] = attributes->getAirFriction(); - mParamsClipboard["flex"]["sen"] = attributes->getWindSensitivity(); - LLVector3 force = attributes->getUserForce(); - mParamsClipboard["flex"]["forx"] = force.mV[0]; - mParamsClipboard["flex"]["fory"] = force.mV[1]; - mParamsClipboard["flex"]["forz"] = force.mV[2]; - } - } - - // Sculpted Prim - if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) - { - LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); - - if (!objectp->isMesh()) - { - LLUUID texture_id = sculpt_params->getSculptTexture(); - if (canCopyTexture(texture_id)) - { - LL_INFOS() << "copy texture " << LL_ENDL; - mParamsClipboard["sculpt"]["id"] = texture_id; - } - else - { - mParamsClipboard["sculpt"]["id"] = LLUUID(SCULPT_DEFAULT_TEXTURE); - } - - mParamsClipboard["sculpt"]["type"] = sculpt_params->getSculptType(); - } - } - - // Light Source - if (volobjp && volobjp->getIsLight()) - { - mParamsClipboard["light"]["intensity"] = volobjp->getLightIntensity(); - mParamsClipboard["light"]["radius"] = volobjp->getLightRadius(); - mParamsClipboard["light"]["falloff"] = volobjp->getLightFalloff(); - LLColor3 color = volobjp->getLightSRGBColor(); - mParamsClipboard["light"]["r"] = color.mV[0]; - mParamsClipboard["light"]["g"] = color.mV[1]; - mParamsClipboard["light"]["b"] = color.mV[2]; - - // Spotlight - if (volobjp->isLightSpotlight()) - { - LLUUID id = volobjp->getLightTextureID(); - if (id.notNull() && canCopyTexture(id)) - { - mParamsClipboard["spot"]["id"] = id; - LLVector3 spot_params = volobjp->getSpotLightParams(); - mParamsClipboard["spot"]["fov"] = spot_params.mV[0]; - mParamsClipboard["spot"]["focus"] = spot_params.mV[1]; - mParamsClipboard["spot"]["ambiance"] = spot_params.mV[2]; - } - } - } - - // Physics - { - mParamsClipboard["physics"]["shape"] = objectp->getPhysicsShapeType(); - mParamsClipboard["physics"]["gravity"] = objectp->getPhysicsGravity(); - mParamsClipboard["physics"]["friction"] = objectp->getPhysicsFriction(); - mParamsClipboard["physics"]["density"] = objectp->getPhysicsDensity(); - mParamsClipboard["physics"]["restitution"] = objectp->getPhysicsRestitution(); - - U8 material_code = 0; - struct f : public LLSelectedTEGetFunctor - { - U8 get(LLViewerObject* object, S32 te) - { - return object->getMaterial(); - } - } func; - bool material_same = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &func, material_code ); - // This should always be true since material should be per object. - if (material_same) - { - mParamsClipboard["physics"]["material"] = material_code; - } - } - - mHasParamsClipboard = TRUE; -} - -void LLPanelObject::onPasteParams() -{ - LLViewerObject* objectp = mObject; - if (!objectp || !mHasParamsClipboard) - { - return; - } - - LLVOVolume *volobjp = NULL; - if (objectp && (objectp->getPCode() == LL_PCODE_VOLUME)) - { - volobjp = (LLVOVolume *)objectp; - } - - // Light Source - if (mPasteLight && volobjp) - { - if (mParamsClipboard.has("light")) - { - volobjp->setIsLight(TRUE); - volobjp->setLightIntensity((F32)mParamsClipboard["light"]["intensity"].asReal()); - volobjp->setLightRadius((F32)mParamsClipboard["light"]["radius"].asReal()); - volobjp->setLightFalloff((F32)mParamsClipboard["light"]["falloff"].asReal()); - F32 r = (F32)mParamsClipboard["light"]["r"].asReal(); - F32 g = (F32)mParamsClipboard["light"]["g"].asReal(); - F32 b = (F32)mParamsClipboard["light"]["b"].asReal(); - volobjp->setLightSRGBColor(LLColor3(r, g, b)); - } - else - { - volobjp->setIsLight(FALSE); - } - - if (mParamsClipboard.has("spot")) - { - volobjp->setLightTextureID(mParamsClipboard["spot"]["id"].asUUID()); - LLVector3 spot_params; - spot_params.mV[0] = (F32)mParamsClipboard["spot"]["fov"].asReal(); - spot_params.mV[1] = (F32)mParamsClipboard["spot"]["focus"].asReal(); - spot_params.mV[2] = (F32)mParamsClipboard["spot"]["ambiance"].asReal(); - volobjp->setSpotLightParams(spot_params); - } - } - - // Physics - if (mPastePhysics) - { - bool is_root = objectp->isRoot(); - - // Not sure if phantom should go under physics, but doesn't fit elsewhere - BOOL is_phantom = mParamsClipboard["is_phantom"].asBoolean() && is_root; - LLSelectMgr::getInstance()->selectionUpdatePhantom(is_phantom); - - BOOL is_physical = mParamsClipboard["is_physical"].asBoolean() && is_root; - LLSelectMgr::getInstance()->selectionUpdatePhysics(is_physical); - - if (mParamsClipboard.has("physics")) - { - objectp->setPhysicsShapeType((U8)mParamsClipboard["physics"]["shape"].asInteger()); - U8 cur_material = objectp->getMaterial(); - U8 material = (U8)mParamsClipboard["physics"]["material"].asInteger() | (cur_material & ~LL_MCODE_MASK); - - objectp->setMaterial(material); - objectp->sendMaterialUpdate(); - objectp->setPhysicsGravity(mParamsClipboard["physics"]["gravity"].asReal()); - objectp->setPhysicsFriction(mParamsClipboard["physics"]["friction"].asReal()); - objectp->setPhysicsDensity(mParamsClipboard["physics"]["density"].asReal()); - objectp->setPhysicsRestitution(mParamsClipboard["physics"]["restitution"].asReal()); - objectp->updateFlags(TRUE); - } - } - - if (mPasteFlexible) - { - bool is_flexible = mParamsClipboard.has("flex"); - if (is_flexible) - { - LLVOVolume *volobjp = (LLVOVolume *)objectp; - BOOL update_shape = FALSE; - if (!mPasteParametric) - { - // do before setParameterEntry or it will think that it is already flexi - update_shape = volobjp->setIsFlexible(is_flexible); - } - - if (objectp->getClickAction() == CLICK_ACTION_SIT) - { - objectp->setClickAction(CLICK_ACTION_NONE); - } - - LLFlexibleObjectData *attributes = (LLFlexibleObjectData *)objectp->getParameterEntry(LLNetworkData::PARAMS_FLEXIBLE); - if (attributes) - { - LLFlexibleObjectData new_attributes; - new_attributes = *attributes; - new_attributes.setSimulateLOD(mParamsClipboard["flex"]["lod"].asInteger()); - new_attributes.setGravity(mParamsClipboard["flex"]["gav"].asReal()); - new_attributes.setTension(mParamsClipboard["flex"]["ten"].asReal()); - new_attributes.setAirFriction(mParamsClipboard["flex"]["fri"].asReal()); - new_attributes.setWindSensitivity(mParamsClipboard["flex"]["sen"].asReal()); - F32 fx = (F32)mParamsClipboard["flex"]["forx"].asReal(); - F32 fy = (F32)mParamsClipboard["flex"]["fory"].asReal(); - F32 fz = (F32)mParamsClipboard["flex"]["forz"].asReal(); - LLVector3 force(fx, fy, fz); - new_attributes.setUserForce(force); - objectp->setParameterEntry(LLNetworkData::PARAMS_FLEXIBLE, new_attributes, true); - } - - if (!mPasteParametric && update_shape) - { - mObject->sendShapeUpdate(); - LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom()); - } - } - else if (!mPasteParametric) - { - LLVOVolume *volobjp = (LLVOVolume *)objectp; - if (volobjp->setIsFlexible(is_flexible)) - { - mObject->sendShapeUpdate(); - LLSelectMgr::getInstance()->selectionUpdatePhantom(volobjp->flagPhantom()); - } - } - } - // Parametric does updateVolume(), make sure we won't affect flexible - else if (mPasteParametric) - { - LLVOVolume *volobjp = (LLVOVolume *)objectp; - if (volobjp->isFlexible()) - { - if (mClipboardVolumeParams.getPathParams().getCurveType() == LL_PCODE_PATH_LINE) - { - mClipboardVolumeParams.getPathParams().setCurveType(LL_PCODE_PATH_FLEXIBLE); - } - } - else if (mClipboardVolumeParams.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE) - { - mClipboardVolumeParams.getPathParams().setCurveType(LL_PCODE_PATH_LINE); - } - } - - // Parametrics - if(mPasteParametric) - { - // Sculpted Prim - if (mParamsClipboard.has("sculpt")) - { - LLSculptParams sculpt_params; - LLUUID sculpt_id = mParamsClipboard["sculpt"]["id"].asUUID(); - U8 sculpt_type = (U8)mParamsClipboard["sculpt"]["type"].asInteger(); - sculpt_params.setSculptTexture(sculpt_id, sculpt_type); - objectp->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE); - } - else - { - LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); - if (sculpt_params) - { - objectp->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE); - } - } - - objectp->updateVolume(mClipboardVolumeParams); - } -} - -bool LLPanelObject::pasteCheckMenuItem(const LLSD& userdata) -{ - std::string command = userdata.asString(); - - if ("Parametric" == command) - { - return mPasteParametric; - } - if ("Flexible" == command) - { - return mPasteFlexible; - } - if ("Physics" == command) - { - return mPastePhysics; - } - if ("Light" == command) - { - return mPasteLight; - } - - return false; -} - -void LLPanelObject::pasteDoMenuItem(const LLSD& userdata) -{ - std::string command = userdata.asString(); - - if ("Parametric" == command) - { - mPasteParametric = !mPasteParametric; - } - if ("Flexible" == command) - { - mPasteFlexible = !mPasteFlexible; - } - if ("Physics" == command) - { - mPastePhysics = !mPastePhysics; - } - if ("Light" == command) - { - mPasteLight = !mPasteLight; - } -} - -bool LLPanelObject::pasteEnabletMenuItem(const LLSD& userdata) -{ - std::string command = userdata.asString(); - - // Keep at least one option enabled - if (mPasteParametric + mPasteFlexible + mPastePhysics + mPasteLight == 1) - { - if ("Parametric" == command && mPasteParametric) - { - return false; - } - if ("Flexible" == command && mPasteFlexible) - { - return false; - } - if ("Physics" == command && mPastePhysics) - { - return false; - } - if ("Light" == command && mPasteLight) - { - return false; - } - } - - return true; -} - -//static -bool LLPanelObject::isLibraryTexture(LLUUID image_id) -{ - if (gInventory.isObjectDescendentOf(image_id, gInventory.getLibraryRootFolderID()) - || image_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture")) - || image_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID")) - || image_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")) - || image_id == LLUUID(SCULPT_DEFAULT_TEXTURE)) - { - return true; - } - return false; -} - -//static -LLUUID LLPanelObject::getCopyPermInventoryTextureId(LLUUID image_id) -{ - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLAssetIDMatches asset_id_matches(image_id); - gInventory.collectDescendentsIf(LLUUID::null, - cats, - items, - LLInventoryModel::INCLUDE_TRASH, - asset_id_matches); - if (items.size()) - { - for (S32 i = 0; i < items.size(); i++) - { - LLViewerInventoryItem* itemp = items[i]; - if (itemp) - { - LLPermissions item_permissions = itemp->getPermissions(); - if (item_permissions.allowOperationBy(PERM_COPY, - gAgent.getID(), - gAgent.getGroupID())) - { - return itemp->getUUID(); - } - } - } - } - return LLUUID::null; -} - -// Static -bool LLPanelObject::canCopyTexture(LLUUID image_id) -{ - // User is allowed to copy a texture if: - // library asset or default texture, - // or copy perm asset exists in user's inventory - - return isLibraryTexture(image_id) || getCopyPermInventoryTextureId(image_id).notNull(); -} diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h index 65f46a8ed3..e9b9254a78 100644 --- a/indra/newview/llpanelobject.h +++ b/indra/newview/llpanelobject.h @@ -37,7 +37,6 @@ class LLCheckBoxCtrl; class LLTextBox; class LLUICtrl; class LLButton; -class LLMenuButton; class LLViewerObject; class LLComboBox; class LLColorSwatchCtrl; @@ -73,9 +72,6 @@ public: void onPasteSize(); void onCopyRot(); void onPasteRot(); - void onCopyParams(); - void onPasteParams(); - static void onCommitParametric(LLUICtrl* ctrl, void* userdata); @@ -85,17 +81,6 @@ public: BOOL onDropSculpt(LLInventoryItem* item); static void onCommitSculptType( LLUICtrl *ctrl, void* userdata); - bool pasteCheckMenuItem(const LLSD& userdata); - void pasteDoMenuItem(const LLSD& userdata); - bool pasteEnabletMenuItem(const LLSD& userdata); - static bool isLibraryTexture(LLUUID image_id); - - // Finds copy-enabled texture with specified asset from inventory - // This can be performance unfriendly and doesn't warranty that - // the texture is original source of asset - static LLUUID getCopyPermInventoryTextureId(LLUUID image_id); - static bool canCopyTexture(LLUUID image_id); - protected: void getState(); @@ -168,16 +153,6 @@ protected: LLSpinCtrl* mCtrlRotY; LLSpinCtrl* mCtrlRotZ; - LLButton *mBtnCopyPos; - LLButton *mBtnPastePos; - LLButton *mBtnCopySize; - LLButton *mBtnPasteSize; - LLButton *mBtnCopyRot; - LLButton *mBtnPasteRot; - LLButton *mBtnCopyParams; - LLButton *mBtnPasteParams; - LLMenuButton *mBtnPasteMenu; - LLCheckBoxCtrl *mCheckLock; LLCheckBoxCtrl *mCheckPhysics; LLCheckBoxCtrl *mCheckTemporary; @@ -206,15 +181,6 @@ protected: BOOL mHasSizeClipboard; BOOL mHasRotClipboard; - LLSD mParamsClipboard; - LLVolumeParams mClipboardVolumeParams; - BOOL mHasParamsClipboard; - - BOOL mPasteParametric; - BOOL mPasteFlexible; - BOOL mPastePhysics; - BOOL mPasteLight; - LLPointer mObject; LLPointer mRootObject; }; diff --git a/indra/newview/skins/default/textures/icons/Paste.png b/indra/newview/skins/default/textures/icons/Paste.png deleted file mode 100644 index 10211df427..0000000000 Binary files a/indra/newview/skins/default/textures/icons/Paste.png and /dev/null differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index dd70354dd9..b041e6197c 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -186,7 +186,6 @@ with the same filename but different name - diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 425af16261..0abee2ff80 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -1397,18 +1397,6 @@ even though the user gets a free copy. name="Object" top="16" width="295"> - -Paste Position -[VALUE] - - -Paste Size -[VALUE] - - -Paste Rotation -[VALUE] - - - - @@ -1858,7 +1722,7 @@ Paste Rotation increment="5" initial_value="0" layout="topleft" - left="135" + left="125" max_val="95" name="Scale 1" top_pad="4" @@ -1882,7 +1746,7 @@ Paste Rotation follows="left|top" height="15" layout="topleft" - left="135" + left="125" name="Hollow Shape" top_pad="4" width="150"> @@ -1960,7 +1824,7 @@ Paste Rotation follows="left|top" height="10" layout="topleft" - left="135" + left="125" name="scale_taper" top_pad="3" width="150"> @@ -2013,7 +1877,7 @@ Paste Rotation follows="left|top" height="10" layout="topleft" - left="135" + left="125" name="text topshear" top_pad="3" width="141"> @@ -2056,7 +1920,7 @@ Paste Rotation follows="left|top" height="10" layout="topleft" - left="135" + left="125" name="advanced_cut" top_pad="3" width="150"> @@ -2120,7 +1984,7 @@ Paste Rotation follows="left|top" height="10" layout="topleft" - left="135" + left="125" name="text taper2" top_pad="3" width="150"> @@ -2163,7 +2027,7 @@ Paste Rotation follows="left|top" height="10" layout="topleft" - left="135" + left="125" name="text radius delta" top_pad="2" width="78"> @@ -2188,7 +2052,7 @@ Paste Rotation increment="0.05" initial_value="0" layout="topleft" - left="135" + left="125" min_val="-1" name="Radius Offset" top_pad="4" @@ -2213,7 +2077,7 @@ Paste Rotation height="141" label="Sculpt Texture" layout="topleft" - left="135" + left="125" name="sculpt texture control" tool_tip="Click to choose a picture" top="70" @@ -2671,7 +2535,7 @@ Paste Rotation top_pad="8" width="132" /> - - - - - - - - - - - - - - - - - - - - - - - - -- cgit v1.3 From 1310fac3b10b3927cb502008c156c16631b97663 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 17 Jun 2020 23:38:55 +0300 Subject: SL-13359 #5 Implemented revised changes --- indra/newview/llfloatermodelpreview.cpp | 1 + indra/newview/llpanelface.cpp | 64 +----- indra/newview/llpanelface.h | 7 - indra/newview/llpanelobject.cpp | 219 ++++++++++++++++++--- indra/newview/llpanelobject.h | 11 +- indra/newview/lltexturectrl.cpp | 55 ++++++ indra/newview/lltexturectrl.h | 10 + .../textures/icons/ClipboardMenu_Disabled.png | Bin 0 -> 231 bytes .../default/textures/icons/ClipboardMenu_Off.png | Bin 0 -> 231 bytes .../default/textures/icons/ClipboardMenu_Press.png | Bin 0 -> 224 bytes indra/newview/skins/default/textures/textures.xml | 3 + .../newview/skins/default/xui/en/floater_tools.xml | 31 ++- .../default/xui/en/menu_copy_paste_generic.xml | 21 ++ .../skins/default/xui/en/menu_copy_paste_pos.xml | 26 ++- .../skins/default/xui/en/menu_copy_paste_rot.xml | 26 ++- .../skins/default/xui/en/menu_copy_paste_size.xml | 26 ++- 16 files changed, 382 insertions(+), 118 deletions(-) create mode 100644 indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png create mode 100644 indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png create mode 100644 indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png create mode 100644 indra/newview/skins/default/xui/en/menu_copy_paste_generic.xml (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index bc44e37c5a..f44dd92ddb 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -4379,6 +4379,7 @@ void LLModelPreview::textureLoadedCallback( if(final && preview->mModelLoader) { + // for areTexturesReady() if(preview->mModelLoader->mNumOfFetchingTextures > 0) { preview->mModelLoader->mNumOfFetchingTextures-- ; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 369861fa25..6e99a10b98 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -54,7 +54,6 @@ #include "llmediaentry.h" #include "llmenubutton.h" #include "llnotificationsutil.h" -#include "llpanelobject.h" // LLPanelObject::canCopyTexture #include "llradiogroup.h" #include "llresmgr.h" #include "llselectmgr.h" @@ -2929,7 +2928,7 @@ void LLPanelFace::onCopyFaces() { LLUUID item_id; LLUUID id = te_data["te"]["imageid"].asUUID(); - bool full_perm = LLPanelFace::isLibraryTexture(id) || (objectp->permCopy() && objectp->permTransfer() && objectp->permModify()); + bool full_perm = get_is_library_texture(id) || (objectp->permCopy() && objectp->permTransfer() && objectp->permModify()); if (id.notNull() && !full_perm) { @@ -2944,7 +2943,7 @@ void LLPanelFace::onCopyFaces() // as result it is Hightly unreliable, leaves little control to user, borderline hack // but there are little options to preserve permissions - multiple inventory // items might reference same asset and inventory search is expensive. - item_id = LLPanelFace::getCopyPermInventoryTextureId(id); + item_id = get_copy_free_item_by_asset_id(id); // record value to avoid repeating inventory search when possible asset_item_map[id] = item_id; } @@ -3022,7 +3021,7 @@ void LLPanelFace::onCopyFaces() if (mat_data.has("NormMap")) { LLUUID id = mat_data["NormMap"].asUUID(); - if (id.notNull() && !LLPanelFace::canCopyTexture(id)) + if (id.notNull() && !get_can_copy_texture(id)) { mat_data["NormMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); mat_data["NormMapNoCopy"] = true; @@ -3032,7 +3031,7 @@ void LLPanelFace::onCopyFaces() if (mat_data.has("SpecMap")) { LLUUID id = mat_data["SpecMap"].asUUID(); - if (id.notNull() && !LLPanelFace::canCopyTexture(id)) + if (id.notNull() && !get_can_copy_texture(id)) { mat_data["SpecMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); mat_data["SpecMapNoCopy"] = true; @@ -3504,58 +3503,3 @@ bool LLPanelFace::pasteEnabletMenuItem(const LLSD& userdata) return true; } - -//static -bool LLPanelFace::isLibraryTexture(LLUUID image_id) -{ - if (gInventory.isObjectDescendentOf(image_id, gInventory.getLibraryRootFolderID()) - || image_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture")) - || image_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID")) - || image_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")) - || image_id == LLUUID(SCULPT_DEFAULT_TEXTURE)) - { - return true; - } - return false; -} - -//static -LLUUID LLPanelFace::getCopyPermInventoryTextureId(LLUUID image_id) -{ - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLAssetIDMatches asset_id_matches(image_id); - gInventory.collectDescendentsIf(LLUUID::null, - cats, - items, - LLInventoryModel::INCLUDE_TRASH, - asset_id_matches); - if (items.size()) - { - for (S32 i = 0; i < items.size(); i++) - { - LLViewerInventoryItem* itemp = items[i]; - if (itemp) - { - LLPermissions item_permissions = itemp->getPermissions(); - if (item_permissions.allowOperationBy(PERM_COPY, - gAgent.getID(), - gAgent.getGroupID())) - { - return itemp->getUUID(); - } - } - } - } - return LLUUID::null; -} - -// Static -bool LLPanelFace::canCopyTexture(LLUUID image_id) -{ - // User is allowed to copy a texture if: - // library asset or default texture, - // or copy perm asset exists in user's inventory - - return isLibraryTexture(image_id) || getCopyPermInventoryTextureId(image_id).notNull(); -} diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index dbf3531332..770f10e2ee 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -115,13 +115,6 @@ public: LLRender::eTexIndex getTextureChannelToEdit(); void pasteFace(LLViewerObject* object, S32 te); - static bool isLibraryTexture(LLUUID image_id); - - // Finds copy-enabled texture with specified asset from inventory - // This can be performance unfriendly and doesn't warranty that - // the texture is original source of asset - static LLUUID getCopyPermInventoryTextureId(LLUUID image_id); - static bool canCopyTexture(LLUUID image_id); protected: void getState(); diff --git a/indra/newview/llpanelobject.cpp b/indra/newview/llpanelobject.cpp index 6fa2da7bac..f1426ddf33 100644 --- a/indra/newview/llpanelobject.cpp +++ b/indra/newview/llpanelobject.cpp @@ -159,6 +159,8 @@ BOOL LLPanelObject::postBuild() mComboBaseType = getChild("comboBaseType"); childSetCommitCallback("comboBaseType",onCommitParametric,this); + mMenuClipboardParams = getChild("clipboard_params_btn"); + // Cut mLabelCut = getChild("text cut"); mSpinCutBegin = getChild("cut begin"); @@ -289,9 +291,10 @@ LLPanelObject::LLPanelObject() mSelectedType(MI_BOX), mSculptTextureRevert(LLUUID::null), mSculptTypeRevert(0), - mHasPosClipboard(FALSE), - mHasSizeClipboard(FALSE), - mHasRotClipboard(FALSE), + mHasClipboardPos(false), + mHasClipboardSize(false), + mHasClipboardRot(false), + mHasClipboardParams(false), mSizeChanged(FALSE) { mCommitCallbackRegistrar.add("PanelObject.menuDoToSelected", boost::bind(&LLPanelObject::menuDoToSelected, this, _2)); @@ -618,7 +621,7 @@ void LLPanelObject::getState( ) } else { - LL_INFOS() << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << LL_ENDL; + LL_INFOS("FloaterTools") << "Unknown path " << (S32) path << " profile " << (S32) profile << " in getState" << LL_ENDL; selected_item = MI_BOX; } @@ -944,6 +947,7 @@ void LLPanelObject::getState( ) // Update field enablement mComboBaseType ->setEnabled( enabled ); + mMenuClipboardParams->setEnabled(enabled); mLabelCut ->setEnabled( enabled ); mSpinCutBegin ->setEnabled( enabled ); @@ -1104,7 +1108,8 @@ void LLPanelObject::getState( ) } mComboBaseType->setEnabled(!isMesh); - + mMenuClipboardParams->setEnabled(!isMesh); + if (mCtrlSculptType) { if (sculpt_stitching == LL_SCULPT_TYPE_NONE) @@ -1168,11 +1173,11 @@ void LLPanelObject::sendIsPhysical() LLSelectMgr::getInstance()->selectionUpdatePhysics(value); mIsPhysical = value; - LL_INFOS() << "update physics sent" << LL_ENDL; + LL_INFOS("FloaterTools") << "update physics sent" << LL_ENDL; } else { - LL_INFOS() << "update physics not changed" << LL_ENDL; + LL_INFOS("FloaterTools") << "update physics not changed" << LL_ENDL; } } @@ -1184,11 +1189,11 @@ void LLPanelObject::sendIsTemporary() LLSelectMgr::getInstance()->selectionUpdateTemporary(value); mIsTemporary = value; - LL_INFOS() << "update temporary sent" << LL_ENDL; + LL_INFOS("FloaterTools") << "update temporary sent" << LL_ENDL; } else { - LL_INFOS() << "update temporary not changed" << LL_ENDL; + LL_INFOS("FloaterTools") << "update temporary not changed" << LL_ENDL; } } @@ -1201,11 +1206,11 @@ void LLPanelObject::sendIsPhantom() LLSelectMgr::getInstance()->selectionUpdatePhantom(value); mIsPhantom = value; - LL_INFOS() << "update phantom sent" << LL_ENDL; + LL_INFOS("FloaterTools") << "update phantom sent" << LL_ENDL; } else { - LL_INFOS() << "update phantom not changed" << LL_ENDL; + LL_INFOS("FloaterTools") << "update phantom not changed" << LL_ENDL; } } @@ -1315,7 +1320,7 @@ void LLPanelObject::getVolumeParams(LLVolumeParams& volume_params) break; default: - LL_WARNS() << "Unknown base type " << selected_type + LL_WARNS("FloaterTools") << "Unknown base type " << selected_type << " in getVolumeParams()" << LL_ENDL; // assume a box selected_type = MI_BOX; @@ -2019,7 +2024,13 @@ void LLPanelObject::menuDoToSelected(const LLSD& userdata) std::string command = userdata.asString(); // paste - if (command == "pos_paste") + if (command == "psr_paste") + { + onPastePos(); + onPasteSize(); + onPasteRot(); + } + else if (command == "pos_paste") { onPastePos(); } @@ -2031,7 +2042,17 @@ void LLPanelObject::menuDoToSelected(const LLSD& userdata) { onPasteRot(); } + else if (command == "params_paste") + { + onPasteParams(); + } // copy + else if (command == "psr_copy") + { + onCopyPos(); + onCopySize(); + onCopyRot(); + } else if (command == "pos_copy") { onCopyPos(); @@ -2044,23 +2065,71 @@ void LLPanelObject::menuDoToSelected(const LLSD& userdata) { onCopyRot(); } + else if (command == "params_copy") + { + onCopyParams(); + } } bool LLPanelObject::menuEnableItem(const LLSD& userdata) { std::string command = userdata.asString(); - if (command == "pos_paste") + // paste options + if (command == "psr_paste") + { + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode(LL_PCODE_VOLUME)) + && (selected_count == 1); + + if (!single_volume) + { + return false; + } + + bool enable_move; + bool enable_modify; + + LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(enable_move, enable_modify); + + return enable_move && enable_modify && mHasClipboardPos && mHasClipboardSize && mHasClipboardRot; + } + else if (command == "pos_paste") { - return mHasPosClipboard; + // assumes that menu won't be active if there is no move permission + return mHasClipboardPos; } else if (command == "size_paste") { - return mHasSizeClipboard; + return mHasClipboardSize; } else if (command == "rot_paste") { - return mHasRotClipboard; + return mHasClipboardRot; + } + else if (command == "params_paste") + { + return mHasClipboardParams; + } + // copy options + else if (command == "psr_copy") + { + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + BOOL single_volume = (LLSelectMgr::getInstance()->selectionAllPCode(LL_PCODE_VOLUME)) + && (selected_count == 1); + + if (!single_volume) + { + return false; + } + + bool enable_move; + bool enable_modify; + + LLSelectMgr::getInstance()->selectGetEditMoveLinksetPermissions(enable_move, enable_modify); + + // since we forbid seeing values we also should forbid copying them + return enable_move && enable_modify; } return false; } @@ -2072,7 +2141,7 @@ void LLPanelObject::onCopyPos() std::string stringVec = llformat("<%g, %g, %g>", mClipboardPos.mV[VX], mClipboardPos.mV[VY], mClipboardPos.mV[VZ]); LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec)); - mHasPosClipboard = TRUE; + mHasClipboardPos = true; } void LLPanelObject::onCopySize() @@ -2082,7 +2151,7 @@ void LLPanelObject::onCopySize() std::string stringVec = llformat("<%g, %g, %g>", mClipboardSize.mV[VX], mClipboardSize.mV[VY], mClipboardSize.mV[VZ]); LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec)); - mHasSizeClipboard = TRUE; + mHasClipboardSize = true; } void LLPanelObject::onCopyRot() @@ -2092,12 +2161,12 @@ void LLPanelObject::onCopyRot() std::string stringVec = llformat("<%g, %g, %g>", mClipboardRot.mV[VX], mClipboardRot.mV[VY], mClipboardRot.mV[VZ]); LLView::getWindow()->copyTextToClipboard(utf8str_to_wstring(stringVec)); - mHasRotClipboard = TRUE; + mHasClipboardRot = true; } void LLPanelObject::onPastePos() { - if (!mHasPosClipboard) return; + if (!mHasClipboardPos) return; if (mObject.isNull()) return; LLViewerRegion* regionp = mObject->getRegion(); @@ -2122,26 +2191,118 @@ void LLPanelObject::onPastePos() void LLPanelObject::onPasteSize() { - if (!mHasSizeClipboard) return; + if (!mHasClipboardSize) return; mClipboardSize.mV[VX] = llclamp(mClipboardSize.mV[VX], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE); mClipboardSize.mV[VY] = llclamp(mClipboardSize.mV[VY], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE); mClipboardSize.mV[VZ] = llclamp(mClipboardSize.mV[VZ], MIN_PRIM_SCALE, DEFAULT_MAX_PRIM_SCALE); - mCtrlScaleX->set( mClipboardSize.mV[VX] ); - mCtrlScaleY->set( mClipboardSize.mV[VY] ); - mCtrlScaleZ->set( mClipboardSize.mV[VZ] ); + mCtrlScaleX->set(mClipboardSize.mV[VX]); + mCtrlScaleY->set(mClipboardSize.mV[VY]); + mCtrlScaleZ->set(mClipboardSize.mV[VZ]); sendScale(FALSE); } void LLPanelObject::onPasteRot() { - if (!mHasRotClipboard) return; + if (!mHasClipboardRot) return; - mCtrlRotX->set( mClipboardRot.mV[VX] ); - mCtrlRotY->set( mClipboardRot.mV[VY] ); - mCtrlRotZ->set( mClipboardRot.mV[VZ] ); + mCtrlRotX->set(mClipboardRot.mV[VX]); + mCtrlRotY->set(mClipboardRot.mV[VY]); + mCtrlRotZ->set(mClipboardRot.mV[VZ]); sendRotation(FALSE); } + +void LLPanelObject::onCopyParams() +{ + LLViewerObject* objectp = mObject; + if (!objectp) + { + return; + } + + mClipboardParams.clear(); + + // Parametrics + if (!objectp->isMesh()) + { + LLVolumeParams params; + getVolumeParams(params); + mClipboardParams["volume_params"] = params.asLLSD(); + } + + // Sculpted Prim + if (objectp->getParameterEntryInUse(LLNetworkData::PARAMS_SCULPT)) + { + LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + + if (!objectp->isMesh()) + { + LLUUID texture_id = sculpt_params->getSculptTexture(); + if (get_can_copy_texture(texture_id)) + { + LL_DEBUGS("FloaterTools") << "Recording texture" << LL_ENDL; + mClipboardParams["sculpt"]["id"] = texture_id; + } + else + { + mClipboardParams["sculpt"]["id"] = LLUUID(SCULPT_DEFAULT_TEXTURE); + } + + mClipboardParams["sculpt"]["type"] = sculpt_params->getSculptType(); + } + } + + mHasClipboardParams = TRUE; +} + +void LLPanelObject::onPasteParams() +{ + LLViewerObject* objectp = mObject; + if (!objectp || !mHasClipboardParams) + { + return; + } + + // Sculpted Prim + if (mClipboardParams.has("sculpt")) + { + LLSculptParams sculpt_params; + LLUUID sculpt_id = mClipboardParams["sculpt"]["id"].asUUID(); + U8 sculpt_type = (U8)mClipboardParams["sculpt"]["type"].asInteger(); + sculpt_params.setSculptTexture(sculpt_id, sculpt_type); + objectp->setParameterEntry(LLNetworkData::PARAMS_SCULPT, sculpt_params, TRUE); + } + else + { + LLSculptParams *sculpt_params = (LLSculptParams *)objectp->getParameterEntry(LLNetworkData::PARAMS_SCULPT); + if (sculpt_params) + { + objectp->setParameterEntryInUse(LLNetworkData::PARAMS_SCULPT, FALSE, TRUE); + } + } + + // volume params + // make sure updateVolume() won't affect flexible + if (mClipboardParams.has("volume_params")) + { + LLVolumeParams params; + params.fromLLSD(mClipboardParams["volume_params"]); + LLVOVolume *volobjp = (LLVOVolume *)objectp; + if (volobjp->isFlexible()) + { + if (params.getPathParams().getCurveType() == LL_PCODE_PATH_LINE) + { + params.getPathParams().setCurveType(LL_PCODE_PATH_FLEXIBLE); + } + } + else if (params.getPathParams().getCurveType() == LL_PCODE_PATH_FLEXIBLE) + { + params.getPathParams().setCurveType(LL_PCODE_PATH_LINE); + } + + objectp->updateVolume(params); + } +} diff --git a/indra/newview/llpanelobject.h b/indra/newview/llpanelobject.h index 764c0d8af4..5ea3d07699 100644 --- a/indra/newview/llpanelobject.h +++ b/indra/newview/llpanelobject.h @@ -73,6 +73,8 @@ public: void onPasteSize(); void onCopyRot(); void onPasteRot(); + void onCopyParams(); + void onPasteParams(); static void onCommitParametric(LLUICtrl* ctrl, void* userdata); @@ -102,6 +104,7 @@ protected: protected: // Per-object options LLComboBox* mComboBaseType; + LLMenuButton* mMenuClipboardParams; LLTextBox* mLabelCut; LLSpinCtrl* mSpinCutBegin; @@ -183,10 +186,12 @@ protected: LLVector3 mClipboardPos; LLVector3 mClipboardSize; LLVector3 mClipboardRot; + LLSD mClipboardParams; - BOOL mHasPosClipboard; - BOOL mHasSizeClipboard; - BOOL mHasRotClipboard; + bool mHasClipboardPos; + bool mHasClipboardSize; + bool mHasClipboardRot; + bool mHasClipboardParams; LLPointer mObject; LLPointer mRootObject; diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 6a0464c657..2f5be2b32e 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -79,6 +79,61 @@ static const S32 LOCAL_TRACKING_ID_COLUMN = 1; //static const char WHITE_IMAGE_NAME[] = "Blank Texture"; //static const char NO_IMAGE_NAME[] = "None"; + + +//static +bool get_is_library_texture(LLUUID image_id) +{ + if (gInventory.isObjectDescendentOf(image_id, gInventory.getLibraryRootFolderID()) + || image_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture")) + || image_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID")) + || image_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")) + || image_id == LLUUID(SCULPT_DEFAULT_TEXTURE)) + { + return true; + } + return false; +} + +LLUUID get_copy_free_item_by_asset_id(LLUUID image_id) +{ + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLAssetIDMatches asset_id_matches(image_id); + gInventory.collectDescendentsIf(LLUUID::null, + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + asset_id_matches); + if (items.size()) + { + for (S32 i = 0; i < items.size(); i++) + { + LLViewerInventoryItem* itemp = items[i]; + if (itemp) + { + LLPermissions item_permissions = itemp->getPermissions(); + if (item_permissions.allowOperationBy(PERM_COPY, + gAgent.getID(), + gAgent.getGroupID())) + { + return itemp->getUUID(); + } + } + } + } + return LLUUID::null; +} + +bool get_can_copy_texture(LLUUID image_id) +{ + // User is allowed to copy a texture if: + // library asset or default texture, + // or copy perm asset exists in user's inventory + + return get_is_library_texture(image_id) || get_copy_free_item_by_asset_id(image_id).notNull(); +} + LLFloaterTexturePicker::LLFloaterTexturePicker( LLView* owner, LLUUID image_asset_id, diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index b2a34a37c4..2b2c5fa237 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -53,6 +53,16 @@ class LLViewerFetchedTexture; typedef boost::function drag_n_drop_callback; typedef boost::function texture_selected_callback; +// Helper functions for UI that work with picker +bool get_is_library_texture(LLUUID image_id); + +// texture picker works by asset ids since objects normaly do +// not retain inventory ids as result these functions are looking +// for textures in inventory by asset ids +// This search can be performance unfriendly and doesn't warranty +// that the texture is original source of asset +LLUUID get_copy_free_item_by_asset_id(LLUUID image_id); +bool get_can_copy_texture(LLUUID image_id); ////////////////////////////////////////////////////////////////////////////////////////// // LLTextureCtrl diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png new file mode 100644 index 0000000000..9a81c5f94b Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ClipboardMenu_Disabled.png differ diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png new file mode 100644 index 0000000000..88012cf8d1 Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ClipboardMenu_Off.png differ diff --git a/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png b/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png new file mode 100644 index 0000000000..ab02e7d42d Binary files /dev/null and b/indra/newview/skins/default/textures/icons/ClipboardMenu_Press.png differ diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index b7fa1e72f8..473b074213 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -441,6 +441,9 @@ with the same filename but different name + + + diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index afc6155585..0b2b1abeb9 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -1436,7 +1436,7 @@ even though the user gets a free copy. height="0" layout="topleft" left_delta="0" - name="lod_tab_border" + name="object_horizontal" top_pad="10" width="95" /> Prim Type --> + + + width="125"> + Path Cut (begin/end) diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_generic.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_generic.xml new file mode 100644 index 0000000000..8e016e4a1c --- /dev/null +++ b/indra/newview/skins/default/xui/en/menu_copy_paste_generic.xml @@ -0,0 +1,21 @@ + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml index c2763af603..3ea95b281f 100644 --- a/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml +++ b/indra/newview/skins/default/xui/en/menu_copy_paste_pos.xml @@ -3,19 +3,35 @@ layout="topleft" name="Copy Paste Position Menu"> + + + + - + + + + + - - + + diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml index dcfb3faeca..06ce80f897 100644 --- a/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml +++ b/indra/newview/skins/default/xui/en/menu_copy_paste_rot.xml @@ -3,19 +3,35 @@ layout="topleft" name="Copy Paste Rotation Menu"> + + + + - + + + + + - - + + diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml index 58d71b12d5..7082a0e65b 100644 --- a/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml +++ b/indra/newview/skins/default/xui/en/menu_copy_paste_size.xml @@ -3,19 +3,35 @@ layout="topleft" name="Copy Paste Size Menu"> + + + + - + + + + + - - + + -- cgit v1.3 From 15f02e2da231827a7cac18a2444c212efc8c1d1c Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 19 Jun 2020 17:34:57 +0300 Subject: SL-13359 #8 Reverted changes to texture tab This reverts commit 1e1707d532560583744bb877adfed11864f2db31. --- indra/newview/llpanelface.cpp | 659 +-------------------- indra/newview/llpanelface.h | 29 +- .../skins/default/xui/en/menu_texture_paste.xml | 70 --- .../skins/default/xui/en/panel_tools_texture.xml | 55 +- 4 files changed, 16 insertions(+), 797 deletions(-) delete mode 100644 indra/newview/skins/default/xui/en/menu_texture_paste.xml (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 6e99a10b98..778cb77309 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -38,7 +38,6 @@ #include "llfontgl.h" // project includes -#include "llagent.h" // gAgent #include "llagentdata.h" #include "llbutton.h" #include "llcheckboxctrl.h" @@ -46,13 +45,9 @@ #include "llcombobox.h" #include "lldrawpoolbump.h" #include "llface.h" -#include "llinventoryfunctions.h" -#include "llinventorymodel.h" // gInventory -#include "llinventorymodelbackgroundfetch.h" #include "lllineeditor.h" #include "llmaterialmgr.h" #include "llmediaentry.h" -#include "llmenubutton.h" #include "llnotificationsutil.h" #include "llradiogroup.h" #include "llresmgr.h" @@ -305,18 +300,7 @@ BOOL LLPanelFace::postBuild() { mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this); } - - mBtnCopyFaces = getChild("copy_face_btn"); - if(mBtnCopyFaces) - { - mBtnCopyFaces->setCommitCallback(boost::bind(&LLPanelFace::onCopyFaces, this)); - } - mBtnPasteFaces = getChild("paste_face_btn"); - if (mBtnPasteFaces) - { - mBtnPasteFaces->setCommitCallback(boost::bind(&LLPanelFace::onPasteFaces, this)); - } - mBtnPasteMenu = getChild("paste_face_gear_btn"); + clearCtrls(); @@ -325,22 +309,9 @@ BOOL LLPanelFace::postBuild() LLPanelFace::LLPanelFace() : LLPanel(), - mIsAlpha(false), - mPasteColor(TRUE), - mPasteAlpha(TRUE), - mPasteGlow(TRUE), - mPasteDiffuse(TRUE), - mPasteNormal(TRUE), - mPasteSpecular(TRUE), - mPasteMapping(TRUE), - mPasteMedia(TRUE), - mPopulateAllTEs(TRUE) + mIsAlpha(false) { USE_TEXTURE = LLTrans::getString("use_texture"); - - mEnableCallbackRegistrar.add("BuildFace.PasteCheckItem", boost::bind(&LLPanelFace::pasteCheckMenuItem, this, _2)); - mCommitCallbackRegistrar.add("BuildFace.PasteDoToSelected", boost::bind(&LLPanelFace::pasteDoMenuItem, this, _2)); - mEnableCallbackRegistrar.add("BuildFace.PasteEnable", boost::bind(&LLPanelFace::pasteEnabletMenuItem, this, _2)); } @@ -1566,12 +1537,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } } - S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); - BOOL single_volume = (selected_count == 1); - mBtnCopyFaces->setEnabled(editable && single_volume); - mBtnPasteFaces->setEnabled(editable && (mClipboard.size() > 0)); - mBtnPasteMenu->setEnabled(editable); - // Set variable values for numeric expressions LLCalc* calcp = LLCalc::getInstance(); calcp->setVar(LLCalc::TEX_U_SCALE, childGetValue("TexScaleU").asReal()); @@ -1772,6 +1737,8 @@ void LLPanelFace::updateVisibility() getChildView("bumpyRot")->setVisible(show_bumpiness); getChildView("bumpyOffsetU")->setVisible(show_bumpiness); getChildView("bumpyOffsetV")->setVisible(show_bumpiness); + + } // static @@ -2885,621 +2852,3 @@ void LLPanelFace::LLSelectedTE::getMaxDiffuseRepeats(F32& repeats, bool& identic } max_diff_repeats_func; identical = LLSelectMgr::getInstance()->getSelection()->getSelectedTEValue( &max_diff_repeats_func, repeats ); } - -static LLSD texture_clipboard; - -void LLPanelFace::onCopyFaces() -{ - LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); - LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); - S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); - if( !objectp || !node - || objectp->getPCode() != LL_PCODE_VOLUME - || !objectp->permModify() - || objectp->isPermanentEnforced() - || selected_count > 1) - { - return; - } - - mClipboard.clear(); - std::map asset_item_map; - - S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); - mPopulateAllTEs = (num_tes != 1) || (LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()); - for (S32 te = 0; te < num_tes; ++te) - { - if (node->isTESelected(te)) - { - LLTextureEntry* tep = objectp->getTE(te); - if (tep) - { - LLSD te_data; - - // asLLSD() includes media - te_data["te"] = tep->asLLSD(); - te_data["te"]["glow"] = tep->getGlow(); - te_data["te"]["shiny"] = tep->getShiny(); - te_data["te"]["bumpmap"] = tep->getBumpmap(); - te_data["te"]["bumpshiny"] = tep->getBumpShiny(); - te_data["te"]["bumpfullbright"] = tep->getBumpShinyFullbright(); - - if (te_data["te"].has("imageid")) - { - LLUUID item_id; - LLUUID id = te_data["te"]["imageid"].asUUID(); - bool full_perm = get_is_library_texture(id) || (objectp->permCopy() && objectp->permTransfer() && objectp->permModify()); - - if (id.notNull() && !full_perm) - { - std::map::iterator iter = asset_item_map.find(id); - if (iter != asset_item_map.end()) - { - item_id = iter->second; - } - else - { - // What this does is simply searches inventory for item with same asset id, - // as result it is Hightly unreliable, leaves little control to user, borderline hack - // but there are little options to preserve permissions - multiple inventory - // items might reference same asset and inventory search is expensive. - item_id = get_copy_free_item_by_asset_id(id); - // record value to avoid repeating inventory search when possible - asset_item_map[id] = item_id; - } - } - - if (id.isNull() - || (!full_perm && item_id.isNull())) - { - if (!LLLocalBitmapMgr::getInstance()->isLocal(id)) - { - te_data["te"].erase("imageid"); - te_data["te"]["imageid"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); - } - te_data["te"]["itemfullperm"] = true; - } - else - { - te_data["te"]["itemfullperm"] = full_perm; - // If full permission object, texture is free to copy, - // but otherwise we need to check inventory and extract permissions - // - // Normally we care only about restrictions for current user and objects - // don't inherit any 'next owner' permissions from texture, so there is - // no need to record item id if full_perm==true - if (!full_perm && item_id.notNull()) - { - LLViewerInventoryItem* itemp = gInventory.getItem(item_id); - if (itemp) - { - LLPermissions item_permissions = itemp->getPermissions(); - if (item_permissions.allowOperationBy(PERM_COPY, - gAgent.getID(), - gAgent.getGroupID())) - { - te_data["te"]["imageitemid"] = item_id; - te_data["te"]["itemfullperm"] = itemp->getIsFullPerm(); - if (!itemp->isFinished()) - { - // needed for dropTextureAllFaces - LLInventoryModelBackgroundFetch::instance().start(item_id, false); - } - } - } - } - } - } - - LLMaterialPtr material_ptr = tep->getMaterialParams(); - if (!material_ptr.isNull()) - { - LLSD mat_data; - - mat_data["NormMap"] = material_ptr->getNormalID(); - mat_data["SpecMap"] = material_ptr->getSpecularID(); - - mat_data["NormRepX"] = material_ptr->getNormalRepeatX(); - mat_data["NormRepY"] = material_ptr->getNormalRepeatY(); - mat_data["NormOffX"] = material_ptr->getNormalOffsetX(); - mat_data["NormOffY"] = material_ptr->getNormalOffsetY(); - mat_data["NormRot"] = material_ptr->getNormalRotation(); - - mat_data["SpecRepX"] = material_ptr->getSpecularRepeatX(); - mat_data["SpecRepY"] = material_ptr->getSpecularRepeatY(); - mat_data["SpecOffX"] = material_ptr->getSpecularOffsetX(); - mat_data["SpecOffY"] = material_ptr->getSpecularOffsetY(); - mat_data["SpecRot"] = material_ptr->getSpecularRotation(); - - mat_data["SpecColor"] = material_ptr->getSpecularLightColor().getValue(); - mat_data["SpecExp"] = material_ptr->getSpecularLightExponent(); - mat_data["EnvIntensity"] = material_ptr->getEnvironmentIntensity(); - mat_data["AlphaMaskCutoff"] = material_ptr->getAlphaMaskCutoff(); - mat_data["DiffuseAlphaMode"] = material_ptr->getDiffuseAlphaMode(); - - // Replace no-copy textures, destination texture will get used instead if available - if (mat_data.has("NormMap")) - { - LLUUID id = mat_data["NormMap"].asUUID(); - if (id.notNull() && !get_can_copy_texture(id)) - { - mat_data["NormMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); - mat_data["NormMapNoCopy"] = true; - } - - } - if (mat_data.has("SpecMap")) - { - LLUUID id = mat_data["SpecMap"].asUUID(); - if (id.notNull() && !get_can_copy_texture(id)) - { - mat_data["SpecMap"] = LLUUID(gSavedSettings.getString( "DefaultObjectTexture" )); - mat_data["SpecMapNoCopy"] = true; - } - - } - - te_data["material"] = mat_data; - } - - mClipboard.append(te_data); - } - } - } -} - -void LLPanelFace::pasteFace(LLViewerObject* objectp, S32 te) -{ - LLSD te_data; - if ((mClipboard.size() == 1) && mPopulateAllTEs) - { - te_data = *(mClipboard.beginArray()); - } - else if (mClipboard[te]) - { - te_data = mClipboard[te]; - } - else - { - return; - } - - LLTextureEntry* tep = objectp->getTE(te); - if (tep) - { - if (te_data.has("te")) - { - // Texture - bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean(); - if (mPasteDiffuse && te_data["te"].has("imageid")) - { - const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); //texture or asset id - LLViewerInventoryItem* itemp_res = NULL; - - if (te_data["te"].has("imageitemid")) - { - LLUUID item_id = te_data["te"]["imageitemid"].asUUID(); - if (item_id.notNull()) - { - LLViewerInventoryItem* itemp = gInventory.getItem(item_id); - if (itemp && itemp->isFinished()) - { - // dropTextureAllFaces will fail if incomplete - itemp_res = itemp; - } - } - } - - // for case when item got removed from inventory after we pressed 'copy' - if (!itemp_res && !full_perm) - { - // todo: fix this, we are often searching same tuxter multiple times (equal to number of faces) - LLViewerInventoryCategory::cat_array_t cats; - LLViewerInventoryItem::item_array_t items; - LLAssetIDMatches asset_id_matches(imageid); - gInventory.collectDescendentsIf(LLUUID::null, - cats, - items, - LLInventoryModel::INCLUDE_TRASH, - asset_id_matches); - - // Extremely unreliable and perfomance unfriendly. - // But we need this to check permissions and it is how texture control finds items - for (S32 i = 0; i < items.size(); i++) - { - LLViewerInventoryItem* itemp = items[i]; - if (itemp && itemp->isFinished()) - { - // dropTextureAllFaces will fail if incomplete - LLPermissions item_permissions = itemp->getPermissions(); - if (item_permissions.allowOperationBy(PERM_COPY, - gAgent.getID(), - gAgent.getGroupID())) - { - itemp_res = itemp; - break; // first match - } - } - } - } - - if (itemp_res) - { - if (te == -1) // all faces - { - LLToolDragAndDrop::dropTextureAllFaces(objectp, - itemp_res, - LLToolDragAndDrop::SOURCE_AGENT, - LLUUID::null); - } - else // one face - { - LLToolDragAndDrop::dropTextureOneFace(objectp, - te, - itemp_res, - LLToolDragAndDrop::SOURCE_AGENT, - LLUUID::null); - } - } - // not an inventory item or no complete items - else if (full_perm) - { - // Either library, local or existed as fullperm when user made a copy - LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); - objectp->setTEImage(U8(te), image); - } - } - - // Color / Alpha - if ((mPasteColor || mPasteAlpha) && te_data["te"].has("colors")) - { - LLColor4 color = tep->getColor(); - - LLColor4 clip_color; - clip_color.setValue(te_data["te"]["colors"]); - - // Color - if (mPasteColor) - { - color.mV[VRED] = clip_color.mV[VRED]; - color.mV[VGREEN] = clip_color.mV[VGREEN]; - color.mV[VBLUE] = clip_color.mV[VBLUE]; - } - - // Alpha - if (mPasteAlpha) - { - color.mV[VALPHA] = clip_color.mV[VALPHA]; - } - - objectp->setTEColor(te, color); - } - - if (mPasteColor && te_data["te"].has("fullbright")) - { - objectp->setTEFullbright(te, te_data["te"]["fullbright"].asInteger()); - } - - - // Glow - if (mPasteGlow && te_data["te"].has("glow")) - { - objectp->setTEGlow(te, (F32)te_data["te"]["glow"].asReal()); - } - - if (mPasteNormal && te_data["te"].has("bumpmap")) - { - objectp->setTEBumpmap(te, (U8)te_data["te"]["bumpmap"].asInteger()); - } - if (mPasteSpecular && te_data["te"].has("bumpshiny")) - { - objectp->setTEBumpShiny(te, (U8)te_data["te"]["bumpshiny"].asInteger()); - } - if (mPasteSpecular && te_data["te"].has("bumpfullbright")) - { - objectp->setTEBumpShinyFullbright(te, (U8)te_data["te"]["bumpfullbright"].asInteger()); - } - - // Texture map - if (mPasteMapping) - { - if (te_data["te"].has("scales") && te_data["te"].has("scalet")) - { - objectp->setTEScale(te, (F32)te_data["te"]["scales"].asReal(), (F32)te_data["te"]["scalet"].asReal()); - } - if (te_data["te"].has("offsets") && te_data["te"].has("offsett")) - { - objectp->setTEOffset(te, (F32)te_data["te"]["offsets"].asReal(), (F32)te_data["te"]["offsett"].asReal()); - } - if (te_data["te"].has("imagerot")) - { - objectp->setTERotation(te, (F32)te_data["te"]["imagerot"].asReal()); - } - } - - // Media - if (mPasteMedia && te_data["te"].has("media_flags")) - { - U8 media_flags = te_data["te"]["media_flags"].asInteger(); - objectp->setTEMediaFlags(te, media_flags); - LLVOVolume *vo = dynamic_cast(objectp); - if (vo && te_data["te"].has(LLTextureEntry::TEXTURE_MEDIA_DATA_KEY)) - { - vo->syncMediaData(te, te_data["te"][LLTextureEntry::TEXTURE_MEDIA_DATA_KEY], true/*merge*/, true/*ignore_agent*/); - } - } - else - { - // Keep media flags on destination unchanged - } - } - - if (te_data.has("material")) - { - LLUUID object_id = objectp->getID(); - - LLSelectedTEMaterial::setAlphaMaskCutoff(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id); - - if (mPasteNormal) - { - // Replace placeholders with target's - if (te_data["material"].has("NormMapNoCopy")) - { - LLMaterialPtr material = tep->getMaterialParams(); - if (material.notNull()) - { - LLUUID id = material->getNormalID(); - if (id.notNull()) - { - te_data["material"]["NormMap"] = id; - } - } - } - LLSelectedTEMaterial::setNormalID(this, te_data["material"]["NormMap"].asUUID(), te, object_id); - LLSelectedTEMaterial::setNormalRepeatX(this, (F32)te_data["material"]["NormRepX"].asReal(), te, object_id); - LLSelectedTEMaterial::setNormalRepeatY(this, (F32)te_data["material"]["NormRepY"].asReal(), te, object_id); - LLSelectedTEMaterial::setNormalOffsetX(this, (F32)te_data["material"]["NormOffX"].asReal(), te, object_id); - LLSelectedTEMaterial::setNormalOffsetY(this, (F32)te_data["material"]["NormOffY"].asReal(), te, object_id); - LLSelectedTEMaterial::setNormalRotation(this, (F32)te_data["material"]["NormRot"].asReal(), te, object_id); - } - - if (mPasteSpecular) - { - // Replace placeholders with target's - if (te_data["material"].has("SpecMapNoCopy")) - { - LLMaterialPtr material = tep->getMaterialParams(); - if (material.notNull()) - { - LLUUID id = material->getSpecularID(); - if (id.notNull()) - { - te_data["material"]["SpecMap"] = id; - } - } - } - LLSelectedTEMaterial::setSpecularID(this, te_data["material"]["SpecMap"].asUUID(), te, object_id); - LLSelectedTEMaterial::setSpecularRepeatX(this, (F32)te_data["material"]["SpecRepX"].asReal(), te, object_id); - LLSelectedTEMaterial::setSpecularRepeatY(this, (F32)te_data["material"]["SpecRepY"].asReal(), te, object_id); - LLSelectedTEMaterial::setSpecularOffsetX(this, (F32)te_data["material"]["SpecOffX"].asReal(), te, object_id); - LLSelectedTEMaterial::setSpecularOffsetY(this, (F32)te_data["material"]["SpecOffY"].asReal(), te, object_id); - LLSelectedTEMaterial::setSpecularRotation(this, (F32)te_data["material"]["SpecRot"].asReal(), te, object_id); - LLColor4 spec_color(te_data["material"]["SpecColor"]); - LLSelectedTEMaterial::setSpecularLightColor(this, spec_color, te); - LLSelectedTEMaterial::setSpecularLightExponent(this, (U8)te_data["material"]["SpecExp"].asInteger(), te, object_id); - LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te, object_id); - LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id); - if (te_data.has("te") && te_data["te"].has("shiny")) - { - objectp->setTEShiny(te, (U8)te_data["te"]["shiny"].asInteger()); - } - } - } - } -} - -struct LLPanelFacePasteTexFunctor : public LLSelectedTEFunctor -{ - LLPanelFacePasteTexFunctor(LLPanelFace* panel) : - mPanelFace(panel){} - - virtual bool apply(LLViewerObject* objectp, S32 te) - { - mPanelFace->pasteFace(objectp, te); - return true; - } -private: - LLPanelFace *mPanelFace; -}; - -struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor -{ - LLPanelFaceUpdateFunctor(bool update_media) : mUpdateMedia(update_media) {} - virtual bool apply(LLViewerObject* object) - { - object->sendTEUpdate(); - if (mUpdateMedia) - { - LLVOVolume *vo = dynamic_cast(object); - if (vo && vo->hasMedia()) - { - vo->sendMediaDataUpdate(); - } - } - return true; - } -private: - bool mUpdateMedia; -}; - -struct LLPanelFaceNavigateHomeFunctor : public LLSelectedTEFunctor -{ - virtual bool apply(LLViewerObject* objectp, S32 te) - { - if (objectp && objectp->getTE(te)) - { - LLTextureEntry* tep = objectp->getTE(te); - const LLMediaEntry *media_data = tep->getMediaData(); - if (media_data) - { - if (media_data->getCurrentURL().empty() && media_data->getAutoPlay()) - { - viewer_media_t media_impl = - LLViewerMedia::getInstance()->getMediaImplFromTextureID(tep->getMediaData()->getMediaID()); - if (media_impl) - { - media_impl->navigateHome(); - } - } - } - } - return true; - } -}; - -void LLPanelFace::onPasteFaces() -{ - LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); - - LLPanelFacePasteTexFunctor paste_func(this); - selected_objects->applyToTEs(&paste_func); - - LLPanelFaceUpdateFunctor sendfunc(mPasteMedia); - selected_objects->applyToObjects(&sendfunc); - - if (mPasteMedia) - { - LLPanelFaceNavigateHomeFunctor navigate_home_func; - selected_objects->applyToTEs(&navigate_home_func); - } -} - -bool LLPanelFace::pasteCheckMenuItem(const LLSD& userdata) -{ - std::string command = userdata.asString(); - - if ("Color" == command) - { - return mPasteColor; - } - if ("Transparency" == command) - { - return mPasteAlpha; - } - if ("Glow" == command) - { - return mPasteGlow; - } - if ("Diffuse" == command) - { - return mPasteDiffuse; - } - if ("Normal" == command) - { - return mPasteNormal; - } - if ("Specular" == command) - { - return mPasteSpecular; - } - if ("Mapping" == command) - { - return mPasteMapping; - } - if ("Media" == command) - { - return mPasteMedia; - } - - return false; -} - -void LLPanelFace::pasteDoMenuItem(const LLSD& userdata) -{ - std::string command = userdata.asString(); - - if ("Color" == command) - { - mPasteColor = !mPasteColor; - } - if ("Transparency" == command) - { - mPasteAlpha = !mPasteAlpha; - } - if ("Glow" == command) - { - mPasteGlow = !mPasteGlow; - } - if ("Diffuse" == command) - { - mPasteDiffuse = !mPasteDiffuse; - } - if ("Normal" == command) - { - mPasteNormal = !mPasteNormal; - } - if ("Specular" == command) - { - mPasteSpecular = !mPasteSpecular; - } - if ("Mapping" == command) - { - mPasteMapping = !mPasteMapping; - } - if ("Media" == command) - { - mPasteMedia = !mPasteMedia; - } -} - -bool LLPanelFace::pasteEnabletMenuItem(const LLSD& userdata) -{ - std::string command = userdata.asString(); - - // Keep at least one option enabled - S32 num_enabled = mPasteColor - + mPasteAlpha - + mPasteGlow - + mPasteDiffuse - + mPasteNormal - + mPasteSpecular - + mPasteMapping - + mPasteMedia; - if ( num_enabled == 1) - { - if ("Color" == command && mPasteColor) - { - return false; - } - if ("Transparency" == command && mPasteAlpha) - { - return false; - } - if ("Glow" == command && mPasteGlow) - { - return false; - } - if ("Diffuse" == command && mPasteDiffuse) - { - return false; - } - if ("Normal" == command && mPasteNormal) - { - return false; - } - if ("Specular" == command && mPasteSpecular) - { - return false; - } - if ("Mapping" == command && mPasteMapping) - { - return false; - } - if ("Media" == command && mPasteMedia) - { - return false; - } - } - - return true; -} diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 770f10e2ee..2d57d89a44 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -47,7 +47,6 @@ class LLUICtrl; class LLViewerObject; class LLFloater; class LLMaterialID; -class LLMenuButton; // Represents an edit for use in replicating the op across one or more materials in the selection set. // @@ -114,8 +113,6 @@ public: LLRender::eTexIndex getTextureChannelToEdit(); - void pasteFace(LLViewerObject* object, S32 te); - protected: void getState(); @@ -208,14 +205,10 @@ protected: static void onClickAutoFix(void*); static void onAlignTexture(void*); - void onCopyFaces(); - void onPasteFaces(); - bool pasteCheckMenuItem(const LLSD& userdata); - void pasteDoMenuItem(const LLSD& userdata); - bool pasteEnabletMenuItem(const LLSD& userdata); - static F32 valueGlow(LLViewerObject* object, S32 face); + + private: bool isAlpha() { return mIsAlpha; } @@ -241,22 +234,6 @@ private: F32 getCurrentShinyOffsetU(); F32 getCurrentShinyOffsetV(); - LLButton *mBtnCopyFaces; - LLButton *mBtnPasteFaces; - LLMenuButton *mBtnPasteMenu; - - LLSD mClipboard; - BOOL mPasteColor; - BOOL mPasteAlpha; - BOOL mPasteGlow; - BOOL mPasteDiffuse; - BOOL mPasteNormal; - BOOL mPasteSpecular; - BOOL mPasteMapping; - BOOL mPasteMedia; - - BOOL mPopulateAllTEs; - // Update visibility of controls to match current UI mode // (e.g. materials vs media editing) // @@ -520,8 +497,6 @@ public: DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID); DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID); DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor); - - DEF_EDIT_MAT_STATE(LLSD, const LLSD&, fromLLSD); }; class LLSelectedTE diff --git a/indra/newview/skins/default/xui/en/menu_texture_paste.xml b/indra/newview/skins/default/xui/en/menu_texture_paste.xml deleted file mode 100644 index be6535b989..0000000000 --- a/indra/newview/skins/default/xui/en/menu_texture_paste.xml +++ /dev/null @@ -1,70 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index 1819106970..438fb1e8ed 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -43,7 +43,7 @@ follows="left|top" height="10" layout="topleft" - left_pad="10" + left_pad="15" name="color trans" text_readonly_color="LabelDisabledColor" top="6" @@ -68,7 +68,7 @@ follows="left|top" height="10" layout="topleft" - left_pad="13" + left_pad="15" name="glow label" text_readonly_color="LabelDisabledColor" top="6" @@ -84,7 +84,7 @@ left_delta="0" name="glow" top_pad="4" - width="50" /> + width="80" /> - - - - + Date: Fri, 19 Jun 2020 22:18:31 +0300 Subject: SL-13359 #9 Texture tab --- indra/newview/llpanelface.cpp | 633 ++++++++++++++++++++- indra/newview/llpanelface.h | 20 +- indra/newview/llpanelvolume.cpp | 3 - .../newview/skins/default/xui/en/floater_tools.xml | 6 +- .../skins/default/xui/en/menu_copy_paste_color.xml | 21 + .../default/xui/en/menu_copy_paste_features.xml | 2 +- .../skins/default/xui/en/menu_copy_paste_light.xml | 2 +- .../default/xui/en/menu_copy_paste_object.xml | 2 +- .../default/xui/en/menu_copy_paste_texture.xml | 21 + .../skins/default/xui/en/panel_tools_texture.xml | 51 +- 10 files changed, 740 insertions(+), 21 deletions(-) create mode 100644 indra/newview/skins/default/xui/en/menu_copy_paste_color.xml create mode 100644 indra/newview/skins/default/xui/en/menu_copy_paste_texture.xml (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 778cb77309..6b5d14300f 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -45,9 +45,11 @@ #include "llcombobox.h" #include "lldrawpoolbump.h" #include "llface.h" +#include "llinventorymodel.h" // gInventory #include "lllineeditor.h" #include "llmaterialmgr.h" #include "llmediaentry.h" +#include "llmenubutton.h" #include "llnotificationsutil.h" #include "llradiogroup.h" #include "llresmgr.h" @@ -300,7 +302,9 @@ BOOL LLPanelFace::postBuild() { mCtrlGlow->setCommitCallback(LLPanelFace::onCommitGlow, this); } - + + mMenuClipboardColor = getChild("clipboard_color_params_btn"); + mMenuClipboardTexture = getChild("clipboard_texture_params_btn"); clearCtrls(); @@ -311,7 +315,9 @@ LLPanelFace::LLPanelFace() : LLPanel(), mIsAlpha(false) { - USE_TEXTURE = LLTrans::getString("use_texture"); + USE_TEXTURE = LLTrans::getString("use_texture"); + mCommitCallbackRegistrar.add("PanelFace.menuDoToSelected", boost::bind(&LLPanelFace::menuDoToSelected, this, _2)); + mEnableCallbackRegistrar.add("PanelFace.menuEnable", boost::bind(&LLPanelFace::menuEnableItem, this, _2)); } @@ -1536,6 +1542,10 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } } } + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + BOOL single_volume = (selected_count == 1); + mMenuClipboardColor->setEnabled(editable && single_volume); + mMenuClipboardTexture->setEnabled(editable && single_volume); // Set variable values for numeric expressions LLCalc* calcp = LLCalc::getInstance(); @@ -2566,6 +2576,625 @@ void LLPanelFace::onAlignTexture(void* userdata) self->alignTestureLayer(); } +void LLPanelFace::onCopyColor() +{ + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + if (!objectp || !node + || objectp->getPCode() != LL_PCODE_VOLUME + || !objectp->permModify() + || objectp->isPermanentEnforced() + || selected_count > 1) + { + return; + } + + if (mClipboardParams.has("color")) + { + mClipboardParams["color"].clear(); + } + else + { + mClipboardParams["color"] = LLSD::emptyArray(); + } + + std::map asset_item_map; + + // a way to resolve situations where source and target have different amount of faces + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + mClipboardParams["color_all_tes"] = (num_tes != 1) || (LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()); + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + LLTextureEntry* tep = objectp->getTE(te); + if (tep) + { + LLSD te_data; + + // asLLSD() includes media + te_data["te"] = tep->asLLSD(); // Note: includes a lot more than just color/alpha/glow + + mClipboardParams["color"].append(te_data); + } + } + } +} + +void LLPanelFace::onPasteColor(LLViewerObject* objectp, S32 te) +{ + if (!mClipboardParams.has("color")) + { + return; + } + LLSD te_data; + LLSD &clipboard = mClipboardParams["color"]; // array + if ((clipboard.size() == 1) && mClipboardParams["color_all_tes"].asBoolean()) + { + te_data = *(clipboard.beginArray()); + } + else if (clipboard[te]) + { + te_data = clipboard[te]; + } + else + { + return; + } + + LLTextureEntry* tep = objectp->getTE(te); + if (tep) + { + if (te_data.has("te")) + { + // Color / Alpha + if (te_data["te"].has("colors")) + { + LLColor4 color = tep->getColor(); + + LLColor4 clip_color; + clip_color.setValue(te_data["te"]["colors"]); + + // Color + color.mV[VRED] = clip_color.mV[VRED]; + color.mV[VGREEN] = clip_color.mV[VGREEN]; + color.mV[VBLUE] = clip_color.mV[VBLUE]; + + // Alpha + color.mV[VALPHA] = clip_color.mV[VALPHA]; + + objectp->setTEColor(te, color); + } + + // Color/fullbright + if (te_data["te"].has("fullbright")) + { + objectp->setTEFullbright(te, te_data["te"]["fullbright"].asInteger()); + } + + // Glow + if (te_data["te"].has("glow")) + { + objectp->setTEGlow(te, (F32)te_data["te"]["glow"].asReal()); + } + } + } +} + +void LLPanelFace::onCopyTexture() +{ + + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + if (!objectp || !node + || objectp->getPCode() != LL_PCODE_VOLUME + || !objectp->permModify() + || objectp->isPermanentEnforced() + || selected_count > 1) + { + return; + } + + if (mClipboardParams.has("texture")) + { + mClipboardParams["texture"].clear(); + } + else + { + mClipboardParams["texture"] = LLSD::emptyArray(); + } + + std::map asset_item_map; + + // a way to resolve situations where source and target have different amount of faces + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + mClipboardParams["texture_all_tes"] = (num_tes != 1) || (LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool()); + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + LLTextureEntry* tep = objectp->getTE(te); + if (tep) + { + LLSD te_data; + + // asLLSD() includes media + te_data["te"] = tep->asLLSD(); + te_data["te"]["shiny"] = tep->getShiny(); + te_data["te"]["bumpmap"] = tep->getBumpmap(); + te_data["te"]["bumpshiny"] = tep->getBumpShiny(); + te_data["te"]["bumpfullbright"] = tep->getBumpShinyFullbright(); + + if (te_data["te"].has("imageid")) + { + LLUUID item_id; + LLUUID id = te_data["te"]["imageid"].asUUID(); + bool full_perm = get_is_library_texture(id) || (objectp->permCopy() && objectp->permTransfer() && objectp->permModify()); + + if (id.notNull() && !full_perm) + { + std::map::iterator iter = asset_item_map.find(id); + if (iter != asset_item_map.end()) + { + item_id = iter->second; + } + else + { + // What this does is simply searches inventory for item with same asset id, + // as result it is Hightly unreliable, leaves little control to user, borderline hack + // but there are little options to preserve permissions - multiple inventory + // items might reference same asset and inventory search is expensive. + item_id = get_copy_free_item_by_asset_id(id); + // record value to avoid repeating inventory search when possible + asset_item_map[id] = item_id; + } + } + + if (id.isNull() + || (!full_perm && item_id.isNull())) + { + if (!LLLocalBitmapMgr::getInstance()->isLocal(id)) + { + te_data["te"].erase("imageid"); + te_data["te"]["imageid"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); + } + te_data["te"]["itemfullperm"] = true; + } + else + { + te_data["te"]["itemfullperm"] = full_perm; + // If full permission object, texture is free to copy, + // but otherwise we need to check inventory and extract permissions + // + // Normally we care only about restrictions for current user and objects + // don't inherit any 'next owner' permissions from texture, so there is + // no need to record item id if full_perm==true + if (!full_perm && item_id.notNull()) + { + //Todo: + // also same thing probably needs to be present in object and volume panels for sculpt and projector images + /* + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (itemp) + { + LLPermissions item_permissions = itemp->getPermissions(); + if (item_permissions.allowOperationBy(PERM_COPY, + gAgent.getID(), + gAgent.getGroupID())) + { + te_data["te"]["imageitemid"] = item_id; + te_data["te"]["itemfullperm"] = itemp->getIsFullPerm(); + if (!itemp->isFinished()) + { + // needed for dropTextureAllFaces + LLInventoryModelBackgroundFetch::instance().start(item_id, false); + } + } + } + */ + } + } + } + + LLMaterialPtr material_ptr = tep->getMaterialParams(); + if (!material_ptr.isNull()) + { + LLSD mat_data; + + mat_data["NormMap"] = material_ptr->getNormalID(); + mat_data["SpecMap"] = material_ptr->getSpecularID(); + + mat_data["NormRepX"] = material_ptr->getNormalRepeatX(); + mat_data["NormRepY"] = material_ptr->getNormalRepeatY(); + mat_data["NormOffX"] = material_ptr->getNormalOffsetX(); + mat_data["NormOffY"] = material_ptr->getNormalOffsetY(); + mat_data["NormRot"] = material_ptr->getNormalRotation(); + + mat_data["SpecRepX"] = material_ptr->getSpecularRepeatX(); + mat_data["SpecRepY"] = material_ptr->getSpecularRepeatY(); + mat_data["SpecOffX"] = material_ptr->getSpecularOffsetX(); + mat_data["SpecOffY"] = material_ptr->getSpecularOffsetY(); + mat_data["SpecRot"] = material_ptr->getSpecularRotation(); + + mat_data["SpecColor"] = material_ptr->getSpecularLightColor().getValue(); + mat_data["SpecExp"] = material_ptr->getSpecularLightExponent(); + mat_data["EnvIntensity"] = material_ptr->getEnvironmentIntensity(); + mat_data["AlphaMaskCutoff"] = material_ptr->getAlphaMaskCutoff(); + mat_data["DiffuseAlphaMode"] = material_ptr->getDiffuseAlphaMode(); + + // Replace no-copy textures, destination texture will get used instead if available + if (mat_data.has("NormMap")) + { + LLUUID id = mat_data["NormMap"].asUUID(); + if (id.notNull() && !get_can_copy_texture(id)) + { + mat_data["NormMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); + mat_data["NormMapNoCopy"] = true; + } + + } + if (mat_data.has("SpecMap")) + { + LLUUID id = mat_data["SpecMap"].asUUID(); + if (id.notNull() && !get_can_copy_texture(id)) + { + mat_data["SpecMap"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); + mat_data["SpecMapNoCopy"] = true; + } + + } + + te_data["material"] = mat_data; + } + + mClipboardParams["texture"].append(te_data); + } + } + } +} + +void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) +{ + if (!mClipboardParams.has("texture")) + { + return; + } + LLSD te_data; + LLSD &clipboard = mClipboardParams["texture"]; // array + if ((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean()) + { + te_data = *(clipboard.beginArray()); + } + else if (clipboard[te]) + { + te_data = clipboard[te]; + } + else + { + return; + } + + LLTextureEntry* tep = objectp->getTE(te); + if (tep) + { + if (te_data.has("te")) + { + // Texture + bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean(); + if (te_data["te"].has("imageid")) + { + const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); //texture or asset id + LLViewerInventoryItem* itemp_res = NULL; + + if (te_data["te"].has("imageitemid")) + { + LLUUID item_id = te_data["te"]["imageitemid"].asUUID(); + if (item_id.notNull()) + { + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (itemp && itemp->isFinished()) + { + // dropTextureAllFaces will fail if incomplete + itemp_res = itemp; + } + } + } + //todo: + // for case when item got removed from inventory after we pressed 'copy' + /*if (!itemp_res && !full_perm) + { + // todo: fix this, we are often searching same tuxter multiple times (equal to number of faces) + LLViewerInventoryCategory::cat_array_t cats; + LLViewerInventoryItem::item_array_t items; + LLAssetIDMatches asset_id_matches(imageid); + gInventory.collectDescendentsIf(LLUUID::null, + cats, + items, + LLInventoryModel::INCLUDE_TRASH, + asset_id_matches); + + // Extremely unreliable and perfomance unfriendly. + // But we need this to check permissions and it is how texture control finds items + for (S32 i = 0; i < items.size(); i++) + { + LLViewerInventoryItem* itemp = items[i]; + if (itemp && itemp->isFinished()) + { + // dropTextureAllFaces will fail if incomplete + LLPermissions item_permissions = itemp->getPermissions(); + if (item_permissions.allowOperationBy(PERM_COPY, + gAgent.getID(), + gAgent.getGroupID())) + { + itemp_res = itemp; + break; // first match + } + } + } + }*/ + + if (itemp_res) + { + if (te == -1) // all faces + { + LLToolDragAndDrop::dropTextureAllFaces(objectp, + itemp_res, + LLToolDragAndDrop::SOURCE_AGENT, + LLUUID::null); + } + else // one face + { + LLToolDragAndDrop::dropTextureOneFace(objectp, + te, + itemp_res, + LLToolDragAndDrop::SOURCE_AGENT, + LLUUID::null); + } + } + // not an inventory item or no complete items + else if (full_perm) + { + // Either library, local or existed as fullperm when user made a copy + LLViewerTexture* image = LLViewerTextureManager::getFetchedTexture(imageid, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + objectp->setTEImage(U8(te), image); + } + } + + if (te_data["te"].has("bumpmap")) + { + objectp->setTEBumpmap(te, (U8)te_data["te"]["bumpmap"].asInteger()); + } + if (te_data["te"].has("bumpshiny")) + { + objectp->setTEBumpShiny(te, (U8)te_data["te"]["bumpshiny"].asInteger()); + } + if (te_data["te"].has("bumpfullbright")) + { + objectp->setTEBumpShinyFullbright(te, (U8)te_data["te"]["bumpfullbright"].asInteger()); + } + + // Texture map + if (te_data["te"].has("scales") && te_data["te"].has("scalet")) + { + objectp->setTEScale(te, (F32)te_data["te"]["scales"].asReal(), (F32)te_data["te"]["scalet"].asReal()); + } + if (te_data["te"].has("offsets") && te_data["te"].has("offsett")) + { + objectp->setTEOffset(te, (F32)te_data["te"]["offsets"].asReal(), (F32)te_data["te"]["offsett"].asReal()); + } + if (te_data["te"].has("imagerot")) + { + objectp->setTERotation(te, (F32)te_data["te"]["imagerot"].asReal()); + } + + // Media + if (te_data["te"].has("media_flags")) + { + U8 media_flags = te_data["te"]["media_flags"].asInteger(); + objectp->setTEMediaFlags(te, media_flags); + LLVOVolume *vo = dynamic_cast(objectp); + if (vo && te_data["te"].has(LLTextureEntry::TEXTURE_MEDIA_DATA_KEY)) + { + vo->syncMediaData(te, te_data["te"][LLTextureEntry::TEXTURE_MEDIA_DATA_KEY], true/*merge*/, true/*ignore_agent*/); + } + } + else + { + // Keep media flags on destination unchanged + } + } + + if (te_data.has("material")) + { + LLUUID object_id = objectp->getID(); + + LLSelectedTEMaterial::setAlphaMaskCutoff(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id); + + // Normal + // Replace placeholders with target's + if (te_data["material"].has("NormMapNoCopy")) + { + LLMaterialPtr material = tep->getMaterialParams(); + if (material.notNull()) + { + LLUUID id = material->getNormalID(); + if (id.notNull()) + { + te_data["material"]["NormMap"] = id; + } + } + } + LLSelectedTEMaterial::setNormalID(this, te_data["material"]["NormMap"].asUUID(), te, object_id); + LLSelectedTEMaterial::setNormalRepeatX(this, (F32)te_data["material"]["NormRepX"].asReal(), te, object_id); + LLSelectedTEMaterial::setNormalRepeatY(this, (F32)te_data["material"]["NormRepY"].asReal(), te, object_id); + LLSelectedTEMaterial::setNormalOffsetX(this, (F32)te_data["material"]["NormOffX"].asReal(), te, object_id); + LLSelectedTEMaterial::setNormalOffsetY(this, (F32)te_data["material"]["NormOffY"].asReal(), te, object_id); + LLSelectedTEMaterial::setNormalRotation(this, (F32)te_data["material"]["NormRot"].asReal(), te, object_id); + + // Specular + // Replace placeholders with target's + if (te_data["material"].has("SpecMapNoCopy")) + { + LLMaterialPtr material = tep->getMaterialParams(); + if (material.notNull()) + { + LLUUID id = material->getSpecularID(); + if (id.notNull()) + { + te_data["material"]["SpecMap"] = id; + } + } + } + LLSelectedTEMaterial::setSpecularID(this, te_data["material"]["SpecMap"].asUUID(), te, object_id); + LLSelectedTEMaterial::setSpecularRepeatX(this, (F32)te_data["material"]["SpecRepX"].asReal(), te, object_id); + LLSelectedTEMaterial::setSpecularRepeatY(this, (F32)te_data["material"]["SpecRepY"].asReal(), te, object_id); + LLSelectedTEMaterial::setSpecularOffsetX(this, (F32)te_data["material"]["SpecOffX"].asReal(), te, object_id); + LLSelectedTEMaterial::setSpecularOffsetY(this, (F32)te_data["material"]["SpecOffY"].asReal(), te, object_id); + LLSelectedTEMaterial::setSpecularRotation(this, (F32)te_data["material"]["SpecRot"].asReal(), te, object_id); + LLColor4 spec_color(te_data["material"]["SpecColor"]); + LLSelectedTEMaterial::setSpecularLightColor(this, spec_color, te); + LLSelectedTEMaterial::setSpecularLightExponent(this, (U8)te_data["material"]["SpecExp"].asInteger(), te, object_id); + LLSelectedTEMaterial::setEnvironmentIntensity(this, (U8)te_data["material"]["EnvIntensity"].asInteger(), te, object_id); + LLSelectedTEMaterial::setDiffuseAlphaMode(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id); + if (te_data.has("te") && te_data["te"].has("shiny")) + { + objectp->setTEShiny(te, (U8)te_data["te"]["shiny"].asInteger()); + } + } + } +} + +enum EPasteMode +{ + PASTE_COLOR, + PASTE_TEXTURE +}; + +struct LLPanelFacePasteTexFunctor : public LLSelectedTEFunctor +{ + LLPanelFacePasteTexFunctor(LLPanelFace* panel, EPasteMode mode) : + mPanelFace(panel), mMode(mode) {} + + virtual bool apply(LLViewerObject* objectp, S32 te) + { + switch (mMode) + { + case PASTE_COLOR: + mPanelFace->onPasteColor(objectp, te); + break; + case PASTE_TEXTURE: + mPanelFace->onPasteTexture(objectp, te); + break; + } + return true; + } +private: + LLPanelFace *mPanelFace; + EPasteMode mMode; +}; + +struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor +{ + LLPanelFaceUpdateFunctor(bool update_media) : mUpdateMedia(update_media) {} + virtual bool apply(LLViewerObject* object) + { + object->sendTEUpdate(); + if (mUpdateMedia) + { + LLVOVolume *vo = dynamic_cast(object); + if (vo && vo->hasMedia()) + { + vo->sendMediaDataUpdate(); + } + } + return true; + } +private: + bool mUpdateMedia; +}; + +struct LLPanelFaceNavigateHomeFunctor : public LLSelectedTEFunctor +{ + virtual bool apply(LLViewerObject* objectp, S32 te) + { + if (objectp && objectp->getTE(te)) + { + LLTextureEntry* tep = objectp->getTE(te); + const LLMediaEntry *media_data = tep->getMediaData(); + if (media_data) + { + if (media_data->getCurrentURL().empty() && media_data->getAutoPlay()) + { + viewer_media_t media_impl = + LLViewerMedia::getInstance()->getMediaImplFromTextureID(tep->getMediaData()->getMediaID()); + if (media_impl) + { + media_impl->navigateHome(); + } + } + } + } + return true; + } +}; + +void LLPanelFace::menuDoToSelected(const LLSD& userdata) +{ + std::string command = userdata.asString(); + + // paste + if (command == "color_paste") + { + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + + LLPanelFacePasteTexFunctor paste_func(this, PASTE_COLOR); + selected_objects->applyToTEs(&paste_func); + + LLPanelFaceUpdateFunctor sendfunc(false); + selected_objects->applyToObjects(&sendfunc); + } + else if (command == "texture_paste") + { + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + + LLPanelFacePasteTexFunctor paste_func(this, PASTE_TEXTURE); + selected_objects->applyToTEs(&paste_func); + + LLPanelFaceUpdateFunctor sendfunc(true); + selected_objects->applyToObjects(&sendfunc); + + LLPanelFaceNavigateHomeFunctor navigate_home_func; + selected_objects->applyToTEs(&navigate_home_func); + } + // copy + else if (command == "color_copy") + { + onCopyColor(); + } + else if (command == "texture_copy") + { + onCopyTexture(); + } +} + +bool LLPanelFace::menuEnableItem(const LLSD& userdata) +{ + std::string command = userdata.asString(); + + // paste options + if (command == "color_paste") + { + return mClipboardParams.has("color"); + } + else if (command == "texture_paste") + { + return mClipboardParams.has("texture"); + } + return false; +} + // TODO: I don't know who put these in or what these are for??? void LLPanelFace::setMediaURL(const std::string& url) diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 2d57d89a44..5c1fb7f64d 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -47,6 +47,7 @@ class LLUICtrl; class LLViewerObject; class LLFloater; class LLMaterialID; +class LLMenuButton; // Represents an edit for use in replicating the op across one or more materials in the selection set. // @@ -205,6 +206,16 @@ protected: static void onClickAutoFix(void*); static void onAlignTexture(void*); +public: // needs to be accessible to selection manager + void onCopyColor(); // records all selected faces + void onPasteColor(LLViewerObject* objectp, S32 te); // to specific face + void onCopyTexture(); + void onPasteTexture(LLViewerObject* objectp, S32 te); + +protected: + void menuDoToSelected(const LLSD& userdata); + bool menuEnableItem(const LLSD& userdata); + static F32 valueGlow(LLViewerObject* object, S32 face); @@ -400,7 +411,10 @@ private: * If agent selects texture which is not allowed to be applied for the currently selected object, * all controls of the floater texture picker which allow to apply the texture will be disabled. */ - void onTextureSelectionChanged(LLInventoryItem* itemp); + void onTextureSelectionChanged(LLInventoryItem* itemp); + + LLMenuButton* mMenuClipboardColor; + LLMenuButton* mMenuClipboardTexture; bool mIsAlpha; @@ -415,7 +429,9 @@ private: * up-arrow on a spinner, and avoids running afoul of its throttle. */ bool mUpdateInFlight; - bool mUpdatePending; + bool mUpdatePending; + + LLSD mClipboardParams; public: #if defined(DEF_GET_MAT_STATE) diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index a03e85daff..dd7ef708f2 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -670,9 +670,6 @@ void LLPanelVolume::clearCtrls() mSpinPhysicsRestitution->setEnabled(FALSE); mComboMaterial->setEnabled( FALSE ); - - mMenuClipboardFeatures->setEnabled(false); - mMenuClipboardLight->setEnabled(false); } // diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 6e08be4866..1bbc2302c3 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2,7 +2,7 @@ + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml b/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml index dd58658472..4823d74a26 100644 --- a/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml +++ b/indra/newview/skins/default/xui/en/menu_copy_paste_features.xml @@ -1,7 +1,7 @@ + name="Copy Paste Features Menu"> + name="Copy Paste Light Menu"> + name="Copy Paste Object Menu"> + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index 438fb1e8ed..611433bc1d 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -11,6 +11,19 @@ name="Texture" top="0" width="295"> + + width="54" /> + width="77" /> + + top_pad="17" + width="90"> - + + Date: Fri, 19 Jun 2020 22:45:20 +0300 Subject: SL-13359 #9.5 Texture tab --- indra/newview/llpanelface.cpp | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 6b5d14300f..f4122cac5f 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -38,6 +38,7 @@ #include "llfontgl.h" // project includes +#include "llagent.h" #include "llagentdata.h" #include "llbutton.h" #include "llcheckboxctrl.h" @@ -45,7 +46,9 @@ #include "llcombobox.h" #include "lldrawpoolbump.h" #include "llface.h" +#include "llinventoryfunctions.h" #include "llinventorymodel.h" // gInventory +#include "llinventorymodelbackgroundfetch.h" #include "lllineeditor.h" #include "llmaterialmgr.h" #include "llmediaentry.h" @@ -2773,9 +2776,6 @@ void LLPanelFace::onCopyTexture() // no need to record item id if full_perm==true if (!full_perm && item_id.notNull()) { - //Todo: - // also same thing probably needs to be present in object and volume panels for sculpt and projector images - /* LLViewerInventoryItem* itemp = gInventory.getItem(item_id); if (itemp) { @@ -2793,7 +2793,6 @@ void LLPanelFace::onCopyTexture() } } } - */ } } } @@ -2901,11 +2900,12 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) } } } - //todo: // for case when item got removed from inventory after we pressed 'copy' - /*if (!itemp_res && !full_perm) + // or texture got pasted into previous object + if (!itemp_res && !full_perm) { - // todo: fix this, we are often searching same tuxter multiple times (equal to number of faces) + // Todo: fix this, we are often searching same texture multiple times (equal to number of faces) + // Perhaps just mPanelFace->onPasteTexture(objectp, te, &asset_to_item_id_map); ? Not pretty, but will work LLViewerInventoryCategory::cat_array_t cats; LLViewerInventoryItem::item_array_t items; LLAssetIDMatches asset_id_matches(imageid); @@ -2933,7 +2933,7 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) } } } - }*/ + } if (itemp_res) { @@ -3013,7 +3013,7 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) LLSelectedTEMaterial::setAlphaMaskCutoff(this, (U8)te_data["material"]["SpecRot"].asInteger(), te, object_id); // Normal - // Replace placeholders with target's + // Replace placeholders with target's if (te_data["material"].has("NormMapNoCopy")) { LLMaterialPtr material = tep->getMaterialParams(); -- cgit v1.3 From 23f20c207d1e69c03e2ce2cb9100ad216ac60708 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Tue, 23 Jun 2020 22:02:33 +0300 Subject: SL-12688 Warnings part #1 --- indra/newview/llpanelface.cpp | 299 ++++++++++++++------- indra/newview/llpanelface.h | 2 + .../newview/skins/default/xui/en/notifications.xml | 10 + .../skins/default/xui/en/panel_tools_texture.xml | 9 + 4 files changed, 226 insertions(+), 94 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index f4122cac5f..3849e5c8f7 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2579,6 +2579,80 @@ void LLPanelFace::onAlignTexture(void* userdata) self->alignTestureLayer(); } +enum EPasteMode +{ + PASTE_COLOR, + PASTE_TEXTURE +}; + +struct LLPanelFacePasteTexFunctor : public LLSelectedTEFunctor +{ + LLPanelFacePasteTexFunctor(LLPanelFace* panel, EPasteMode mode) : + mPanelFace(panel), mMode(mode) {} + + virtual bool apply(LLViewerObject* objectp, S32 te) + { + switch (mMode) + { + case PASTE_COLOR: + mPanelFace->onPasteColor(objectp, te); + break; + case PASTE_TEXTURE: + mPanelFace->onPasteTexture(objectp, te); + break; + } + return true; + } +private: + LLPanelFace *mPanelFace; + EPasteMode mMode; +}; + +struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor +{ + LLPanelFaceUpdateFunctor(bool update_media) : mUpdateMedia(update_media) {} + virtual bool apply(LLViewerObject* object) + { + object->sendTEUpdate(); + if (mUpdateMedia) + { + LLVOVolume *vo = dynamic_cast(object); + if (vo && vo->hasMedia()) + { + vo->sendMediaDataUpdate(); + } + } + return true; + } +private: + bool mUpdateMedia; +}; + +struct LLPanelFaceNavigateHomeFunctor : public LLSelectedTEFunctor +{ + virtual bool apply(LLViewerObject* objectp, S32 te) + { + if (objectp && objectp->getTE(te)) + { + LLTextureEntry* tep = objectp->getTE(te); + const LLMediaEntry *media_data = tep->getMediaData(); + if (media_data) + { + if (media_data->getCurrentURL().empty() && media_data->getAutoPlay()) + { + viewer_media_t media_impl = + LLViewerMedia::getInstance()->getMediaImplFromTextureID(tep->getMediaData()->getMediaID()); + if (media_impl) + { + media_impl->navigateHome(); + } + } + } + } + return true; + } +}; + void LLPanelFace::onCopyColor() { LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); @@ -2625,12 +2699,74 @@ void LLPanelFace::onCopyColor() } } -void LLPanelFace::onPasteColor(LLViewerObject* objectp, S32 te) +void LLPanelFace::onPasteColor() { if (!mClipboardParams.has("color")) { return; } + + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + if (!objectp || !node + || objectp->getPCode() != LL_PCODE_VOLUME + || !objectp->permModify() + || objectp->isPermanentEnforced() + || selected_count > 1) + { + // not supposed to happen + LL_WARNS() << "Failed to paste color due to missing or wrong selection" << LL_ENDL; + return; + } + + bool face_selection_mode = LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool(); + LLSD &clipboard = mClipboardParams["color"]; // array + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + S32 compare_tes = num_tes; + + if (face_selection_mode) + { + compare_tes = 0; + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + compare_tes++; + } + } + } + + // we can copy if single face was copied in edit face mode or if face count matches + if (!((clipboard.size() == 1) && mClipboardParams["color_all_tes"].asBoolean()) + && compare_tes != clipboard.size()) + { + LLSD notif_args; + if (face_selection_mode) + { + static std::string reason = getString("paste_error_face_selection_mismatch"); + notif_args["REASON"] = reason; + } + else + { + static std::string reason = getString("paste_error_object_face_count_mismatch"); + notif_args["REASON"] = reason; + } + LLNotificationsUtil::add("FacePasteFailed", notif_args); + return; + } + + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + + LLPanelFacePasteTexFunctor paste_func(this, PASTE_COLOR); + selected_objects->applyToTEs(&paste_func); + + LLPanelFaceUpdateFunctor sendfunc(false); + selected_objects->applyToObjects(&sendfunc); +} + +void LLPanelFace::onPasteColor(LLViewerObject* objectp, S32 te) +{ LLSD te_data; LLSD &clipboard = mClipboardParams["color"]; // array if ((clipboard.size() == 1) && mClipboardParams["color_all_tes"].asBoolean()) @@ -2687,7 +2823,6 @@ void LLPanelFace::onPasteColor(LLViewerObject* objectp, S32 te) void LLPanelFace::onCopyTexture() { - LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); @@ -2854,12 +2989,77 @@ void LLPanelFace::onCopyTexture() } } -void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) +void LLPanelFace::onPasteTexture() { if (!mClipboardParams.has("texture")) { return; } + + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + LLSelectNode* node = LLSelectMgr::getInstance()->getSelection()->getFirstNode(); + S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); + if (!objectp || !node + || objectp->getPCode() != LL_PCODE_VOLUME + || !objectp->permModify() + || objectp->isPermanentEnforced() + || selected_count > 1) + { + // not supposed to happen + LL_WARNS() << "Failed to paste texture due to missing or wrong selection" << LL_ENDL; + return; + } + + bool face_selection_mode = LLToolFace::getInstance() == LLToolMgr::getInstance()->getCurrentTool(); + LLSD &clipboard = mClipboardParams["texture"]; // array + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); + S32 compare_tes = num_tes; + + if (face_selection_mode) + { + compare_tes = 0; + for (S32 te = 0; te < num_tes; ++te) + { + if (node->isTESelected(te)) + { + compare_tes++; + } + } + } + + // we can copy if single face was copied in edit face mode or if face count matches + if (!((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean()) + && compare_tes != clipboard.size()) + { + LLSD notif_args; + if (face_selection_mode) + { + static std::string reason = getString("paste_error_face_selection_mismatch"); + notif_args["REASON"] = reason; + } + else + { + static std::string reason = getString("paste_error_object_face_count_mismatch"); + notif_args["REASON"] = reason; + } + LLNotificationsUtil::add("FacePasteFailed", notif_args); + return; + } + + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); + + LLPanelFacePasteTexFunctor paste_func(this, PASTE_TEXTURE); + selected_objects->applyToTEs(&paste_func); + + LLPanelFaceUpdateFunctor sendfunc(true); + selected_objects->applyToObjects(&sendfunc); + + LLPanelFaceNavigateHomeFunctor navigate_home_func; + selected_objects->applyToTEs(&navigate_home_func); +} + +void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) +{ LLSD te_data; LLSD &clipboard = mClipboardParams["texture"]; // array if ((clipboard.size() == 1) && mClipboardParams["texture_all_tes"].asBoolean()) @@ -3066,80 +3266,6 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) } } -enum EPasteMode -{ - PASTE_COLOR, - PASTE_TEXTURE -}; - -struct LLPanelFacePasteTexFunctor : public LLSelectedTEFunctor -{ - LLPanelFacePasteTexFunctor(LLPanelFace* panel, EPasteMode mode) : - mPanelFace(panel), mMode(mode) {} - - virtual bool apply(LLViewerObject* objectp, S32 te) - { - switch (mMode) - { - case PASTE_COLOR: - mPanelFace->onPasteColor(objectp, te); - break; - case PASTE_TEXTURE: - mPanelFace->onPasteTexture(objectp, te); - break; - } - return true; - } -private: - LLPanelFace *mPanelFace; - EPasteMode mMode; -}; - -struct LLPanelFaceUpdateFunctor : public LLSelectedObjectFunctor -{ - LLPanelFaceUpdateFunctor(bool update_media) : mUpdateMedia(update_media) {} - virtual bool apply(LLViewerObject* object) - { - object->sendTEUpdate(); - if (mUpdateMedia) - { - LLVOVolume *vo = dynamic_cast(object); - if (vo && vo->hasMedia()) - { - vo->sendMediaDataUpdate(); - } - } - return true; - } -private: - bool mUpdateMedia; -}; - -struct LLPanelFaceNavigateHomeFunctor : public LLSelectedTEFunctor -{ - virtual bool apply(LLViewerObject* objectp, S32 te) - { - if (objectp && objectp->getTE(te)) - { - LLTextureEntry* tep = objectp->getTE(te); - const LLMediaEntry *media_data = tep->getMediaData(); - if (media_data) - { - if (media_data->getCurrentURL().empty() && media_data->getAutoPlay()) - { - viewer_media_t media_impl = - LLViewerMedia::getInstance()->getMediaImplFromTextureID(tep->getMediaData()->getMediaID()); - if (media_impl) - { - media_impl->navigateHome(); - } - } - } - } - return true; - } -}; - void LLPanelFace::menuDoToSelected(const LLSD& userdata) { std::string command = userdata.asString(); @@ -3147,26 +3273,11 @@ void LLPanelFace::menuDoToSelected(const LLSD& userdata) // paste if (command == "color_paste") { - LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); - - LLPanelFacePasteTexFunctor paste_func(this, PASTE_COLOR); - selected_objects->applyToTEs(&paste_func); - - LLPanelFaceUpdateFunctor sendfunc(false); - selected_objects->applyToObjects(&sendfunc); + onPasteColor(); } else if (command == "texture_paste") { - LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); - - LLPanelFacePasteTexFunctor paste_func(this, PASTE_TEXTURE); - selected_objects->applyToTEs(&paste_func); - - LLPanelFaceUpdateFunctor sendfunc(true); - selected_objects->applyToObjects(&sendfunc); - - LLPanelFaceNavigateHomeFunctor navigate_home_func; - selected_objects->applyToTEs(&navigate_home_func); + onPasteTexture(); } // copy else if (command == "color_copy") diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 5c1fb7f64d..948d33c2c1 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -208,8 +208,10 @@ protected: public: // needs to be accessible to selection manager void onCopyColor(); // records all selected faces + void onPasteColor(); // to specific face void onPasteColor(LLViewerObject* objectp, S32 te); // to specific face void onCopyTexture(); + void onPasteTexture(); void onPasteTexture(LLViewerObject* objectp, S32 te); protected: diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 8a91a1f721..f59ac450f2 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -8946,6 +8946,16 @@ We cannot display a preview of this texture because it is no-copy and/or no-tran name="okignore" yestext="OK"/> + + +Paste failed. [REASON] + + + + When multiple faces are copied, the target object must have the same number of faces selected. + + + When all faces of an object are copied, the target object must have the same number of faces. + + Date: Wed, 24 Jun 2020 18:57:49 +0300 Subject: SL-12688 Warnings part #2 --- indra/newview/llpanelface.cpp | 64 +++++++++++++++++++++- indra/newview/lltexturectrl.cpp | 19 +++---- indra/newview/lltexturectrl.h | 2 +- .../newview/skins/default/xui/en/notifications.xml | 15 ++++- .../skins/default/xui/en/panel_tools_texture.xml | 4 ++ 5 files changed, 89 insertions(+), 15 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 3849e5c8f7..641a3602c8 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2869,7 +2869,8 @@ void LLPanelFace::onCopyTexture() { LLUUID item_id; LLUUID id = te_data["te"]["imageid"].asUUID(); - bool full_perm = get_is_library_texture(id) || (objectp->permCopy() && objectp->permTransfer() && objectp->permModify()); + bool from_library = get_is_predefined_texture(id); + bool full_perm = from_library || (objectp->permCopy() && objectp->permTransfer() && objectp->permModify()); if (id.notNull() && !full_perm) { @@ -2890,6 +2891,12 @@ void LLPanelFace::onCopyTexture() } } + if (item_id.notNull() && gInventory.isObjectDescendentOf(item_id, gInventory.getLibraryRootFolderID())) + { + full_perm = true; + from_library = true; + } + if (id.isNull() || (!full_perm && item_id.isNull())) { @@ -2899,10 +2906,15 @@ void LLPanelFace::onCopyTexture() te_data["te"]["imageid"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); } te_data["te"]["itemfullperm"] = true; + te_data["te"]["fromlibrary"] = true; } else { te_data["te"]["itemfullperm"] = full_perm; + // from_library is unreliable since we don't get texture item if source object + // is fullperm but it merely means additional checks when assigning texture + te_data["te"]["fromlibrary"] = from_library; + // If full permission object, texture is free to copy, // but otherwise we need to check inventory and extract permissions // @@ -3046,6 +3058,40 @@ void LLPanelFace::onPasteTexture() return; } + bool full_perm = true; + LLSD::array_const_iterator iter = clipboard.beginArray(); + LLSD::array_const_iterator end = clipboard.endArray(); + for (; iter != end; ++iter) + { + const LLSD& te_data = *iter; + if (te_data.has("te")) + { + full_perm &= te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean(); + if (te_data["te"].has("imageitemid")) + { + LLUUID item_id = te_data["te"]["imageitemid"].asUUID(); + if (item_id.notNull()) + { + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (!itemp) + { + // image might be in object's inventory, but it can be not up to date + LLSD notif_args; + static std::string reason = getString("paste_error_inventory_not_found"); + notif_args["REASON"] = reason; + LLNotificationsUtil::add("FacePasteFailed", notif_args); + return; + } + } + } + } + } + + if (!full_perm) + { + LLNotificationsUtil::add("FacePasteTexturePermissions"); + } + LLObjectSelectionHandle selected_objects = LLSelectMgr::getInstance()->getSelection(); LLPanelFacePasteTexFunctor paste_func(this, PASTE_TEXTURE); @@ -3082,6 +3128,7 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) { // Texture bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean(); + bool from_library = te_data["te"].has("fromlibrary") && te_data["te"]["fromlibrary"].asBoolean(); if (te_data["te"].has("imageid")) { const LLUUID& imageid = te_data["te"]["imageid"].asUUID(); //texture or asset id @@ -3098,12 +3145,21 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) // dropTextureAllFaces will fail if incomplete itemp_res = itemp; } + else + { + // Theoretically shouldn't happend, but if it does happen, we + // might need to add a notification to user that paste will fail + // since inventory isn't fully loaded + LL_WARNS() << "Item " << item_id << " is incomplete, paste might fail silently." << LL_ENDL; + } } } // for case when item got removed from inventory after we pressed 'copy' // or texture got pasted into previous object if (!itemp_res && !full_perm) { + // Due to checks for imageitemid in LLPanelFace::onPasteTexture() this should no longer be reachable. + LL_INFOS() << "Item " << te_data["te"]["imageitemid"].asUUID() << " no longer in inventory." << LL_ENDL; // Todo: fix this, we are often searching same texture multiple times (equal to number of faces) // Perhaps just mPanelFace->onPasteTexture(objectp, te, &asset_to_item_id_map); ? Not pretty, but will work LLViewerInventoryCategory::cat_array_t cats; @@ -3137,11 +3193,13 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) if (itemp_res) { + // from_library is unreliable since we don't get texture item if object is + // fullperm but it merely means additional checks when assigning texture if (te == -1) // all faces { LLToolDragAndDrop::dropTextureAllFaces(objectp, itemp_res, - LLToolDragAndDrop::SOURCE_AGENT, + from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null); } else // one face @@ -3149,7 +3207,7 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) LLToolDragAndDrop::dropTextureOneFace(objectp, te, itemp_res, - LLToolDragAndDrop::SOURCE_AGENT, + from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null); } } diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 2f5be2b32e..b5e4b3608a 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -82,24 +82,23 @@ static const S32 LOCAL_TRACKING_ID_COLUMN = 1; //static -bool get_is_library_texture(LLUUID image_id) +bool get_is_predefined_texture(LLUUID asset_id) { - if (gInventory.isObjectDescendentOf(image_id, gInventory.getLibraryRootFolderID()) - || image_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture")) - || image_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID")) - || image_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")) - || image_id == LLUUID(SCULPT_DEFAULT_TEXTURE)) + if (asset_id == LLUUID(gSavedSettings.getString("DefaultObjectTexture")) + || asset_id == LLUUID(gSavedSettings.getString("UIImgWhiteUUID")) + || asset_id == LLUUID(gSavedSettings.getString("UIImgInvisibleUUID")) + || asset_id == LLUUID(SCULPT_DEFAULT_TEXTURE)) { return true; } return false; } -LLUUID get_copy_free_item_by_asset_id(LLUUID image_id) +LLUUID get_copy_free_item_by_asset_id(LLUUID asset_id) { LLViewerInventoryCategory::cat_array_t cats; LLViewerInventoryItem::item_array_t items; - LLAssetIDMatches asset_id_matches(image_id); + LLAssetIDMatches asset_id_matches(asset_id); gInventory.collectDescendentsIf(LLUUID::null, cats, items, @@ -125,13 +124,13 @@ LLUUID get_copy_free_item_by_asset_id(LLUUID image_id) return LLUUID::null; } -bool get_can_copy_texture(LLUUID image_id) +bool get_can_copy_texture(LLUUID asset_id) { // User is allowed to copy a texture if: // library asset or default texture, // or copy perm asset exists in user's inventory - return get_is_library_texture(image_id) || get_copy_free_item_by_asset_id(image_id).notNull(); + return get_is_predefined_texture(asset_id) || get_copy_free_item_by_asset_id(asset_id).notNull(); } LLFloaterTexturePicker::LLFloaterTexturePicker( diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 2b2c5fa237..97e7bb0d20 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -54,7 +54,7 @@ typedef boost::function drag_n_drop_callback typedef boost::function texture_selected_callback; // Helper functions for UI that work with picker -bool get_is_library_texture(LLUUID image_id); +bool get_is_predefined_texture(LLUUID asset_id); // texture picker works by asset ids since objects normaly do // not retain inventory ids as result these functions are looking diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index f59ac450f2..196d507507 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -8946,7 +8946,7 @@ We cannot display a preview of this texture because it is no-copy and/or no-tran name="okignore" yestext="OK"/> - + + + You applied a texture with limited permissions, object will inherit permissions from texture. + + + + When all faces of an object are copied, the target object must have the same number of faces. + + One or more texture not found in inventory. + Date: Thu, 25 Jun 2020 23:34:22 +0300 Subject: SL-12688 Restored stricter permission requirements You need to own texture in inventory to be able to copy it --- indra/newview/llpanelface.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 641a3602c8..4249a13827 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2870,7 +2870,7 @@ void LLPanelFace::onCopyTexture() LLUUID item_id; LLUUID id = te_data["te"]["imageid"].asUUID(); bool from_library = get_is_predefined_texture(id); - bool full_perm = from_library || (objectp->permCopy() && objectp->permTransfer() && objectp->permModify()); + bool full_perm = from_library; if (id.notNull() && !full_perm) { @@ -2911,8 +2911,6 @@ void LLPanelFace::onCopyTexture() else { te_data["te"]["itemfullperm"] = full_perm; - // from_library is unreliable since we don't get texture item if source object - // is fullperm but it merely means additional checks when assigning texture te_data["te"]["fromlibrary"] = from_library; // If full permission object, texture is free to copy, @@ -2921,7 +2919,7 @@ void LLPanelFace::onCopyTexture() // Normally we care only about restrictions for current user and objects // don't inherit any 'next owner' permissions from texture, so there is // no need to record item id if full_perm==true - if (!full_perm && item_id.notNull()) + if (!full_perm && !from_library && item_id.notNull()) { LLViewerInventoryItem* itemp = gInventory.getItem(item_id); if (itemp) @@ -3193,8 +3191,6 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) if (itemp_res) { - // from_library is unreliable since we don't get texture item if object is - // fullperm but it merely means additional checks when assigning texture if (te == -1) // all faces { LLToolDragAndDrop::dropTextureAllFaces(objectp, -- cgit v1.3 From ccf51f173ca80215e5ecb02cdb04724374349de9 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Jul 2020 17:21:09 +0300 Subject: SL-12334 Texture UUID is not copied to clipboard from a full-perms object --- indra/newview/llpanelface.cpp | 23 +++++++++++++++++++---- 1 file changed, 19 insertions(+), 4 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 4249a13827..091ea3764d 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2872,6 +2872,20 @@ void LLPanelFace::onCopyTexture() bool from_library = get_is_predefined_texture(id); bool full_perm = from_library; + if (!full_perm + && objectp->permCopy() + && objectp->permTransfer() + && objectp->permModify()) + { + // If agent created this object and nothing is limiting permissions, mark as full perm + // If agent was granted permission to edit objects owned and created by somebody else, mark full perm + // This check is not perfect since we can't figure out whom textures belong to so this ended up restrictive + std::string creator_app_link; + LLUUID creator_id; + LLSelectMgr::getInstance()->selectGetCreator(creator_id, creator_app_link); + full_perm = objectp->mOwnerID == creator_id; + } + if (id.notNull() && !full_perm) { std::map::iterator iter = asset_item_map.find(id); @@ -3056,7 +3070,7 @@ void LLPanelFace::onPasteTexture() return; } - bool full_perm = true; + bool full_perm_object = true; LLSD::array_const_iterator iter = clipboard.beginArray(); LLSD::array_const_iterator end = clipboard.endArray(); for (; iter != end; ++iter) @@ -3064,8 +3078,9 @@ void LLPanelFace::onPasteTexture() const LLSD& te_data = *iter; if (te_data.has("te")) { - full_perm &= te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean(); - if (te_data["te"].has("imageitemid")) + bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean(); + full_perm_object &= full_perm; + if (!full_perm && te_data["te"].has("imageitemid")) { LLUUID item_id = te_data["te"]["imageitemid"].asUUID(); if (item_id.notNull()) @@ -3085,7 +3100,7 @@ void LLPanelFace::onPasteTexture() } } - if (!full_perm) + if (!full_perm_object) { LLNotificationsUtil::add("FacePasteTexturePermissions"); } -- cgit v1.3 From 3fde31b61026f9052243a5a716dbc0a6419880ae Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Jul 2020 18:36:19 +0300 Subject: SL-12688 Fixed Warning --- indra/newview/llpanelface.cpp | 50 ++++++++++++++++++++++--------------------- 1 file changed, 26 insertions(+), 24 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 091ea3764d..a3f9acb85a 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2911,18 +2911,6 @@ void LLPanelFace::onCopyTexture() from_library = true; } - if (id.isNull() - || (!full_perm && item_id.isNull())) - { - if (!LLLocalBitmapMgr::getInstance()->isLocal(id)) - { - te_data["te"].erase("imageid"); - te_data["te"]["imageid"] = LLUUID(gSavedSettings.getString("DefaultObjectTexture")); - } - te_data["te"]["itemfullperm"] = true; - te_data["te"]["fromlibrary"] = true; - } - else { te_data["te"]["itemfullperm"] = full_perm; te_data["te"]["fromlibrary"] = from_library; @@ -3076,26 +3064,40 @@ void LLPanelFace::onPasteTexture() for (; iter != end; ++iter) { const LLSD& te_data = *iter; - if (te_data.has("te")) + if (te_data.has("te") && te_data["te"].has("imageid")) { bool full_perm = te_data["te"].has("itemfullperm") && te_data["te"]["itemfullperm"].asBoolean(); full_perm_object &= full_perm; - if (!full_perm && te_data["te"].has("imageitemid")) + if (!full_perm) { - LLUUID item_id = te_data["te"]["imageitemid"].asUUID(); - if (item_id.notNull()) + if (te_data["te"].has("imageitemid")) { - LLViewerInventoryItem* itemp = gInventory.getItem(item_id); - if (!itemp) + LLUUID item_id = te_data["te"]["imageitemid"].asUUID(); + if (item_id.notNull()) { - // image might be in object's inventory, but it can be not up to date - LLSD notif_args; - static std::string reason = getString("paste_error_inventory_not_found"); - notif_args["REASON"] = reason; - LLNotificationsUtil::add("FacePasteFailed", notif_args); - return; + LLViewerInventoryItem* itemp = gInventory.getItem(item_id); + if (!itemp) + { + // image might be in object's inventory, but it can be not up to date + LLSD notif_args; + static std::string reason = getString("paste_error_inventory_not_found"); + notif_args["REASON"] = reason; + LLNotificationsUtil::add("FacePasteFailed", notif_args); + return; + } } } + else + { + // Item was not found on 'copy' stage + // Since this happened at copy, might be better to either show this + // at copy stage or to drop clipboard here + LLSD notif_args; + static std::string reason = getString("paste_error_inventory_not_found"); + notif_args["REASON"] = reason; + LLNotificationsUtil::add("FacePasteFailed", notif_args); + return; + } } } } -- cgit v1.3 From bbdbd6c2dd79adc4749e24c88c9f04755a4b12a1 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Fri, 15 Apr 2022 22:14:38 +0300 Subject: SL-17204 FIXED The texture with full permissions is settled on the prim after copying texture from the object with texture with no transfer permission --- indra/newview/llpanelface.cpp | 7 ++++++- indra/newview/lltexturectrl.cpp | 13 ++++++++++--- indra/newview/lltexturectrl.h | 2 +- 3 files changed, 17 insertions(+), 5 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 2ac5022695..f50f587f8f 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -2873,7 +2873,12 @@ void LLPanelFace::onCopyTexture() // as result it is Hightly unreliable, leaves little control to user, borderline hack // but there are little options to preserve permissions - multiple inventory // items might reference same asset and inventory search is expensive. - item_id = get_copy_free_item_by_asset_id(id); + bool no_transfer = false; + if (objectp->getInventoryItemByAsset(id)) + { + no_transfer = !objectp->getInventoryItemByAsset(id)->getIsFullPerm(); + } + item_id = get_copy_free_item_by_asset_id(id, no_transfer); // record value to avoid repeating inventory search when possible asset_item_map[id] = item_id; } diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index cc912758e2..51ee5b6157 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -95,7 +95,7 @@ bool get_is_predefined_texture(LLUUID asset_id) return false; } -LLUUID get_copy_free_item_by_asset_id(LLUUID asset_id) +LLUUID get_copy_free_item_by_asset_id(LLUUID asset_id, bool no_trans_perm) { LLViewerInventoryCategory::cat_array_t cats; LLViewerInventoryItem::item_array_t items; @@ -105,6 +105,8 @@ LLUUID get_copy_free_item_by_asset_id(LLUUID asset_id) items, LLInventoryModel::INCLUDE_TRASH, asset_id_matches); + + LLUUID res; if (items.size()) { for (S32 i = 0; i < items.size(); i++) @@ -117,12 +119,17 @@ LLUUID get_copy_free_item_by_asset_id(LLUUID asset_id) gAgent.getID(), gAgent.getGroupID())) { - return itemp->getUUID(); + bool allow_trans = item_permissions.allowOperationBy(PERM_TRANSFER, gAgent.getID(), gAgent.getGroupID()); + if (allow_trans != no_trans_perm) + { + return itemp->getUUID(); + } + res = itemp->getUUID(); } } } } - return LLUUID::null; + return res; } bool get_can_copy_texture(LLUUID asset_id) diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 4250cf86b8..3769f43737 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -60,7 +60,7 @@ bool get_is_predefined_texture(LLUUID asset_id); // for textures in inventory by asset ids // This search can be performance unfriendly and doesn't warranty // that the texture is original source of asset -LLUUID get_copy_free_item_by_asset_id(LLUUID image_id); +LLUUID get_copy_free_item_by_asset_id(LLUUID image_id, bool no_trans_perm = false); bool get_can_copy_texture(LLUUID image_id); ////////////////////////////////////////////////////////////////////////////////////////// -- cgit v1.3 From 2445525cc573024f8eb64cabac1e6e3dc3362085 Mon Sep 17 00:00:00 2001 From: Mnikolenko Productengine Date: Tue, 19 Apr 2022 02:33:59 +0300 Subject: SL-17231 Copying textures should be disabled if object content was not yet updated --- indra/newview/llpanelface.cpp | 19 ++++++++++++++++++- indra/newview/llpanelface.h | 4 ++++ .../skins/default/xui/en/panel_tools_texture.xml | 4 ++++ 3 files changed, 26 insertions(+), 1 deletion(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index f50f587f8f..d50d42bf2f 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -330,6 +330,13 @@ LLPanelFace::~LLPanelFace() } +void LLPanelFace::draw() +{ + updateCopyTexButton(); + + LLPanel::draw(); +} + void LLPanelFace::sendTexture() { LLTextureCtrl* mTextureCtrl = getChild("texture control"); @@ -1522,7 +1529,6 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) S32 selected_count = LLSelectMgr::getInstance()->getSelection()->getObjectCount(); BOOL single_volume = (selected_count == 1); mMenuClipboardColor->setEnabled(editable && single_volume); - mMenuClipboardTexture->setEnabled(editable && single_volume); // Set variable values for numeric expressions LLCalc* calcp = LLCalc::getInstance(); @@ -1583,6 +1589,17 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) } +void LLPanelFace::updateCopyTexButton() +{ + LLViewerObject* objectp = LLSelectMgr::getInstance()->getSelection()->getFirstObject(); + mMenuClipboardTexture->setEnabled(objectp && objectp->getPCode() == LL_PCODE_VOLUME && objectp->permModify() + && !objectp->isPermanentEnforced() && !objectp->isInventoryPending() + && (LLSelectMgr::getInstance()->getSelection()->getObjectCount() == 1)); + std::string tooltip = (objectp && objectp->isInventoryPending()) ? LLTrans::getString("LoadingContents") : getString("paste_options"); + mMenuClipboardTexture->setToolTip(tooltip); + +} + void LLPanelFace::refresh() { LL_DEBUGS("Materials") << LL_ENDL; diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index 948d33c2c1..e3b925c1d4 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -97,6 +97,8 @@ public: LLPanelFace(); virtual ~LLPanelFace(); + void draw(); + void refresh(); void setMediaURL(const std::string& url); void setMediaType(const std::string& mime_type); @@ -129,6 +131,8 @@ protected: void sendMedia(); void alignTestureLayer(); + void updateCopyTexButton(); + // this function is to return TRUE if the drag should succeed. static BOOL onDragTexture(LLUICtrl* ctrl, LLInventoryItem* item); diff --git a/indra/newview/skins/default/xui/en/panel_tools_texture.xml b/indra/newview/skins/default/xui/en/panel_tools_texture.xml index a33d425964..0cbd7fe2dd 100644 --- a/indra/newview/skins/default/xui/en/panel_tools_texture.xml +++ b/indra/newview/skins/default/xui/en/panel_tools_texture.xml @@ -23,6 +23,10 @@ name="paste_error_inventory_not_found"> One or more texture not found in inventory. + + Paste options + Date: Tue, 26 Apr 2022 19:07:39 +0300 Subject: SL-16026 FIXED Copying only one diffuse texture allows pasting this texture into other types of textures --- indra/newview/llpanelface.cpp | 3 ++- indra/newview/lltooldraganddrop.cpp | 6 ++++-- indra/newview/lltooldraganddrop.h | 3 ++- 3 files changed, 8 insertions(+), 4 deletions(-) (limited to 'indra/newview/llpanelface.cpp') diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index d50d42bf2f..7fe5b1dd3f 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -3217,7 +3217,8 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) te, itemp_res, from_library ? LLToolDragAndDrop::SOURCE_LIBRARY : LLToolDragAndDrop::SOURCE_AGENT, - LLUUID::null); + LLUUID::null, + 0); } } // not an inventory item or no complete items diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 50868d0fa5..f76a2f7f90 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1100,7 +1100,8 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, S32 hit_face, LLInventoryItem* item, LLToolDragAndDrop::ESource source, - const LLUUID& src_id) + const LLUUID& src_id, + S32 tex_channel) { if (hit_face == -1) return; if (!item) @@ -1124,7 +1125,8 @@ void LLToolDragAndDrop::dropTextureOneFace(LLViewerObject* hit_obj, if (gFloaterTools->getVisible() && panel_face) { - switch (LLSelectMgr::getInstance()->getTextureChannel()) + tex_channel = (tex_channel > -1) ? tex_channel : LLSelectMgr::getInstance()->getTextureChannel(); + switch (tex_channel) { case 0: diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 24a712029c..4537d73332 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -244,7 +244,8 @@ public: static void dropTextureOneFace(LLViewerObject* hit_obj, S32 hit_face, LLInventoryItem* item, ESource source, - const LLUUID& src_id); + const LLUUID& src_id, + S32 tex_channel = -1); static void dropTextureAllFaces(LLViewerObject* hit_obj, LLInventoryItem* item, ESource source, -- cgit v1.3