diff --git a/src/Gui/Application.cpp b/src/Gui/Application.cpp index 1fd880074b..c355dcf4e1 100644 --- a/src/Gui/Application.cpp +++ b/src/Gui/Application.cpp @@ -122,6 +122,7 @@ #include "ViewProviderPart.h" #include "ViewProviderPythonFeature.h" #include "ViewProviderTextDocument.h" +#include "ViewProviderTextureExtension.h" #include "ViewProviderVRMLObject.h" #include "ViewProviderVarSet.h" #include "WaitCursor.h" @@ -1926,6 +1927,8 @@ void Application::initTypes() Gui::ViewProviderMaterialObject ::init(); Gui::ViewProviderMaterialObjectPython ::init(); Gui::ViewProviderTextDocument ::init(); + Gui::ViewProviderTextureExtension ::init(); + Gui::ViewProviderFaceTexture ::init(); Gui::ViewProviderLinkObserver ::init(); Gui::LinkView ::init(); Gui::ViewProviderLink ::init(); diff --git a/src/Gui/CMakeLists.txt b/src/Gui/CMakeLists.txt index 21ec70d4fa..ae6ed25a5c 100644 --- a/src/Gui/CMakeLists.txt +++ b/src/Gui/CMakeLists.txt @@ -944,6 +944,7 @@ SET(Viewprovider_CPP_SRCS ViewProviderOrigin.cpp ViewProviderMaterialObject.cpp ViewProviderTextDocument.cpp + ViewProviderTextureExtension.cpp ViewProviderLink.cpp LinkViewPyImp.cpp ViewProviderLinkPyImp.cpp @@ -981,6 +982,7 @@ SET(Viewprovider_SRCS ViewProviderOrigin.h ViewProviderMaterialObject.h ViewProviderTextDocument.h + ViewProviderTextureExtension.h ViewProviderLink.h ViewProviderVarSet.h AxisOrigin.h diff --git a/src/Gui/ViewProviderGeometryObject.cpp b/src/Gui/ViewProviderGeometryObject.cpp index d55ccd0071..d7c1754c15 100644 --- a/src/Gui/ViewProviderGeometryObject.cpp +++ b/src/Gui/ViewProviderGeometryObject.cpp @@ -34,14 +34,12 @@ #include #include #include -#include #endif #include #include #include -#include #include "Application.h" #include "Document.h" @@ -96,29 +94,10 @@ ViewProviderGeometryObject::ViewProviderGeometryObject() Selectable.setValue(isSelectionEnabled()); - pcSwitchAppearance = new SoSwitch; - pcSwitchAppearance->ref(); - pcSwitchTexture = new SoSwitch; - pcSwitchTexture->ref(); - pcShapeMaterial = new SoMaterial; setCoinAppearance(mat); pcShapeMaterial->ref(); - pcShapeTexture2D = new SoTexture2; - pcShapeTexture2D->ref(); - - pcTextureGroup3D = new SoGroup; - pcTextureGroup3D->ref(); - - // Materials go first, with textured faces drawing over them - pcSwitchAppearance->addChild(pcShapeMaterial); - pcSwitchAppearance->addChild(pcSwitchTexture); - pcSwitchTexture->addChild(pcShapeTexture2D); - pcSwitchTexture->addChild(pcTextureGroup3D); - pcSwitchAppearance->whichChild.setValue(0); - pcSwitchTexture->whichChild.setValue(SO_SWITCH_NONE); - pcBoundingBox = new Gui::SoFCBoundingBox; pcBoundingBox->ref(); @@ -130,11 +109,7 @@ ViewProviderGeometryObject::ViewProviderGeometryObject() ViewProviderGeometryObject::~ViewProviderGeometryObject() { - pcSwitchAppearance->unref(); - pcSwitchTexture->unref(); pcShapeMaterial->unref(); - pcShapeTexture2D->unref(); - pcTextureGroup3D->unref(); pcBoundingBox->unref(); pcBoundColor->unref(); } @@ -274,31 +249,12 @@ unsigned long ViewProviderGeometryObject::getBoundColor() const void ViewProviderGeometryObject::setCoinAppearance(const App::Material& source) { -#if 0 - if (!source.image.empty()) { - Base::Console().Log("setCoinAppearance(Texture)\n"); - activateTexture2D(); - - QByteArray by = QByteArray::fromBase64(QString::fromStdString(source.image).toUtf8()); - auto image = QImage::fromData(by, "PNG"); //.scaled(64, 64, Qt::KeepAspectRatio); - - SoSFImage texture; - Gui::BitmapFactory().convert(image, texture); - pcShapeTexture2D->image = texture; - } else { - Base::Console().Log("setCoinAppearance(Material)\n"); - activateMaterial(); - } -#endif - activateMaterial(); - - // Always set the material for items such as lines that don't support textures pcShapeMaterial->ambientColor.setValue(source.ambientColor.r, - source.ambientColor.g, - source.ambientColor.b); + source.ambientColor.g, + source.ambientColor.b); pcShapeMaterial->diffuseColor.setValue(source.diffuseColor.r, - source.diffuseColor.g, - source.diffuseColor.b); + source.diffuseColor.g, + source.diffuseColor.b); pcShapeMaterial->specularColor.setValue(source.specularColor.r, source.specularColor.g, source.specularColor.b); @@ -309,31 +265,6 @@ void ViewProviderGeometryObject::setCoinAppearance(const App::Material& source) pcShapeMaterial->transparency.setValue(source.transparency); } -void ViewProviderGeometryObject::activateMaterial() -{ - pcSwitchAppearance->whichChild.setValue(0); - pcSwitchTexture->whichChild.setValue(SO_SWITCH_NONE); -} - -void ViewProviderGeometryObject::activateTexture2D() -{ - pcSwitchAppearance->whichChild.setValue(1); - pcSwitchTexture->whichChild.setValue(0); -} - -void ViewProviderGeometryObject::activateTexture3D() -{ - pcSwitchAppearance->whichChild.setValue(1); - pcSwitchTexture->whichChild.setValue(1); -} - -void ViewProviderGeometryObject::activateMixed3D() -{ - pcSwitchAppearance->whichChild.setValue(SO_SWITCH_ALL); - pcSwitchTexture->whichChild.setValue(1); -} - - namespace { float getBoundBoxFontSize() diff --git a/src/Gui/ViewProviderGeometryObject.h b/src/Gui/ViewProviderGeometryObject.h index 48e04369b6..607cd42d2f 100644 --- a/src/Gui/ViewProviderGeometryObject.h +++ b/src/Gui/ViewProviderGeometryObject.h @@ -30,7 +30,6 @@ class SoPickedPointList; class SoSwitch; class SoSensor; -class SoTexture2; class SbVec2s; class SoBaseColor; @@ -109,28 +108,11 @@ protected: const char* PropName) override; void setCoinAppearance(const App::Material& source); - /** - * Select which appearance type is active - * - */ - /** Material only */ - void activateMaterial(); - /** 2D Texture */ - void activateTexture2D(); - /** 3D texture only */ - void activateTexture3D(); - /** Mix of material and 3D textures */ - void activateMixed3D(); - private: bool isSelectionEnabled() const; protected: - SoSwitch* pcSwitchAppearance {nullptr}; - SoSwitch* pcSwitchTexture {nullptr}; SoMaterial* pcShapeMaterial {nullptr}; - SoTexture2* pcShapeTexture2D {nullptr}; - SoGroup* pcTextureGroup3D {nullptr}; SoFCBoundingBox* pcBoundingBox {nullptr}; SoSwitch* pcBoundSwitch {nullptr}; SoBaseColor* pcBoundColor {nullptr}; diff --git a/src/Gui/ViewProviderTextureExtension.cpp b/src/Gui/ViewProviderTextureExtension.cpp new file mode 100644 index 0000000000..b720fa2a08 --- /dev/null +++ b/src/Gui/ViewProviderTextureExtension.cpp @@ -0,0 +1,183 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +/*************************************************************************** + * Copyright (c) 2024 David Carter * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + **************************************************************************/ + +#include "PreCompiled.h" +#ifndef _PreComp_ +#include +#include +#include +#include +#include +#include +#endif + +#include "ViewProviderTextureExtension.h" +#include +#include + + +using namespace Gui; + + +EXTENSION_PROPERTY_SOURCE(Gui::ViewProviderTextureExtension, Gui::ViewProviderExtension) + + +ViewProviderTextureExtension::ViewProviderTextureExtension() +{ + initExtensionType(ViewProviderTextureExtension::getExtensionClassTypeId()); + + pcSwitchAppearance = new SoSwitch; + pcSwitchAppearance->ref(); + pcSwitchTexture = new SoSwitch; + pcSwitchTexture->ref(); + + pcShapeTexture2D = new SoTexture2; + pcShapeTexture2D->ref(); + + pcTextureGroup3D = new SoGroup; + pcTextureGroup3D->ref(); +} + +void ViewProviderTextureExtension::setup(SoMaterial* pcShapeMaterial) +{ + // Materials go first, with textured faces drawing over them + pcSwitchAppearance->addChild(pcShapeMaterial); + pcSwitchAppearance->addChild(pcSwitchTexture); + pcSwitchTexture->addChild(pcShapeTexture2D); + pcSwitchTexture->addChild(pcTextureGroup3D); + pcSwitchAppearance->whichChild.setValue(0); + pcSwitchTexture->whichChild.setValue(SO_SWITCH_NONE); +} + +ViewProviderTextureExtension::~ViewProviderTextureExtension() +{ + pcSwitchAppearance->unref(); + pcSwitchTexture->unref(); + pcShapeTexture2D->unref(); + pcTextureGroup3D->unref(); +} + +SoSwitch* ViewProviderTextureExtension::getAppearance() const +{ + return pcSwitchAppearance; +} + +SoGroup* ViewProviderTextureExtension::getTextureGroup3D() const +{ + return pcTextureGroup3D; +} + +void ViewProviderTextureExtension::setCoinAppearance(SoMaterial* pcShapeMaterial, const App::Material& source) +{ +#if 0 + if (!source.image.empty()) { + Base::Console().Log("setCoinAppearance(Texture)\n"); + activateTexture2D(); + + QByteArray by = QByteArray::fromBase64(QString::fromStdString(source.image).toUtf8()); + auto image = QImage::fromData(by, "PNG"); //.scaled(64, 64, Qt::KeepAspectRatio); + + SoSFImage texture; + Gui::BitmapFactory().convert(image, texture); + pcShapeTexture2D->image = texture; + } else { + Base::Console().Log("setCoinAppearance(Material)\n"); + activateMaterial(); + } +#endif + activateMaterial(); + + // Always set the material for items such as lines that don't support textures + pcShapeMaterial->ambientColor.setValue(source.ambientColor.r, + source.ambientColor.g, + source.ambientColor.b); + pcShapeMaterial->diffuseColor.setValue(source.diffuseColor.r, + source.diffuseColor.g, + source.diffuseColor.b); + pcShapeMaterial->specularColor.setValue(source.specularColor.r, + source.specularColor.g, + source.specularColor.b); + pcShapeMaterial->emissiveColor.setValue(source.emissiveColor.r, + source.emissiveColor.g, + source.emissiveColor.b); + pcShapeMaterial->shininess.setValue(source.shininess); + pcShapeMaterial->transparency.setValue(source.transparency); +} + +void ViewProviderTextureExtension::activateMaterial() +{ + pcSwitchAppearance->whichChild.setValue(0); + pcSwitchTexture->whichChild.setValue(SO_SWITCH_NONE); +} + +void ViewProviderTextureExtension::activateTexture2D() +{ + pcSwitchAppearance->whichChild.setValue(1); + pcSwitchTexture->whichChild.setValue(0); +} + +void ViewProviderTextureExtension::activateTexture3D() +{ + pcSwitchAppearance->whichChild.setValue(1); + pcSwitchTexture->whichChild.setValue(1); +} + +void ViewProviderTextureExtension::activateMixed3D() +{ + pcSwitchAppearance->whichChild.setValue(SO_SWITCH_ALL); + pcSwitchTexture->whichChild.setValue(1); +} + +// ------------------------------------------------------------------------------------------------ + +EXTENSION_PROPERTY_SOURCE(Gui::ViewProviderFaceTexture, Gui::ViewProviderTextureExtension) + + +ViewProviderFaceTexture::ViewProviderFaceTexture() +{ + initExtensionType(ViewProviderFaceTexture::getExtensionClassTypeId()); + + // Support for textured faces + pcShapeTexture3D = new SoTexture3; + pcShapeTexture3D->ref(); + pcShapeCoordinates = new SoCoordinate3; + pcShapeCoordinates->ref(); + pcShapeFaceset = new SoIndexedFaceSet; + pcShapeFaceset->ref(); +} + +ViewProviderFaceTexture::~ViewProviderFaceTexture() +{ + pcShapeTexture3D->unref(); + pcShapeCoordinates->unref(); + pcShapeFaceset->unref(); +} + +void ViewProviderFaceTexture::setup(SoMaterial* mat) +{ + ViewProviderTextureExtension::setup(mat); + + getTextureGroup3D()->addChild(pcShapeTexture3D); + getTextureGroup3D()->addChild(pcShapeCoordinates); + getTextureGroup3D()->addChild(pcShapeFaceset); +} diff --git a/src/Gui/ViewProviderTextureExtension.h b/src/Gui/ViewProviderTextureExtension.h new file mode 100644 index 0000000000..dd3e0590cf --- /dev/null +++ b/src/Gui/ViewProviderTextureExtension.h @@ -0,0 +1,100 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later + +/*************************************************************************** + * Copyright (c) 2024 David Carter * + * * + * This file is part of FreeCAD. * + * * + * FreeCAD is free software: you can redistribute it and/or modify it * + * under the terms of the GNU Lesser General Public License as * + * published by the Free Software Foundation, either version 2.1 of the * + * License, or (at your option) any later version. * + * * + * FreeCAD is distributed in the hope that it will be useful, but * + * WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * + * Lesser General Public License for more details. * + * * + * You should have received a copy of the GNU Lesser General Public * + * License along with FreeCAD. If not, see * + * . * + * * + **************************************************************************/ + + +#ifndef GUI_VIEWPROVIDERTEXTUREEXT_H +#define GUI_VIEWPROVIDERTEXTUREEXT_H + +#include + +class SoCoordinate3; +class SoGroup; +class SoIndexedFaceSet; +class SoMaterial; +class SoSwitch; +class SoTexture2; +class SoTexture3; + +namespace App +{ +class Material; +} + +namespace Gui +{ + +class GuiExport ViewProviderTextureExtension: public Gui::ViewProviderExtension +{ + EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(Gui::ViewProviderTextureExtension); + +public: + /// Constructor + ViewProviderTextureExtension(); + ~ViewProviderTextureExtension() override; + void setup(SoMaterial*); + void setCoinAppearance(SoMaterial* pcShapeMaterial, const App::Material& source); + SoSwitch* getAppearance() const; + SoGroup* getTextureGroup3D() const; + + /** + * Select which appearance type is active + * + */ + /** Material only */ + void activateMaterial(); + /** 2D Texture */ + void activateTexture2D(); + /** 3D texture only */ + void activateTexture3D(); + /** Mix of material and 3D textures */ + void activateMixed3D(); + +private: + SoSwitch* pcSwitchAppearance {nullptr}; + SoSwitch* pcSwitchTexture {nullptr}; + SoTexture2* pcShapeTexture2D {nullptr}; + SoGroup* pcTextureGroup3D {nullptr}; +}; + +class GuiExport ViewProviderFaceTexture: public Gui::ViewProviderTextureExtension +{ + EXTENSION_PROPERTY_HEADER_WITH_OVERRIDE(Gui::ViewProviderFaceTexture); + +public: + /// Constructor + ViewProviderFaceTexture(); + ~ViewProviderFaceTexture() override; + void setup(SoMaterial*); + +private: + // Used to support per face textures + SoTexture3 * pcShapeTexture3D; + SoCoordinate3 * pcShapeCoordinates; + SoIndexedFaceSet * pcShapeFaceset; +}; + +} //namespace Gui + + +#endif // GUI_VIEWPROVIDERTEXTUREEXT_H + diff --git a/src/Mod/Part/Gui/ViewProvider.cpp b/src/Mod/Part/Gui/ViewProvider.cpp index 7f17c6ee22..4c4b248746 100644 --- a/src/Mod/Part/Gui/ViewProvider.cpp +++ b/src/Mod/Part/Gui/ViewProvider.cpp @@ -72,8 +72,8 @@ void ViewProviderPart::applyColor(const Part::ShapeHistory& hist, } void ViewProviderPart::applyMaterial(const Part::ShapeHistory& hist, - const App::PropertyMaterialList& colBase, - std::vector& colBool) + const std::vector& colBase, + std::vector& colBool) { std::map>::const_iterator jt; // apply color from modified faces @@ -85,8 +85,7 @@ void ViewProviderPart::applyMaterial(const Part::ShapeHistory& hist, } } -void ViewProviderPart::applyTransparency(const float& transparency, - std::vector& colors) +void ViewProviderPart::applyTransparency(float transparency, std::vector& colors) { if (transparency != 0.0) { // transparency has been set object-wide @@ -99,7 +98,7 @@ void ViewProviderPart::applyTransparency(const float& transparency, } } -void ViewProviderPart::applyTransparency(const float& transparency, std::vector& colors) +void ViewProviderPart::applyTransparency(float transparency, std::vector& colors) { if (transparency != 0.0) { // transparency has been set object-wide diff --git a/src/Mod/Part/Gui/ViewProvider.h b/src/Mod/Part/Gui/ViewProvider.h index dae2d2ef29..1286a9a53d 100644 --- a/src/Mod/Part/Gui/ViewProvider.h +++ b/src/Mod/Part/Gui/ViewProvider.h @@ -58,12 +58,10 @@ protected: const std::vector& colBase, std::vector& colBool); void applyMaterial(const Part::ShapeHistory& hist, - const App::PropertyMaterialList& colBase, + const std::vector& colBase, std::vector& colBool); - void applyTransparency(const float& transparency, - std::vector& colors); - void applyTransparency(const float& transparency, - std::vector& colors); + void applyTransparency(float transparency, std::vector& colors); + void applyTransparency(float transparency, std::vector& colors); }; } // namespace PartGui diff --git a/src/Mod/Part/Gui/ViewProviderBoolean.cpp b/src/Mod/Part/Gui/ViewProviderBoolean.cpp index df8ebf5383..dd07cb959f 100644 --- a/src/Mod/Part/Gui/ViewProviderBoolean.cpp +++ b/src/Mod/Part/Gui/ViewProviderBoolean.cpp @@ -100,27 +100,27 @@ void ViewProviderBoolean::updateData(const App::Property* prop) auto vpTool = dynamic_cast( Gui::Application::Instance->getViewProvider(objTool)); if (vpBase && vpTool) { + std::vector colBase = vpBase->ShapeAppearance.getValues(); + std::vector colTool = vpTool->ShapeAppearance.getValues(); std::vector colBool; colBool.resize(boolMap.Extent(), this->ShapeAppearance[0]); - vpBase->ShapeAppearance.setTransparency(vpBase->Transparency.getValue()); - vpTool->ShapeAppearance.setTransparency(vpTool->Transparency.getValue()); + applyTransparency(vpBase->Transparency.getValue(),colBase); + applyTransparency(vpTool->Transparency.getValue(),colTool); - if (static_cast(vpBase->ShapeAppearance.getSize()) == baseMap.Extent()) { - applyMaterial(hist[0], vpBase->ShapeAppearance, colBool); + if (static_cast(colBase.size()) == baseMap.Extent()) { + applyMaterial(hist[0], colBase, colBool); } - else if (vpBase->ShapeAppearance.getSize() > 0 - && vpBase->ShapeAppearance[0] != this->ShapeAppearance[0]) { - vpBase->ShapeAppearance.setSize(baseMap.Extent(), vpBase->ShapeAppearance[0]); - applyMaterial(hist[0], vpBase->ShapeAppearance, colBool); + else if (!colBase.empty() && colBase[0] != this->ShapeAppearance[0]) { + colBase.resize(baseMap.Extent(), colBase[0]); + applyMaterial(hist[0], colBase, colBool); } - if (static_cast(vpTool->ShapeAppearance.getSize()) == toolMap.Extent()) { - applyMaterial(hist[1], vpTool->ShapeAppearance, colBool); + if (static_cast(colTool.size()) == toolMap.Extent()) { + applyMaterial(hist[1], colTool, colBool); } - else if (vpTool->ShapeAppearance.getSize() > 0 - && vpTool->ShapeAppearance[0] != this->ShapeAppearance[0]) { - vpTool->ShapeAppearance.setSize(toolMap.Extent(), vpTool->ShapeAppearance[0]); - applyMaterial(hist[1], vpTool->ShapeAppearance, colBool); + else if (!colTool.empty() && colTool[0] != this->ShapeAppearance[0]) { + colTool.resize(toolMap.Extent(), colTool[0]); + applyMaterial(hist[1], colTool, colBool); } // If the view provider has set a transparency then override the values @@ -201,14 +201,14 @@ void ViewProviderMultiFuse::updateData(const App::Property* prop) auto vpBase = dynamic_cast(Gui::Application::Instance->getViewProvider(objBase)); if (vpBase) { - vpBase->ShapeAppearance.setTransparency(vpBase->Transparency.getValue()); - if (static_cast(vpBase->ShapeAppearance.getSize()) == baseMap.Extent()) { - applyMaterial(hist[index], vpBase->ShapeAppearance, colBool); + std::vector colBase = vpBase->ShapeAppearance.getValues(); + applyTransparency(vpBase->Transparency.getValue(),colBase); + if (static_cast(colBase.size()) == baseMap.Extent()) { + applyMaterial(hist[index], colBase, colBool); } - else if (vpBase->ShapeAppearance.getSize() > 0 - && vpBase->ShapeAppearance[0] != this->ShapeAppearance[0]) { - vpBase->ShapeAppearance.setSize(baseMap.Extent(), vpBase->ShapeAppearance[0]); - applyMaterial(hist[index], vpBase->ShapeAppearance, colBool); + else if (!colBase.empty() && colBase[0] != this->ShapeAppearance[0]) { + colBase.resize(baseMap.Extent(), colBase[0]); + applyMaterial(hist[index], colBase, colBool); } } } @@ -336,14 +336,14 @@ void ViewProviderMultiCommon::updateData(const App::Property* prop) auto vpBase = dynamic_cast(Gui::Application::Instance->getViewProvider(objBase)); if (vpBase) { - vpBase->ShapeAppearance.setTransparency(vpBase->Transparency.getValue()); - if (static_cast(vpBase->ShapeAppearance.getSize()) == baseMap.Extent()) { - applyMaterial(hist[index], vpBase->ShapeAppearance, colBool); + std::vector colBase = vpBase->ShapeAppearance.getValues(); + applyTransparency(vpBase->Transparency.getValue(),colBase); + if (static_cast(colBase.size()) == baseMap.Extent()) { + applyMaterial(hist[index], colBase, colBool); } - else if (vpBase->ShapeAppearance.getSize() > 0 - && vpBase->ShapeAppearance[0] != this->ShapeAppearance[0]) { - vpBase->ShapeAppearance.setSize(baseMap.Extent(), vpBase->ShapeAppearance[0]); - applyMaterial(hist[index], vpBase->ShapeAppearance, colBool); + else if (!colBase.empty() && colBase[0] != this->ShapeAppearance[0]) { + colBase.resize(baseMap.Extent(), colBase[0]); + applyMaterial(hist[index], colBase, colBool); } } } diff --git a/src/Mod/Part/Gui/ViewProviderCompound.cpp b/src/Mod/Part/Gui/ViewProviderCompound.cpp index 9754362524..50d34cd12d 100644 --- a/src/Mod/Part/Gui/ViewProviderCompound.cpp +++ b/src/Mod/Part/Gui/ViewProviderCompound.cpp @@ -111,14 +111,14 @@ void ViewProviderCompound::updateData(const App::Property* prop) auto vpBase = dynamic_cast(Gui::Application::Instance->getViewProvider(objBase)); if (vpBase) { - vpBase->ShapeAppearance.setTransparency(vpBase->Transparency.getValue()); - if (static_cast(vpBase->ShapeAppearance.getSize()) == baseMap.Extent()) { - applyMaterial(hist[index], vpBase->ShapeAppearance, compCol); + std::vector baseCol = vpBase->ShapeAppearance.getValues(); + applyTransparency(vpBase->Transparency.getValue(), baseCol); + if (static_cast(baseCol.size()) == baseMap.Extent()) { + applyMaterial(hist[index], baseCol, compCol); } - else if (vpBase->ShapeAppearance.getSize() > 0 - && vpBase->ShapeAppearance[0] != this->ShapeAppearance[0]) { - vpBase->ShapeAppearance.setSize(baseMap.Extent(), vpBase->ShapeAppearance[0]); - applyMaterial(hist[index], vpBase->ShapeAppearance, compCol); + else if (!baseCol.empty() && baseCol[0] != this->ShapeAppearance[0]) { + baseCol.resize(baseMap.Extent(), baseCol[0]); + applyMaterial(hist[index], baseCol, compCol); } } } diff --git a/src/Mod/Part/Gui/ViewProviderExt.cpp b/src/Mod/Part/Gui/ViewProviderExt.cpp index 38140df7de..5f6f550601 100644 --- a/src/Mod/Part/Gui/ViewProviderExt.cpp +++ b/src/Mod/Part/Gui/ViewProviderExt.cpp @@ -66,7 +66,6 @@ # include # include # include -# include # include #endif @@ -125,6 +124,8 @@ const char* ViewProviderPartExt::DrawStyleEnums[]= {"Solid","Dashed","Dotted","D ViewProviderPartExt::ViewProviderPartExt() { + texture.initExtension(this); + VisualTouched = true; forceUpdateCount = 0; NormalsFromUV = true; @@ -197,16 +198,6 @@ ViewProviderPartExt::ViewProviderPartExt() ADD_PROPERTY_TYPE(DrawStyle,((long int)0), osgroup, App::Prop_None, "Defines the style of the edges in the 3D view."); DrawStyle.setEnums(DrawStyleEnums); - // This is needed to restore old DiffuseColor values since the restore - // function is asynchronous - App::PropertyColor noColor; - ADD_PROPERTY_TYPE(_diffuseColor, - (noColor.getValue()), - osgroup, - App::Prop_NoPersist, - "Object diffuse color."); - _diffuseColor.setStatus(App::Property::PropHidden, true); - coords = new SoCoordinate3(); coords->ref(); faceset = new SoBrepFaceSet(); @@ -221,14 +212,6 @@ ViewProviderPartExt::ViewProviderPartExt() nodeset = new SoBrepPointSet(); nodeset->ref(); - // Support for textured faces - pcShapeTexture3D = new SoTexture3; - pcShapeTexture3D->ref(); - pcShapeCoordinates = new SoCoordinate3; - pcShapeCoordinates->ref(); - pcShapeFaceset = new SoIndexedFaceSet; - pcShapeFaceset->ref(); - pcFaceBind = new SoMaterialBinding(); pcFaceBind->ref(); @@ -280,10 +263,6 @@ ViewProviderPartExt::~ViewProviderPartExt() normb->unref(); lineset->unref(); nodeset->unref(); - - pcShapeTexture3D->unref(); - pcShapeCoordinates->unref(); - pcShapeFaceset->unref(); } PyObject* ViewProviderPartExt::getPyObject() @@ -363,7 +342,7 @@ void ViewProviderPartExt::onChanged(const App::Property* prop) else if (prop == &_diffuseColor) { // Used to load the old DiffuseColor values asynchronously ShapeAppearance.setDiffuseColors(_diffuseColor.getValues()); - ShapeAppearance.setTransparency(Transparency.getValue() / 100.0f); + ShapeAppearance.setTransparency(Transparency.getValue() / 100.0F); } else if (prop == &ShapeAppearance) { setHighlightedFaces(ShapeAppearance); @@ -374,11 +353,7 @@ void ViewProviderPartExt::onChanged(const App::Property* prop) long value = toPercent(Mat.transparency); if (value != Transparency.getValue()) { float trans = fromPercent(Transparency.getValue()); - - App::PropertyContainer* parent = ShapeAppearance.getContainer(); - ShapeAppearance.setContainer(nullptr); ShapeAppearance.setTransparency(trans); - ShapeAppearance.setContainer(parent); } } else if (prop == &Lighting) { @@ -467,10 +442,8 @@ void ViewProviderPartExt::attach(App::DocumentObject *pcFeat) // just faces with no edges or points pcFlatRoot->addChild(pShapeHints); pcFlatRoot->addChild(pcFaceBind); - pcFlatRoot->addChild(pcSwitchAppearance); - pcTextureGroup3D->addChild(pcShapeTexture3D); - pcTextureGroup3D->addChild(pcShapeCoordinates); - pcTextureGroup3D->addChild(pcShapeFaceset); + pcFlatRoot->addChild(texture.getAppearance()); + texture.setup(pcShapeMaterial); SoDrawStyle* pcFaceStyle = new SoDrawStyle(); pcFaceStyle->style = SoDrawStyle::FILLED; pcFlatRoot->addChild(pcFaceStyle); @@ -627,10 +600,16 @@ std::vector ViewProviderPartExt::getSelectionShape(const char* / void ViewProviderPartExt::setHighlightedFaces(const std::vector& materials) { + if (getObject() && getObject()->testStatus(App::ObjectStatus::TouchOnColorChange)) + getObject()->touch(true); + + Gui::SoUpdateVBOAction action; + action.apply(this->faceset); + int size = static_cast(materials.size()); if (size > 1 && size == this->faceset->partIndex.getNum()) { pcFaceBind->value = SoMaterialBinding::PER_PART; - activateMaterial(); + texture.activateMaterial(); pcShapeMaterial->diffuseColor.setNum(size); pcShapeMaterial->ambientColor.setNum(size); @@ -666,49 +645,7 @@ void ViewProviderPartExt::setHighlightedFaces(const std::vector& void ViewProviderPartExt::setHighlightedFaces(const App::PropertyMaterialList& appearance) { - int size = static_cast(appearance.getSize()); - if (size > 1 && size == this->faceset->partIndex.getNum()) { - pcFaceBind->value = SoMaterialBinding::PER_PART; - activateMaterial(); - - pcShapeMaterial->diffuseColor.setNum(size); - pcShapeMaterial->ambientColor.setNum(size); - pcShapeMaterial->specularColor.setNum(size); - pcShapeMaterial->emissiveColor.setNum(size); - pcShapeMaterial->shininess.setNum(size); - - SbColor* dc = pcShapeMaterial->diffuseColor.startEditing(); - SbColor* ac = pcShapeMaterial->ambientColor.startEditing(); - SbColor* sc = pcShapeMaterial->specularColor.startEditing(); - SbColor* ec = pcShapeMaterial->emissiveColor.startEditing(); - float* sh = pcShapeMaterial->shininess.startEditing(); - - for (int i = 0; i < size; i++) { - dc[i].setValue(appearance.getDiffuseColor(i).r, - appearance.getDiffuseColor(i).g, - appearance.getDiffuseColor(i).b); - ac[i].setValue(appearance.getAmbientColor(i).r, - appearance.getAmbientColor(i).g, - appearance.getAmbientColor(i).b); - sc[i].setValue(appearance.getSpecularColor(i).r, - appearance.getSpecularColor(i).g, - appearance.getSpecularColor(i).b); - ec[i].setValue(appearance.getEmissiveColor(i).r, - appearance.getEmissiveColor(i).g, - appearance.getEmissiveColor(i).b); - sh[i] = appearance.getShininess(i); - } - - pcShapeMaterial->diffuseColor.finishEditing(); - pcShapeMaterial->ambientColor.finishEditing(); - pcShapeMaterial->specularColor.finishEditing(); - pcShapeMaterial->emissiveColor.finishEditing(); - pcShapeMaterial->shininess.finishEditing(); - } - else if (size == 1) { - pcFaceBind->value = SoMaterialBinding::OVERALL; - setCoinAppearance(appearance[0]); - } + setHighlightedFaces(appearance.getValues()); } std::map ViewProviderPartExt::getElementColors(const char *element) const { @@ -802,7 +739,6 @@ std::map ViewProviderPartExt::getElementColors(const cha void ViewProviderPartExt::unsetHighlightedFaces() { - // DiffuseColor.touch(); ShapeAppearance.touch(); Transparency.touch(); } @@ -925,7 +861,9 @@ void ViewProviderPartExt::finishRestoring() // and currently sets a single color. // In case DiffuseColor has defined multiple colors they will // be passed to the scene graph now. - ShapeAppearance.touch(); + if (_diffuseColor.getSize() > 1) { + onChanged(&_diffuseColor); + } Gui::ViewProviderGeometryObject::finishRestoring(); } @@ -1371,8 +1309,7 @@ void ViewProviderPartExt::updateVisual() VisualTouched = false; // The material has to be checked again - // setHighlightedFaces(DiffuseColor.getValues()); - setHighlightedFaces(ShapeAppearance); + setHighlightedFaces(ShapeAppearance.getValues()); setHighlightedEdges(LineColorArray.getValues()); setHighlightedPoints(PointColorArray.getValue()); } diff --git a/src/Mod/Part/Gui/ViewProviderExt.h b/src/Mod/Part/Gui/ViewProviderExt.h index 249cae1d2f..af366249ae 100644 --- a/src/Mod/Part/Gui/ViewProviderExt.h +++ b/src/Mod/Part/Gui/ViewProviderExt.h @@ -27,6 +27,7 @@ #include #include +#include #include #include @@ -52,7 +53,6 @@ class SoNormal; class SoNormalBinding; class SoMaterialBinding; class SoIndexedLineSet; -class SoTexture3; namespace PartGui { @@ -86,8 +86,6 @@ public: App::PropertyColor LineColor; App::PropertyMaterial LineMaterial; App::PropertyColorList LineColorArray; - // Faces (Gui::ViewProviderGeometryObject::ShapeAppearance and Gui::ViewProviderGeometryObject::ShapeMaterial apply) - // App::PropertyColorList DiffuseColor; void attach(App::DocumentObject *) override; void setDisplayMode(const char* ModeName) override; @@ -186,15 +184,11 @@ protected: SoBrepEdgeSet * lineset; SoBrepPointSet * nodeset; - // Used to support per face textures - SoTexture3 * pcShapeTexture3D; - SoCoordinate3 * pcShapeCoordinates; - SoIndexedFaceSet * pcShapeFaceset; - bool VisualTouched; bool NormalsFromUV; private: + Gui::ViewProviderFaceTexture texture; // settings stuff int forceUpdateCount; static App::PropertyFloatConstraint::Constraints sizeRange; diff --git a/src/Mod/Part/Gui/ViewProviderMirror.cpp b/src/Mod/Part/Gui/ViewProviderMirror.cpp index df93218245..579ec03e17 100644 --- a/src/Mod/Part/Gui/ViewProviderMirror.cpp +++ b/src/Mod/Part/Gui/ViewProviderMirror.cpp @@ -263,18 +263,17 @@ void ViewProviderFillet::updateData(const App::Property* prop) auto vpBase = dynamic_cast(Gui::Application::Instance->getViewProvider(objBase)); if (vpBase) { - // std::vector colBase = vpBase->DiffuseColor.getValues(); + auto colBase = static_cast(vpBase)->ShapeAppearance.getValues(); std::vector colFill; - colFill.resize(fillMap.Extent(), vpBase->ShapeAppearance[0]); - vpBase->ShapeAppearance.setTransparency(vpBase->Transparency.getValue()); + colFill.resize(fillMap.Extent(), colBase[0]); + applyTransparency(static_cast(vpBase)->Transparency.getValue(), colBase); - if (static_cast(vpBase->ShapeAppearance.getSize()) == baseMap.Extent()) { - applyMaterial(hist[0], vpBase->ShapeAppearance, colFill); + if (static_cast(colBase.size()) == baseMap.Extent()) { + applyMaterial(hist[0], colBase, colFill); } - else if (vpBase->ShapeAppearance.getSize() > 0 - && vpBase->ShapeAppearance[0] != this->ShapeAppearance[0]) { - vpBase->ShapeAppearance.setSize(baseMap.Extent(), vpBase->ShapeAppearance[0]); - applyMaterial(hist[0], vpBase->ShapeAppearance, colFill); + else if (!colBase.empty() && colBase[0] != this->ShapeAppearance[0]) { + colBase.resize(baseMap.Extent(), colBase[0]); + applyMaterial(hist[0], colBase, colFill); } // If the view provider has set a transparency then override the values @@ -374,17 +373,16 @@ void ViewProviderChamfer::updateData(const App::Property* prop) auto vpBase = dynamic_cast(Gui::Application::Instance->getViewProvider(objBase)); if (vpBase) { - // std::vector colBase = static_cast(vpBase)->DiffuseColor.getValues(); - auto& colBase = static_cast(vpBase)->ShapeAppearance; + auto colBase = static_cast(vpBase)->ShapeAppearance.getValues(); std::vector colCham; colCham.resize(chamMap.Extent(), colBase[0]); - colBase.setTransparency(static_cast(vpBase)->Transparency.getValue()); + applyTransparency(static_cast(vpBase)->Transparency.getValue(), colBase); - if (static_cast(colBase.getSize()) == baseMap.Extent()) { + if (static_cast(colBase.size()) == baseMap.Extent()) { applyMaterial(hist[0], colBase, colCham); } - else if (colBase.getSize() > 0 && colBase[0] != this->ShapeAppearance[0]) { - colBase.setSize(baseMap.Extent(), colBase[0]); + else if (!colBase.empty() && colBase[0] != this->ShapeAppearance[0]) { + colBase.resize(baseMap.Extent(), colBase[0]); applyMaterial(hist[0], colBase, colCham); } diff --git a/src/Mod/PartDesign/Gui/ViewProviderBody.cpp b/src/Mod/PartDesign/Gui/ViewProviderBody.cpp index 429a359fd4..8722e0a024 100644 --- a/src/Mod/PartDesign/Gui/ViewProviderBody.cpp +++ b/src/Mod/PartDesign/Gui/ViewProviderBody.cpp @@ -427,6 +427,7 @@ void ViewProviderBody::unifyVisualProperty(const App::Property* prop) { if (prop == &Visibility || prop == &Selectable || prop == &DisplayModeBody || + prop == &ShapeAppearance || prop == &PointColorArray || prop == &LineColorArray) { return;