mirror of
https://git.salome-platform.org/gitpub/modules/geom.git
synced 2025-01-06 06:40:46 +05:00
785 lines
28 KiB
C++
785 lines
28 KiB
C++
// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE
|
|
//
|
|
// This library 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.
|
|
//
|
|
// 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
|
|
// Lesser General Public License for more details.
|
|
//
|
|
// You should have received a copy of the GNU Lesser General Public
|
|
// License along with this library; if not, write to the Free Software
|
|
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
//
|
|
// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
|
|
//
|
|
|
|
// File : GEOMToolsGUI_MaterialPropertiesDlg.cxx
|
|
// Author : Margarita KARPUNINA, Open CASCADE S.A.S. (margarita.karpunina@opencascade.com)
|
|
|
|
#include "GEOMToolsGUI_MaterialPropertiesDlg.h"
|
|
|
|
#include "GeometryGUI.h"
|
|
#include "GEOM_Constants.h"
|
|
#include "GEOM_VTKPropertyMaterial.hxx"
|
|
#include "GEOMBase.h"
|
|
#include "GEOM_Displayer.h"
|
|
|
|
#include <QtxColorButton.h>
|
|
#include <QtxDoubleSpinBox.h>
|
|
#include <SUIT_Desktop.h>
|
|
#include <SUIT_MessageBox.h>
|
|
#include <SUIT_OverrideCursor.h>
|
|
#include <SUIT_ResourceMgr.h>
|
|
#include <SUIT_Session.h>
|
|
#include <SUIT_ViewManager.h>
|
|
#include <SALOME_ListIO.hxx>
|
|
#include <OCCViewer_ViewModel.h>
|
|
#include <SVTK_ViewModel.h>
|
|
#include <SVTK_ViewWindow.h>
|
|
#include <SVTK_View.h>
|
|
#include <LightApp_SelectionMgr.h>
|
|
#include <SalomeApp_Application.h>
|
|
#include <SalomeApp_Study.h>
|
|
#include <SalomeApp_Tools.h>
|
|
|
|
#include <QCheckBox>
|
|
#include <QGridLayout>
|
|
#include <QHBoxLayout>
|
|
#include <QKeyEvent>
|
|
#include <QLabel>
|
|
#include <QLineEdit>
|
|
#include <QMap>
|
|
#include <QMenu>
|
|
#include <QPushButton>
|
|
#include <QVBoxLayout>
|
|
|
|
#define MARGIN 9 // layout spacing
|
|
#define SPACING 6 // layout margin
|
|
|
|
/*!
|
|
\class GEOMToolsGUI_MaterialList
|
|
\brief Internal class, used to handle context menu event from materials list
|
|
\internal
|
|
*/
|
|
|
|
/*!
|
|
\brief Contructor
|
|
*/
|
|
GEOMToolsGUI_MaterialList::GEOMToolsGUI_MaterialList( QWidget* parent )
|
|
: QListWidget( parent )
|
|
{}
|
|
|
|
/*!
|
|
\brief Context menu event, emits context menu signal passing event as parameter
|
|
*/
|
|
void GEOMToolsGUI_MaterialList::contextMenuEvent( QContextMenuEvent* e )
|
|
{
|
|
emit contextMenu( e );
|
|
}
|
|
|
|
/*!
|
|
\class GEOMToolsGUI_MaterialPropertiesDlg
|
|
\brief GEOM material properties dialog box class
|
|
|
|
The dialog box is used to set material properties for the presentation objects.
|
|
*/
|
|
|
|
/*!
|
|
\brief Constructor
|
|
\param parent parent widget
|
|
\param showSelWidget if \c true then objects can be selected by user
|
|
\param modal if \c true dialog box is modal
|
|
\param f specified control buttons for dialog box (QtxDialog::ButtonFlags)
|
|
*/
|
|
GEOMToolsGUI_MaterialPropertiesDlg::GEOMToolsGUI_MaterialPropertiesDlg( QWidget* parent,bool showSelWidget, bool modal,const int f )
|
|
: QtxDialog( parent, modal, true, f )
|
|
{
|
|
myShowSelWidget = showSelWidget;
|
|
// Set title
|
|
setWindowTitle( tr( "MATERIAL_PROPERTIES_TLT" ) );
|
|
|
|
// main layout
|
|
QVBoxLayout* main = new QVBoxLayout( mainFrame() );
|
|
main->setMargin( 0 );
|
|
main->setSpacing( SPACING );
|
|
|
|
// add top-level frame box to enclose all main widgets (excluding buttons)
|
|
QFrame* fr = new QFrame( mainFrame() );
|
|
fr->setFrameStyle( QFrame::Box | QFrame::Sunken );
|
|
main->addWidget( fr );
|
|
// selection widget
|
|
myLineEditCurArg = new QLineEdit(fr);
|
|
myLineEditCurArg->setReadOnly(true);
|
|
myPushBtn = new QPushButton(fr);
|
|
QLabel* PushBtnLab = new QLabel( tr( "GEOM_OBJECTS" ), fr );
|
|
|
|
// materials list widget
|
|
myMaterials = new GEOMToolsGUI_MaterialList( fr );
|
|
// properties widget
|
|
QWidget* propWidget = new QWidget( fr );
|
|
|
|
// layout main widgets
|
|
QHBoxLayout* frLayout = new QHBoxLayout( fr );
|
|
frLayout->setMargin( MARGIN );
|
|
frLayout->setSpacing( SPACING );
|
|
frLayout->addWidget( myMaterials );
|
|
frLayout->addWidget( propWidget );
|
|
|
|
// layout for material properties widgets
|
|
QGridLayout* propLayout = new QGridLayout( propWidget );
|
|
propLayout->setMargin( 0 );
|
|
propLayout->setSpacing( SPACING );
|
|
|
|
// current color widgets
|
|
myColorLab = new QLabel( tr( "CURRENT_COLOR" ), propWidget );
|
|
myColor = new QtxColorButton( propWidget );
|
|
|
|
// "physical" material type widgets
|
|
myPhysical = new QCheckBox( tr( "PHYSICAL" ), propWidget );
|
|
|
|
// Labels for front and back reflection components
|
|
QLabel* aFrontLabel = new QLabel( tr( "FRONT_FACE" ), propWidget );
|
|
QLabel* aBackLabel = new QLabel( tr( "BACK_FACE" ), propWidget );
|
|
|
|
// reflection components widgets
|
|
for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ )
|
|
{
|
|
Reflection refl;
|
|
|
|
refl.enabled = new QCheckBox( propWidget );
|
|
|
|
refl.label = new QLabel( tr( QString( "REFLECTION_%1" ).arg( i ).toLatin1().data() ), propWidget );
|
|
|
|
refl.color = new QtxColorButton( propWidget );
|
|
//refl.color->setSizePolicy( QSizePolicy( QSizePolicy::Expanding, QSizePolicy::Fixed ) );
|
|
|
|
refl.front_coef = new QtxDoubleSpinBox( propWidget );
|
|
refl.front_coef->setPrecision( 4 );
|
|
refl.front_coef->setDecimals( 4 );
|
|
refl.front_coef->setRange( 0., 1. );
|
|
refl.front_coef->setSingleStep( 0.05 );
|
|
refl.front_coef->setMinimumWidth( 80 );
|
|
|
|
refl.back_coef = new QtxDoubleSpinBox( propWidget );
|
|
refl.back_coef->setPrecision( 4 );
|
|
refl.back_coef->setDecimals( 4 );
|
|
refl.back_coef->setRange( 0., 1. );
|
|
refl.back_coef->setSingleStep( 0.05 );
|
|
refl.back_coef->setMinimumWidth( 80 );
|
|
|
|
myReflection << refl;
|
|
}
|
|
|
|
// shininess widgets
|
|
QLabel* shininessLab = new QLabel( tr( "SHININESS" ), propWidget );
|
|
myFrontShininess = new QtxDoubleSpinBox( propWidget );
|
|
myFrontShininess->setPrecision( 4 );
|
|
myFrontShininess->setDecimals( 4 );
|
|
myFrontShininess->setRange( 0., 1. );
|
|
myFrontShininess->setSingleStep( 0.05 );
|
|
|
|
myBackShininess = new QtxDoubleSpinBox( propWidget );
|
|
myBackShininess->setPrecision( 4 );
|
|
myBackShininess->setDecimals( 4 );
|
|
myBackShininess->setRange( 0., 1. );
|
|
myBackShininess->setSingleStep( 0.05 );
|
|
|
|
// separator widgets
|
|
QFrame* line1 = new QFrame( propWidget );
|
|
line1->setFrameStyle( QFrame::HLine | QFrame::Sunken );
|
|
QFrame* line2 = new QFrame( propWidget );
|
|
line2->setFrameStyle( QFrame::HLine | QFrame::Sunken );
|
|
QFrame* line3 = new QFrame( propWidget );
|
|
line3->setFrameStyle( QFrame::VLine | QFrame::Sunken );
|
|
QFrame* line4 = new QFrame( propWidget );
|
|
line4->setFrameStyle( QFrame::VLine | QFrame::Sunken );
|
|
QFrame* line5 = new QFrame( propWidget );
|
|
line5->setFrameStyle( QFrame::HLine | QFrame::Sunken );
|
|
|
|
// add / remove material buttons
|
|
myAddButton = new QPushButton( tr( "ADD_MATERIAL" ), propWidget );
|
|
myDelButton = new QPushButton( tr( "DELETE_MATERIAL" ), propWidget );
|
|
|
|
// buttons layout
|
|
QHBoxLayout* btnLayout = new QHBoxLayout;
|
|
btnLayout->setMargin( 0 );
|
|
btnLayout->setSpacing( SPACING );
|
|
btnLayout->addWidget( myAddButton );
|
|
btnLayout->addWidget( myDelButton );
|
|
|
|
// layout all properties widgets together
|
|
propLayout->addWidget( PushBtnLab,0,0);
|
|
propLayout->addWidget( myPushBtn,0,1);
|
|
propLayout->addWidget( myLineEditCurArg, 0, 2, 1, 5 );
|
|
propLayout->addWidget( line1, 1, 0, 1, 7 );
|
|
propLayout->addWidget( myColorLab, 2, 1 );
|
|
propLayout->addWidget( myColor, 2, 2 );
|
|
propLayout->addWidget( myPhysical, 2, 0 );
|
|
propLayout->addWidget( line2, 3, 0, 1, 7 );
|
|
propLayout->addWidget( aFrontLabel, 4, 4);
|
|
propLayout->addWidget( aBackLabel, 4, 6);
|
|
|
|
propLayout->addWidget( line3, 4, 3, 6, 1 );
|
|
propLayout->addWidget( line4, 4, 5, 6, 1 );
|
|
|
|
if( !myShowSelWidget ) {
|
|
myColorLab->hide();
|
|
myColor->hide();
|
|
line1->hide();
|
|
myLineEditCurArg->hide();
|
|
myPushBtn->hide();
|
|
PushBtnLab->hide();
|
|
}
|
|
for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ ) {
|
|
propLayout->addWidget( myReflection[i].enabled, i+5, 0 );
|
|
propLayout->addWidget( myReflection[i].label, i+5, 1 );
|
|
propLayout->addWidget( myReflection[i].color, i+5, 2 );
|
|
propLayout->addWidget( myReflection[i].front_coef, i+5, 4 );
|
|
propLayout->addWidget( myReflection[i].back_coef, i+5, 6 );
|
|
}
|
|
|
|
propLayout->addWidget( shininessLab, 9, 0 );
|
|
propLayout->addWidget( myFrontShininess, 9, 4 );
|
|
propLayout->addWidget( myBackShininess, 9, 6 );
|
|
propLayout->addWidget( line5, 10, 0, 1, 7 );
|
|
propLayout->setRowStretch( 11, 5 );
|
|
propLayout->addLayout( btnLayout, 12, 0, 1, 7 );
|
|
|
|
// initialize dialog box
|
|
setButtonPosition( Right, Close );
|
|
|
|
// fill in the list of materials
|
|
QStringList globalMaterials = myResourceMgr.materials( Material_ResourceMgr::Global );
|
|
QStringList userMaterials = myResourceMgr.materials( Material_ResourceMgr::User );
|
|
|
|
QListWidgetItem* item;
|
|
|
|
// - current material
|
|
item = new QListWidgetItem( tr( "CURRENT_MATERIAL" ) );
|
|
item->setForeground( QColor( Qt::red ) );
|
|
item->setData( TypeRole, QVariant( Current ) );
|
|
myMaterials->addItem( item );
|
|
// - global materials
|
|
foreach( QString material, globalMaterials ) {
|
|
item = new QListWidgetItem( material );
|
|
item->setForeground( QColor( Qt::blue ) );
|
|
item->setData( TypeRole, QVariant( Global ) );
|
|
item->setData( NameRole, QVariant( material ) );
|
|
myMaterials->addItem( item );
|
|
}
|
|
// - user materials
|
|
foreach ( QString material, userMaterials ) {
|
|
item = new QListWidgetItem( material );
|
|
item->setData( TypeRole, QVariant( User ) );
|
|
item->setData( NameRole, QVariant( material ) );
|
|
item->setFlags( item->flags() | Qt::ItemIsEditable );
|
|
myMaterials->addItem( item );
|
|
}
|
|
// install event filter to the materials list to process key press events
|
|
myMaterials->installEventFilter( this );
|
|
|
|
//Set image
|
|
myPushBtn->setIcon(SUIT_Session::session()->resourceMgr()->loadPixmap("GEOM", tr("ICON_SELECT")));
|
|
|
|
// connect signals
|
|
// note: all widgets, that change material properties, are connected to the common signal
|
|
// changed(), instead of connecting directly to the slot - this allows easy temporary blocking
|
|
// of the change signal
|
|
connect( myPhysical, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
|
|
for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ ) {
|
|
connect( myReflection[i].color, SIGNAL( changed( QColor ) ), this, SIGNAL( changed() ) );
|
|
connect( myReflection[i].front_coef, SIGNAL( valueChanged( double ) ), this, SIGNAL( changed() ) );
|
|
connect( myReflection[i].back_coef, SIGNAL( valueChanged( double ) ), this, SIGNAL( changed() ) );
|
|
connect( myReflection[i].enabled, SIGNAL( toggled( bool ) ), this, SIGNAL( changed() ) );
|
|
}
|
|
connect( myFrontShininess, SIGNAL( valueChanged( double ) ), this, SIGNAL( changed() ) );
|
|
connect( myBackShininess, SIGNAL( valueChanged( double ) ), this, SIGNAL( changed() ) );
|
|
connect( myMaterials, SIGNAL( itemSelectionChanged() ),
|
|
this, SLOT( onMaterialChanged() ) );
|
|
connect( myMaterials, SIGNAL( itemChanged( QListWidgetItem* ) ),
|
|
this, SLOT( onItemChanged( QListWidgetItem* ) ) );
|
|
connect( myMaterials, SIGNAL( contextMenu( QContextMenuEvent* ) ),
|
|
this, SLOT( onContextMenu( QContextMenuEvent* ) ) );
|
|
connect( myAddButton, SIGNAL( clicked() ), this, SLOT( onAddMaterial() ) );
|
|
connect( myDelButton, SIGNAL( clicked() ), this, SLOT( onDeleteMaterial() ) );
|
|
connect( this, SIGNAL( dlgApply() ), this, SLOT( onApply() ) );
|
|
connect( this, SIGNAL( dlgHelp() ), this, SLOT( onHelp() ) );
|
|
connect( this, SIGNAL( changed() ), this, SLOT( onChanged() ) );
|
|
connect(myPushBtn, SIGNAL(clicked()), this, SLOT(SetEditCurrentArgument()));
|
|
connect(((SalomeApp_Application*)(SUIT_Session::session()->activeApplication()))->selectionMgr(),
|
|
SIGNAL(currentSelectionChanged()), this, SLOT(SelectionIntoArgument()));
|
|
|
|
// initialize current material model according to the selection
|
|
myColor->setColor( SUIT_Session::session()->resourceMgr()->colorValue( "Geometry", "shading_color", QColor( 255, 0, 0 ) ) );
|
|
myCurrentModel.fromResources( SUIT_Session::session()->resourceMgr()->stringValue( "Geometry", "material", "Plastic" ) );
|
|
SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
|
|
SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
|
|
LightApp_SelectionMgr* selMgr = app->selectionMgr();
|
|
if ( study ) {
|
|
SALOME_ListIO selected;
|
|
selMgr->selectedObjects( selected );
|
|
if ( selected.Extent() > 0 ) {
|
|
Handle(SALOME_InteractiveObject) io = selected.First();
|
|
if ( !io.IsNull() ) {
|
|
SUIT_ViewWindow* window = app->desktop()->activeWindow();
|
|
if ( window ) {
|
|
int mgrId = window->getViewManager()->getGlobalId();
|
|
PropMap propMap = study->getObjectProperties( mgrId, io->getEntry() );
|
|
QString matProp = propMap.value(GEOM::propertyName( GEOM::Material )).toString();
|
|
if ( !matProp.isEmpty() )
|
|
myCurrentModel.fromProperties( matProp );
|
|
QColor c = propMap.value(GEOM::propertyName( GEOM::Color )).value<QColor>();
|
|
if ( c.isValid() )
|
|
myColor->setColor( c );
|
|
}
|
|
}
|
|
}
|
|
}
|
|
myLineEditCurArg->setText("");
|
|
myPushBtn->click();
|
|
SelectionIntoArgument();
|
|
|
|
// finally activate current material properties
|
|
myMaterials->setCurrentRow( 0 );
|
|
}
|
|
|
|
/*!
|
|
\brief Destructor
|
|
*/
|
|
GEOMToolsGUI_MaterialPropertiesDlg::~GEOMToolsGUI_MaterialPropertiesDlg()
|
|
{
|
|
}
|
|
|
|
/*!
|
|
\brief Called when "OK" button is clicked
|
|
*/
|
|
void GEOMToolsGUI_MaterialPropertiesDlg::accept()
|
|
{
|
|
onApply();
|
|
QtxDialog::accept();
|
|
}
|
|
|
|
/*!
|
|
\brief Event filter
|
|
\param o sender
|
|
\param e event
|
|
*/
|
|
bool GEOMToolsGUI_MaterialPropertiesDlg::eventFilter( QObject* o, QEvent* e )
|
|
{
|
|
// process key press event from materials list
|
|
if ( o == myMaterials && e->type() == QEvent::KeyPress ) {
|
|
QKeyEvent* ke = (QKeyEvent*)e;
|
|
if ( ke->key() == Qt::Key_Delete ) {
|
|
onDeleteMaterial();
|
|
}
|
|
}
|
|
return QtxDialog::eventFilter( o, e );
|
|
}
|
|
|
|
/*!
|
|
\brief Initialize dialog box widgets from material model
|
|
\param model material model
|
|
*/
|
|
void GEOMToolsGUI_MaterialPropertiesDlg::fromModel( const Material_Model& model )
|
|
{
|
|
// reflection components
|
|
for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ )
|
|
{
|
|
myReflection[i].color->setColor( model.color( (Material_Model::ReflectionType)i ) );
|
|
myReflection[i].front_coef->setValue( model.reflection( (Material_Model::ReflectionType)i, true ) );
|
|
myReflection[i].back_coef->setValue( model.reflection( (Material_Model::ReflectionType)i, false ) );
|
|
myReflection[i].enabled->setChecked( model.hasReflection( (Material_Model::ReflectionType)i ) );
|
|
}
|
|
|
|
// shininess
|
|
myFrontShininess->setValue( model.shininess( true ) );
|
|
myBackShininess->setValue( model.shininess( false ) );
|
|
|
|
// type (physical or no)
|
|
myPhysical->setChecked( model.isPhysical() );
|
|
}
|
|
|
|
/*!
|
|
\brief Save values from dialog box widgets to material model
|
|
\param model material model to be filled in
|
|
*/
|
|
void GEOMToolsGUI_MaterialPropertiesDlg::toModel( Material_Model& model ) const
|
|
{
|
|
// type (physical or no)
|
|
model.setPhysical( myPhysical->isChecked() );
|
|
|
|
// shininess
|
|
model.setShininess( myFrontShininess->value(), true );
|
|
model.setShininess( myBackShininess->value(), false );
|
|
|
|
// reflection components
|
|
for ( int i = Material_Model::Ambient; i <= Material_Model::Emissive; i++ )
|
|
{
|
|
model.setColor ( (Material_Model::ReflectionType)i, myReflection[i].color->color() );
|
|
model.setReflection( (Material_Model::ReflectionType)i, myReflection[i].front_coef->value(), true );
|
|
model.setReflection( (Material_Model::ReflectionType)i, myReflection[i].back_coef->value(), false );
|
|
model.setReflection( (Material_Model::ReflectionType)i, myReflection[i].enabled->isChecked() );
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief Find unique name for the material name
|
|
\param name material name template
|
|
\param item the item to be ignored when browsing through the materials list
|
|
\param addSuffix if \c true, the integrer suffix is always added to the material name (otherwise
|
|
suffix is added only if item name is not unique)
|
|
\return new unique material name
|
|
*/
|
|
QString GEOMToolsGUI_MaterialPropertiesDlg::findUniqueName( const QString& name, QListWidgetItem* item, bool addSuffix )
|
|
{
|
|
bool found = false;
|
|
int idx = 0;
|
|
for( int i = 1; i < myMaterials->count(); i++ ) {
|
|
if ( item == myMaterials->item( i ) ) continue;
|
|
QString iname = myMaterials->item( i )->text();
|
|
if ( iname == name ) {
|
|
found = true;
|
|
}
|
|
else if ( iname.startsWith( name ) ) {
|
|
iname = iname.mid( name.length() ).trimmed();
|
|
bool ok = false;
|
|
int nx = iname.toInt( &ok );
|
|
if ( ok ) idx = qMax( idx, nx );
|
|
}
|
|
}
|
|
return found || addSuffix ? QString( "%1 %2" ).arg( name ).arg( idx+1 ) : name;
|
|
}
|
|
|
|
/*!
|
|
\brief Called when "Apply" button is pressed
|
|
*/
|
|
void GEOMToolsGUI_MaterialPropertiesDlg::onApply()
|
|
{
|
|
// save user materials
|
|
myResourceMgr.save();
|
|
if( !myShowSelWidget ) return;
|
|
// store selected material properties in the current model
|
|
toModel( myCurrentModel );
|
|
|
|
SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
|
|
LightApp_SelectionMgr* selMgr = app->selectionMgr();
|
|
SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
|
|
|
|
if ( !study ) return;
|
|
|
|
// get selection
|
|
SALOME_ListIO selected;
|
|
selMgr->selectedObjects( selected );
|
|
if ( selected.IsEmpty() ) return;
|
|
|
|
SUIT_ViewWindow* window = app->desktop()->activeWindow();
|
|
int mgrId = window->getViewManager()->getGlobalId();
|
|
|
|
// convert current material properties to the string representation
|
|
QString prop = myCurrentModel.toProperties();
|
|
|
|
if ( window && window->getViewManager()->getType() == SVTK_Viewer::Type() ) {
|
|
// for VTK viewer
|
|
SVTK_ViewWindow* vtkVW = dynamic_cast<SVTK_ViewWindow*>( window );
|
|
if ( !vtkVW )
|
|
return;
|
|
|
|
SVTK_View* aView = vtkVW->getView();
|
|
|
|
// get VTK material properties from the current model
|
|
GEOM_VTKPropertyMaterial* vtkPropF = myCurrentModel.getMaterialVTKProperty();
|
|
GEOM_VTKPropertyMaterial* vtkPropB = myCurrentModel.getMaterialVTKProperty( false );
|
|
|
|
SUIT_OverrideCursor wc();
|
|
|
|
for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
|
|
// set material property to the presentation
|
|
aView->SetMaterial( It.Value(), vtkPropF, vtkPropB );
|
|
// store chosen material in the property map
|
|
study->setObjectProperty( mgrId, It.Value()->getEntry(), GEOM::propertyName( GEOM::Material ), prop );
|
|
// set correct color for the non-physical material
|
|
if ( !myCurrentModel.isPhysical() ) {
|
|
aView->SetColor( It.Value(), myColor->color() );
|
|
study->setObjectProperty( mgrId, It.Value()->getEntry(), GEOM::propertyName( GEOM::Color ), myColor->color() );
|
|
}
|
|
}
|
|
aView->Repaint();
|
|
GeometryGUI::Modified();
|
|
}
|
|
else if ( window && window->getViewManager()->getType() == OCCViewer_Viewer::Type() ) {
|
|
// for OCC viewer
|
|
OCCViewer_Viewer* vm = dynamic_cast<OCCViewer_Viewer*>( window->getViewManager()->getViewModel() );
|
|
if ( !vm )
|
|
return;
|
|
|
|
Handle(AIS_InteractiveContext) ic = vm->getAISContext();
|
|
|
|
// get OCC material aspect from the current model
|
|
Graphic3d_MaterialAspect front_occAspect = myCurrentModel.getMaterialOCCAspect( true );
|
|
Graphic3d_MaterialAspect back_occAspect = myCurrentModel.getMaterialOCCAspect( false );
|
|
|
|
SUIT_OverrideCursor wc();
|
|
|
|
for ( SALOME_ListIteratorOfListIO It( selected ); It.More(); It.Next() ) {
|
|
Handle(GEOM_AISShape) aisShape = GEOMBase::ConvertIOinGEOMAISShape( It.Value(), true );
|
|
if ( !aisShape.IsNull() ) {
|
|
// Set front material for the selected shape
|
|
aisShape->SetCurrentFacingModel(Aspect_TOFM_FRONT_SIDE);
|
|
aisShape->SetMaterial(front_occAspect);
|
|
// Set back material for the selected shape
|
|
aisShape->SetCurrentFacingModel(Aspect_TOFM_BACK_SIDE);
|
|
aisShape->SetMaterial(back_occAspect);
|
|
// Return to the default facing mode
|
|
aisShape->SetCurrentFacingModel(Aspect_TOFM_BOTH_SIDE);
|
|
// store chosen material in the property map
|
|
study->setObjectProperty( mgrId, It.Value()->getEntry(), GEOM::propertyName( GEOM::Material ), prop );
|
|
// set correct color for the non-physical material
|
|
if ( !myCurrentModel.isPhysical() ) {
|
|
aisShape->SetShadingColor( SalomeApp_Tools::color( myColor->color() ) );
|
|
study->setObjectProperty( mgrId, It.Value()->getEntry(), GEOM::propertyName( GEOM::Color ), myColor->color() );
|
|
ic->RecomputePrsOnly( aisShape, Standard_False );
|
|
}
|
|
//if ( aisShape->DisplayMode() != AIS_Shaded/*aisShape->DisplayMode() == GEOM_AISShape::ShadingWithEdges*/)
|
|
ic->Redisplay( aisShape, Standard_False );
|
|
}
|
|
}
|
|
ic->UpdateCurrentViewer();
|
|
GeometryGUI::Modified();
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief Called when "Help" button is pressed
|
|
*/
|
|
void GEOMToolsGUI_MaterialPropertiesDlg::onHelp()
|
|
{
|
|
LightApp_Application* app = (LightApp_Application*)(SUIT_Session::session()->activeApplication());
|
|
app->onHelpContextModule( "GEOM", "material_page.html" );
|
|
}
|
|
|
|
/*!
|
|
\brief Called when user selects any material item in the materials list
|
|
*/
|
|
void GEOMToolsGUI_MaterialPropertiesDlg::onMaterialChanged()
|
|
{
|
|
// get currently selected item
|
|
QListWidgetItem* item = myMaterials->currentItem();
|
|
if ( !item ) return;
|
|
|
|
bool blocked = blockSignals( true );
|
|
|
|
int type = item->data( TypeRole ).toInt();
|
|
if ( type == Current ) {
|
|
// initialize widgets from current material model
|
|
fromModel( myCurrentModel );
|
|
}
|
|
else {
|
|
// initialize widgets from chosen material model (using resources manager)
|
|
Material_Model model;
|
|
model.fromResources( item->data( NameRole ).toString(), &myResourceMgr );
|
|
fromModel( model );
|
|
}
|
|
|
|
blockSignals( blocked );
|
|
|
|
// update buttons state
|
|
updateState();
|
|
}
|
|
|
|
/*!
|
|
\brief Called when any material parameter is changed by the user
|
|
*/
|
|
void GEOMToolsGUI_MaterialPropertiesDlg::onChanged()
|
|
{
|
|
// get currently selected item
|
|
QListWidgetItem* item = myMaterials->currentItem();
|
|
int type = item->data( TypeRole ).toInt();
|
|
if ( !item ) return;
|
|
|
|
if ( type == Current ) {
|
|
// for the current model do not perform any actions except store changed values
|
|
toModel( myCurrentModel );
|
|
}
|
|
else if ( type == User ) {
|
|
// for the user model, simply store the changes in the resource manager
|
|
Material_Model model;
|
|
toModel( model );
|
|
// check if the user model is renamed
|
|
QString oldName = item->data( NameRole ).toString(), newName = item->text();
|
|
if ( oldName == newName ) {
|
|
// model is not renamed: store data using current name
|
|
model.toResources( oldName, &myResourceMgr );
|
|
}
|
|
else {
|
|
// model is renamed: remove model with old name and store model using new name
|
|
myResourceMgr.remove( oldName );
|
|
model.toResources( newName, &myResourceMgr );
|
|
item->setData( NameRole, newName );
|
|
}
|
|
}
|
|
else {
|
|
// it is no allowed to change global material
|
|
// user is asked about creating of a new user material model based on the currently selected one
|
|
if ( SUIT_MessageBox::question( this,
|
|
tr( "GEOM_WRN_WARNING" ),
|
|
tr( "QUE_CREATE_NEW_MATERIAL" ),
|
|
QMessageBox::Yes | QMessageBox::No,
|
|
QMessageBox::Yes ) == QMessageBox::Yes ) {
|
|
// user has chosen creation of new user model
|
|
onAddMaterial();
|
|
}
|
|
else {
|
|
// user has rejected creation of new user model: revert changes
|
|
bool blocked = blockSignals( true );
|
|
Material_Model model;
|
|
model.fromResources( item->data( NameRole ).toString(), &myResourceMgr );
|
|
fromModel( model );
|
|
blockSignals( blocked );
|
|
}
|
|
}
|
|
|
|
// update buttons state
|
|
updateState();
|
|
}
|
|
|
|
/*!
|
|
\brief Called when user material is renamed by the user
|
|
*/
|
|
void GEOMToolsGUI_MaterialPropertiesDlg::onItemChanged( QListWidgetItem* item )
|
|
{
|
|
// check new name to be unique (add suffix if necessary)
|
|
QString newName = item->text();
|
|
QString uniqueName = findUniqueName( newName, item );
|
|
if ( uniqueName != newName ) {
|
|
bool blocked = myMaterials->blockSignals( true );
|
|
item->setText( uniqueName );
|
|
myMaterials->blockSignals( blocked );
|
|
}
|
|
onChanged();
|
|
}
|
|
|
|
/*!
|
|
\brief Process context menu event from materials list
|
|
*/
|
|
void GEOMToolsGUI_MaterialPropertiesDlg::onContextMenu( QContextMenuEvent* e )
|
|
{
|
|
QListWidgetItem* item = myMaterials->itemAt( e->pos() );
|
|
QMap<QAction*, int> actionMap;
|
|
QMenu m;
|
|
// rename
|
|
if ( item && item->data( TypeRole ).toInt() == User ) {
|
|
actionMap[ m.addAction( tr( "RENAME_MATERIAL" ) ) ] = 0;
|
|
m.addSeparator();
|
|
}
|
|
// add user material
|
|
actionMap[ m.addAction( tr( "ADD_MATERIAL" ) ) ] = 1;
|
|
// delete user material
|
|
if ( item && item->data( TypeRole ).toInt() == User ) {
|
|
actionMap[ m.addAction( tr( "DELETE_MATERIAL" ) ) ] = 2;
|
|
}
|
|
QAction* a = m.exec( e->globalPos() );
|
|
switch( actionMap[ a ] ) {
|
|
case 0:
|
|
// rename
|
|
myMaterials->editItem( item );
|
|
break;
|
|
case 1:
|
|
// add user material
|
|
onAddMaterial();
|
|
break;
|
|
case 2:
|
|
// delete user material
|
|
onDeleteMaterial();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief Delete currently selected user model
|
|
*/
|
|
void GEOMToolsGUI_MaterialPropertiesDlg::onDeleteMaterial()
|
|
{
|
|
QListWidgetItem* item = myMaterials->currentItem();
|
|
if ( item && item->data( TypeRole ).toInt() == User ) {
|
|
if ( SUIT_MessageBox::question( this,
|
|
tr( "GEOM_WRN_WARNING" ),
|
|
tr( "QUE_REMOVE_MATERIAL" ).arg( item->text() ),
|
|
QMessageBox::Yes | QMessageBox::No,
|
|
QMessageBox::Yes ) == QMessageBox::Yes ) {
|
|
myResourceMgr.remove( item->data( NameRole ).toString() );
|
|
delete item;
|
|
}
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief Add new user material model
|
|
*/
|
|
void GEOMToolsGUI_MaterialPropertiesDlg::onAddMaterial()
|
|
{
|
|
QString newName = findUniqueName( tr( "CUSTOM_MATERIAL" ), 0, true );
|
|
QListWidgetItem* item = new QListWidgetItem( newName );
|
|
item->setData( TypeRole, QVariant( User ) );
|
|
item->setData( NameRole, QVariant( newName ) );
|
|
item->setFlags( item->flags() | Qt::ItemIsEditable );
|
|
myMaterials->addItem( item );
|
|
|
|
Material_Model model;
|
|
toModel( model );
|
|
model.toResources( newName, &myResourceMgr );
|
|
myMaterials->setCurrentItem( item );
|
|
myMaterials->editItem( item );
|
|
}
|
|
|
|
/*!
|
|
\brief Update buttons state
|
|
*/
|
|
void GEOMToolsGUI_MaterialPropertiesDlg::updateState()
|
|
{
|
|
QListWidgetItem* item = myMaterials->currentItem();
|
|
myDelButton->setEnabled( item && item->data( TypeRole ).toInt() == User );
|
|
myColorLab->setEnabled( !myPhysical->isChecked() );
|
|
myColor->setEnabled( !myPhysical->isChecked() );
|
|
myReflection[0].color->setEnabled( myPhysical->isChecked() );
|
|
}
|
|
|
|
|
|
void GEOMToolsGUI_MaterialPropertiesDlg::SetEditCurrentArgument()
|
|
{
|
|
QPushButton* send = (QPushButton*)sender();
|
|
|
|
if (send == myPushBtn) {
|
|
// enable line edit
|
|
myLineEditCurArg->setEnabled(true);
|
|
myLineEditCurArg->setFocus();
|
|
SelectionIntoArgument();
|
|
// after setFocus(), because it will be setDown(false) when loses focus
|
|
send->setDown(true);
|
|
}
|
|
}
|
|
|
|
/*!
|
|
\brief Called when selection as changed or other case
|
|
*/
|
|
void GEOMToolsGUI_MaterialPropertiesDlg::SelectionIntoArgument()
|
|
{
|
|
myLineEditCurArg->setText( "" );
|
|
QString aString = "";
|
|
|
|
SalomeApp_Application* app = dynamic_cast< SalomeApp_Application* >( SUIT_Session::session()->activeApplication() );
|
|
SalomeApp_Study* study = dynamic_cast<SalomeApp_Study*>( app->activeStudy() );
|
|
LightApp_SelectionMgr* aSelMgr = app->selectionMgr();
|
|
if ( study ) {
|
|
SALOME_ListIO aSelList;
|
|
aSelMgr->selectedObjects(aSelList);
|
|
int nbSel = GEOMBase::GetNameOfSelectedIObjects(aSelList, aString, true);
|
|
}
|
|
myLineEditCurArg->setText( aString );
|
|
}
|