Material: Material appearance

Uses new material system for appearance

Each feature object now has a property called ShapeMaterial that
describes its physical properties. If it has a shape, it has a
material.

The ShapeColor attribute is replaced by a ShapeAppearance attribute.
This is a material list that describes all appearance properties, not
just diffuse color. As a list in can be used for all elements of a
shape, such as edges and faces.

A new widget is provided to allow the user to select materials in a
consistent fashion. It can also launch the material editor with its
more advanced capabilities.
This commit is contained in:
David Carter
2024-03-17 18:37:56 -04:00
committed by Chris Hennes
parent 37c38acd19
commit ba20441935
121 changed files with 4682 additions and 1685 deletions

View File

@@ -220,6 +220,7 @@ generate_from_xml(DocumentPy)
generate_from_xml(PythonWorkbenchPy)
generate_from_xml(ViewProviderPy)
generate_from_xml(ViewProviderDocumentObjectPy)
generate_from_xml(ViewProviderGeometryObjectPy)
generate_from_xml(ViewProviderExtensionPy)
generate_from_xml(WorkbenchPy)
generate_from_xml(SelectionObjectPy)
@@ -233,6 +234,7 @@ generate_from_py(FreeCADGuiInit GuiInitScript.h)
# The XML files
SET(FreeCADGui_XML_SRCS
ViewProviderDocumentObjectPy.xml
ViewProviderGeometryObjectPy.xml
ViewProviderPy.xml
ViewProviderExtensionPy.xml
PythonWorkbenchPy.xml
@@ -297,7 +299,6 @@ SET(Gui_UIC_SRCS
DlgChooseIcon.ui
DlgCreateNewPreferencePack.ui
DlgCustomizeSpNavSettings.ui
DlgDisplayProperties.ui
DlgInputDialog.ui
DlgKeyboard.ui
DlgMacroExecute.ui
@@ -407,7 +408,6 @@ SET(Dialog_CPP_SRCS
DlgActivateWindowImp.cpp
DlgCreateNewPreferencePackImp.cpp
DlgUnitsCalculatorImp.cpp
DlgDisplayPropertiesImp.cpp
DlgInputDialogImp.cpp
DlgMacroExecuteImp.cpp
DlgRunExternal.cpp
@@ -447,7 +447,6 @@ SET(Dialog_HPP_SRCS
DlgActivateWindowImp.h
DlgCreateNewPreferencePackImp.h
DlgUnitsCalculatorImp.h
DlgDisplayPropertiesImp.h
DlgInputDialogImp.h
DlgMacroExecuteImp.h
DlgRunExternal.h
@@ -490,7 +489,6 @@ SET(Dialog_SRCS
DlgActivateWindow.ui
DlgUnitsCalculator.ui
DlgAuthorization.ui
DlgDisplayProperties.ui
DlgInputDialog.ui
DlgAddProperty.ui
DlgLocationAngle.ui
@@ -900,6 +898,7 @@ SET(Viewprovider_CPP_SRCS
ViewProviderDocumentObject.cpp
ViewProviderDocumentObjectGroup.cpp
ViewProviderDocumentObjectPyImp.cpp
ViewProviderGeometryObjectPyImp.cpp
ViewProviderDragger.cpp
ViewProviderExtern.cpp
ViewProviderFeature.cpp

View File

@@ -785,7 +785,8 @@ void Command::_copyVisual(const char *file, int line, const App::DocumentObject
if(!from || !from->isAttachedToDocument() || !to || !to->isAttachedToDocument())
return;
static std::map<std::string,std::string> attrMap = {
{"ShapeColor","ShapeMaterial.DiffuseColor"},
// {"ShapeColor","ShapeMaterial.DiffuseColor"},
{"ShapeAppearance", "ShapeMaterial"},
// {"LineColor","ShapeMaterial.DiffuseColor"},
// {"PointColor","ShapeMaterial.DiffuseColor"},
{"Transparency","Transparency"},

View File

@@ -104,9 +104,11 @@ void StdCmdRandomColor::activated(int iMsg)
vpLink->ShapeMaterial.setDiffuseColor(objColor);
}
else if (view) {
if (auto color = dynamic_cast<App::PropertyColor*>(view->getPropertyByName("ShapeColor"))) {
auto appearance =
dynamic_cast<App::PropertyMaterial*>(view->getPropertyByName("ShapeAppearance"));
if (appearance) {
// get the view provider of the selected object and set the shape color
color->setValue(objColor);
appearance->setDiffuseColor(objColor);
}
}
};

View File

@@ -62,7 +62,6 @@
#include "Control.h"
#include "Clipping.h"
#include "DemoMode.h"
#include "DlgDisplayPropertiesImp.h"
#include "DlgSettingsImageImp.h"
#include "Document.h"
#include "FileDialog.h"
@@ -1262,36 +1261,6 @@ bool StdCmdHideObjects::isActive()
return App::GetApplication().getActiveDocument();
}
//===========================================================================
// Std_SetAppearance
//===========================================================================
DEF_STD_CMD_A(StdCmdSetAppearance)
StdCmdSetAppearance::StdCmdSetAppearance()
: Command("Std_SetAppearance")
{
sGroup = "Standard-View";
sMenuText = QT_TR_NOOP("Appearance...");
sToolTipText = QT_TR_NOOP("Sets the display properties of the selected object");
sWhatsThis = "Std_SetAppearance";
sStatusTip = QT_TR_NOOP("Sets the display properties of the selected object");
sPixmap = "Std_SetAppearance";
sAccel = "Ctrl+D";
eType = Alter3DView;
}
void StdCmdSetAppearance::activated(int iMsg)
{
Q_UNUSED(iMsg);
Gui::Control().showDialog(new Gui::Dialog::TaskDisplayProperties());
}
bool StdCmdSetAppearance::isActive()
{
return (Gui::Control().activeDialog() == nullptr) &&
(Gui::Selection().size() != 0);
}
//===========================================================================
// Std_ViewHome
//===========================================================================
@@ -4123,7 +4092,6 @@ void CreateViewStdCommands()
rcCmdMgr.addCommand(new StdViewLoadImage());
rcCmdMgr.addCommand(new StdMainFullscreen());
rcCmdMgr.addCommand(new StdViewDockUndockFullscreen());
rcCmdMgr.addCommand(new StdCmdSetAppearance());
rcCmdMgr.addCommand(new StdCmdToggleVisibility());
rcCmdMgr.addCommand(new StdCmdToggleTransparency());
rcCmdMgr.addCommand(new StdCmdToggleSelectability());

View File

@@ -1,528 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Gui::Dialog::DlgDisplayProperties</class>
<widget class="QDialog" name="Gui::Dialog::DlgDisplayProperties">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>290</width>
<height>503</height>
</rect>
</property>
<property name="windowTitle">
<string>Display properties</string>
</property>
<layout class="QGridLayout" name="gridLayout_4">
<item row="0" column="0">
<widget class="QGroupBox" name="groupBox1">
<property name="title">
<string>Viewing mode</string>
</property>
<layout class="QGridLayout" name="gridLayout_3">
<property name="leftMargin">
<number>11</number>
</property>
<property name="topMargin">
<number>11</number>
</property>
<property name="rightMargin">
<number>11</number>
</property>
<property name="bottomMargin">
<number>11</number>
</property>
<item row="0" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="textLabel1">
<property name="text">
<string>Document window:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="changeMode"/>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="textLabel1_3">
<property name="enabled">
<bool>false</bool>
</property>
<property name="text">
<string>Plot mode:</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="changePlot">
<property name="enabled">
<bool>false</bool>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="1" column="0">
<widget class="QGroupBox" name="groupBox3">
<property name="title">
<string>Material</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QComboBox" name="changeMaterial"/>
</item>
<item>
<widget class="QPushButton" name="buttonUserDefinedMaterial">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>40</width>
<height>32767</height>
</size>
</property>
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QLabel" name="label_4">
<property name="text">
<string>Color plot:</string>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="QPushButton" name="buttonColorPlot">
<property name="text">
<string notr="true">...</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Shape color:</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="Gui::ColorButton" name="buttonColor">
<property name="text">
<string/>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>Line color:</string>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="Gui::ColorButton" name="buttonLineColor"/>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_5">
<property name="text">
<string>Point color:</string>
</property>
</widget>
</item>
<item row="3" column="1">
<widget class="Gui::ColorButton" name="buttonPointColor"/>
</item>
</layout>
</item>
</layout>
</widget>
</item>
<item row="2" column="0">
<widget class="QGroupBox" name="groupBox2">
<property name="title">
<string>Display</string>
</property>
<layout class="QGridLayout">
<property name="leftMargin">
<number>9</number>
</property>
<property name="topMargin">
<number>9</number>
</property>
<property name="rightMargin">
<number>9</number>
</property>
<property name="bottomMargin">
<number>9</number>
</property>
<property name="spacing">
<number>6</number>
</property>
<item row="0" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="textLabel2">
<property name="text">
<string>Point size:</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>71</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSpinBox" name="spinPointSize">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>64</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLabel" name="textLabel3">
<property name="text">
<string>Line width:</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Expanding</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>71</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QSpinBox" name="spinLineWidth">
<property name="minimum">
<number>1</number>
</property>
<property name="maximum">
<number>64</number>
</property>
<property name="value">
<number>2</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="2" column="0">
<widget class="QLabel" name="textLabel1_2">
<property name="text">
<string>Transparency:</string>
</property>
</widget>
</item>
<item row="3" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSlider" name="horizontalSlider">
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinTransparency">
<property name="sizePolicy">
<sizepolicy hsizetype="Maximum" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
</widget>
</item>
</layout>
</item>
<item row="4" column="0">
<widget class="QLabel" name="label">
<property name="text">
<string>Line transparency:</string>
</property>
</widget>
</item>
<item row="5" column="0">
<layout class="QHBoxLayout">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QSlider" name="sliderLineTransparency">
<property name="maximum">
<number>100</number>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
</widget>
</item>
<item>
<widget class="QSpinBox" name="spinLineTransparency">
<property name="maximum">
<number>100</number>
</property>
<property name="singleStep">
<number>5</number>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<layoutdefault spacing="6" margin="11"/>
<customwidgets>
<customwidget>
<class>Gui::ColorButton</class>
<extends>QPushButton</extends>
<header>Gui/Widgets.h</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>changeMode</tabstop>
<tabstop>changePlot</tabstop>
<tabstop>changeMaterial</tabstop>
<tabstop>buttonUserDefinedMaterial</tabstop>
<tabstop>buttonColor</tabstop>
<tabstop>buttonLineColor</tabstop>
<tabstop>spinPointSize</tabstop>
<tabstop>spinLineWidth</tabstop>
<tabstop>horizontalSlider</tabstop>
<tabstop>spinTransparency</tabstop>
<tabstop>sliderLineTransparency</tabstop>
<tabstop>spinLineTransparency</tabstop>
</tabstops>
<resources/>
<connections>
<connection>
<sender>spinTransparency</sender>
<signal>valueChanged(int)</signal>
<receiver>horizontalSlider</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>240</x>
<y>339</y>
</hint>
<hint type="destinationlabel">
<x>113</x>
<y>339</y>
</hint>
</hints>
</connection>
<connection>
<sender>horizontalSlider</sender>
<signal>valueChanged(int)</signal>
<receiver>spinTransparency</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>113</x>
<y>339</y>
</hint>
<hint type="destinationlabel">
<x>240</x>
<y>339</y>
</hint>
</hints>
</connection>
<connection>
<sender>sliderLineTransparency</sender>
<signal>valueChanged(int)</signal>
<receiver>spinLineTransparency</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>147</x>
<y>408</y>
</hint>
<hint type="destinationlabel">
<x>246</x>
<y>393</y>
</hint>
</hints>
</connection>
<connection>
<sender>spinLineTransparency</sender>
<signal>valueChanged(int)</signal>
<receiver>sliderLineTransparency</receiver>
<slot>setValue(int)</slot>
<hints>
<hint type="sourcelabel">
<x>254</x>
<y>402</y>
</hint>
<hint type="destinationlabel">
<x>98</x>
<y>404</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@@ -1,647 +0,0 @@
/***************************************************************************
* Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
# include <algorithm>
# include <boost_signals2.hpp>
# include <QDockWidget>
# include <QSignalBlocker>
#endif
#include <Base/Console.h>
#include "DlgDisplayPropertiesImp.h"
#include "ui_DlgDisplayProperties.h"
#include "Application.h"
#include "Document.h"
#include "DlgMaterialPropertiesImp.h"
#include "DockWindowManager.h"
#include "Selection.h"
#include "ViewProvider.h"
#include "WaitCursor.h"
using namespace Gui::Dialog;
using namespace std;
namespace sp = std::placeholders;
/* TRANSLATOR Gui::Dialog::DlgDisplayPropertiesImp */
#if 0 // needed for Qt's lupdate utility
qApp->translate("QDockWidget", "Display properties");
#endif
class DlgDisplayPropertiesImp::Private
{
using DlgDisplayPropertiesImp_Connection = boost::signals2::connection;
public:
Ui::DlgDisplayProperties ui;
bool floating;
DlgDisplayPropertiesImp_Connection connectChangedObject;
static void setElementColor(const std::vector<Gui::ViewProvider*>& views, const char* property, Gui::ColorButton* buttonColor)
{
bool hasElementColor = false;
for (const auto & view : views) {
if (auto* prop = dynamic_cast<App::PropertyColor*>(view->getPropertyByName(property))) {
App::Color color = prop->getValue();
QSignalBlocker block(buttonColor);
buttonColor->setColor(color.asValue<QColor>());
hasElementColor = true;
break;
}
}
buttonColor->setEnabled(hasElementColor);
}
static void setDrawStyle(const std::vector<Gui::ViewProvider*>& views, const char* property, QSpinBox* spinbox)
{
bool hasDrawStyle = false;
for (const auto & view : views) {
if (auto* prop = dynamic_cast<App::PropertyFloat*>(view->getPropertyByName(property))) {
QSignalBlocker block(spinbox);
spinbox->setValue(int(prop->getValue()));
hasDrawStyle = true;
break;
}
}
spinbox->setEnabled(hasDrawStyle);
}
static void setTransparency(const std::vector<Gui::ViewProvider*>& views, const char* property, QSpinBox* spinbox, QSlider* slider)
{
bool hasTransparency = false;
for (const auto & view : views) {
if (auto* prop = dynamic_cast<App::PropertyInteger*>(view->getPropertyByName(property))) {
QSignalBlocker blockSpinBox(spinbox);
spinbox->setValue(prop->getValue());
QSignalBlocker blockSlider(slider);
slider->setValue(prop->getValue());
hasTransparency = true;
break;
}
}
spinbox->setEnabled(hasTransparency);
slider->setEnabled(hasTransparency);
}
};
/**
* Constructs a DlgDisplayPropertiesImp which is a child of 'parent', with the
* name 'name' and widget flags set to 'f'
*
* The dialog will by default be modeless, unless you set 'modal' to
* true to construct a modal dialog.
*/
DlgDisplayPropertiesImp::DlgDisplayPropertiesImp(bool floating, QWidget* parent, Qt::WindowFlags fl)
: QDialog( parent, fl )
, d(new Private)
{
d->ui.setupUi(this);
setupConnections();
d->ui.textLabel1_3->hide();
d->ui.changePlot->hide();
d->ui.buttonLineColor->setModal(false);
d->ui.buttonPointColor->setModal(false);
d->ui.buttonColor->setModal(false);
d->floating = floating;
std::vector<Gui::ViewProvider*> views = getSelection();
setDisplayModes(views);
fillupMaterials();
setMaterial(views);
setColorPlot(views);
setShapeColor(views);
setLineColor(views);
setPointColor(views);
setPointSize(views);
setLineWidth(views);
setTransparency(views);
setLineTransparency(views);
// embed this dialog into a dockable widget container
if (floating) {
Gui::DockWindowManager* pDockMgr = Gui::DockWindowManager::instance();
QDockWidget* dw = pDockMgr->addDockWindow("Display properties", this, Qt::AllDockWidgetAreas);
dw->setFeatures(QDockWidget::DockWidgetMovable|QDockWidget::DockWidgetFloatable);
dw->setFloating(true);
dw->show();
}
Gui::Selection().Attach(this);
//NOLINTBEGIN
d->connectChangedObject =
Gui::Application::Instance->signalChangedObject.connect(std::bind
(&DlgDisplayPropertiesImp::slotChangedObject, this, sp::_1, sp::_2));
//NOLINTEND
}
/**
* Destroys the object and frees any allocated resources
*/
DlgDisplayPropertiesImp::~DlgDisplayPropertiesImp()
{
// no need to delete child widgets, Qt does it all for us
d->connectChangedObject.disconnect();
Gui::Selection().Detach(this);
}
void DlgDisplayPropertiesImp::setupConnections()
{
#if QT_VERSION < QT_VERSION_CHECK(5,14,0)
connect(d->ui.changeMode, qOverload<const QString&>(&QComboBox::activated), this, &DlgDisplayPropertiesImp::onChangeModeActivated);
connect(d->ui.changePlot, qOverload<const QString&>(&QComboBox::activated), this, &DlgDisplayPropertiesImp::onChangePlotActivated);
#else
connect(d->ui.changeMode, &QComboBox::textActivated, this, &DlgDisplayPropertiesImp::onChangeModeActivated);
connect(d->ui.changePlot, &QComboBox::textActivated, this, &DlgDisplayPropertiesImp::onChangePlotActivated);
#endif
connect(d->ui.changeMaterial, qOverload<int>(&QComboBox::activated), this, &DlgDisplayPropertiesImp::onChangeMaterialActivated);
connect(d->ui.buttonColor, &ColorButton::changed, this, &DlgDisplayPropertiesImp::onButtonColorChanged);
connect(d->ui.spinTransparency, qOverload<int>(&QSpinBox::valueChanged), this, &DlgDisplayPropertiesImp::onSpinTransparencyValueChanged);
connect(d->ui.spinPointSize, qOverload<int>(&QSpinBox::valueChanged), this, &DlgDisplayPropertiesImp::onSpinPointSizeValueChanged);
connect(d->ui.buttonLineColor, &ColorButton::changed, this, &DlgDisplayPropertiesImp::onButtonLineColorChanged);
connect(d->ui.buttonPointColor, &ColorButton::changed, this, &DlgDisplayPropertiesImp::onButtonPointColorChanged);
connect(d->ui.spinLineWidth, qOverload<int>(&QSpinBox::valueChanged), this, &DlgDisplayPropertiesImp::onSpinLineWidthValueChanged);
connect(d->ui.spinLineTransparency, qOverload<int>(&QSpinBox::valueChanged), this, &DlgDisplayPropertiesImp::onSpinLineTransparencyValueChanged);
connect(d->ui.buttonUserDefinedMaterial, &ColorButton::clicked, this, &DlgDisplayPropertiesImp::onButtonUserDefinedMaterialClicked);
connect(d->ui.buttonColorPlot, &ColorButton::clicked, this, &DlgDisplayPropertiesImp::onButtonColorPlotClicked);
}
void DlgDisplayPropertiesImp::changeEvent(QEvent *e)
{
if (e->type() == QEvent::LanguageChange) {
d->ui.retranslateUi(this);
}
QDialog::changeEvent(e);
}
/// @cond DOXERR
void DlgDisplayPropertiesImp::OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
Gui::SelectionSingleton::MessageType Reason)
{
Q_UNUSED(rCaller);
if (Reason.Type == SelectionChanges::AddSelection ||
Reason.Type == SelectionChanges::RmvSelection ||
Reason.Type == SelectionChanges::SetSelection ||
Reason.Type == SelectionChanges::ClrSelection) {
std::vector<Gui::ViewProvider*> views = getSelection();
setDisplayModes(views);
setMaterial(views);
setColorPlot(views);
setShapeColor(views);
setLineColor(views);
setPointColor(views);
setPointSize(views);
setLineWidth(views);
setTransparency(views);
setLineTransparency(views);
}
}
/// @endcond
void DlgDisplayPropertiesImp::slotChangedObject(const Gui::ViewProvider& obj,
const App::Property& prop)
{
// This method gets called if a property of any view provider is changed.
// We pick out all the properties for which we need to update this dialog.
std::vector<Gui::ViewProvider*> Provider = getSelection();
auto vp = std::find_if(Provider.begin(),
Provider.end(),
[&obj](Gui::ViewProvider* v) { return v == &obj; });
if (vp != Provider.end()) {
const char* name = obj.getPropertyName(&prop);
// this is not a property of the view provider but of the document object
if (!name)
return;
std::string prop_name = name;
if (prop.is<App::PropertyColor>()) {
App::Color value = static_cast<const App::PropertyColor&>(prop).getValue();
if (prop_name == "ShapeColor") {
bool blocked = d->ui.buttonColor->blockSignals(true);
d->ui.buttonColor->setColor(QColor((int)(255.0f * value.r),
(int)(255.0f * value.g),
(int)(255.0f * value.b)));
d->ui.buttonColor->blockSignals(blocked);
}
else if (prop_name == "LineColor") {
bool blocked = d->ui.buttonLineColor->blockSignals(true);
d->ui.buttonLineColor->setColor(QColor((int)(255.0f * value.r),
(int)(255.0f * value.g),
(int)(255.0f * value.b)));
d->ui.buttonLineColor->blockSignals(blocked);
}
else if (prop_name == "PointColor") {
bool blocked = d->ui.buttonPointColor->blockSignals(true);
d->ui.buttonPointColor->setColor(QColor((int)(255.0f * value.r),
(int)(255.0f * value.g),
(int)(255.0f * value.b)));
d->ui.buttonPointColor->blockSignals(blocked);
}
}
else if (prop.isDerivedFrom<App::PropertyInteger>()) {
long value = static_cast<const App::PropertyInteger&>(prop).getValue();
if (prop_name == "Transparency") {
bool blocked = d->ui.spinTransparency->blockSignals(true);
d->ui.spinTransparency->setValue(value);
d->ui.spinTransparency->blockSignals(blocked);
blocked = d->ui.horizontalSlider->blockSignals(true);
d->ui.horizontalSlider->setValue(value);
d->ui.horizontalSlider->blockSignals(blocked);
}
else if (prop_name == "LineTransparency") {
bool blocked = d->ui.spinLineTransparency->blockSignals(true);
d->ui.spinLineTransparency->setValue(value);
d->ui.spinLineTransparency->blockSignals(blocked);
blocked = d->ui.sliderLineTransparency->blockSignals(true);
d->ui.sliderLineTransparency->setValue(value);
d->ui.sliderLineTransparency->blockSignals(blocked);
}
}
else if (prop.isDerivedFrom<App::PropertyFloat>()) {
double value = static_cast<const App::PropertyFloat&>(prop).getValue();
if (prop_name == "PointSize") {
bool blocked = d->ui.spinPointSize->blockSignals(true);
d->ui.spinPointSize->setValue((int)value);
d->ui.spinPointSize->blockSignals(blocked);
}
else if (prop_name == "LineWidth") {
bool blocked = d->ui.spinLineWidth->blockSignals(true);
d->ui.spinLineWidth->setValue((int)value);
d->ui.spinLineWidth->blockSignals(blocked);
}
}
}
}
/**
* Destroys the dock window this object is embedded into without destroying itself.
*/
void DlgDisplayPropertiesImp::reject()
{
if (d->floating) {
// closes the dock window
Gui::DockWindowManager* pDockMgr = Gui::DockWindowManager::instance();
pDockMgr->removeDockWindow(this);
}
QDialog::reject();
}
/**
* Opens a dialog that allows to modify the 'ShapeMaterial' property of all selected view providers.
*/
void DlgDisplayPropertiesImp::onButtonUserDefinedMaterialClicked()
{
std::vector<Gui::ViewProvider*> Provider = getSelection();
DlgMaterialPropertiesImp dlg("ShapeMaterial", this);
dlg.setViewProviders(Provider);
dlg.exec();
d->ui.buttonColor->setColor(dlg.diffuseColor());
}
/**
* Opens a dialog that allows to modify the 'ShapeMaterial' property of all selected view providers.
*/
void DlgDisplayPropertiesImp::onButtonColorPlotClicked()
{
std::vector<Gui::ViewProvider*> Provider = getSelection();
static QPointer<DlgMaterialPropertiesImp> dlg = nullptr;
if (!dlg)
dlg = new DlgMaterialPropertiesImp("TextureMaterial", this);
dlg->setModal(false);
dlg->setAttribute(Qt::WA_DeleteOnClose);
dlg->setViewProviders(Provider);
dlg->show();
}
/**
* Sets the 'ShapeMaterial' property of all selected view providers.
*/
void DlgDisplayPropertiesImp::onChangeMaterialActivated(int index)
{
std::vector<Gui::ViewProvider*> Provider = getSelection();
App::Material::MaterialType matType = static_cast<App::Material::MaterialType>(d->ui.changeMaterial->itemData(index).toInt());
App::Material mat(matType);
App::Color diffuseColor = mat.diffuseColor;
d->ui.buttonColor->setColor(QColor((int)(diffuseColor.r*255.0f),
(int)(diffuseColor.g*255.0f),
(int)(diffuseColor.b*255.0f)));
for (auto it : Provider) {
if (auto* prop = dynamic_cast<App::PropertyMaterial*>(it->getPropertyByName("ShapeMaterial"))) {
prop->setValue(mat);
}
}
}
/**
* Sets the 'Display' property of all selected view providers.
*/
void DlgDisplayPropertiesImp::onChangeModeActivated(const QString& s)
{
Gui::WaitCursor wc;
std::vector<Gui::ViewProvider*> Provider = getSelection();
for (auto it : Provider) {
if (auto* prop = dynamic_cast<App::PropertyEnumeration*>(it->getPropertyByName("DisplayMode"))) {
prop->setValue(static_cast<const char*>(s.toLatin1()));
}
}
}
void DlgDisplayPropertiesImp::onChangePlotActivated(const QString&s)
{
Base::Console().Log("Plot = %s\n",(const char*)s.toLatin1());
}
/**
* Sets the 'ShapeColor' property of all selected view providers.
*/
void DlgDisplayPropertiesImp::onButtonColorChanged()
{
std::vector<Gui::ViewProvider*> Provider = getSelection();
QColor s = d->ui.buttonColor->color();
App::Color c(s.red() / 255.0, s.green() / 255.0, s.blue() / 255.0);
for (auto it : Provider) {
if (auto* prop = dynamic_cast<App::PropertyColor*>(it->getPropertyByName("ShapeColor"))) {
prop->setValue(c);
}
}
}
/**
* Sets the 'Transparency' property of all selected view providers.
*/
void DlgDisplayPropertiesImp::onSpinTransparencyValueChanged(int transparency)
{
std::vector<Gui::ViewProvider*> Provider = getSelection();
for (auto it : Provider) {
if (auto* prop = dynamic_cast<App::PropertyInteger*>(it->getPropertyByName("Transparency"))) {
prop->setValue(transparency);
}
}
}
/**
* Sets the 'PointSize' property of all selected view providers.
*/
void DlgDisplayPropertiesImp::onSpinPointSizeValueChanged(int pointsize)
{
std::vector<Gui::ViewProvider*> Provider = getSelection();
for (auto it : Provider) {
if (auto* prop = dynamic_cast<App::PropertyFloat*>(it->getPropertyByName("PointSize"))) {
prop->setValue(static_cast<double>(pointsize));
}
}
}
/**
* Sets the 'LineWidth' property of all selected view providers.
*/
void DlgDisplayPropertiesImp::onSpinLineWidthValueChanged(int linewidth)
{
std::vector<Gui::ViewProvider*> Provider = getSelection();
for (auto it : Provider) {
if (auto* prop = dynamic_cast<App::PropertyFloat*>(it->getPropertyByName("LineWidth"))) {
prop->setValue(static_cast<double>(linewidth));
}
}
}
void DlgDisplayPropertiesImp::onButtonLineColorChanged()
{
std::vector<Gui::ViewProvider*> Provider = getSelection();
QColor s = d->ui.buttonLineColor->color();
App::Color c(s.red() / 255.0, s.green() / 255.0, s.blue() / 255.0);
for (auto it : Provider) {
if (auto* prop = dynamic_cast<App::PropertyColor*>(it->getPropertyByName("LineColor"))) {
prop->setValue(c);
}
}
}
void DlgDisplayPropertiesImp::onButtonPointColorChanged()
{
std::vector<Gui::ViewProvider*> Provider = getSelection();
QColor s = d->ui.buttonPointColor->color();
App::Color c(s.red() / 255.0, s.green() / 255.0, s.blue() / 255.0);
for (auto it : Provider) {
if (auto* prop = dynamic_cast<App::PropertyColor*>(it->getPropertyByName("PointColor"))) {
prop->setValue(c);
}
}
}
void DlgDisplayPropertiesImp::onSpinLineTransparencyValueChanged(int transparency)
{
std::vector<Gui::ViewProvider*> Provider = getSelection();
for (auto it : Provider) {
if (auto* prop = dynamic_cast<App::PropertyInteger*>(it->getPropertyByName("LineTransparency"))) {
prop->setValue(transparency);
}
}
}
void DlgDisplayPropertiesImp::setDisplayModes(const std::vector<Gui::ViewProvider*>& views)
{
QStringList commonModes, modes;
for (auto it = views.begin(); it != views.end(); ++it) {
if (auto* prop = dynamic_cast<App::PropertyEnumeration*>((*it)->getPropertyByName("DisplayMode"))) {
if (!prop->hasEnums())
return;
std::vector<std::string> value = prop->getEnumVector();
if (it == views.begin()) {
for (const auto & jt : value)
commonModes << QLatin1String(jt.c_str());
}
else {
for (const auto & jt : value) {
if (commonModes.contains(QLatin1String(jt.c_str())))
modes << QLatin1String(jt.c_str());
}
commonModes = modes;
modes.clear();
}
}
}
d->ui.changeMode->clear();
d->ui.changeMode->addItems(commonModes);
d->ui.changeMode->setDisabled(commonModes.isEmpty());
// find the display mode to activate
for (const auto & view : views) {
if (auto* prop = dynamic_cast<App::PropertyEnumeration*>(view->getPropertyByName("DisplayMode"))) {
QString activeMode = QString::fromLatin1(prop->getValueAsString());
int index = d->ui.changeMode->findText(activeMode);
if (index != -1) {
d->ui.changeMode->setCurrentIndex(index);
break;
}
}
}
}
void DlgDisplayPropertiesImp::setMaterial(const std::vector<Gui::ViewProvider*>& views)
{
bool material = false;
App::Material::MaterialType matType = App::Material::DEFAULT;
for (auto view : views) {
if (auto* prop = dynamic_cast<App::PropertyMaterial*>(view->getPropertyByName("ShapeMaterial"))) {
material = true;
matType = prop->getValue().getType();
break;
}
}
int index = d->ui.changeMaterial->findData(matType);
if (index >= 0) {
d->ui.changeMaterial->setCurrentIndex(index);
}
d->ui.changeMaterial->setEnabled(material);
d->ui.buttonUserDefinedMaterial->setEnabled(material);
}
void DlgDisplayPropertiesImp::setColorPlot(const std::vector<Gui::ViewProvider*>& views)
{
bool material = false;
for (auto view : views) {
auto* prop = dynamic_cast<App::PropertyMaterial*>(view->getPropertyByName("TextureMaterial"));
if (prop) {
material = true;
break;
}
}
d->ui.buttonColorPlot->setEnabled(material);
}
void DlgDisplayPropertiesImp::fillupMaterials()
{
d->ui.changeMaterial->addItem(tr("Default"), App::Material::DEFAULT);
d->ui.changeMaterial->addItem(tr("Aluminium"), App::Material::ALUMINIUM);
d->ui.changeMaterial->addItem(tr("Brass"), App::Material::BRASS);
d->ui.changeMaterial->addItem(tr("Bronze"), App::Material::BRONZE);
d->ui.changeMaterial->addItem(tr("Copper"), App::Material::COPPER);
d->ui.changeMaterial->addItem(tr("Chrome"), App::Material::CHROME);
d->ui.changeMaterial->addItem(tr("Emerald"), App::Material::EMERALD);
d->ui.changeMaterial->addItem(tr("Gold"), App::Material::GOLD);
d->ui.changeMaterial->addItem(tr("Jade"), App::Material::JADE);
d->ui.changeMaterial->addItem(tr("Metalized"), App::Material::METALIZED);
d->ui.changeMaterial->addItem(tr("Neon GNC"), App::Material::NEON_GNC);
d->ui.changeMaterial->addItem(tr("Neon PHC"), App::Material::NEON_PHC);
d->ui.changeMaterial->addItem(tr("Obsidian"), App::Material::OBSIDIAN);
d->ui.changeMaterial->addItem(tr("Pewter"), App::Material::PEWTER);
d->ui.changeMaterial->addItem(tr("Plaster"), App::Material::PLASTER);
d->ui.changeMaterial->addItem(tr("Plastic"), App::Material::PLASTIC);
d->ui.changeMaterial->addItem(tr("Ruby"), App::Material::RUBY);
d->ui.changeMaterial->addItem(tr("Satin"), App::Material::SATIN);
d->ui.changeMaterial->addItem(tr("Shiny plastic"), App::Material::SHINY_PLASTIC);
d->ui.changeMaterial->addItem(tr("Silver"), App::Material::SILVER);
d->ui.changeMaterial->addItem(tr("Steel"), App::Material::STEEL);
d->ui.changeMaterial->addItem(tr("Stone"), App::Material::STONE);
}
void DlgDisplayPropertiesImp::setShapeColor(const std::vector<Gui::ViewProvider*>& views)
{
Private::setElementColor(views, "ShapeColor", d->ui.buttonColor);
}
void DlgDisplayPropertiesImp::setLineColor(const std::vector<Gui::ViewProvider*>& views)
{
Private::setElementColor(views, "LineColor", d->ui.buttonLineColor);
}
void DlgDisplayPropertiesImp::setPointColor(const std::vector<Gui::ViewProvider*>& views)
{
Private::setElementColor(views, "PointColor", d->ui.buttonPointColor);
}
void DlgDisplayPropertiesImp::setPointSize(const std::vector<Gui::ViewProvider*>& views)
{
Private::setDrawStyle(views, "PointSize", d->ui.spinPointSize);
}
void DlgDisplayPropertiesImp::setLineWidth(const std::vector<Gui::ViewProvider*>& views)
{
Private::setDrawStyle(views, "LineWidth", d->ui.spinLineWidth);
}
void DlgDisplayPropertiesImp::setTransparency(const std::vector<Gui::ViewProvider*>& views)
{
Private::setTransparency(views, "Transparency", d->ui.spinTransparency, d->ui.horizontalSlider);
}
void DlgDisplayPropertiesImp::setLineTransparency(const std::vector<Gui::ViewProvider*>& views)
{
Private::setTransparency(views, "LineTransparency", d->ui.spinLineTransparency, d->ui.sliderLineTransparency);
}
std::vector<Gui::ViewProvider*> DlgDisplayPropertiesImp::getSelection() const
{
std::vector<Gui::ViewProvider*> views;
// get the complete selection
std::vector<SelectionSingleton::SelObj> sel = Selection().getCompleteSelection();
for (const auto & it : sel) {
Gui::ViewProvider* view = Application::Instance->getDocument(it.pDoc)->getViewProvider(it.pObject);
views.push_back(view);
}
return views;
}
// ----------------------------------------------------------------------------
/* TRANSLATOR Gui::Dialog::TaskDisplayProperties */
TaskDisplayProperties::TaskDisplayProperties()
{
this->setButtonPosition(TaskDisplayProperties::North);
widget = new DlgDisplayPropertiesImp(false);
addTaskBox(widget);
}
TaskDisplayProperties::~TaskDisplayProperties() = default;
QDialogButtonBox::StandardButtons TaskDisplayProperties::getStandardButtons() const
{
return QDialogButtonBox::Close;
}
bool TaskDisplayProperties::reject()
{
widget->reject();
return (widget->result() == QDialog::Rejected);
}
#include "moc_DlgDisplayPropertiesImp.cpp"

View File

@@ -1,131 +0,0 @@
/***************************************************************************
* Copyright (c) 2002 Jürgen Riegel <juergen.riegel@web.de> *
* *
* This file is part of the FreeCAD CAx development system. *
* *
* This library is free software; you can redistribute it and/or *
* modify it under the terms of the GNU Library General Public *
* License as published by the Free Software Foundation; either *
* version 2 of the License, or (at your option) any later version. *
* *
* This library 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 Library General Public License for more details. *
* *
* You should have received a copy of the GNU Library General Public *
* License along with this library; see the file COPYING.LIB. If not, *
* write to the Free Software Foundation, Inc., 59 Temple Place, *
* Suite 330, Boston, MA 02111-1307, USA *
* *
***************************************************************************/
#ifndef GUI_DIALOG_DLGDISPLAYPROPERTIES_IMP_H
#define GUI_DIALOG_DLGDISPLAYPROPERTIES_IMP_H
#include <memory>
#include <vector>
#include <QDialog>
#include <Gui/Selection.h>
#include <Gui/TaskView/TaskDialog.h>
#include <Gui/TaskView/TaskView.h>
#include <App/Material.h>
namespace App
{
class Property;
}
namespace Gui {
class ViewProvider;
class Command;
namespace Dialog {
/**
* The DlgDisplayPropertiesImp class implements a dialog containing all available document
* templates to create a new document.
* \author Jürgen Riegel
*/
class DlgDisplayPropertiesImp : public QDialog,
public Gui::SelectionSingleton::ObserverType
{
Q_OBJECT
public:
explicit DlgDisplayPropertiesImp(bool floating, QWidget* parent = nullptr, Qt::WindowFlags fl = Qt::WindowFlags());
~DlgDisplayPropertiesImp() override;
/// Observer message from the Selection
void OnChange(Gui::SelectionSingleton::SubjectType &rCaller,
Gui::SelectionSingleton::MessageType Reason) override;
void showDefaultButtons(bool);
void reject() override;
private Q_SLOTS:
void onChangeMaterialActivated(int);
void onChangeModeActivated(const QString&);
void onChangePlotActivated(const QString&);
void onButtonColorChanged();
void onSpinTransparencyValueChanged(int);
void onSpinPointSizeValueChanged(int);
void onButtonLineColorChanged();
void onButtonPointColorChanged();
void onSpinLineWidthValueChanged(int);
void onSpinLineTransparencyValueChanged(int);
void onButtonUserDefinedMaterialClicked();
void onButtonColorPlotClicked();
protected:
void changeEvent(QEvent *e) override;
private:
void setupConnections();
void slotChangedObject(const Gui::ViewProvider&, const App::Property& Prop);
void setDisplayModes(const std::vector<ViewProvider*>&);
void setMaterial(const std::vector<ViewProvider*>&);
void setColorPlot(const std::vector<ViewProvider*>&);
void fillupMaterials();
void setShapeColor(const std::vector<ViewProvider*>&);
void setLineColor(const std::vector<ViewProvider*>&);
void setPointColor(const std::vector<ViewProvider*>&);
void setPointSize(const std::vector<ViewProvider*>&);
void setLineWidth(const std::vector<ViewProvider*>&);
void setTransparency(const std::vector<ViewProvider*>&);
void setLineTransparency(const std::vector<ViewProvider*>&);
std::vector<ViewProvider*> getSelection() const;
private:
class Private;
std::unique_ptr<Private> d;
};
class TaskDisplayProperties : public Gui::TaskView::TaskDialog
{
Q_OBJECT
public:
TaskDisplayProperties();
~TaskDisplayProperties() override;
public:
bool reject() override;
bool isAllowedAlterDocument() const override
{ return true; }
bool isAllowedAlterView() const override
{ return true; }
bool isAllowedAlterSelection() const override
{ return true; }
QDialogButtonBox::StandardButtons getStandardButtons() const override;
private:
DlgDisplayPropertiesImp* widget;
};
} // namespace Dialog
} // namespace Gui
#endif // GUI_DIALOG_DLGDISPLAYPROPERTIES_IMP_H

View File

@@ -28,18 +28,22 @@
#include <memory>
#include <vector>
namespace Gui {
namespace Gui
{
class ViewProvider;
namespace Dialog {
namespace Dialog
{
class Ui_DlgMaterialProperties;
class DlgMaterialPropertiesImp : public QDialog
class GuiExport DlgMaterialPropertiesImp: public QDialog
{
Q_OBJECT
public:
explicit DlgMaterialPropertiesImp(const std::string& mat, QWidget* parent = nullptr, Qt::WindowFlags fl = Qt::WindowFlags());
explicit DlgMaterialPropertiesImp(const std::string& mat,
QWidget* parent = nullptr,
Qt::WindowFlags fl = Qt::WindowFlags());
~DlgMaterialPropertiesImp() override;
void setViewProviders(const std::vector<Gui::ViewProvider*>&);
QColor diffuseColor() const;
@@ -58,8 +62,7 @@ private:
std::vector<Gui::ViewProvider*> Objects;
};
} // namespace Dialog
} // namespace Gui
#endif // GUI_DIALOG_DLGMATERIALPROPERTIES_IMP_H
} // namespace Dialog
} // namespace Gui
#endif // GUI_DIALOG_DLGMATERIALPROPERTIES_IMP_H

View File

@@ -201,9 +201,11 @@ void AlignmentGroup::setAlignable(bool align)
}
// leaving alignment mode
else if (!align){
auto pColor = dynamic_cast<App::PropertyColor*>((*it)->getPropertyByName("ShapeColor"));
if (pColor)
pColor->touch(); // resets to color defined by property
auto pAppearance =
dynamic_cast<App::PropertyMaterial*>((*it)->getPropertyByName("ShapeAppearance"));
if (pAppearance) {
pAppearance->touch(); // resets to color defined by property
}
}
}
}

View File

@@ -451,6 +451,9 @@ void StartupPostProcess::showMainWindow()
void StartupPostProcess::activateWorkbench()
{
// Always activate the material workbench
guiApp.activateWorkbench("MaterialWorkbench");
// Activate the correct workbench
std::string start = App::Application::Config()["StartWorkbench"];
Base::Console().Log("Init: Activating default workbench %s\n", start.c_str());

View File

@@ -23,17 +23,17 @@
#include "PreCompiled.h"
#ifndef _PreComp_
# include <Inventor/SoPickedPoint.h>
# include <Inventor/actions/SoRayPickAction.h>
# include <Inventor/actions/SoSearchAction.h>
# include <Inventor/nodes/SoBaseColor.h>
# include <Inventor/nodes/SoCamera.h>
# include <Inventor/nodes/SoDrawStyle.h>
# include <Inventor/nodes/SoFont.h>
# include <Inventor/nodes/SoMaterial.h>
# include <Inventor/nodes/SoSeparator.h>
# include <Inventor/nodes/SoSwitch.h>
# include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/SoPickedPoint.h>
#include <Inventor/actions/SoRayPickAction.h>
#include <Inventor/actions/SoSearchAction.h>
#include <Inventor/nodes/SoBaseColor.h>
#include <Inventor/nodes/SoCamera.h>
#include <Inventor/nodes/SoDirectionalLight.h>
#include <Inventor/nodes/SoDrawStyle.h>
#include <Inventor/nodes/SoFont.h>
#include <Inventor/nodes/SoMaterial.h>
#include <Inventor/nodes/SoSeparator.h>
#include <Inventor/nodes/SoSwitch.h>
#endif
#include <Inventor/nodes/SoResetTransform.h>
@@ -41,13 +41,13 @@
#include <App/GeoFeature.h>
#include <App/PropertyGeo.h>
#include "ViewProviderGeometryObject.h"
#include "Application.h"
#include "Document.h"
#include "SoFCBoundingBox.h"
#include "SoFCSelection.h"
#include "View3DInventorViewer.h"
#include "ViewProviderGeometryObject.h"
#include "ViewProviderGeometryObjectPy.h"
using namespace Gui;
@@ -57,44 +57,59 @@ const App::PropertyIntegerConstraint::Constraints intPercent = {0, 100, 5};
ViewProviderGeometryObject::ViewProviderGeometryObject()
{
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
bool randomColor = hGrp->GetBool("RandomColor", false);
float r, g, b;
if (randomColor){
auto fMax = (float)RAND_MAX;
r = (float)rand() / fMax;
g = (float)rand() / fMax;
b = (float)rand() / fMax;
}
else {
unsigned long shcol = hGrp->GetUnsigned("DefaultShapeColor", 3435980543UL);
r = ((shcol >> 24) & 0xff) / 255.0;
g = ((shcol >> 16) & 0xff) / 255.0;
b = ((shcol >> 8) & 0xff) / 255.0;
}
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
int initialTransparency = hGrp->GetInt("DefaultShapeTransparency", 0);
static const char *dogroup = "Display Options";
static const char *sgroup = "Selection";
static const char *osgroup = "Object Style";
static const char* dogroup = "Display Options";
static const char* sgroup = "Selection";
static const char* osgroup = "Object Style";
ADD_PROPERTY_TYPE(ShapeColor, (r, g, b), osgroup, App::Prop_None, "Set shape color");
ADD_PROPERTY_TYPE(Transparency, (initialTransparency), osgroup, App::Prop_None, "Set object transparency");
ADD_PROPERTY_TYPE(Transparency,
(initialTransparency),
osgroup,
App::Prop_None,
"Set object transparency");
Transparency.setConstraints(&intPercent);
App::Material mat(App::Material::DEFAULT);
mat.transparency = (float)initialTransparency / 100.0f;
ADD_PROPERTY_TYPE(ShapeMaterial,(mat), osgroup, App::Prop_None, "Shape material");
auto geometry = dynamic_cast<App::GeoFeature*>(getObject());
if (geometry) {
mat = geometry->getMaterialAppearance();
} else {
// This is handled in the material code when using the object appearance
bool randomColor = hGrp->GetBool("RandomColor", false);
float r, g, b;
if (randomColor) {
auto fMax = (float)RAND_MAX;
r = (float)rand() / fMax;
g = (float)rand() / fMax;
b = (float)rand() / fMax;
}
else {
unsigned long shcol = hGrp->GetUnsigned("DefaultShapeColor", 3435980543UL);
r = ((shcol >> 24) & 0xff) / 255.0;
g = ((shcol >> 16) & 0xff) / 255.0;
b = ((shcol >> 8) & 0xff) / 255.0;
}
mat.diffuseColor = App::Color(r,g,b);
}
ADD_PROPERTY_TYPE(ShapeAppearance, (mat), osgroup, App::Prop_None, "Shape appearrance");
ADD_PROPERTY_TYPE(BoundingBox, (false), dogroup, App::Prop_None, "Display object bounding box");
ADD_PROPERTY_TYPE(Selectable, (true), sgroup, App::Prop_None, "Set if the object is selectable in the 3d view");
ADD_PROPERTY_TYPE(Selectable,
(true),
sgroup,
App::Prop_None,
"Set if the object is selectable in the 3d view");
bool enableSel = hGrp->GetBool("EnableSelection", true);
Selectable.setValue(enableSel);
pcShapeMaterial = new SoMaterial;
pcShapeMaterial->diffuseColor.setValue(r, g, b);
pcShapeMaterial->transparency = float(initialTransparency);
setSoMaterial(mat);
pcShapeMaterial->ref();
pcBoundingBox = new Gui::SoFCBoundingBox;
@@ -115,44 +130,32 @@ ViewProviderGeometryObject::~ViewProviderGeometryObject()
void ViewProviderGeometryObject::onChanged(const App::Property* prop)
{
// Actually, the properties 'ShapeColor' and 'Transparency' are part of the property 'ShapeMaterial'.
// Both redundant properties are kept due to more convenience for the user. But we must keep the values
// consistent of all these properties.
// Actually, the properties 'ShapeColor' and 'Transparency' are part of the property
// 'ShapeMaterial'. Both redundant properties are kept due to more convenience for the user. But
// we must keep the values consistent of all these properties.
std::string propName = prop->getName();
if (prop == &Selectable) {
bool Sel = Selectable.getValue();
setSelectable(Sel);
}
else if (prop == &ShapeColor) {
const App::Color &c = ShapeColor.getValue();
pcShapeMaterial->diffuseColor.setValue(c.r, c.g, c.b);
if (c != ShapeMaterial.getValue().diffuseColor)
ShapeMaterial.setDiffuseColor(c);
}
else if (prop == &Transparency) {
const App::Material &Mat = ShapeMaterial.getValue();
long value = (long)(100 * Mat.transparency);
long value = (long)(100 * ShapeAppearance.getTransparency());
if (value != Transparency.getValue()) {
float trans = Transparency.getValue() / 100.0f;
float trans = (float)Transparency.getValue() / 100.0f;
pcShapeMaterial->transparency = trans;
ShapeMaterial.setTransparency(trans);
ShapeAppearance.setTransparency(trans);
}
}
else if (prop == &ShapeMaterial) {
if (getObject() && getObject()->testStatus(App::ObjectStatus::TouchOnColorChange))
else if (prop == &ShapeAppearance) {
if (getObject() && getObject()->testStatus(App::ObjectStatus::TouchOnColorChange)) {
getObject()->touch(true);
const App::Material &Mat = ShapeMaterial.getValue();
long value = (long)(100 * Mat.transparency);
if (value != Transparency.getValue())
}
const App::Material& Mat = ShapeAppearance[0];
long value = (long)(100.0 * ShapeAppearance.getTransparency() + 0.5);
if (value != Transparency.getValue()) {
Transparency.setValue(value);
const App::Color &color = Mat.diffuseColor;
if (color != ShapeColor.getValue())
ShapeColor.setValue(Mat.diffuseColor);
pcShapeMaterial->ambientColor.setValue(Mat.ambientColor.r, Mat.ambientColor.g, Mat.ambientColor.b);
pcShapeMaterial->diffuseColor.setValue(Mat.diffuseColor.r, Mat.diffuseColor.g, Mat.diffuseColor.b);
pcShapeMaterial->specularColor.setValue(Mat.specularColor.r, Mat.specularColor.g, Mat.specularColor.b);
pcShapeMaterial->emissiveColor.setValue(Mat.emissiveColor.r, Mat.emissiveColor.g, Mat.emissiveColor.b);
pcShapeMaterial->shininess.setValue(Mat.shininess);
pcShapeMaterial->transparency.setValue(Mat.transparency);
}
setSoMaterial(Mat);
}
else if (prop == &BoundingBox) {
showBoundingBox(BoundingBox.getValue());
@@ -161,15 +164,22 @@ void ViewProviderGeometryObject::onChanged(const App::Property* prop)
ViewProviderDragger::onChanged(prop);
}
void ViewProviderGeometryObject::attach(App::DocumentObject *pcObj)
void ViewProviderGeometryObject::attach(App::DocumentObject* pcObj)
{
ViewProviderDragger::attach(pcObj);
}
void ViewProviderGeometryObject::updateData(const App::Property* prop)
{
std::string propName = prop->getName();
if (propName == "Shape") {
// Reapply the appearance
const App::Material& Mat = ShapeAppearance[0];
setSoMaterial(Mat);
}
if (prop->isDerivedFrom(App::PropertyComplexGeoData::getClassTypeId())) {
Base::BoundBox3d box = static_cast<const App::PropertyComplexGeoData*>(prop)->getBoundingBox();
Base::BoundBox3d box =
static_cast<const App::PropertyComplexGeoData*>(prop)->getBoundingBox();
pcBoundingBox->minBounds.setValue(box.MinX, box.MinY, box.MinZ);
pcBoundingBox->maxBounds.setValue(box.MaxX, box.MaxY, box.MaxZ);
}
@@ -184,11 +194,21 @@ void ViewProviderGeometryObject::updateData(const App::Property* prop)
}
}
}
else if (std::string(prop->getName()) == "ShapeMaterial") {
// Set the appearance from the material
auto geometry = dynamic_cast<App::GeoFeature*>(getObject());
if (geometry) {
auto material = geometry->getMaterialAppearance();
ShapeAppearance.setValue(material);
}
}
ViewProviderDragger::updateData(prop);
}
SoPickedPointList ViewProviderGeometryObject::getPickedPoints(const SbVec2s& pos, const View3DInventorViewer& viewer,bool pickAll) const
SoPickedPointList ViewProviderGeometryObject::getPickedPoints(const SbVec2s& pos,
const View3DInventorViewer& viewer,
bool pickAll) const
{
auto root = new SoSeparator;
root->ref();
@@ -207,7 +227,8 @@ SoPickedPointList ViewProviderGeometryObject::getPickedPoints(const SbVec2s& pos
return rp.getPickedPointList();
}
SoPickedPoint* ViewProviderGeometryObject::getPickedPoint(const SbVec2s& pos, const View3DInventorViewer& viewer) const
SoPickedPoint* ViewProviderGeometryObject::getPickedPoint(const SbVec2s& pos,
const View3DInventorViewer& viewer) const
{
auto root = new SoSeparator;
root->ref();
@@ -223,31 +244,55 @@ SoPickedPoint* ViewProviderGeometryObject::getPickedPoint(const SbVec2s& pos, co
// returns a copy of the point
SoPickedPoint* pick = rp.getPickedPoint();
//return (pick ? pick->copy() : 0); // needs the same instance of CRT under MS Windows
// return (pick ? pick->copy() : 0); // needs the same instance of CRT under MS Windows
return (pick ? new SoPickedPoint(*pick) : nullptr);
}
unsigned long ViewProviderGeometryObject::getBoundColor() const
{
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
unsigned long bbcol = hGrp->GetUnsigned("BoundingBoxColor",4294967295UL); // white (255,255,255)
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
unsigned long bbcol =
hGrp->GetUnsigned("BoundingBoxColor", 4294967295UL); // white (255,255,255)
return bbcol;
}
namespace {
void ViewProviderGeometryObject::setSoMaterial(const App::Material& source)
{
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);
}
namespace
{
float getBoundBoxFontSize()
{
ParameterGrp::handle hGrp = App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
ParameterGrp::handle hGrp =
App::GetApplication().GetParameterGroupByPath("User parameter:BaseApp/Preferences/View");
return hGrp->GetFloat("BoundingBoxFontSize", 10.0);
}
}
} // namespace
void ViewProviderGeometryObject::showBoundingBox(bool show)
{
if (!pcBoundSwitch && show) {
unsigned long bbcol = getBoundColor();
float r,g,b;
r = ((bbcol >> 24) & 0xff) / 255.0; g = ((bbcol >> 16) & 0xff) / 255.0; b = ((bbcol >> 8) & 0xff) / 255.0;
float r, g, b;
r = ((bbcol >> 24) & 0xff) / 255.0;
g = ((bbcol >> 16) & 0xff) / 255.0;
b = ((bbcol >> 8) & 0xff) / 255.0;
pcBoundSwitch = new SoSwitch();
auto pBoundingSep = new SoSeparator();
@@ -284,9 +329,9 @@ void ViewProviderGeometryObject::setSelectable(bool selectable)
sa.setType(Gui::SoFCSelection::getClassTypeId());
sa.apply(pcRoot);
SoPathList & pathList = sa.getPaths();
SoPathList& pathList = sa.getPaths();
for (int i=0;i<pathList.getLength();i++) {
for (int i = 0; i < pathList.getLength(); i++) {
auto selNode = dynamic_cast<SoFCSelection*>(pathList[i]->getTail());
if (selectable) {
if (selNode) {
@@ -303,3 +348,33 @@ void ViewProviderGeometryObject::setSelectable(bool selectable)
}
}
}
PyObject* ViewProviderGeometryObject::getPyObject()
{
if (!pyViewObject) {
pyViewObject = new ViewProviderGeometryObjectPy(this);
}
pyViewObject->IncRef();
return pyViewObject;
}
void ViewProviderGeometryObject::handleChangedPropertyName(Base::XMLReader& reader,
const char* TypeName,
const char* PropName)
{
if (strcmp(PropName, "ShapeColor") == 0
&& strcmp(TypeName, App::PropertyColor::getClassTypeId().getName()) == 0) {
App::PropertyColor prop;
prop.Restore(reader);
ShapeAppearance.setDiffuseColor(prop.getValue());
}
else if (strcmp(PropName, "ShapeMaterial") == 0
&& strcmp(TypeName, App::PropertyMaterial::getClassTypeId().getName()) == 0) {
App::PropertyMaterial prop;
prop.Restore(reader);
ShapeAppearance.setValue(prop.getValue());
}
else {
App::PropertyContainer::handleChangedPropertyName(reader, TypeName, PropName);
}
}

View File

@@ -33,17 +33,19 @@ class SoSensor;
class SbVec2s;
class SoBaseColor;
namespace Gui {
namespace Gui
{
class SoFCSelection;
class SoFCBoundingBox;
class View3DInventorViewer;
/**
* The base class for all view providers that display geometric data, like mesh, point clouds and shapes.
* The base class for all view providers that display geometric data, like mesh, point clouds and
* shapes.
* @author Werner Mayer
*/
class GuiExport ViewProviderGeometryObject : public ViewProviderDragger
class GuiExport ViewProviderGeometryObject: public ViewProviderDragger
{
PROPERTY_HEADER_WITH_OVERRIDE(Gui::ViewProviderGeometryObject);
@@ -55,30 +57,35 @@ public:
~ViewProviderGeometryObject() override;
// Display properties
App::PropertyColor ShapeColor;
App::PropertyPercent Transparency;
App::PropertyMaterial ShapeMaterial;
// App::PropertyMaterial ShapeMaterial; // Default appearance and physical properties
App::PropertyMaterialList ShapeAppearance; // May be different from material
App::PropertyBool BoundingBox;
App::PropertyBool Selectable;
/**
* Attaches the document object to this view provider.
*/
void attach(App::DocumentObject *pcObject) override;
void attach(App::DocumentObject* pcObject) override;
void updateData(const App::Property*) override;
bool isSelectable() const override {return Selectable.getValue();}
bool isSelectable() const override
{
return Selectable.getValue();
}
/**
* Returns a list of picked points from the geometry under \a getRoot().
* If \a pickAll is false (the default) only the intersection point closest to the camera will be picked, otherwise
* all intersection points will be picked.
* If \a pickAll is false (the default) only the intersection point closest to the camera will
* be picked, otherwise all intersection points will be picked.
*/
SoPickedPointList getPickedPoints(const SbVec2s& pos, const View3DInventorViewer& viewer,bool pickAll=false) const;
SoPickedPointList getPickedPoints(const SbVec2s& pos,
const View3DInventorViewer& viewer,
bool pickAll = false) const;
/**
* This method is provided for convenience and does basically the same as getPickedPoints() unless that only the closest
* point to the camera will be picked.
* \note It is in the response of the client programmer to delete the returned SoPickedPoint object.
* This method is provided for convenience and does basically the same as getPickedPoints()
* unless that only the closest point to the camera will be picked. \note It is in the response
* of the client programmer to delete the returned SoPickedPoint object.
*/
SoPickedPoint* getPickedPoint(const SbVec2s& pos, const View3DInventorViewer& viewer) const;
@@ -87,21 +94,29 @@ public:
virtual void showBoundingBox(bool);
//@}
/// Get the python wrapper for that ViewProvider
PyObject* getPyObject() override;
protected:
/// get called by the container whenever a property has been changed
void onChanged(const App::Property* prop) override;
void setSelectable(bool Selectable=true);
void setSelectable(bool Selectable = true);
virtual unsigned long getBoundColor() const;
void setSoMaterial(const App::Material& source);
void handleChangedPropertyName(Base::XMLReader& reader,
const char* TypeName,
const char* PropName) override;
protected:
SoMaterial * pcShapeMaterial{nullptr};
SoFCBoundingBox * pcBoundingBox{nullptr};
SoSwitch * pcBoundSwitch{nullptr};
SoBaseColor * pcBoundColor{nullptr};
SoMaterial* pcShapeMaterial {nullptr};
SoFCBoundingBox* pcBoundingBox {nullptr};
SoSwitch* pcBoundSwitch {nullptr};
SoBaseColor* pcBoundColor {nullptr};
};
} // namespace Gui
} // namespace Gui
#endif // GUI_VIEWPROVIDER_GEOMETRYOBJECT_H
#endif // GUI_VIEWPROVIDER_GEOMETRYOBJECT_H

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<GenerateModel xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="generateMetaModel_Module.xsd">
<PythonExport
Father="ViewProviderDocumentObjectPy"
Name="ViewProviderGeometryObjectPy"
Twin="ViewProviderGeometryObject"
TwinPointer="ViewProviderGeometryObject"
Include="Gui/ViewProviderGeometryObject.h"
Namespace="Gui"
FatherInclude="Gui/ViewProviderDocumentObjectPy.h"
FatherNamespace="Gui">
<Documentation>
<Author Licence="LGPL" Name="Werner Mayer" EMail="wmayer@users.sourceforge.net" />
<UserDocu>This is the ViewProvider geometry class</UserDocu>
</Documentation>
</PythonExport>
</GenerateModel>

View File

@@ -0,0 +1,94 @@
// SPDX-License-Identifier: LGPL-2.1-or-later
/***************************************************************************
* Copyright (c) 2024 Werner Mayer <wmayer[at]users.sourceforge.net> *
* *
* 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 *
* <https://www.gnu.org/licenses/>. *
* *
**************************************************************************/
#include "PreCompiled.h"
#ifndef _PreComp_
#include <sstream>
#endif
#include <App/GeoFeature.h>
#include <App/PropertyStandard.h>
#include "ViewProviderGeometryObjectPy.h"
#include "ViewProviderGeometryObjectPy.cpp"
using namespace Gui;
// returns a string which represents the object e.g. when printed in python
std::string ViewProviderGeometryObjectPy::representation() const
{
std::stringstream str;
str << "<View provider geometry object at " << getViewProviderGeometryObjectPtr() << ">";
return str.str();
}
PyObject* ViewProviderGeometryObjectPy::getCustomAttributes(const char* attr) const
{
ViewProviderGeometryObject* vp = getViewProviderGeometryObjectPtr();
if (strcmp(attr, "ShapeColor") == 0) {
// Get material property of ViewProviderGeometryObject
App::PropertyColor prop;
prop.setValue(vp->ShapeAppearance.getDiffuseColor());
return prop.getPyObject();
}
if (strcmp(attr, "ShapeMaterial") == 0) {
// Get material property of ViewProviderGeometryObject
auto geometry = dynamic_cast<App::GeoFeature*>(vp->getObject());
if (geometry) {
auto material = geometry->getMaterialAppearance();
App::PropertyMaterial prop;
prop.setValue(material);
return prop.getPyObject();
}
}
return nullptr;
}
int ViewProviderGeometryObjectPy::setCustomAttributes(const char* attr, PyObject* obj)
{
ViewProviderGeometryObject* vp = getViewProviderGeometryObjectPtr();
if (strcmp(attr, "ShapeColor") == 0) {
// Get material property of ViewProviderGeometryObject
App::PropertyColor prop;
prop.setPyObject(obj);
vp->ShapeAppearance.setDiffuseColor(prop.getValue());
// Assign the value to the new property type
// ...
return 1;
}
if (strcmp(attr, "ShapeMaterial") == 0) {
// Get material property of ViewProviderGeometryObject
auto geometry = dynamic_cast<App::GeoFeature*>(vp->getObject());
if (geometry) {
App::PropertyMaterial prop;
prop.setPyObject(obj);
geometry->setMaterialAppearance(prop.getValue());
}
return 1;
}
return 0;
}

View File

@@ -50,7 +50,8 @@ ViewProviderOriginFeature::ViewProviderOriginFeature () {
ADD_PROPERTY_TYPE ( Size, (ViewProviderOrigin::defaultSize()), 0, App::Prop_ReadOnly,
QT_TRANSLATE_NOOP("App::Property", "Visual size of the feature"));
ShapeColor.setValue ( ViewProviderOrigin::defaultColor ); // Set default color for origin (light-blue)
ShapeAppearance.setDiffuseColor(
ViewProviderOrigin::defaultColor); // Set default color for origin (light-blue)
Transparency.setValue(0);
BoundingBox.setStatus(App::Property::Hidden, true); // Hide Boundingbox from the user due to it doesn't make sense
@@ -108,13 +109,13 @@ void ViewProviderOriginFeature::attach(App::DocumentObject* pcObject)
auto axisRoles = App::Origin::AxisRoles;
if ( strncmp(axisName, axisRoles[0], strlen(axisRoles[0]) ) == 0 ) {
// X-axis: red
ShapeColor.setValue ( 0xFF0000FF );
ShapeAppearance.setDiffuseColor(0xFF0000FF);
} else if ( strncmp(axisName, axisRoles[1], strlen(axisRoles[1]) ) == 0 ) {
// Y-axis: green
ShapeColor.setValue ( 0x00FF00FF );
ShapeAppearance.setDiffuseColor(0x00FF00FF);
} else if ( strncmp(axisName, axisRoles[2], strlen(axisRoles[2]) ) == 0 ) {
// Z-axis: blue
ShapeColor.setValue ( 0x0000FFFF );
ShapeAppearance.setDiffuseColor(0x0000FFFF);
}
}
font->size.setValue ( defaultSz / fontRatio );

View File

@@ -601,7 +601,7 @@ void StdWorkbench::setupContextMenu(const char* recipient, MenuItem* item) const
<< "Std_ViewDockUndockFullscreen";
if (Gui::Selection().countObjectsOfType(App::DocumentObject::getClassTypeId()) > 0) {
*item << "Separator" << "Std_SetAppearance" << "Std_ToggleVisibility"
*item << "Separator" << "Std_SetMaterial" << "Std_SetAppearance" << "Std_ToggleVisibility"
<< "Std_ToggleSelectability" << "Std_TreeSelection"
<< "Std_RandomColor" << "Std_ToggleTransparency" << "Separator" << "Std_Delete"
<< "Std_SendToPythonConsole" << "Std_TransformManip" << "Std_Placement";
@@ -613,7 +613,7 @@ void StdWorkbench::setupContextMenu(const char* recipient, MenuItem* item) const
*item << "Std_ToggleFreeze" << "Separator"
<< "Std_Placement" << "Std_ToggleVisibility" << "Std_ShowSelection" << "Std_HideSelection"
<< "Std_ToggleSelectability" << "Std_TreeSelectAllInstances" << "Separator"
<< "Std_SetAppearance" << "Std_RandomColor" << "Std_ToggleTransparency" << "Separator"
<< "Std_SetMaterial" << "Std_SetAppearance" << "Std_RandomColor" << "Std_ToggleTransparency" << "Separator"
<< "Std_Cut" << "Std_Copy" << "Std_Paste" << "Std_Delete"
<< "Std_SendToPythonConsole" << "Separator";
}
@@ -701,6 +701,7 @@ MenuItem* StdWorkbench::setupMenuBar() const
#endif
<< "Separator" << visu
<< "Std_ToggleNavigation"
<< "Std_SetMaterial"
<< "Std_SetAppearance"
<< "Std_RandomColor"
<< "Std_ToggleTransparency"