Merge pull request #2094 from berndhahnebach/bhbdev210
FEM and Material: small fixes and code formating
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2013 Juergen Riegel <FreeCAD@juergen-riegel.net> *
|
||||
# * Copyright (c) 2013 Juergen Riegel <FreeCAD@juergen-riegel.net> *
|
||||
# * Copyright (c) 2016 Bernd Hahnebach <bernd@bimstatik.org> *
|
||||
# * *
|
||||
# * This program is free software; you can redistribute it and/or modify *
|
||||
# * it under the terms of the GNU Lesser General Public License (LGPL) *
|
||||
@@ -77,10 +77,12 @@ class _ViewProviderFemMaterial:
|
||||
FreeCADGui.Control.closeDialog()
|
||||
return True
|
||||
|
||||
# overwrite the doubleClicked of material object python to make sure no other Material taskd (and thus no selection observer) is still active
|
||||
# overwrite the doubleClicked of material object python to make sure no other Material taskd
|
||||
# (and thus no selection observer) is still active
|
||||
def doubleClicked(self, vobj):
|
||||
guidoc = FreeCADGui.getDocument(vobj.Object.Document)
|
||||
# check if another VP is in edit mode, https://forum.freecadweb.org/viewtopic.php?t=13077#p104702
|
||||
# check if another VP is in edit mode
|
||||
# https://forum.freecadweb.org/viewtopic.php?t=13077#p104702
|
||||
if not guidoc.getInEdit():
|
||||
guidoc.setEdit(vobj.Object.Name)
|
||||
else:
|
||||
@@ -106,31 +108,79 @@ class _TaskPanelFemMaterial:
|
||||
self.material = self.obj.Material # FreeCAD material dictionary of current material
|
||||
self.card_path = ''
|
||||
self.materials = {} # { card_path : FreeCAD material dict }
|
||||
self.icons = {} # { card_path : icon_path }
|
||||
# mat_card is the FCMat file
|
||||
# card_name is the file name of the mat_card
|
||||
# card_path is the whole file path of the mat_card
|
||||
# material_name is the value of the key name in FreeCAD material dictionary
|
||||
# they might not match because of special letters in the material_name which are changed in the card_name to english standard characters
|
||||
# they might not match because of special letters in the material_name
|
||||
# which are changed in the card_name to english standard characters
|
||||
self.has_transient_mat = False
|
||||
|
||||
# parameter widget
|
||||
self.parameterWidget = FreeCADGui.PySideUic.loadUi(FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/Material.ui")
|
||||
self.parameterWidget = FreeCADGui.PySideUic.loadUi(
|
||||
FreeCAD.getHomePath() + "Mod/Fem/Resources/ui/Material.ui"
|
||||
)
|
||||
# globals
|
||||
QtCore.QObject.connect(self.parameterWidget.cb_materials, QtCore.SIGNAL("activated(int)"), self.choose_material)
|
||||
QtCore.QObject.connect(self.parameterWidget.chbu_allow_edit, QtCore.SIGNAL("clicked()"), self.toggleInputFieldsReadOnly)
|
||||
QtCore.QObject.connect(self.parameterWidget.pushButton_editMat, QtCore.SIGNAL("clicked()"), self.edit_material)
|
||||
QtCore.QObject.connect(
|
||||
self.parameterWidget.cb_materials,
|
||||
QtCore.SIGNAL("activated(int)"),
|
||||
self.choose_material
|
||||
)
|
||||
QtCore.QObject.connect(
|
||||
self.parameterWidget.chbu_allow_edit,
|
||||
QtCore.SIGNAL("clicked()"),
|
||||
self.toggleInputFieldsReadOnly
|
||||
)
|
||||
QtCore.QObject.connect(
|
||||
self.parameterWidget.pushButton_editMat,
|
||||
QtCore.SIGNAL("clicked()"),
|
||||
self.edit_material
|
||||
)
|
||||
# basic properties must be provided
|
||||
QtCore.QObject.connect(self.parameterWidget.input_fd_density, QtCore.SIGNAL("editingFinished()"), self.density_changed)
|
||||
QtCore.QObject.connect(
|
||||
self.parameterWidget.input_fd_density,
|
||||
QtCore.SIGNAL("editingFinished()"),
|
||||
self.density_changed
|
||||
)
|
||||
# mechanical properties
|
||||
QtCore.QObject.connect(self.parameterWidget.input_fd_young_modulus, QtCore.SIGNAL("editingFinished()"), self.ym_changed)
|
||||
QtCore.QObject.connect(self.parameterWidget.spinBox_poisson_ratio, QtCore.SIGNAL("editingFinished()"), self.pr_changed)
|
||||
QtCore.QObject.connect(
|
||||
self.parameterWidget.input_fd_young_modulus,
|
||||
QtCore.SIGNAL("editingFinished()"),
|
||||
self.ym_changed
|
||||
)
|
||||
QtCore.QObject.connect(
|
||||
self.parameterWidget.spinBox_poisson_ratio,
|
||||
QtCore.SIGNAL("editingFinished()"),
|
||||
self.pr_changed
|
||||
)
|
||||
# thermal properties
|
||||
QtCore.QObject.connect(self.parameterWidget.input_fd_thermal_conductivity, QtCore.SIGNAL("editingFinished()"), self.tc_changed)
|
||||
QtCore.QObject.connect(self.parameterWidget.input_fd_expansion_coefficient, QtCore.SIGNAL("editingFinished()"), self.tec_changed)
|
||||
QtCore.QObject.connect(self.parameterWidget.input_fd_specific_heat, QtCore.SIGNAL("editingFinished()"), self.sh_changed)
|
||||
QtCore.QObject.connect(
|
||||
self.parameterWidget.input_fd_thermal_conductivity,
|
||||
QtCore.SIGNAL("editingFinished()"),
|
||||
self.tc_changed
|
||||
)
|
||||
QtCore.QObject.connect(
|
||||
self.parameterWidget.input_fd_expansion_coefficient,
|
||||
QtCore.SIGNAL("editingFinished()"),
|
||||
self.tec_changed
|
||||
)
|
||||
QtCore.QObject.connect(
|
||||
self.parameterWidget.input_fd_specific_heat,
|
||||
QtCore.SIGNAL("editingFinished()"),
|
||||
self.sh_changed
|
||||
)
|
||||
# fluidic properties, only volumetric thermal expansion coeff makes sense
|
||||
QtCore.QObject.connect(self.parameterWidget.input_fd_kinematic_viscosity, QtCore.SIGNAL("editingFinished()"), self.kinematic_viscosity_changed)
|
||||
QtCore.QObject.connect(self.parameterWidget.input_fd_vol_expansion_coefficient, QtCore.SIGNAL("editingFinished()"), self.vtec_changed)
|
||||
QtCore.QObject.connect(
|
||||
self.parameterWidget.input_fd_kinematic_viscosity,
|
||||
QtCore.SIGNAL("editingFinished()"),
|
||||
self.kinematic_viscosity_changed
|
||||
)
|
||||
QtCore.QObject.connect(
|
||||
self.parameterWidget.input_fd_vol_expansion_coefficient,
|
||||
QtCore.SIGNAL("editingFinished()"),
|
||||
self.vtec_changed
|
||||
)
|
||||
|
||||
# init all parameter input files with read only
|
||||
self.parameterWidget.chbu_allow_edit.setCheckState(QtCore.Qt.CheckState.Unchecked)
|
||||
@@ -147,8 +197,10 @@ class _TaskPanelFemMaterial:
|
||||
self.parameterWidget.label_vol_expansion_coefficient.setVisible(0)
|
||||
self.parameterWidget.input_fd_vol_expansion_coefficient.setVisible(0)
|
||||
|
||||
# fill self.materials dict and fill the combobox with material cards
|
||||
# get all available materials (fill self.materials and self.icons)
|
||||
self.import_materials()
|
||||
# fill the material comboboxes with material cards
|
||||
self.add_cards_to_combo_box()
|
||||
|
||||
# search for exact this mat_card in all known cards, choose the current material
|
||||
self.card_path = self.get_material_card(self.material)
|
||||
@@ -156,22 +208,38 @@ class _TaskPanelFemMaterial:
|
||||
if not self.card_path:
|
||||
# we have not found our material in self.materials dict :-(
|
||||
# we're going to add a user-defined temporary material: a document material
|
||||
FreeCAD.Console.PrintMessage("Previously used material card cannot be found in material directories. Add document material.\n")
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Previously used material card cannot be found in material directories. "
|
||||
"Add document material.\n"
|
||||
)
|
||||
self.card_path = '_document_material'
|
||||
self.materials[self.card_path] = self.material
|
||||
self.parameterWidget.cb_materials.addItem(QtGui.QIcon(":/icons/help-browser.svg"), self.card_path, self.card_path)
|
||||
self.parameterWidget.cb_materials.addItem(
|
||||
QtGui.QIcon(":/icons/help-browser.svg"),
|
||||
self.card_path,
|
||||
self.card_path
|
||||
)
|
||||
index = self.parameterWidget.cb_materials.findData(self.card_path)
|
||||
# print(index)
|
||||
self.choose_material(index) # fill input fields and set the current material in the cb widget
|
||||
# fill input fields and set the current material in the cb widget
|
||||
self.choose_material(index)
|
||||
else:
|
||||
# we found our exact material in self.materials dict :-)
|
||||
FreeCAD.Console.PrintMessage("Previously used material card was found in material directories. We will use this material.\n")
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Previously used material card was found in material directories. "
|
||||
"We will use this material.\n"
|
||||
)
|
||||
index = self.parameterWidget.cb_materials.findData(self.card_path)
|
||||
# print(index)
|
||||
self.choose_material(index) # fill input fields and set the current material in the cb widget
|
||||
# fill input fields and set the current material in the cb widget
|
||||
self.choose_material(index)
|
||||
|
||||
# geometry selection widget
|
||||
self.selectionWidget = FemSelectionWidgets.GeometryElementsSelection(obj.References, ['Solid', 'Face', 'Edge'], False) # start with Solid in list!
|
||||
self.selectionWidget = FemSelectionWidgets.GeometryElementsSelection(
|
||||
obj.References,
|
||||
['Solid', 'Face', 'Edge'],
|
||||
False
|
||||
) # start with Solid in list!
|
||||
|
||||
# form made from param and selection widget
|
||||
self.form = [self.parameterWidget, self.selectionWidget]
|
||||
@@ -179,10 +247,11 @@ class _TaskPanelFemMaterial:
|
||||
# check references, has to be after initialisation of selectionWidget
|
||||
self.selectionWidget.has_equal_references_shape_types()
|
||||
|
||||
# leave task panel **********************************************
|
||||
# leave task panel ***************************************************************************
|
||||
def accept(self):
|
||||
# print(self.material)
|
||||
if self.selectionWidget.has_equal_references_shape_types():
|
||||
self.do_not_set_thermal_zeros()
|
||||
self.obj.Material = self.material
|
||||
self.obj.References = self.selectionWidget.references
|
||||
self.recompute_and_set_back_all()
|
||||
@@ -200,11 +269,35 @@ class _TaskPanelFemMaterial:
|
||||
FreeCADGui.Selection.removeObserver(self.selectionWidget.sel_server)
|
||||
doc.resetEdit()
|
||||
|
||||
# choose material ***********************************************
|
||||
def do_not_set_thermal_zeros(self):
|
||||
''' thermal material parameter are set to 0.0 if not available
|
||||
this leads to wrong material values and to not finding the card
|
||||
on reopen the task pane, thus do not write thermal parameter,
|
||||
if they are 0.0
|
||||
'''
|
||||
if Units.Quantity(self.material['ThermalConductivity']) == 0.0:
|
||||
self.material.pop('ThermalConductivity', None)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'Zero ThermalConductivity value. It is not saved in the card data.\n'
|
||||
)
|
||||
if Units.Quantity(self.material['ThermalExpansionCoefficient']) == 0.0:
|
||||
self.material.pop('ThermalExpansionCoefficient', None)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'Zero ThermalExpansionCoefficient value. It is not saved in the card data.\n'
|
||||
)
|
||||
if Units.Quantity(self.material['SpecificHeat']) == 0.0:
|
||||
self.material.pop('SpecificHeat', None)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'Zero SpecificHeat value. It is not saved in the card data.\n'
|
||||
)
|
||||
|
||||
# choose material ****************************************************************************
|
||||
def get_material_card(self, material):
|
||||
for a_mat in self.materials:
|
||||
unmatched_items = set(self.materials[a_mat].items()) ^ set(material.items())
|
||||
# print(a_mat + ' --> unmatched_items = ' + str(len(unmatched_items)))
|
||||
# if len(unmatched_items) < 4:
|
||||
# print(unmatched_items)
|
||||
if len(unmatched_items) == 0:
|
||||
return a_mat
|
||||
return ""
|
||||
@@ -212,7 +305,7 @@ class _TaskPanelFemMaterial:
|
||||
def choose_material(self, index):
|
||||
if index < 0:
|
||||
return
|
||||
self.card_path = self.parameterWidget.cb_materials.itemData(index) # returns the whole path !
|
||||
self.card_path = self.parameterWidget.cb_materials.itemData(index) # returns whole path
|
||||
# print('choose_material: ' + self.card_path)
|
||||
self.material = self.materials[self.card_path]
|
||||
self.check_material_keys()
|
||||
@@ -237,28 +330,52 @@ class _TaskPanelFemMaterial:
|
||||
def add_transient_material(self):
|
||||
self.has_transient_mat = True
|
||||
self.card_path = '_transient_material'
|
||||
self.parameterWidget.cb_materials.addItem(QtGui.QIcon(":/icons/help-browser.svg"), self.card_path, self.card_path)
|
||||
self.parameterWidget.cb_materials.addItem(
|
||||
QtGui.QIcon(":/icons/help-browser.svg"),
|
||||
self.card_path,
|
||||
self.card_path
|
||||
)
|
||||
self.set_transient_material()
|
||||
|
||||
# how to edit a material ****************************************
|
||||
# how to edit a material *********************************************************************
|
||||
def edit_material(self):
|
||||
# opens the material editor to choose a material or edit material params
|
||||
# self.print_material_params()
|
||||
import MaterialEditor
|
||||
new_material_params = self.material.copy()
|
||||
new_material_params = MaterialEditor.editMaterial(new_material_params)
|
||||
# if the material editor was canceled a empty params dict will be returned, do not change the self.material
|
||||
# if the material editor was canceled a empty params dict will be returned
|
||||
# do not change the self.material
|
||||
# self.print_material_params(new_material_params)
|
||||
if new_material_params: # returns True if dict is not empty (do not use 'is True', this would return False for a non empty dict)
|
||||
# check if dict is not empty (do not use 'is True'
|
||||
if new_material_params:
|
||||
self.material = new_material_params
|
||||
self.check_material_keys()
|
||||
self.set_mat_params_in_input_fields(self.material)
|
||||
if self.has_transient_mat is False:
|
||||
self.add_transient_material()
|
||||
self.card_path = self.get_material_card(self.material)
|
||||
# print('card_path: ' + self.card_path)
|
||||
self.check_material_keys()
|
||||
self.set_mat_params_in_input_fields(self.material)
|
||||
if not self.card_path:
|
||||
if self.has_transient_mat is False:
|
||||
self.add_transient_material()
|
||||
else:
|
||||
self.set_transient_material()
|
||||
else:
|
||||
# we found our exact material in self.materials dict :-)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Material card was found in material directories. "
|
||||
"We will use this material.\n"
|
||||
)
|
||||
index = self.parameterWidget.cb_materials.findData(self.card_path)
|
||||
# print(index)
|
||||
# set the current material in the cb widget
|
||||
self.choose_material(index)
|
||||
else:
|
||||
self.set_transient_material()
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'No changes where made by the material editor.\n'
|
||||
)
|
||||
# self.print_material_params()
|
||||
# material editor returns the mat_dict only not a card_path, if a standard FreeCAD mat_card was used
|
||||
# material editor returns the mat_dict only not a card_path
|
||||
# if a standard FreeCAD mat_card was used
|
||||
|
||||
def toggleInputFieldsReadOnly(self):
|
||||
if self.parameterWidget.chbu_allow_edit.isChecked():
|
||||
@@ -280,10 +397,11 @@ class _TaskPanelFemMaterial:
|
||||
self.parameterWidget.input_fd_kinematic_viscosity.setReadOnly(True)
|
||||
self.parameterWidget.input_fd_vol_expansion_coefficient.setReadOnly(True)
|
||||
|
||||
# material parameter input fields *******************************
|
||||
# material parameter input fields ************************************************************
|
||||
def print_material_params(self, material=None):
|
||||
# in rare cases we gone pass a empty dict
|
||||
# in such a case a empty dict should be printed and not self.material thus we check for None
|
||||
# in such a case a empty dict should be printed and not self.material
|
||||
# thus we check for None
|
||||
if material is None:
|
||||
material = self.material
|
||||
if not material:
|
||||
@@ -297,72 +415,131 @@ class _TaskPanelFemMaterial:
|
||||
def check_material_keys(self):
|
||||
# FreeCAD units definition is at file end of src/Base/Unit.cpp
|
||||
if not self.material:
|
||||
print('For some reason all material data is empty!')
|
||||
FreeCAD.Console.PrintMessage('For some reason all material data is empty!\n')
|
||||
self.material['Name'] = 'Empty'
|
||||
if 'Density' in self.material:
|
||||
if 'Density' not in str(Units.Unit(self.material['Density'])):
|
||||
print('Density in material data seems to have no unit or a wrong unit (reset the value): ' + self.material['Name'])
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'Density in material data seems to have no unit '
|
||||
'or a wrong unit (reset the value): {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['Density'] = '0 kg/m^3'
|
||||
else:
|
||||
print('Density not found in material data of: ' + self.material['Name'])
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'Density not found in material data of: {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['Density'] = '0 kg/m^3'
|
||||
if self.obj.Category == 'Solid':
|
||||
# mechanical properties
|
||||
if 'YoungsModulus' in self.material:
|
||||
if 'Pressure' not in str(Units.Unit(self.material['YoungsModulus'])): # unit type of YoungsModulus is Pressure
|
||||
print('YoungsModulus in material data seems to have no unit or a wrong unit (reset the value): ' + self.material['Name'])
|
||||
# unit type of YoungsModulus is Pressure
|
||||
if 'Pressure' not in str(Units.Unit(self.material['YoungsModulus'])):
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'YoungsModulus in material data seems to have no unit '
|
||||
'or a wrong unit (reset the value): {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['YoungsModulus'] = '0 MPa'
|
||||
else:
|
||||
print('YoungsModulus not found in material data of: ' + self.material['Name'])
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'YoungsModulus not found in material data of: {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['YoungsModulus'] = '0 MPa'
|
||||
if 'PoissonRatio' in self.material:
|
||||
# PoissonRatio does not have a unit, but it is checked it there is no value at all
|
||||
try:
|
||||
float(self.material['PoissonRatio'])
|
||||
except:
|
||||
print('PoissonRatio has wrong or no data (reset the value): ' + self.material['PoissonRatio'])
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'PoissonRatio has wrong or no data (reset the value): {}\n'
|
||||
.format(self.material['PoissonRatio'])
|
||||
)
|
||||
self.material['PoissonRatio'] = '0'
|
||||
else:
|
||||
print('PoissonRatio not found in material data of: ' + self.material['Name'])
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'PoissonRatio not found in material data of: {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['PoissonRatio'] = '0'
|
||||
if self.obj.Category == 'Fluid':
|
||||
# Fluidic properties
|
||||
if 'KinematicViscosity' in self.material:
|
||||
if 'KinematicViscosity' not in str(Units.Unit(self.material['KinematicViscosity'])):
|
||||
print('KinematicViscosity in material data seems to have no unit or a wrong unit (reset the value): ' + self.material['Name'])
|
||||
ki_vis = self.material['KinematicViscosity']
|
||||
if 'KinematicViscosity' not in str(Units.Unit(ki_vis)):
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'KinematicViscosity in material data seems to have no unit '
|
||||
'or a wrong unit (reset the value): {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['KinematicViscosity'] = '0 m^2/s'
|
||||
else:
|
||||
print('KinematicViscosity not found in material data of: ' + self.material['Name'])
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'KinematicViscosity not found in material data of: {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['KinematicViscosity'] = '0 m^2/s'
|
||||
if 'VolumetricThermalExpansionCoefficient' in self.material:
|
||||
# unit type of VolumetricThermalExpansionCoefficient is ThermalExpansionCoefficient
|
||||
if 'VolumetricThermalExpansionCoefficient' not in str(Units.Unit(self.material['VolumetricThermalExpansionCoefficient'])):
|
||||
print('VolumetricThermalExpansionCoefficient in material data seems to have no unit or a wrong unit (reset the value): ' + self.material['Name'])
|
||||
# unit type VolumetricThermalExpansionCoefficient is ThermalExpansionCoefficient
|
||||
vol_ther_ex_co = self.material['VolumetricThermalExpansionCoefficient']
|
||||
if 'VolumetricThermalExpansionCoefficient' not in str(Units.Unit(vol_ther_ex_co)):
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'VolumetricThermalExpansionCoefficient in material data '
|
||||
'seems to have no unit or a wrong unit (reset the value): {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['VolumetricThermalExpansionCoefficient'] = '0 m/m/K'
|
||||
else:
|
||||
print('VolumetricThermalExpansionCoefficient not found in material data of: ' + self.material['Name'])
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'VolumetricThermalExpansionCoefficient not found in material data of: {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['VolumetricThermalExpansionCoefficient'] = '0 m/m/K'
|
||||
# Thermal properties
|
||||
if 'ThermalConductivity' in self.material:
|
||||
if 'ThermalConductivity' not in str(Units.Unit(self.material['ThermalConductivity'])):
|
||||
print('ThermalConductivity in material data seems to have no unit or a wrong unit (reset the value): ' + self.material['Name'])
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'ThermalConductivity in material data seems to have no unit '
|
||||
'or a wrong unit (reset the value): {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['ThermalConductivity'] = '0 W/m/K'
|
||||
else:
|
||||
print('ThermalConductivity not found in material data of: ' + self.material['Name'])
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'ThermalConductivity not found in material data of: {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['ThermalConductivity'] = '0 W/m/K'
|
||||
if 'ThermalExpansionCoefficient' in self.material:
|
||||
if 'ThermalExpansionCoefficient' not in str(Units.Unit(self.material['ThermalExpansionCoefficient'])):
|
||||
print('ThermalExpansionCoefficient in material data seems to have no unit or a wrong unit (reset the value): ' + self.material['Name'])
|
||||
the_ex_co = self.material['ThermalExpansionCoefficient']
|
||||
if 'ThermalExpansionCoefficient' not in str(Units.Unit(the_ex_co)):
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'ThermalExpansionCoefficient in material data seems to have no unit '
|
||||
'or a wrong unit (reset the value): {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['ThermalExpansionCoefficient'] = '0 um/m/K'
|
||||
else:
|
||||
print('ThermalExpansionCoefficient not found in material data of: ' + self.material['Name'])
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'ThermalExpansionCoefficient not found in material data of: {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['ThermalExpansionCoefficient'] = '0 um/m/K'
|
||||
if 'SpecificHeat' in self.material:
|
||||
if 'SpecificHeat' not in str(Units.Unit(self.material['SpecificHeat'])):
|
||||
print('SpecificHeat in material data seems to have no unit or a wrong unit (reset the value): ' + self.material['Name'])
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'SpecificHeat in material data seems to have no unit '
|
||||
'or a wrong unit (reset the value): {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['SpecificHeat'] = '0 J/kg/K'
|
||||
else:
|
||||
print('SpecificHeat not found in material data of: ' + self.material['Name'])
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'SpecificHeat not found in material data of: {}\n'
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['SpecificHeat'] = '0 J/kg/K'
|
||||
|
||||
# mechanical input fields
|
||||
@@ -392,7 +569,8 @@ class _TaskPanelFemMaterial:
|
||||
# density has changed
|
||||
material = self.material
|
||||
value_in_kg_per_m3 = value * 1e9
|
||||
material['Density'] = unicode(value_in_kg_per_m3) + " kg/m^3" # SvdW:Keep density in SI units for easier readability
|
||||
# SvdW:Keep density in SI units for easier readability
|
||||
material['Density'] = unicode(value_in_kg_per_m3) + " kg/m^3"
|
||||
self.material = material
|
||||
if self.has_transient_mat is False:
|
||||
self.add_transient_material()
|
||||
@@ -442,7 +620,9 @@ class _TaskPanelFemMaterial:
|
||||
|
||||
def tec_changed(self):
|
||||
value = self.parameterWidget.input_fd_expansion_coefficient.property("rawValue")
|
||||
old_tec = Units.Quantity(self.material['ThermalExpansionCoefficient']).getValueAs("um/m/K")
|
||||
old_tec = Units.Quantity(
|
||||
self.material['ThermalExpansionCoefficient']
|
||||
).getValueAs("um/m/K")
|
||||
variation = 0.001
|
||||
if value:
|
||||
if not (1 - variation < float(old_tec) / value < 1 + variation):
|
||||
@@ -475,14 +655,16 @@ class _TaskPanelFemMaterial:
|
||||
# fluidic input fields
|
||||
def vtec_changed(self):
|
||||
value = self.parameterWidget.input_fd_vol_expansion_coefficient.property("rawValue")
|
||||
old_vtec = Units.Quantity(self.material['VolumetricThermalExpansionCoefficient']).getValueAs("m/m/K")
|
||||
old_vtec = Units.Quantity(
|
||||
self.material['VolumetricThermalExpansionCoefficient']
|
||||
).getValueAs("m/m/K")
|
||||
variation = 0.001
|
||||
if value:
|
||||
if not (1 - variation < float(old_vtec) / value < 1 + variation):
|
||||
# VolumetricThermalExpansionCoefficient has changed
|
||||
material = self.material
|
||||
value_in_one_per_K = value
|
||||
material['VolumetricThermalExpansionCoefficient'] = unicode(value_in_one_per_K) + " m/m/K"
|
||||
value_in_one_per_K = unicode(value) + " m/m/K"
|
||||
material['VolumetricThermalExpansionCoefficient'] = value_in_one_per_K
|
||||
self.material = material
|
||||
if self.has_transient_mat is False:
|
||||
self.add_transient_material()
|
||||
@@ -521,7 +703,8 @@ class _TaskPanelFemMaterial:
|
||||
nu_with_new_unit = nu.getValueAs(nu_new_unit)
|
||||
q = FreeCAD.Units.Quantity("{} {}".format(nu_with_new_unit, nu_new_unit))
|
||||
self.parameterWidget.input_fd_kinematic_viscosity.setText(q.UserString)
|
||||
# For isotropic materials the volumetric thermal expansion coefficient is three times the linear coefficient:
|
||||
# For isotropic materials the volumetric thermal expansion coefficient
|
||||
# is three times the linear coefficient:
|
||||
if 'VolumetricThermalExpansionCoefficient' in matmap: # linear, only for solid
|
||||
vtec_new_unit = "m/m/K"
|
||||
vtec = FreeCAD.Units.Quantity(matmap['VolumetricThermalExpansionCoefficient'])
|
||||
@@ -532,7 +715,9 @@ class _TaskPanelFemMaterial:
|
||||
density_new_unit = "kg/m^3"
|
||||
density = FreeCAD.Units.Quantity(matmap['Density'])
|
||||
density_with_new_unit = density.getValueAs(density_new_unit)
|
||||
# self.parameterWidget.input_fd_density.setText("{} {}".format(density_with_new_unit, density_new_unit))
|
||||
# self.parameterWidget.input_fd_density.setText(
|
||||
# "{} {}".format(density_with_new_unit, density_new_unit)
|
||||
# )
|
||||
q = FreeCAD.Units.Quantity("{} {}".format(density_with_new_unit, density_new_unit))
|
||||
self.parameterWidget.input_fd_density.setText(q.UserString)
|
||||
# thermal properties
|
||||
@@ -555,7 +740,20 @@ class _TaskPanelFemMaterial:
|
||||
q = FreeCAD.Units.Quantity("{} {}".format(sh_with_new_unit, sh_new_unit))
|
||||
self.parameterWidget.input_fd_specific_heat.setText(q.UserString)
|
||||
|
||||
# material import and export ************************************
|
||||
# fill the combo box with cards **************************************************************
|
||||
def add_cards_to_combo_box(self):
|
||||
# fill combobox, in combo box the card name is used not the material name
|
||||
from os.path import basename
|
||||
self.parameterWidget.cb_materials.clear()
|
||||
card_name_list = []
|
||||
for a_path in self.materials:
|
||||
card_name = basename(a_path[:-(len(".FCMat"))])
|
||||
card_name_list.append([card_name, a_path, self.icons[a_path]])
|
||||
card_name_list.sort()
|
||||
for mat in card_name_list:
|
||||
self.parameterWidget.cb_materials.addItem(QtGui.QIcon(mat[2]), mat[0], mat[1])
|
||||
|
||||
# material card handling *********************************************************************
|
||||
def print_materialsdict(self):
|
||||
print('\n\n')
|
||||
for mat_card in self.materials:
|
||||
@@ -564,10 +762,9 @@ class _TaskPanelFemMaterial:
|
||||
print('\n\n')
|
||||
|
||||
def import_materials(self):
|
||||
self.pathList = []
|
||||
self.parameterWidget.cb_materials.clear()
|
||||
|
||||
self.fem_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Material/Resources")
|
||||
self.fem_prefs = FreeCAD.ParamGet(
|
||||
"User parameter:BaseApp/Preferences/Mod/Material/Resources"
|
||||
)
|
||||
if self.obj.Category == 'Fluid':
|
||||
self.import_fluid_materials()
|
||||
else:
|
||||
@@ -607,18 +804,15 @@ class _TaskPanelFemMaterial:
|
||||
self.add_cards_from_a_dir(custom_mat_dir, ":/icons/user.svg")
|
||||
|
||||
def add_cards_from_a_dir(self, mat_dir, icon):
|
||||
# fill self.materials and self.icons
|
||||
import glob
|
||||
import os
|
||||
import Material
|
||||
mat_file_extension = ".FCMat"
|
||||
ext_len = len(mat_file_extension)
|
||||
dir_path_list = glob.glob(mat_dir + '/*' + mat_file_extension)
|
||||
self.pathList = self.pathList + dir_path_list
|
||||
card_name_list = []
|
||||
from importFCMat import read
|
||||
dir_path_list = glob.glob(mat_dir + '/*' + ".FCMat")
|
||||
|
||||
for a_path in dir_path_list:
|
||||
card_name = os.path.basename(a_path[:-ext_len])
|
||||
self.materials[a_path] = Material.importFCMat(a_path)
|
||||
card_name_list.append([card_name, a_path])
|
||||
card_name_list.sort()
|
||||
for mat in card_name_list:
|
||||
self.parameterWidget.cb_materials.addItem(QtGui.QIcon(icon), mat[0], mat[1])
|
||||
mat_dict = read(a_path)
|
||||
# check if the dict exists in materials
|
||||
# TODO if the unit is different two cards would be different too
|
||||
if mat_dict not in self.materials.values():
|
||||
self.materials[a_path] = mat_dict
|
||||
self.icons[a_path] = icon
|
||||
|
||||
@@ -20,6 +20,9 @@
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
import FreeCAD
|
||||
|
||||
|
||||
# here the usage description if you use this tool from the command line ("__main__")
|
||||
CommandlineUsage = """Material - Tool to work with FreeCAD Material definition cards
|
||||
|
||||
@@ -49,8 +52,9 @@ Version:
|
||||
"""
|
||||
|
||||
|
||||
# see comments in module importFCMat, there is an independent parser implementation for reading and writing FCMat files
|
||||
# inside FreeCAD a mixture of these parsers and the ones in importFCMat.py is used
|
||||
# see comments in module importFCMat, there is an independent parser implementation
|
||||
# for reading and writing FCMat files
|
||||
# inside FreeCAD mostly the one from importFCMat.py is used
|
||||
|
||||
|
||||
def importFCMat(fileName):
|
||||
@@ -60,6 +64,10 @@ def importFCMat(fileName):
|
||||
except ImportError:
|
||||
import configparser
|
||||
|
||||
FreeCAD.Console.PrintError(
|
||||
'This mat card reader is probably depretiated and not widely used in FreeCAD. '
|
||||
'See comment in Material.py module.\n'
|
||||
)
|
||||
Config = configparser.RawConfigParser()
|
||||
Config.optionxform = str
|
||||
Config.read(fileName)
|
||||
@@ -81,6 +89,10 @@ def exportFCMat(fileName, matDict):
|
||||
import string
|
||||
Config = configparser.RawConfigParser()
|
||||
|
||||
FreeCAD.Console.PrintError(
|
||||
'This mat card writer is probably depretiated and not widely used in FreeCAD. '
|
||||
'See comment in Material.py module.\n'
|
||||
)
|
||||
# create groups
|
||||
for x in matDict.keys():
|
||||
grp, key = string.split(x, sep='_')
|
||||
@@ -104,7 +116,8 @@ def getMaterialAttributeStructure(withSpaces=None):
|
||||
''''''
|
||||
|
||||
# material properties
|
||||
# see the following resources in the FreeCAD wiki for more information about the material specific properties:
|
||||
# see the following resources in the FreeCAD wiki for more information
|
||||
# about the material specific properties:
|
||||
# https://www.freecadweb.org/wiki/Material_data_model
|
||||
# https://www.freecadweb.org/wiki/Material
|
||||
|
||||
@@ -115,7 +128,8 @@ def getMaterialAttributeStructure(withSpaces=None):
|
||||
tree = ElementTree.parse(infile)
|
||||
|
||||
if withSpaces:
|
||||
# on attributes, add a space before a capital letter, will be used for better display in the ui
|
||||
# on attributes, add a space before a capital letter
|
||||
# will be used for better display in the ui
|
||||
import re
|
||||
root = tree.getroot()
|
||||
for group in root.getchildren():
|
||||
@@ -131,7 +145,7 @@ def read_cards_from_path(cards_path):
|
||||
from os.path import isfile, join, basename, splitext
|
||||
from importFCMat import read
|
||||
only_files = [f for f in listdir(cards_path) if isfile(join(cards_path, f))]
|
||||
mat_files = [f for f in only_files if basename(splitext(f)[1]) == '.FCMat' or basename(splitext(f)[1]) == '.fcmat']
|
||||
mat_files = [f for f in only_files if basename(splitext(f)[1]).upper() == '.FCMAT']
|
||||
# print(mat_files)
|
||||
mat_cards = []
|
||||
for f in sorted(mat_files):
|
||||
|
||||
@@ -20,23 +20,21 @@
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
|
||||
from __future__ import print_function
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
from Material import getMaterialAttributeStructure
|
||||
import os
|
||||
from PySide import QtCore, QtGui
|
||||
# from PySide import QtUiTools, QtSvg
|
||||
import sys
|
||||
if sys.version_info.major >= 3:
|
||||
unicode = str
|
||||
|
||||
|
||||
__title__ = "FreeCAD material editor"
|
||||
__author__ = "Yorik van Havre"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
|
||||
import os
|
||||
import sys
|
||||
from PySide import QtCore, QtGui
|
||||
# from PySide import QtUiTools, QtSvg
|
||||
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
|
||||
if sys.version_info.major >= 3:
|
||||
unicode = str
|
||||
|
||||
|
||||
class MaterialEditor:
|
||||
|
||||
@@ -78,7 +76,8 @@ class MaterialEditor:
|
||||
standardButtons.button(QtGui.QDialogButtonBox.Ok).setAutoDefault(False)
|
||||
standardButtons.button(QtGui.QDialogButtonBox.Cancel).setAutoDefault(False)
|
||||
self.updateCards()
|
||||
# TODO allow to enter a custom property by pressing Enter in the lineedit (currently closes the dialog)
|
||||
# TODO allow to enter a custom property by pressing Enter in the lineedit
|
||||
# currently closes the dialog
|
||||
|
||||
standardButtons.rejected.connect(self.reject)
|
||||
standardButtons.accepted.connect(self.accept)
|
||||
@@ -119,6 +118,7 @@ class MaterialEditor:
|
||||
treeView.setColumnWidth(1, 250)
|
||||
treeView.setColumnHidden(2, True)
|
||||
|
||||
from Material import getMaterialAttributeStructure
|
||||
tree = getMaterialAttributeStructure(True)
|
||||
MatPropDict = tree.getroot()
|
||||
|
||||
@@ -149,9 +149,12 @@ class MaterialEditor:
|
||||
def updateContents(self, data):
|
||||
|
||||
'''updates the contents of the editor with the given data, can be:
|
||||
- the name of a card, if material is changed in editors combo box
|
||||
- a dictionary, if the editor was called with data.'''
|
||||
- a dictionary, if the editor was called with data
|
||||
- a string, the name of a card, if material is changed in editors combo box
|
||||
the material property keys where added to the editor already
|
||||
not known material property keys will be added to the user defined group'''
|
||||
|
||||
# print type(data)
|
||||
if isinstance(data, dict):
|
||||
# a standard material property dict is provided
|
||||
model = self.widget.treeView.model()
|
||||
@@ -182,18 +185,21 @@ class MaterialEditor:
|
||||
self.customprops.append(k)
|
||||
|
||||
elif isinstance(data, unicode):
|
||||
# a card name is provided, search card, read material data and call this def once more with std material property dict
|
||||
# a card name is provided, search card, read material data and call
|
||||
# this def once more with std material property dict
|
||||
k = str(data)
|
||||
if k:
|
||||
if k in self.cards:
|
||||
|
||||
import importFCMat
|
||||
d = importFCMat.read(self.cards[k])
|
||||
from importFCMat import read
|
||||
d = read(self.cards[k])
|
||||
if d:
|
||||
self.updateContents(d)
|
||||
|
||||
def getMaterialResources(self):
|
||||
self.fem_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Material/Resources")
|
||||
self.fem_prefs = FreeCAD.ParamGet(
|
||||
"User parameter:BaseApp/Preferences/Mod/Material/Resources"
|
||||
)
|
||||
use_built_in_materials = self.fem_prefs.GetBool("UseBuiltInMaterials", True)
|
||||
use_mat_from_config_dir = self.fem_prefs.GetBool("UseMaterialsFromConfigDir", True)
|
||||
use_mat_from_custom_dir = self.fem_prefs.GetBool("UseMaterialsFromCustomDir", True)
|
||||
@@ -203,7 +209,10 @@ class MaterialEditor:
|
||||
# FreeCAD returns paths with / at the end, thus not os.sep is needed on first +
|
||||
self.resources = []
|
||||
if use_built_in_materials:
|
||||
self.resources.append(FreeCAD.getResourceDir() + "Mod" + os.sep + "Material" + os.sep + "StandardMaterial")
|
||||
res_dir = FreeCAD.getResourceDir()
|
||||
self.resources.append(
|
||||
res_dir + "Mod" + os.sep + "Material" + os.sep + "StandardMaterial"
|
||||
)
|
||||
if use_mat_from_config_dir:
|
||||
self.resources.append(FreeCAD.ConfigGet("UserAppData") + "Material")
|
||||
if use_mat_from_custom_dir:
|
||||
@@ -220,12 +229,14 @@ class MaterialEditor:
|
||||
|
||||
def outputCards(self):
|
||||
print('material cards:')
|
||||
for card in self.cards:
|
||||
for card in sorted(self.cards.keys()):
|
||||
print(' ' + card + ': ' + self.cards[card])
|
||||
print('\n')
|
||||
|
||||
def updateCards(self):
|
||||
"updates the contents of the materials combo with existing material cards"
|
||||
|
||||
'''updates the contents of the materials combo with existing material cards'''
|
||||
|
||||
self.getMaterialResources()
|
||||
self.cards = {}
|
||||
for p in self.resources:
|
||||
@@ -238,11 +249,12 @@ class MaterialEditor:
|
||||
if self.cards:
|
||||
self.widget.ComboMaterial.clear()
|
||||
self.widget.ComboMaterial.addItem("") # add a blank item first
|
||||
for k, i in self.cards.items():
|
||||
self.widget.ComboMaterial.addItem(k)
|
||||
for card in sorted(self.cards.keys()):
|
||||
self.widget.ComboMaterial.addItem(card) # all keys in self.cards are unicode
|
||||
|
||||
def openProductURL(self):
|
||||
"opens the contents of the ProductURL field in an external browser."
|
||||
|
||||
'''opens the contents of the ProductURL field in an external browser.'''
|
||||
|
||||
model = self.widget.treeView.model()
|
||||
item = model.findItems(translate("Material", "Product URL"),
|
||||
@@ -383,7 +395,8 @@ class MaterialEditor:
|
||||
kk = group.child(row, 0).text()
|
||||
ii = group.child(row, 1).text()
|
||||
|
||||
# TODO the following should be translated back to english,since text(0) could be translated
|
||||
# TODO the following should be translated back to english
|
||||
# since text(0) could be translated
|
||||
matkey = self.collapseKey(str(kk))
|
||||
matvalue = unicode(ii)
|
||||
if matvalue or (matkey == 'Name'):
|
||||
@@ -395,9 +408,10 @@ class MaterialEditor:
|
||||
def outputDict(self, d):
|
||||
print('MaterialEditor dictionary')
|
||||
for param in d:
|
||||
print(' ' + param + ' : ' + d[param])
|
||||
print(' {} : {}'.format(param, d[param]))
|
||||
|
||||
'''def setTexture(self, pattern):
|
||||
'''
|
||||
def setTexture(self, pattern):
|
||||
"displays a texture preview if needed"
|
||||
self.widget.PreviewVector.hide()
|
||||
if pattern:
|
||||
@@ -409,16 +423,23 @@ class MaterialEditor:
|
||||
pattern = DrawingPatterns.buildFileSwatch(pattern, size=96, png=True)
|
||||
if pattern:
|
||||
self.widget.PreviewVector.setPixmap(QtGui.QPixmap(pattern))
|
||||
self.widget.PreviewVector.show()'''
|
||||
self.widget.PreviewVector.show()
|
||||
'''
|
||||
|
||||
def openfile(self):
|
||||
"Opens a FCMat file"
|
||||
filetuple = QtGui.QFileDialog.getOpenFileName(QtGui.QApplication.activeWindow(), 'Open FreeCAD Material file', self.directory, '*.FCMat')
|
||||
filename = filetuple[0] # a tuple of two empty strings returns True, so use the filename directly
|
||||
filetuple = QtGui.QFileDialog.getOpenFileName(
|
||||
QtGui.QApplication.activeWindow(),
|
||||
'Open FreeCAD Material file',
|
||||
self.directory,
|
||||
'*.FCMat'
|
||||
)
|
||||
# a tuple of two empty strings returns True, so use the filename directly
|
||||
filename = filetuple[0]
|
||||
if filename:
|
||||
import importFCMat
|
||||
from importFCMat import read
|
||||
self.directory = os.path.dirname(filename)
|
||||
d = importFCMat.read(filename)
|
||||
d = read(filename)
|
||||
if d:
|
||||
self.updateContents(d)
|
||||
|
||||
@@ -436,18 +457,21 @@ class MaterialEditor:
|
||||
name = name.encode("utf8")
|
||||
if not name:
|
||||
name = "Material"
|
||||
filetuple =\
|
||||
QtGui.QFileDialog.getSaveFileName(QtGui.QApplication.activeWindow(),
|
||||
'Save FreeCAD Material file',
|
||||
self.directory + '/' + name + '.FCMat', '*.FCMat')
|
||||
filename = filetuple[0] # a tuple of two empty strings returns True, so use the filename directly
|
||||
filetuple = QtGui.QFileDialog.getSaveFileName(
|
||||
QtGui.QApplication.activeWindow(),
|
||||
'Save FreeCAD Material file',
|
||||
self.directory + '/' + name + '.FCMat',
|
||||
'*.FCMat'
|
||||
)
|
||||
# a tuple of two empty strings returns True, so use the filename directly
|
||||
filename = filetuple[0]
|
||||
if filename:
|
||||
self.directory = os.path.dirname(filename)
|
||||
d = self.getDict()
|
||||
# self.outputDict(d)
|
||||
if d:
|
||||
import importFCMat
|
||||
importFCMat.write(filename, d)
|
||||
from importFCMat import write
|
||||
write(filename, d)
|
||||
self.updateCards()
|
||||
|
||||
def show(self):
|
||||
@@ -567,7 +591,7 @@ def matProperWidget(parent=None, matproperty=None, Type="String", Value=None,
|
||||
quantity = FreeCAD.Units.Quantity(1, unit)
|
||||
widget.setProperty('unit', quantity.getUserPreferred()[2])
|
||||
else:
|
||||
FreeCAD.Console.PrintError('Not known unit for property: ' + matproperty + '\n')
|
||||
FreeCAD.Console.PrintError('Not known unit for property: {}\n'.format(matproperty))
|
||||
|
||||
elif Type == "Integer":
|
||||
|
||||
@@ -644,9 +668,11 @@ def editMaterial(material):
|
||||
"""editMaterial(material): opens the editor to edit the contents
|
||||
of the given material dictionary. Returns the modified material dictionary."""
|
||||
# if the material editor is opened with this def the combo box with the card name is empty
|
||||
# this makes sense, because the editor was not opened with a card but with material dictionary instead
|
||||
# this makes sense ...
|
||||
# because the editor was not opened with a card but with material dictionary instead
|
||||
# TODO: add some text in combo box, may be "custom material data" or "user material data"
|
||||
# TODO: all card could be checked if one fits exact ALL provided data and than this card name could be displayed
|
||||
# TODO: all card could be checked if one fits exact ALL provided data
|
||||
# than this card name could be displayed
|
||||
editor = MaterialEditor(material=material)
|
||||
result = editor.exec_()
|
||||
if result:
|
||||
@@ -660,12 +686,19 @@ def editMaterial(material):
|
||||
import MaterialEditor
|
||||
MaterialEditor.openEditor()
|
||||
|
||||
doc = FreeCAD.open(FreeCAD.ConfigGet("AppHomePath") + 'data/examples/FemCalculixCantilever3D.FCStd')
|
||||
doc = FreeCAD.open(
|
||||
FreeCAD.ConfigGet("AppHomePath") + 'data/examples/FemCalculixCantilever3D.FCStd'
|
||||
)
|
||||
import MaterialEditor
|
||||
MaterialEditor.openEditor('SolidMaterial', 'Material')
|
||||
|
||||
import MaterialEditor
|
||||
MaterialEditor.editMaterial({'Density': '1234.0 kg/m^3', 'Name': 'My-Material-Data', 'PoissonRatio': '0.66', 'YoungsModulus': '123456 MPa'})
|
||||
MaterialEditor.editMaterial({
|
||||
'Density': '1234.0 kg/m^3',
|
||||
'Name': 'My-Material-Data',
|
||||
'PoissonRatio': '0.66',
|
||||
'YoungsModulus': '123456 MPa'
|
||||
})
|
||||
|
||||
import MaterialEditor
|
||||
MaterialEditor.editMaterial('ABS')
|
||||
|
||||
@@ -78,13 +78,16 @@ def decode(name):
|
||||
return decodedName
|
||||
|
||||
|
||||
# the reader and writer do not use some Library to read and write the ini file format, they are implemented here
|
||||
# the reader and writer do not use some Library to read and write the ini file format
|
||||
# they are implemented here
|
||||
# thus non standard ini files will be read and written too
|
||||
# in standard ini file format a = in the value without any encapsulation or string quotes is not allowed (AFAIK)
|
||||
# in standard ini file format:
|
||||
# a = in the value without any encapsulation or string quotes is not allowed (AFAIK)
|
||||
# https://en.wikipedia.org/wiki/INI_file
|
||||
# http://www.docuxplorer.com/WebHelp/INI_File_Format.htm
|
||||
# mainly this parser here is used in FreeCAD
|
||||
# in the module Material.py is another implementation of reading and writing FCMat files which uses the module ConfigParser
|
||||
# in the module Material.py is another implementation of reading and writing FCMat files
|
||||
# this implementation uses the ConfigParser module
|
||||
# in ViewProviderFemMaterial in add_cards_from_a_dir() the parser from Material.py is used
|
||||
# since this mixture seams to be there for ages it should not be changed for 0.18
|
||||
# TODO: get rid of this mixture in FreeCAD 0.19
|
||||
@@ -117,7 +120,10 @@ def read(filename):
|
||||
v = v.decode('utf-8')
|
||||
card_name_content = v
|
||||
if card_name_content != d["CardName"]:
|
||||
FreeCAD.Console.PrintError("File CardName (" + card_name_file + ") is not content CardName (" + card_name_content + ")\n")
|
||||
FreeCAD.Console.PrintLog(
|
||||
"File CardName ( {} ) is not content CardName ( {} )\n"
|
||||
.format(card_name_file, card_name_content)
|
||||
)
|
||||
elif ln == 1:
|
||||
v = line.split(";")[1].strip() # Line 2
|
||||
if hasattr(v, "decode"):
|
||||
@@ -128,7 +134,9 @@ def read(filename):
|
||||
# # might be a comment too ?
|
||||
# [ is a Section
|
||||
if line[0] not in ";#[":
|
||||
k = line.split("=", 1) # only split once on first occurrence, a link could contain a = and thus would be splitted
|
||||
# split once on first occurrence
|
||||
# a link could contain a = and thus would be split
|
||||
k = line.split("=", 1)
|
||||
if len(k) == 2:
|
||||
v = k[1].strip()
|
||||
if hasattr(v, "decode"):
|
||||
@@ -166,12 +174,18 @@ def write(filename, dictionary, write_group_section=True):
|
||||
user[k] = i
|
||||
# delete empty properties
|
||||
for group in contents:
|
||||
for k in list(group.keys()): # iterating over a dict and changing it is not allowed, thus we iterate over a list of the keys
|
||||
# iterating over a dict and changing it is not allowed
|
||||
# thus it is iterated over a list of the keys
|
||||
for k in list(group.keys()):
|
||||
if group[k] == '':
|
||||
del group[k]
|
||||
|
||||
# card writer
|
||||
rev = FreeCAD.ConfigGet("BuildVersionMajor") + "." + FreeCAD.ConfigGet("BuildVersionMinor") + "." + FreeCAD.ConfigGet("BuildRevision")
|
||||
rev = "{}.{}.{}".format(
|
||||
FreeCAD.ConfigGet("BuildVersionMajor"),
|
||||
FreeCAD.ConfigGet("BuildVersionMinor"),
|
||||
FreeCAD.ConfigGet("BuildRevision")
|
||||
)
|
||||
if isinstance(filename, unicode):
|
||||
if sys.version_info.major < 3:
|
||||
filename = filename.encode(sys.getfilesystemencoding())
|
||||
@@ -182,7 +196,8 @@ def write(filename, dictionary, write_group_section=True):
|
||||
# write header
|
||||
# first five lines are the same in any card file, see comment above read def
|
||||
if header["CardName"] != card_name_file:
|
||||
FreeCAD.Console.PrintMessage("File CardName is used: " + card_name_file + " \n") # CardName is the MatCard file name
|
||||
# CardName is the MatCard file name
|
||||
FreeCAD.Console.PrintMessage("File CardName is used: {}\n".format(card_name_file))
|
||||
if sys.version_info.major >= 3:
|
||||
f.write("; " + card_name_file + "\n")
|
||||
f.write("; " + header["AuthorAndLicense"] + "\n")
|
||||
|
||||
@@ -17,77 +17,70 @@
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="ButtonURL">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Opens the Product URL of this material in an external browser</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>Material card:</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="ComboMaterial">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Existing material cards</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="horizontalSpacer">
|
||||
<property name="orientation">
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" stdset="0">
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="ButtonOpen">
|
||||
<property name="toolTip">
|
||||
<string>Opens an existing material card</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Open...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="ButtonSave">
|
||||
<property name="toolTip">
|
||||
<string>Saves this material as a card</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save as...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
<widget class="QGroupBox" name="groupBox_3">
|
||||
<property name="title">
|
||||
<string>Material card</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_4">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_7">
|
||||
<item>
|
||||
<widget class="QPushButton" name="ButtonURL">
|
||||
<property name="maximumSize">
|
||||
<size>
|
||||
<width>22</width>
|
||||
<height>22</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Opens the Product URL of this material in an external browser</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QComboBox" name="ComboMaterial">
|
||||
<property name="minimumSize">
|
||||
<size>
|
||||
<width>120</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="toolTip">
|
||||
<string>Existing material cards</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="ButtonOpen">
|
||||
<property name="toolTip">
|
||||
<string>Opens an existing material card</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Open...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="ButtonSave">
|
||||
<property name="toolTip">
|
||||
<string>Saves this material as a card</string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Save as...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="PreviewGroup">
|
||||
@@ -138,19 +131,28 @@
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMaximumSize</enum>
|
||||
<widget class="QGroupBox" name="groupBox_4">
|
||||
<property name="title">
|
||||
<string>Material parameter</string>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTreeView" name="treeView"/>
|
||||
</item>
|
||||
</layout>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_5">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<property name="sizeConstraint">
|
||||
<enum>QLayout::SetMaximumSize</enum>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTreeView" name="treeView"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="groupBox_2">
|
||||
<property name="title">
|
||||
<string>Add / Remove</string>
|
||||
<string>Add / remove parameter</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_3">
|
||||
<item>
|
||||
|
||||
Reference in New Issue
Block a user