Merge pull request #2102 from berndhahnebach/bhbdev211
Material: editor improvements
This commit is contained in:
@@ -6,7 +6,7 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>505</width>
|
||||
<width>519</width>
|
||||
<height>451</height>
|
||||
</rect>
|
||||
</property>
|
||||
@@ -20,7 +20,7 @@
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gb_4_materials">
|
||||
<property name="title">
|
||||
<string>Material Resources</string>
|
||||
<string>Card resources</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_3">
|
||||
<item>
|
||||
@@ -126,6 +126,51 @@
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QGroupBox" name="gb_4_materials_2">
|
||||
<property name="title">
|
||||
<string>Card sorting and duplicates</string>
|
||||
</property>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout_4">
|
||||
<item>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_7">
|
||||
<item>
|
||||
<widget class="Gui::PrefCheckBox" name="cb_delete_duplicates">
|
||||
<property name="text">
|
||||
<string>Delete card duplicates</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>DeleteDuplicates</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Material/Cards</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="Gui::PrefCheckBox" name="cb_sort_by_resources">
|
||||
<property name="text">
|
||||
<string>Sort by resources (opposite would be sort by cards)</string>
|
||||
</property>
|
||||
<property name="checked">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="prefEntry" stdset="0">
|
||||
<cstring>SortByResources</cstring>
|
||||
</property>
|
||||
<property name="prefPath" stdset="0">
|
||||
<cstring>Mod/Material/Cards</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<spacer name="verticalSpacer">
|
||||
<property name="orientation">
|
||||
|
||||
@@ -48,6 +48,8 @@ void DlgSettingsFemMaterialImp::saveSettings()
|
||||
cb_use_mat_from_config_dir->onSave();
|
||||
cb_use_mat_from_custom_dir->onSave();
|
||||
fc_custom_mat_dir->onSave();
|
||||
cb_delete_duplicates->onSave();
|
||||
cb_sort_by_resources->onSave();
|
||||
}
|
||||
|
||||
void DlgSettingsFemMaterialImp::loadSettings()
|
||||
@@ -56,6 +58,8 @@ void DlgSettingsFemMaterialImp::loadSettings()
|
||||
cb_use_mat_from_config_dir->onRestore();
|
||||
cb_use_mat_from_custom_dir->onRestore();
|
||||
fc_custom_mat_dir->onRestore();
|
||||
cb_delete_duplicates->onRestore();
|
||||
cb_sort_by_resources->onRestore();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -222,7 +222,7 @@ class GeometryElementsSelection(QtGui.QWidget):
|
||||
self.obj_notvisible = []
|
||||
self.initElemTypes(eltypes)
|
||||
self.allow_multiple_geom_types = multigeom
|
||||
print(self.allow_multiple_geom_types)
|
||||
# print(self.allow_multiple_geom_types)
|
||||
self.initUI()
|
||||
# set references and fill the list widget
|
||||
self.references = []
|
||||
|
||||
@@ -104,11 +104,13 @@ class _TaskPanelFemMaterial:
|
||||
|
||||
def __init__(self, obj):
|
||||
|
||||
FreeCAD.Console.PrintMessage('\n') # empty line on start task panel
|
||||
self.obj = obj
|
||||
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 }
|
||||
self.materials = {} # { card_path : FreeCAD material dict, ... }
|
||||
self.cards = {} # { card_path : card_names, ... }
|
||||
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
|
||||
@@ -197,19 +199,20 @@ class _TaskPanelFemMaterial:
|
||||
self.parameterWidget.label_vol_expansion_coefficient.setVisible(0)
|
||||
self.parameterWidget.input_fd_vol_expansion_coefficient.setVisible(0)
|
||||
|
||||
# get all available materials (fill self.materials and self.icons)
|
||||
self.import_materials()
|
||||
# get all available materials (fill self.materials, self.cards and self.icons)
|
||||
from materialtools.cardutils import import_materials as getmats
|
||||
self.materials, self.cards, self.icons = getmats()
|
||||
# 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)
|
||||
print('card_path: ' + self.card_path)
|
||||
FreeCAD.Console.PrintLog('card_path: {}'.format(self.card_path))
|
||||
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. "
|
||||
"Previously used material card can not be found in material directories. "
|
||||
"Add document material.\n"
|
||||
)
|
||||
self.card_path = '_document_material'
|
||||
@@ -225,7 +228,7 @@ class _TaskPanelFemMaterial:
|
||||
self.choose_material(index)
|
||||
else:
|
||||
# we found our exact material in self.materials dict :-)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
FreeCAD.Console.PrintLog(
|
||||
"Previously used material card was found in material directories. "
|
||||
"We will use this material.\n"
|
||||
)
|
||||
@@ -278,17 +281,20 @@ class _TaskPanelFemMaterial:
|
||||
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'
|
||||
'Zero ThermalConductivity value. '
|
||||
'This parameter is not saved in the material 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'
|
||||
'Zero ThermalExpansionCoefficient value. '
|
||||
'This parameter is not saved in the material 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'
|
||||
'Zero SpecificHeat value. '
|
||||
'This parameter is not saved in the material data.\n'
|
||||
)
|
||||
|
||||
# choose material ****************************************************************************
|
||||
@@ -306,7 +312,10 @@ class _TaskPanelFemMaterial:
|
||||
if index < 0:
|
||||
return
|
||||
self.card_path = self.parameterWidget.cb_materials.itemData(index) # returns whole path
|
||||
# print('choose_material: ' + self.card_path)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'choose_material in FEM material task panel:\n'
|
||||
' {}\n'.format(self.card_path)
|
||||
)
|
||||
self.material = self.materials[self.card_path]
|
||||
self.check_material_keys()
|
||||
self.set_mat_params_in_input_fields(self.material)
|
||||
@@ -340,14 +349,12 @@ class _TaskPanelFemMaterial:
|
||||
# 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
|
||||
new_material_params = MaterialEditor.editMaterial(card_path=self.card_path)
|
||||
# material editor returns the mat_dict only, not a card_path
|
||||
# if the material editor was canceled a empty dict will be returned
|
||||
# do not change the self.material
|
||||
# self.print_material_params(new_material_params)
|
||||
# check if dict is not empty (do not use 'is True'
|
||||
# check if dict is not empty (do not use 'is True')
|
||||
if new_material_params:
|
||||
self.material = new_material_params
|
||||
self.card_path = self.get_material_card(self.material)
|
||||
@@ -355,27 +362,31 @@ class _TaskPanelFemMaterial:
|
||||
self.check_material_keys()
|
||||
self.set_mat_params_in_input_fields(self.material)
|
||||
if not self.card_path:
|
||||
FreeCAD.Console.PrintMessage(
|
||||
"Material card chosen by the material editor "
|
||||
"was not found in material directories.\n"
|
||||
"Either the card does not exist or some material "
|
||||
"parameter where changed in material editor.\n"
|
||||
)
|
||||
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"
|
||||
FreeCAD.Console.PrintLog(
|
||||
"Material card chosen by the material editor "
|
||||
"was found in material directories. "
|
||||
"The found material card will be used.\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:
|
||||
FreeCAD.Console.PrintMessage(
|
||||
FreeCAD.Console.PrintLog(
|
||||
'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
|
||||
|
||||
def toggleInputFieldsReadOnly(self):
|
||||
if self.parameterWidget.chbu_allow_edit.isChecked():
|
||||
@@ -398,20 +409,6 @@ class _TaskPanelFemMaterial:
|
||||
self.parameterWidget.input_fd_vol_expansion_coefficient.setReadOnly(True)
|
||||
|
||||
# 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
|
||||
if material is None:
|
||||
material = self.material
|
||||
if not material:
|
||||
# empty dict
|
||||
print(' ' + str(material))
|
||||
else:
|
||||
for p in material:
|
||||
print(' ' + p + ' --> ' + material[p])
|
||||
print('\n')
|
||||
|
||||
def check_material_keys(self):
|
||||
# FreeCAD units definition is at file end of src/Base/Unit.cpp
|
||||
if not self.material:
|
||||
@@ -541,6 +538,7 @@ class _TaskPanelFemMaterial:
|
||||
.format(self.material['Name'])
|
||||
)
|
||||
self.material['SpecificHeat'] = '0 J/kg/K'
|
||||
FreeCAD.Console.PrintMessage('\n')
|
||||
|
||||
# mechanical input fields
|
||||
def ym_changed(self):
|
||||
@@ -743,76 +741,26 @@ class _TaskPanelFemMaterial:
|
||||
# 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()
|
||||
|
||||
mat_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Material/Cards")
|
||||
sort_by_resources = mat_prefs.GetBool("SortByResources", False)
|
||||
|
||||
card_name_list = [] # [ [card_name, card_path, icon_path], ... ]
|
||||
|
||||
if sort_by_resources is True:
|
||||
for a_path in sorted(self.materials.keys()):
|
||||
card_name_list.append([self.cards[a_path], a_path, self.icons[a_path]])
|
||||
else:
|
||||
card_names_tmp = {}
|
||||
for path, name in self.cards.items():
|
||||
card_names_tmp[name] = path
|
||||
for a_name in sorted(card_names_tmp.keys()):
|
||||
a_path = card_names_tmp[a_name]
|
||||
card_name_list.append([a_name, a_path, self.icons[a_path]])
|
||||
|
||||
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:
|
||||
print(mat_card)
|
||||
self.print_material_params(self.materials[mat_card])
|
||||
print('\n\n')
|
||||
|
||||
def import_materials(self):
|
||||
self.fem_prefs = FreeCAD.ParamGet(
|
||||
"User parameter:BaseApp/Preferences/Mod/Material/Resources"
|
||||
)
|
||||
if self.obj.Category == 'Fluid':
|
||||
self.import_fluid_materials()
|
||||
else:
|
||||
self.import_solid_materials()
|
||||
# self.print_materialsdict()
|
||||
|
||||
def import_solid_materials(self):
|
||||
use_built_in_materials = self.fem_prefs.GetBool("UseBuiltInMaterials", True)
|
||||
if use_built_in_materials:
|
||||
system_mat_dir = FreeCAD.getResourceDir() + "/Mod/Material/StandardMaterial"
|
||||
self.add_cards_from_a_dir(system_mat_dir, ":/icons/freecad.svg")
|
||||
|
||||
use_mat_from_config_dir = self.fem_prefs.GetBool("UseMaterialsFromConfigDir", True)
|
||||
if use_mat_from_config_dir:
|
||||
user_mat_dirname = FreeCAD.getUserAppDataDir() + "Material"
|
||||
self.add_cards_from_a_dir(user_mat_dirname, ":/icons/preferences-general.svg")
|
||||
|
||||
use_mat_from_custom_dir = self.fem_prefs.GetBool("UseMaterialsFromCustomDir", True)
|
||||
if use_mat_from_custom_dir:
|
||||
custom_mat_dir = self.fem_prefs.GetString("CustomMaterialsDir", "")
|
||||
self.add_cards_from_a_dir(custom_mat_dir, ":/icons/user.svg")
|
||||
|
||||
def import_fluid_materials(self):
|
||||
# use_built_in_materials = self.fem_prefs.GetBool("UseBuiltInMaterials", True)
|
||||
# if use_built_in_materials:
|
||||
system_mat_dir = FreeCAD.getResourceDir() + "/Mod/Material/FluidMaterial"
|
||||
self.add_cards_from_a_dir(system_mat_dir, ":/icons/freecad.svg")
|
||||
|
||||
use_mat_from_config_dir = self.fem_prefs.GetBool("UseMaterialsFromConfigDir", True)
|
||||
if use_mat_from_config_dir:
|
||||
user_mat_dirname = FreeCAD.getUserAppDataDir() + "FluidMaterial"
|
||||
self.add_cards_from_a_dir(user_mat_dirname, ":/icons/preferences-general.svg")
|
||||
|
||||
use_mat_from_custom_dir = self.fem_prefs.GetBool("UseMaterialsFromCustomDir", True)
|
||||
if use_mat_from_custom_dir:
|
||||
custom_mat_dir = self.fem_prefs.GetString("CustomMaterialsDir", "")
|
||||
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
|
||||
from importFCMat import read
|
||||
dir_path_list = glob.glob(mat_dir + '/*' + ".FCMat")
|
||||
|
||||
for a_path in dir_path_list:
|
||||
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
|
||||
# the whole card path is added to the combo box to make it unique
|
||||
# see def choose_material:
|
||||
# for assignment of self.card_path the path form the parameterWidget ist used
|
||||
|
||||
@@ -9,10 +9,15 @@ SET(Material_SRCS
|
||||
importFCMat.py
|
||||
MaterialEditor.py
|
||||
materials-editor.ui
|
||||
MatPropDict.xml
|
||||
Templatematerial.yml
|
||||
)
|
||||
SOURCE_GROUP("Module" FILES ${Material_SRCS})
|
||||
|
||||
SET (MaterialTools_Files
|
||||
materialtools/__init__.py
|
||||
materialtools/cardutils.py
|
||||
)
|
||||
|
||||
# collect all the material cards:
|
||||
#FILE( GLOB MaterialLib_Files ./StandardMaterial/*.FCMat ./StandardMaterial/*.txt )
|
||||
|
||||
@@ -53,6 +58,19 @@ fc_target_copy_resource(Material
|
||||
${CMAKE_BINARY_DIR}/Mod/Material
|
||||
${Material_SRCS})
|
||||
|
||||
|
||||
ADD_CUSTOM_TARGET(MaterialToolsLib ALL
|
||||
SOURCES ${MaterialTools_Files}
|
||||
)
|
||||
|
||||
fc_target_copy_resource(MaterialToolsLib
|
||||
${CMAKE_CURRENT_SOURCE_DIR}
|
||||
${CMAKE_BINARY_DIR}/Mod/Material
|
||||
${MaterialTools_Files})
|
||||
|
||||
INSTALL(FILES ${MaterialTools_Files} DESTINATION Mod/Material/materialtools)
|
||||
|
||||
|
||||
IF (BUILD_GUI)
|
||||
fc_target_copy_resource(Material
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
|
||||
@@ -1,140 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<MatPropDict>
|
||||
|
||||
<Group Name="Meta">
|
||||
<Property Name="CardName" Type="String">
|
||||
</Property>
|
||||
<Property Name="AuthorAndLicense" Type="String">
|
||||
</Property>
|
||||
</Group>
|
||||
|
||||
<Group Name="General">
|
||||
<Property Name="Name" Type="String">
|
||||
</Property>
|
||||
<Property Name="Father" Type="String">
|
||||
</Property>
|
||||
<Property Name="Description" Type="String">
|
||||
</Property>
|
||||
<Property Name="ReferenceSource" Type="String">
|
||||
</Property>
|
||||
<Property Name="SourceURL" Type="URL">
|
||||
</Property>
|
||||
</Group>
|
||||
|
||||
<Group Name="Mechanical">
|
||||
<Property Name="Density" Type="Quantity">
|
||||
<Reference>https://en.wikipedia.org/wiki/Density</Reference>
|
||||
</Property>
|
||||
<Property Name="YoungsModulus" Type="Quantity">
|
||||
<Reference>https://en.wikipedia.org/wiki/Young%27s_modulus</Reference>
|
||||
</Property>
|
||||
<Property Name="ShearModulus" Type="Quantity">
|
||||
<Reference>https://en.wikipedia.org/wiki/Shear_modulus</Reference>
|
||||
</Property>
|
||||
<Property Name="PoissonRatio" Type="Float">
|
||||
<Reference>https://en.wikipedia.org/wiki/Poisson%27s_ratio</Reference>
|
||||
</Property>
|
||||
<Property Name="UltimateTensileStrength" Type="Quantity">
|
||||
<Reference>https://en.wikipedia.org/wiki/Ultimate_tensile_strength</Reference>
|
||||
</Property>
|
||||
<Property Name="CompressiveStrength" Type="Quantity">
|
||||
<Reference>https://en.wikipedia.org/wiki/Compressive_strength</Reference>
|
||||
</Property>
|
||||
<Property Name="YieldStrength" Type="Quantity">
|
||||
<Reference>https://en.wikipedia.org/wiki/Yield_Strength</Reference>
|
||||
</Property>
|
||||
<Property Name="UltimateStrain" Type="Float">
|
||||
<Reference>https://en.wikipedia.org/wiki/Deformation_(mechanics)</Reference>
|
||||
</Property>
|
||||
<Property Name="FractureToughness" Type="Quantity">
|
||||
<Reference>https://en.wikipedia.org/wiki/Fracture_toughness</Reference>
|
||||
</Property>
|
||||
<Property Name="AngleOfFriction" Type="Quantity">
|
||||
<Reference>https://en.wikipedia.org/wiki/Friction#Angle_of_friction</Reference>
|
||||
<Reference>https://en.m.wikipedia.org/wiki/Mohr%E2%80%93Coulomb_theory</Reference>
|
||||
</Property>
|
||||
</Group>
|
||||
|
||||
<Group Name="Thermal">
|
||||
<Property Name="ThermalConductivity" Type="Quantity">
|
||||
<Reference>https://en.wikipedia.org/wiki/Thermal_conductivity</Reference>
|
||||
</Property>
|
||||
<Property Name="ThermalExpansionCoefficient" Type="Quantity">
|
||||
<Reference>https://en.wikipedia.org/wiki/Volumetric_thermal_expansion_coefficient</Reference>
|
||||
</Property>
|
||||
<Property Name="SpecificHeat" Type="Quantity">
|
||||
<Reference>https://en.wikipedia.org/wiki/Heat_capacity</Reference>
|
||||
</Property>
|
||||
</Group>
|
||||
|
||||
<Group Name="Architectural">
|
||||
<Property Name="Model" Type="String">
|
||||
</Property>
|
||||
<Property Name="ExecutionInstructions" Type="String">
|
||||
</Property>
|
||||
<Property Name="FireResistanceClass" Type="String">
|
||||
</Property>
|
||||
<Property Name="StandardCode" Type="String">
|
||||
</Property>
|
||||
<Property Name="SoundTransmissionClass" Type="String">
|
||||
</Property>
|
||||
<Property Name="Color" Type="Color">
|
||||
</Property>
|
||||
<Property Name="Finish" Type="String">
|
||||
</Property>
|
||||
<Property Name="UnitsPerQuantity" Type="Float">
|
||||
</Property>
|
||||
<Property Name="EnvironmentalEfficiencyClass" Type="String">
|
||||
</Property>
|
||||
</Group>
|
||||
|
||||
<Group Name="Rendering">
|
||||
<Property Name="DiffuseColor" Type="Color">
|
||||
</Property>
|
||||
<Property Name="AmbientColor" Type="Color">
|
||||
</Property>
|
||||
<Property Name="SpecularColor" Type="Color">
|
||||
</Property>
|
||||
<Property Name="Shininess" Type="Float">
|
||||
</Property>
|
||||
<Property Name="EmissiveColor" Type="Color">
|
||||
</Property>
|
||||
<Property Name="Transparency" Type="Float">
|
||||
</Property>
|
||||
<Property Name="VertexShader" Type="String">
|
||||
</Property>
|
||||
<Property Name="FragmentShader" Type="String">
|
||||
</Property>
|
||||
<Property Name="TexturePath" Type="File">
|
||||
</Property>
|
||||
<Property Name="TextureScaling" Type="Float">
|
||||
</Property>
|
||||
</Group>
|
||||
|
||||
<Group Name="Vector rendering">
|
||||
<Property Name="ViewColor" Type="Color">
|
||||
</Property>
|
||||
<Property Name="ViewFillPattern" Type="Boolean">
|
||||
</Property>
|
||||
<Property Name="SectionFillPattern" Type="File">
|
||||
</Property>
|
||||
<Property Name="ViewLinewidth" Type="Float">
|
||||
</Property>
|
||||
<Property Name="SectionLinewidth" Type="Float">
|
||||
</Property>
|
||||
</Group>
|
||||
|
||||
<Group Name="Cost">
|
||||
<Property Name="Vendor" Type="String">
|
||||
</Property>
|
||||
<Property Name="SpecificPrice" Type="Float">
|
||||
</Property>
|
||||
<Property Name="ProductURL" Type="URL">
|
||||
</Property>
|
||||
</Group>
|
||||
|
||||
<Group Name="User defined">
|
||||
</Group>
|
||||
|
||||
</MatPropDict>
|
||||
@@ -111,63 +111,6 @@ def exportFCMat(fileName, matDict):
|
||||
Config.write(configfile)
|
||||
|
||||
|
||||
def getMaterialAttributeStructure(withSpaces=None):
|
||||
|
||||
''''''
|
||||
|
||||
# material 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
|
||||
|
||||
import os
|
||||
import xml.etree.ElementTree as ElementTree
|
||||
|
||||
infile = os.path.dirname(__file__) + os.sep + "MatPropDict.xml"
|
||||
tree = ElementTree.parse(infile)
|
||||
|
||||
if withSpaces:
|
||||
# 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():
|
||||
for proper in group.getchildren():
|
||||
proper.set('Name', re.sub(r"(\w)([A-Z]+)", r"\1 \2",
|
||||
proper.attrib['Name']))
|
||||
|
||||
return tree
|
||||
|
||||
|
||||
def read_cards_from_path(cards_path):
|
||||
from os import listdir
|
||||
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]).upper() == '.FCMAT']
|
||||
# print(mat_files)
|
||||
mat_cards = []
|
||||
for f in sorted(mat_files):
|
||||
mat_cards.append(read(join(cards_path, f)))
|
||||
return mat_cards
|
||||
|
||||
|
||||
def write_cards_to_path(cards_path, cards_data, write_group_section=True, write_template=False):
|
||||
from importFCMat import write
|
||||
from os.path import join
|
||||
for card_data in cards_data:
|
||||
if (card_data['CardName'] == 'TEMPLATE') and (write_template is False):
|
||||
continue
|
||||
else:
|
||||
card_path = join(cards_path, (card_data['CardName'] + '.FCMat'))
|
||||
print(card_path)
|
||||
if write_group_section is True:
|
||||
write(card_path, card_data, True)
|
||||
else:
|
||||
write(card_path, card_data, False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
import getopt
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2013 - Yorik van Havre <yorik@uncreated.net> *
|
||||
# * Copyright (c) 2013 Yorik van Havre <yorik@uncreated.net> *
|
||||
# * Copyright (c) 2019 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) *
|
||||
@@ -21,7 +21,7 @@
|
||||
# ***************************************************************************
|
||||
|
||||
__title__ = "FreeCAD material editor"
|
||||
__author__ = "Yorik van Havre"
|
||||
__author__ = "Yorik van Havre, Bernd Hahnebach"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
|
||||
import os
|
||||
@@ -32,13 +32,14 @@ from PySide import QtCore, QtGui
|
||||
import FreeCAD
|
||||
import FreeCADGui
|
||||
|
||||
# is this still needed after the move to card utils???
|
||||
if sys.version_info.major >= 3:
|
||||
unicode = str
|
||||
|
||||
|
||||
class MaterialEditor:
|
||||
|
||||
def __init__(self, obj=None, prop=None, material=None):
|
||||
def __init__(self, obj=None, prop=None, material=None, card_path=''):
|
||||
|
||||
"""Initializes, optionally with an object name and a material property
|
||||
name to edit, or directly with a material dictionary."""
|
||||
@@ -50,6 +51,10 @@ class MaterialEditor:
|
||||
self.internalprops = []
|
||||
self.groups = []
|
||||
self.directory = FreeCAD.getResourceDir() + "Mod/Material"
|
||||
self.materials = {}
|
||||
self.cards = {}
|
||||
self.icons = {}
|
||||
self.card_path = card_path
|
||||
|
||||
# load the UI file from the same directory as this script
|
||||
self.widget = FreeCADGui.PySideUic.loadUi(
|
||||
@@ -75,7 +80,7 @@ class MaterialEditor:
|
||||
buttonDeleteProperty.setEnabled(False)
|
||||
standardButtons.button(QtGui.QDialogButtonBox.Ok).setAutoDefault(False)
|
||||
standardButtons.button(QtGui.QDialogButtonBox.Cancel).setAutoDefault(False)
|
||||
self.updateCards()
|
||||
self.updateCardsInCombo()
|
||||
# TODO allow to enter a custom property by pressing Enter in the lineedit
|
||||
# currently closes the dialog
|
||||
|
||||
@@ -84,7 +89,7 @@ class MaterialEditor:
|
||||
buttonOpen.clicked.connect(self.openfile)
|
||||
buttonSave.clicked.connect(self.savefile)
|
||||
buttonURL.clicked.connect(self.openProductURL)
|
||||
comboMaterial.currentIndexChanged[str].connect(self.updateContents)
|
||||
comboMaterial.currentIndexChanged[int].connect(self.chooseMaterial)
|
||||
buttonAddProperty.clicked.connect(self.addCustomProperty)
|
||||
buttonDeleteProperty.clicked.connect(self.deleteCustomProperty)
|
||||
treeView.clicked.connect(self.checkDeletable)
|
||||
@@ -94,6 +99,9 @@ class MaterialEditor:
|
||||
treeView.setUniformRowHeights(True)
|
||||
treeView.setItemDelegate(MaterialsDelegate())
|
||||
|
||||
# init model
|
||||
self.implementModel()
|
||||
|
||||
# update the editor with the contents of the property, if we have one
|
||||
d = None
|
||||
if self.prop and self.obj:
|
||||
@@ -101,9 +109,18 @@ class MaterialEditor:
|
||||
elif self.material:
|
||||
d = self.material
|
||||
|
||||
self.implementModel()
|
||||
if d:
|
||||
self.updateContents(d)
|
||||
self.updateMatParamsInTree(d)
|
||||
self.widget.ComboMaterial.setCurrentIndex(0)
|
||||
# set after tree params to the none material
|
||||
|
||||
if self.card_path:
|
||||
# we need the index of this path
|
||||
index = self.widget.ComboMaterial.findData(self.card_path)
|
||||
self.chooseMaterial(index)
|
||||
|
||||
# TODO what if material and card_name was given.
|
||||
# In such case ATM mateial is chosen, give some feedback for all those corner cases.
|
||||
|
||||
def implementModel(self):
|
||||
|
||||
@@ -118,26 +135,23 @@ class MaterialEditor:
|
||||
treeView.setColumnWidth(1, 250)
|
||||
treeView.setColumnHidden(2, True)
|
||||
|
||||
from Material import getMaterialAttributeStructure
|
||||
tree = getMaterialAttributeStructure(True)
|
||||
MatPropDict = tree.getroot()
|
||||
from materialtools.cardutils import get_material_template
|
||||
template_data = get_material_template(True)
|
||||
|
||||
for group in MatPropDict.getchildren():
|
||||
gg = group.attrib['Name']
|
||||
for group in template_data:
|
||||
gg = list(group.keys())[0] # group dict has only one key
|
||||
top = QtGui.QStandardItem(gg)
|
||||
model.appendRow([top])
|
||||
self.groups.append(gg)
|
||||
|
||||
for proper in group.getchildren():
|
||||
properDict = proper.attrib
|
||||
|
||||
pp = properDict['Name']
|
||||
for properName in group[gg]:
|
||||
pp = properName # property name
|
||||
item = QtGui.QStandardItem(pp)
|
||||
self.internalprops.append(pp)
|
||||
|
||||
it = QtGui.QStandardItem()
|
||||
|
||||
tt = properDict['Type']
|
||||
tt = group[gg][properName]['Type']
|
||||
itType = QtGui.QStandardItem(tt)
|
||||
|
||||
top.appendRow([item, it, itType])
|
||||
@@ -146,111 +160,85 @@ class MaterialEditor:
|
||||
|
||||
treeView.expandAll()
|
||||
|
||||
def updateContents(self, data):
|
||||
def updateMatParamsInTree(self, data):
|
||||
|
||||
'''updates the contents of the editor with the given data, can be:
|
||||
- a dictionary, if the editor was called with data
|
||||
- a string, the name of a card, if material is changed in editors combo box
|
||||
'''updates the contents of the editor with the given dictionary
|
||||
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()
|
||||
root = model.invisibleRootItem()
|
||||
for gg in range(root.rowCount() - 1):
|
||||
group = root.child(gg, 0)
|
||||
for pp in range(group.rowCount()):
|
||||
item = group.child(pp, 0)
|
||||
it = group.child(pp, 1)
|
||||
kk = self.collapseKey(item.text())
|
||||
# print(data)
|
||||
model = self.widget.treeView.model()
|
||||
root = model.invisibleRootItem()
|
||||
for gg in range(root.rowCount() - 1):
|
||||
group = root.child(gg, 0)
|
||||
for pp in range(group.rowCount()):
|
||||
item = group.child(pp, 0)
|
||||
it = group.child(pp, 1)
|
||||
kk = self.collapseKey(item.text())
|
||||
|
||||
try:
|
||||
value = data[kk]
|
||||
it.setText(value)
|
||||
del data[kk]
|
||||
except KeyError:
|
||||
it.setText("")
|
||||
try:
|
||||
value = data[kk]
|
||||
it.setText(value)
|
||||
del data[kk]
|
||||
except KeyError:
|
||||
it.setText("")
|
||||
|
||||
userGroup = root.child(gg + 1, 0)
|
||||
userGroup.setRowCount(0)
|
||||
self.customprops = []
|
||||
userGroup = root.child(gg + 1, 0)
|
||||
userGroup.setRowCount(0)
|
||||
self.customprops = []
|
||||
|
||||
for k, i in data.items():
|
||||
k = self.expandKey(k)
|
||||
item = QtGui.QStandardItem(k)
|
||||
it = QtGui.QStandardItem(i)
|
||||
userGroup.appendRow([item, it])
|
||||
self.customprops.append(k)
|
||||
for k, i in data.items():
|
||||
k = self.expandKey(k)
|
||||
item = QtGui.QStandardItem(k)
|
||||
it = QtGui.QStandardItem(i)
|
||||
userGroup.appendRow([item, it])
|
||||
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
|
||||
k = str(data)
|
||||
if k:
|
||||
if k in self.cards:
|
||||
|
||||
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"
|
||||
def chooseMaterial(self, index):
|
||||
if index < 0:
|
||||
return
|
||||
self.card_path = self.widget.ComboMaterial.itemData(index)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'choose_material in material editor:\n'
|
||||
' {}\n'.format(self.card_path)
|
||||
)
|
||||
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)
|
||||
if use_mat_from_custom_dir:
|
||||
custom_mat_dir = self.fem_prefs.GetString("CustomMaterialsDir", "")
|
||||
# later found cards with same name will override cards
|
||||
# FreeCAD returns paths with / at the end, thus not os.sep is needed on first +
|
||||
self.resources = []
|
||||
if use_built_in_materials:
|
||||
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:
|
||||
custom_mat_dir = self.fem_prefs.GetString("CustomMaterialsDir", "")
|
||||
if os.path.exists(custom_mat_dir):
|
||||
self.resources.append(custom_mat_dir)
|
||||
self.outputResources()
|
||||
if os.path.isfile(self.card_path):
|
||||
from importFCMat import read
|
||||
d = read(self.card_path)
|
||||
self.updateMatParamsInTree(d)
|
||||
# be careful with reading from materials dict
|
||||
# the card could be updated the dict not
|
||||
self.widget.ComboMaterial.setCurrentIndex(index) # set after tree params
|
||||
else:
|
||||
FreeCAD.Console.PrintError('material card not found: {}\n'.format(self.card_path))
|
||||
|
||||
def outputResources(self):
|
||||
print('locations to look for material cards:')
|
||||
for path in self.resources:
|
||||
print(' ' + path)
|
||||
print('\n')
|
||||
|
||||
def outputCards(self):
|
||||
print('material cards:')
|
||||
for card in sorted(self.cards.keys()):
|
||||
print(' ' + card + ': ' + self.cards[card])
|
||||
print('\n')
|
||||
|
||||
def updateCards(self):
|
||||
def updateCardsInCombo(self):
|
||||
|
||||
'''updates the contents of the materials combo with existing material cards'''
|
||||
|
||||
self.getMaterialResources()
|
||||
self.cards = {}
|
||||
for p in self.resources:
|
||||
if os.path.exists(p):
|
||||
for f in sorted(os.listdir(p)):
|
||||
b, e = os.path.splitext(f)
|
||||
if e.upper() == ".FCMAT":
|
||||
self.cards[b] = p + os.sep + f
|
||||
# self.outputCards()
|
||||
if self.cards:
|
||||
self.widget.ComboMaterial.clear()
|
||||
self.widget.ComboMaterial.addItem("") # add a blank item first
|
||||
for card in sorted(self.cards.keys()):
|
||||
self.widget.ComboMaterial.addItem(card) # all keys in self.cards are unicode
|
||||
mat_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Material/Cards")
|
||||
sort_by_resources = mat_prefs.GetBool("SortByResources", False)
|
||||
|
||||
# get all available materials (fill self.materials, self.cards and self.icons)
|
||||
from materialtools.cardutils import import_materials as getmats
|
||||
self.materials, self.cards, self.icons = getmats()
|
||||
|
||||
card_name_list = [] # [ [card_name, card_path, icon_path], ... ]
|
||||
|
||||
if sort_by_resources is True:
|
||||
for a_path in sorted(self.materials.keys()):
|
||||
card_name_list.append([self.cards[a_path], a_path, self.icons[a_path]])
|
||||
else:
|
||||
card_names_tmp = {}
|
||||
for path, name in self.cards.items():
|
||||
card_names_tmp[name] = path
|
||||
for a_name in sorted(card_names_tmp.keys()):
|
||||
a_path = card_names_tmp[a_name]
|
||||
card_name_list.append([a_name, a_path, self.icons[a_path]])
|
||||
|
||||
card_name_list.insert(0, [None, '', ''])
|
||||
for mat in card_name_list:
|
||||
self.widget.ComboMaterial.addItem(QtGui.QIcon(mat[2]), mat[0], mat[1])
|
||||
|
||||
def openProductURL(self):
|
||||
|
||||
@@ -434,14 +422,28 @@ class MaterialEditor:
|
||||
self.directory,
|
||||
'*.FCMat'
|
||||
)
|
||||
# a tuple of two empty strings returns True, so use the filename directly
|
||||
filename = filetuple[0]
|
||||
if filename:
|
||||
from importFCMat import read
|
||||
self.directory = os.path.dirname(filename)
|
||||
d = read(filename)
|
||||
if d:
|
||||
self.updateContents(d)
|
||||
self.card_path = filetuple[0]
|
||||
index = self.widget.ComboMaterial.findData(self.card_path)
|
||||
print(index)
|
||||
|
||||
# check if card_path is in known path, means it is in combo box already
|
||||
# if not print message, and give some feedbach that the card parameter are loaded
|
||||
if os.path.isfile(self.card_path):
|
||||
if index == -1:
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'Card path: {} not found in known cards.'
|
||||
'The material parameter only are loaded.\n'
|
||||
.format(self.card_path)
|
||||
)
|
||||
from importFCMat import read
|
||||
d = read(self.card_path)
|
||||
if d:
|
||||
self.updateMatParamsInTree(d)
|
||||
self.widget.ComboMaterial.setCurrentIndex(0)
|
||||
# set combo box to the none material after tree params
|
||||
else:
|
||||
self.chooseMaterial(index)
|
||||
self.directory = os.path.dirname(self.card_path)
|
||||
|
||||
def savefile(self):
|
||||
"Saves a FCMat file."
|
||||
@@ -467,12 +469,13 @@ class MaterialEditor:
|
||||
filename = filetuple[0]
|
||||
if filename:
|
||||
self.directory = os.path.dirname(filename)
|
||||
# should not be resource dir but user result dir instead
|
||||
d = self.getDict()
|
||||
# self.outputDict(d)
|
||||
if d:
|
||||
from importFCMat import write
|
||||
write(filename, d)
|
||||
self.updateCards()
|
||||
self.updateCardsInCombo()
|
||||
|
||||
def show(self):
|
||||
return self.widget.show()
|
||||
@@ -664,7 +667,7 @@ def openEditor(obj=None, prop=None):
|
||||
editor.exec_()
|
||||
|
||||
|
||||
def editMaterial(material):
|
||||
def editMaterial(material=None, card_path=None):
|
||||
"""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
|
||||
@@ -673,12 +676,13 @@ def editMaterial(material):
|
||||
# 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
|
||||
# than this card name could be displayed
|
||||
editor = MaterialEditor(material=material)
|
||||
editor = MaterialEditor(material=material, card_path=card_path)
|
||||
result = editor.exec_()
|
||||
if result:
|
||||
return editor.getDict()
|
||||
else:
|
||||
return material
|
||||
# on chancel button an empty dict is returned
|
||||
return {}
|
||||
|
||||
|
||||
'''
|
||||
|
||||
272
src/Mod/Material/Templatematerial.yml
Normal file
272
src/Mod/Material/Templatematerial.yml
Normal file
@@ -0,0 +1,272 @@
|
||||
# ***************************************************************************
|
||||
# * *
|
||||
# * Copyright (c) 2019 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) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program 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 program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
|
||||
# material template for reading and writing FreeCAD material cards
|
||||
# information about FreeCAD material module and material cards can be found here:
|
||||
# http://www.freecadweb.org/wiki/index.php?title=Material
|
||||
|
||||
|
||||
# localized Name, Description and KindOfMaterial uses 2 letter codes
|
||||
# defined in ISO-639-1, see https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes
|
||||
# find unit information in src/App/FreeCADInit.py
|
||||
|
||||
|
||||
# TODO: make multiple line strings out of the long ones, see module ccxtools.py
|
||||
# Use " for descriptions because there a ' can be inside. May be switch to " for all Strings?!
|
||||
|
||||
# matdata
|
||||
- Meta:
|
||||
CardName: # first in group
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
AuthorAndLicense:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
- General:
|
||||
Name: # first in group
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: "General name" # used to be equal with card name, TODO: should all cards be changed back to this?
|
||||
NameDE:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: "German localized name"
|
||||
NamePL:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: "Polish localized name"
|
||||
Description:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: "A more elaborate description of the material"
|
||||
DescriptionDE:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: "German localized description"
|
||||
DescriptionPL:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: "Polish localized description"
|
||||
Father:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: "Father of the material, i.e. for PLA is Thermoplast, for Steel is Metal"
|
||||
KindOfMaterial:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
KindOfMaterialDE:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: "Germand localized kind of material"
|
||||
MaterialNumber:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
Norm: # should be merged with StandardCode
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
ReferenceSource:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
SourceURL:
|
||||
Type: 'URL'
|
||||
URL: ''
|
||||
Description: " "
|
||||
StandardCode:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
- Mechanical:
|
||||
AngleOfFriction:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Friction#Angle_of_friction'
|
||||
Description: "Further information can be found at https://en.wikipedia.org/wiki/Mohr%E2%80%93Coulomb_theory"
|
||||
CompressiveStrength:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Compressive_strength'
|
||||
Description: "Compressive strength in [FreeCAD Pressure unit]"
|
||||
Density:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Density'
|
||||
Description: "Density in [FreeCAD Density unit]"
|
||||
FractureToughness:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Fracture_toughness'
|
||||
Description: " "
|
||||
PoissonRatio:
|
||||
Type: 'Float'
|
||||
URL: 'https://en.wikipedia.org/wiki/Poisson%27s_ratio'
|
||||
Description: "Poisson's ratio [unitless]"
|
||||
ShearModulus:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Shear_modulus'
|
||||
Description: "Shear modulus in [FreeCAD Pressure unit]"
|
||||
UltimateStrain:
|
||||
Type: 'Float'
|
||||
URL: 'https://en.wikipedia.org/wiki/Deformation_(mechanics)'
|
||||
Description: " "
|
||||
UltimateTensileStrength:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Ultimate_tensile_strength'
|
||||
Description: "Ultimate tensile strength in [FreeCAD Pressure unit]"
|
||||
YieldStrength:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Yield_Strength'
|
||||
Description: "Yield strength in [FreeCAD Pressure unit]"
|
||||
YoungsModulus:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Young%27s_modulus'
|
||||
Description: "Young's modulus (or E-Module) in [FreeCAD Pressure unit]"
|
||||
- Thermal:
|
||||
SpecificHeat:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Heat_capacity'
|
||||
Description: " "
|
||||
ThermalConductivity:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Thermal_conductivity'
|
||||
Description: "Thermal conductivity in [FreCAD ThermalConductivity unit]"
|
||||
ThermalExpansionCoefficient:
|
||||
Type: 'Quantity'
|
||||
URL: 'https://en.wikipedia.org/wiki/Volumetric_thermal_expansion_coefficient'
|
||||
Description: "Thermal expansion coefficient (linear) in [FreeCAD ThermalExpansionCoefficient unit]"
|
||||
- Architectural:
|
||||
Color:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
EnvironmentalEfficiencyClass:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
ExecutionInstructions:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
Finish:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
FireResistanceClass:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
Model:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
SoundTransmissionClass:
|
||||
URL: ''
|
||||
Description: " "
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
UnitsPerQuantity:
|
||||
Type: 'Float'
|
||||
URL: ''
|
||||
Description: " "
|
||||
- Rendering:
|
||||
AmbientColor:
|
||||
Type: 'Color'
|
||||
URL: ''
|
||||
Description: " "
|
||||
DiffuseColor:
|
||||
Type: 'Color'
|
||||
URL: ''
|
||||
Description: " "
|
||||
EmissiveColor:
|
||||
Type: 'Color'
|
||||
URL: ''
|
||||
Description: " "
|
||||
FragmentShader:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
Shininess:
|
||||
Type: 'Float'
|
||||
URL: ''
|
||||
Description: " "
|
||||
SpecularColor:
|
||||
Type: 'Color'
|
||||
URL: ''
|
||||
Description: " "
|
||||
TexturePath:
|
||||
Type: 'File'
|
||||
URL: ''
|
||||
Description: " "
|
||||
TextureScaling:
|
||||
Type: 'Float'
|
||||
URL: ''
|
||||
Description: " "
|
||||
Transparency:
|
||||
Type: 'Float'
|
||||
URL: ''
|
||||
Description: " "
|
||||
VertexShader:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: " "
|
||||
- Vector rendering:
|
||||
SectionFillPattern:
|
||||
Type: 'File'
|
||||
URL: ''
|
||||
Description: " "
|
||||
SectionLinewidth:
|
||||
Type: 'Float'
|
||||
URL: ''
|
||||
Description: " "
|
||||
ViewColor:
|
||||
Type: 'Color'
|
||||
URL: ''
|
||||
Description: " "
|
||||
ViewFillPattern:
|
||||
Type: 'Boolean'
|
||||
URL: ''
|
||||
Description: " "
|
||||
ViewLinewidth:
|
||||
Type: 'Float'
|
||||
URL: ''
|
||||
Description: " "
|
||||
- Cost:
|
||||
ProductURL:
|
||||
Type: 'URL'
|
||||
URL: 'https://de.wikipedia.org/wiki/Hyperlink'
|
||||
Description: "Product URL, recommended are wikipedia links"
|
||||
SpecificPrice:
|
||||
Type: 'Float'
|
||||
URL: ''
|
||||
Description: "Specific price in currency / mass. A currency is not supported by FreeCAD unit system. Will be empty in all FreeCAD cards. Means the user needs to put in himself."
|
||||
Vendor:
|
||||
Type: 'String'
|
||||
URL: ''
|
||||
Description: "Vendor of the material"
|
||||
- UserDefined:
|
||||
None: # Python needs something to iterate over
|
||||
Type: ''
|
||||
URL: ''
|
||||
Description: " "
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
|
||||
import FreeCAD
|
||||
import Material
|
||||
from materialtools.cardutils import get_material_template
|
||||
import os
|
||||
import sys
|
||||
if sys.version_info.major >= 3:
|
||||
@@ -151,17 +151,15 @@ def write(filename, dictionary, write_group_section=True):
|
||||
|
||||
# sort the data into sections
|
||||
contents = []
|
||||
tree = Material.getMaterialAttributeStructure()
|
||||
MatPropDict = tree.getroot()
|
||||
for group in MatPropDict.getchildren():
|
||||
groupName = group.attrib['Name']
|
||||
template_data = get_material_template()
|
||||
for group in template_data:
|
||||
groupName = list(group.keys())[0] # group dict has only one key
|
||||
contents.append({"keyname": groupName})
|
||||
if groupName == "Meta":
|
||||
header = contents[-1]
|
||||
elif groupName == "User defined":
|
||||
elif groupName == 'UserDefined':
|
||||
user = contents[-1]
|
||||
for proper in group.getchildren():
|
||||
properName = proper.attrib['Name']
|
||||
for properName in group[groupName]:
|
||||
contents[-1][properName] = ''
|
||||
for k, i in dictionary.items():
|
||||
found = False
|
||||
@@ -226,3 +224,16 @@ def write(filename, dictionary, write_group_section=True):
|
||||
else:
|
||||
f.write(k + " = " + i.encode('utf-8') + "\n")
|
||||
f.close()
|
||||
|
||||
|
||||
# ***** some code examples ***********************************************************************
|
||||
'''
|
||||
from materialtools.cardutils import get_source_path as getsrc
|
||||
from importFCMat import read, write
|
||||
readmatfile = getsrc() + '/src/Mod/Material/StandardMaterial/Concrete-Generic.FCMat'
|
||||
writematfile = '/tmp/Concrete-Generic.FCMat'
|
||||
matdict = read(readmatfile)
|
||||
matdict
|
||||
write(writematfile, matdict)
|
||||
|
||||
'''
|
||||
|
||||
0
src/Mod/Material/materialtools/__init__.py
Normal file
0
src/Mod/Material/materialtools/__init__.py
Normal file
486
src/Mod/Material/materialtools/cardutils.py
Normal file
486
src/Mod/Material/materialtools/cardutils.py
Normal file
@@ -0,0 +1,486 @@
|
||||
# ***************************************************************************
|
||||
# * Copyright (c) 2019 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) *
|
||||
# * as published by the Free Software Foundation; either version 2 of *
|
||||
# * the License, or (at your option) any later version. *
|
||||
# * for detail see the LICENCE text file. *
|
||||
# * *
|
||||
# * This program 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 program; if not, write to the Free Software *
|
||||
# * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 *
|
||||
# * USA *
|
||||
# * *
|
||||
# ***************************************************************************
|
||||
|
||||
__title__ = "material cards utilities"
|
||||
__author__ = "Bernd Hahnebach"
|
||||
__url__ = "http://www.freecadweb.org"
|
||||
|
||||
import os
|
||||
import sys
|
||||
from os.path import join
|
||||
|
||||
import FreeCAD
|
||||
|
||||
|
||||
if sys.version_info.major >= 3:
|
||||
unicode = str
|
||||
|
||||
|
||||
# TODO:
|
||||
# move material GUI preferences from FEM to an own preference tab in Material
|
||||
# move preference GUI code to material module
|
||||
# https://forum.freecadweb.org/viewtopic.php?f=10&t=35515
|
||||
|
||||
|
||||
# TODO:
|
||||
# implement method check_material_keys from FEM material task panel for material editor
|
||||
# may be move out of the FEM material task panel to here
|
||||
# make the method more generic to be compatible with all known params
|
||||
# the material template knows the units
|
||||
|
||||
|
||||
# ***** card handling data models ****************************************************************
|
||||
'''
|
||||
data model:
|
||||
materials = { card_path: mat_dict, ... }
|
||||
cards = { card_path: card_name, ... }
|
||||
icons = { card_path: icon_path, ... }
|
||||
|
||||
- duplicates are allowed
|
||||
- the whole card_path is saved into the combo box widget, this makes card unique
|
||||
- sorting happens on adding to the combo box widgets
|
||||
|
||||
a data modell which uses a class and attributes as well as methods to access the attributes
|
||||
would makes sense, like some material library class
|
||||
this has been done already by eivind see
|
||||
https://forum.freecadweb.org/viewtopic.php?f=38&t=16714
|
||||
'''
|
||||
|
||||
|
||||
# ***** get resources for cards ******************************************************************
|
||||
def get_material_resources(category='Solid'):
|
||||
|
||||
resources = {} # { resource_path: icon_path, ... }
|
||||
|
||||
# TODO: move GUI preferences from FEM to a new side tab Material
|
||||
# https://forum.freecadweb.org/viewtopic.php?f=10&t=35515
|
||||
mat_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Material/Resources")
|
||||
use_built_in_materials = mat_prefs.GetBool("UseBuiltInMaterials", True)
|
||||
use_mat_from_config_dir = mat_prefs.GetBool("UseMaterialsFromConfigDir", True)
|
||||
use_mat_from_custom_dir = mat_prefs.GetBool("UseMaterialsFromCustomDir", True)
|
||||
|
||||
if use_built_in_materials:
|
||||
if category == 'Fluid':
|
||||
builtin_mat_dir = join(
|
||||
FreeCAD.getResourceDir(), "Mod", "Material", "FluidMaterial"
|
||||
)
|
||||
|
||||
else:
|
||||
builtin_mat_dir = join(
|
||||
FreeCAD.getResourceDir(), "Mod", "Material", "StandardMaterial"
|
||||
)
|
||||
resources[builtin_mat_dir] = ":/icons/freecad.svg"
|
||||
|
||||
if use_mat_from_config_dir:
|
||||
config_mat_dir = join(
|
||||
FreeCAD.ConfigGet("UserAppData"), "Material"
|
||||
)
|
||||
resources[config_mat_dir] = ":/icons/preferences-general.svg"
|
||||
|
||||
if use_mat_from_custom_dir:
|
||||
custom_mat_dir = mat_prefs.GetString("CustomMaterialsDir", "")
|
||||
if os.path.exists(custom_mat_dir):
|
||||
resources[custom_mat_dir] = ":/icons/user.svg"
|
||||
else:
|
||||
FreeCAD.Console.PrintError(
|
||||
'Custom material directory set by user: {} does not exist.\n'
|
||||
.format(custom_mat_dir)
|
||||
)
|
||||
|
||||
return resources
|
||||
|
||||
|
||||
def output_resources(resources):
|
||||
FreeCAD.Console.PrintMessage('Directories we gone look for material cards:\n')
|
||||
for path in resources.keys():
|
||||
FreeCAD.Console.PrintMessage(' {}\n'.format(path))
|
||||
|
||||
|
||||
# ***** card handling ****************************************************************************
|
||||
# used in material editor and FEM material task panels
|
||||
|
||||
def import_materials(category='Solid'):
|
||||
|
||||
resources = get_material_resources(category)
|
||||
|
||||
materials = {}
|
||||
cards = {}
|
||||
icons = {}
|
||||
for path in resources.keys():
|
||||
materials, cards, icons = add_cards_from_a_dir(
|
||||
materials,
|
||||
cards,
|
||||
icons,
|
||||
path,
|
||||
resources[path]
|
||||
)
|
||||
|
||||
return (materials, cards, icons)
|
||||
|
||||
|
||||
def add_cards_from_a_dir(materials, cards, icons, mat_dir, icon):
|
||||
# fill materials and icons
|
||||
import glob
|
||||
from importFCMat import read
|
||||
dir_path_list = glob.glob(mat_dir + '/*' + ".FCMat")
|
||||
mat_prefs = FreeCAD.ParamGet("User parameter:BaseApp/Preferences/Mod/Material/Cards")
|
||||
delete_duplicates = mat_prefs.GetBool("DeleteDuplicates", True)
|
||||
# duplicates are indicated on equality of mat dict
|
||||
# TODO if the unit is different two cards would be different too
|
||||
for a_path in dir_path_list:
|
||||
mat_dict = read(a_path)
|
||||
card_name = os.path.splitext(os.path.basename(a_path))[0]
|
||||
if delete_duplicates is False:
|
||||
materials[a_path] = mat_dict
|
||||
cards[a_path] = card_name
|
||||
icons[a_path] = icon
|
||||
else:
|
||||
if mat_dict not in materials.values():
|
||||
materials[a_path] = mat_dict
|
||||
cards[a_path] = card_name
|
||||
icons[a_path] = icon
|
||||
|
||||
return (materials, cards, icons)
|
||||
|
||||
|
||||
def output_trio(trio):
|
||||
materials, cards, icons = trio
|
||||
FreeCAD.Console.PrintMessage('\n\n')
|
||||
for mat_card in materials:
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'{} --> {} -->{}\n'
|
||||
.format(cards[mat_card], mat_card, icons[mat_card])
|
||||
)
|
||||
FreeCAD.Console.PrintMessage('\n\n')
|
||||
|
||||
|
||||
def output_cards(cards):
|
||||
FreeCAD.Console.PrintMessage('\n\n')
|
||||
for mat_card in cards:
|
||||
FreeCAD.Console.PrintMessage('{} --> {}\n'.format(mat_card, cards[mat_card]))
|
||||
FreeCAD.Console.PrintMessage('\n\n')
|
||||
|
||||
|
||||
def output_icons(icons):
|
||||
FreeCAD.Console.PrintMessage('\n\n')
|
||||
for mat_card in icons:
|
||||
FreeCAD.Console.PrintMessage('{} --> {}\n'.format(mat_card, icons[mat_card]))
|
||||
FreeCAD.Console.PrintMessage('\n\n')
|
||||
|
||||
|
||||
def output_materials(materials):
|
||||
FreeCAD.Console.PrintMessage('\n\n')
|
||||
for mat_card in materials:
|
||||
FreeCAD.Console.PrintMessage('{}\n'.format(mat_card))
|
||||
output_material_param(materials[mat_card])
|
||||
FreeCAD.Console.PrintMessage('\n\n')
|
||||
|
||||
|
||||
def output_material_param(mat_dict):
|
||||
# thus we check for None
|
||||
if not mat_dict:
|
||||
FreeCAD.Console.PrintMessage(' empty matdict\n')
|
||||
else:
|
||||
for p in mat_dict:
|
||||
FreeCAD.Console.PrintMessage(' {} --> {}\n'.format(p, mat_dict[p]))
|
||||
FreeCAD.Console.PrintMessage('\n')
|
||||
|
||||
|
||||
# ***** material card template *******************************************************************
|
||||
def get_material_template(withSpaces=False):
|
||||
# material 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
|
||||
|
||||
import yaml
|
||||
template_data = yaml.safe_load(
|
||||
open(join(FreeCAD.ConfigGet('AppHomePath'), 'Mod/Material/Templatematerial.yml'))
|
||||
)
|
||||
if withSpaces:
|
||||
# on attributes, add a space before a capital letter
|
||||
# will be used for better display in the ui
|
||||
import re
|
||||
for group in template_data:
|
||||
gg = list(group.keys())[0] # group dict has only one key
|
||||
# iterating over a dict and changing it is not allowed
|
||||
# thus it is iterated over a list of the keys
|
||||
for proper in list(group[gg].keys()):
|
||||
new_proper = re.sub(r"(\w)([A-Z]+)", r"\1 \2", proper)
|
||||
group[gg][new_proper] = group[gg][proper]
|
||||
del group[gg][proper]
|
||||
return template_data
|
||||
|
||||
|
||||
def create_mat_tools_header():
|
||||
headers = join(get_source_path(), 'src/Mod/Material/StandardMaterial/Tools/headers')
|
||||
print(headers)
|
||||
if not os.path.isfile(headers):
|
||||
FreeCAD.Console.PrintError(
|
||||
'file not found: {}'.format(headers)
|
||||
)
|
||||
return
|
||||
template_data = get_material_template()
|
||||
f = open(headers, "w")
|
||||
for group in template_data:
|
||||
gg = list(group.keys())[0] # group dict has only one key
|
||||
# do not write group UserDefined
|
||||
if gg != 'UserDefined':
|
||||
for prop_name in group[gg]:
|
||||
if prop_name != 'None':
|
||||
f.write(prop_name + '\n')
|
||||
f.close
|
||||
|
||||
|
||||
def create_mat_template_card(write_group_section=True):
|
||||
template_card = join(get_source_path(), 'src/Mod/Material/StandardMaterial/TEMPLATE.FCMat')
|
||||
if not os.path.isfile(template_card):
|
||||
FreeCAD.Console.PrintError(
|
||||
'file not found: {}'.format(template_card)
|
||||
)
|
||||
return
|
||||
rev = "{}.{}.{}".format(
|
||||
FreeCAD.ConfigGet("BuildVersionMajor"),
|
||||
FreeCAD.ConfigGet("BuildVersionMinor"),
|
||||
FreeCAD.ConfigGet("BuildRevision")
|
||||
)
|
||||
template_data = get_material_template()
|
||||
f = open(template_card, "w")
|
||||
f.write('; TEMPLATE\n')
|
||||
f.write('; (c) 2013-2015 Juergen Riegel (CC-BY 3.0)\n')
|
||||
f.write('; information about the content of such cards can be found on the wiki:\n')
|
||||
f.write('; https://www.freecadweb.org/wiki/Material\n')
|
||||
f.write(': this template card was created by FreeCAD ' + rev + '\n\n')
|
||||
f.write('; localized Name, Description and KindOfMaterial uses 2 letter codes\n')
|
||||
f.write('; defined in ISO-639-1, see https://en.wikipedia.org/wiki/List_of_ISO_639-1_codes\n')
|
||||
f.write('; find unit information in src/App/FreeCADInit.py')
|
||||
# write sections
|
||||
# write standard FCMat section if write group section parameter is set to False
|
||||
if write_group_section is False:
|
||||
f.write("\n[FCMat]\n")
|
||||
for group in template_data:
|
||||
gg = list(group.keys())[0] # group dict has only one key
|
||||
# do not write groups Meta and UserDefined
|
||||
if (gg != 'Meta') and (gg != 'UserDefined'):
|
||||
# only write group section if write group section parameter is set to True
|
||||
if write_group_section is True:
|
||||
f.write("\n\n[" + gg + "]")
|
||||
for prop_name in group[gg]:
|
||||
f.write('\n')
|
||||
description = group[gg][prop_name]['Description']
|
||||
if not description.strip():
|
||||
f.write('; Description to be updated\n')
|
||||
else:
|
||||
f.write('; ' + description + '\n')
|
||||
url = group[gg][prop_name]['URL']
|
||||
if url.strip():
|
||||
f.write('; ' + url + '\n')
|
||||
f.write(prop_name + ' =\n')
|
||||
f.close
|
||||
|
||||
|
||||
# card tools will not be copied into build ... thus they are not there ...
|
||||
# thus the source dir is needed, this might not work on windows
|
||||
def get_source_path():
|
||||
# in the file 'Makefile' in build directory the cmake variable CMAKE_SOURCE_DIR has the dir
|
||||
source_dir = ''
|
||||
make_file = join(FreeCAD.ConfigGet('AppHomePath'), 'Makefile')
|
||||
f = open(make_file, 'r')
|
||||
lines = f.readlines()
|
||||
f.close()
|
||||
for line in lines:
|
||||
if line.startswith('CMAKE_SOURCE_DIR'):
|
||||
source_dir = line.lstrip('CMAKE_SOURCE_DIR = ')
|
||||
source_dir = source_dir.rstrip() # get rid on new line and white spaces etc.
|
||||
break
|
||||
# print(source_dir)
|
||||
return source_dir
|
||||
|
||||
|
||||
# ***** debug known and not known material parameter *********************************************
|
||||
def get_and_output_all_carddata(cards):
|
||||
print('\n\n\nSTART--get_and_output_all_carddata\n--------------------')
|
||||
# get all registered material property keys
|
||||
registed_cardkeys = []
|
||||
template_data = get_material_template()
|
||||
# print(template_data)
|
||||
for group in template_data:
|
||||
gg = list(group.keys())[0] # group dict has only one key
|
||||
for key in group[gg]:
|
||||
registed_cardkeys.append(key)
|
||||
registed_cardkeys = sorted(registed_cardkeys)
|
||||
# print(registed_cardkeys)
|
||||
|
||||
# get all data from all known cards
|
||||
all_cards_and_data = {} # {cardfilename: ['path', materialdict]}
|
||||
for card in cards:
|
||||
from importFCMat import read
|
||||
d = read(cards[card])
|
||||
all_cards_and_data[card] = [cards[card], d]
|
||||
'''
|
||||
for card in all_cards_and_data:
|
||||
print(card)
|
||||
print(all_cards_and_data[card][0])
|
||||
print(all_cards_and_data[card][1])
|
||||
print('\n')
|
||||
'''
|
||||
|
||||
# find not registered and registered keys in the used data
|
||||
used_and_registered_cardkeys = []
|
||||
used_and_not_registered_cardkeys = []
|
||||
registered_and_not_used_cardkeys = []
|
||||
for card in all_cards_and_data:
|
||||
for k in all_cards_and_data[card][1]:
|
||||
if k in registed_cardkeys:
|
||||
used_and_registered_cardkeys.append(k)
|
||||
else:
|
||||
used_and_not_registered_cardkeys.append(k)
|
||||
for k in registed_cardkeys:
|
||||
if (k not in used_and_registered_cardkeys) and (k not in used_and_not_registered_cardkeys):
|
||||
registered_and_not_used_cardkeys.append(k)
|
||||
|
||||
used_and_registered_cardkeys = sorted(list(set(used_and_registered_cardkeys)))
|
||||
used_and_not_registered_cardkeys = sorted(list(set(used_and_not_registered_cardkeys)))
|
||||
registered_and_not_used_cardkeys = sorted(list(set(registered_and_not_used_cardkeys)))
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'\nused_and_registered_cardkeys:\n{}\n'
|
||||
.format(used_and_registered_cardkeys)
|
||||
)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'\nused_and_not_registered_cardkeys:\n{}\n'
|
||||
.format(used_and_not_registered_cardkeys)
|
||||
)
|
||||
FreeCAD.Console.PrintMessage(
|
||||
'\nregistered_and_not_used_cardkeys:\n{}\n'
|
||||
.format(registered_and_not_used_cardkeys)
|
||||
)
|
||||
|
||||
# still there might be lots of properties in the template
|
||||
# which are not used in other materials
|
||||
# but the tmplate is handled here like a material
|
||||
print('--------------------\nget_and_output_all_carddata--END\n\n\n')
|
||||
|
||||
|
||||
# ***** process multiple material cards **********************************************************
|
||||
def read_cards_from_path(cards_path):
|
||||
from os import listdir
|
||||
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))]
|
||||
# to make sure all file lower and upper and mixed endings are found, use upper and .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):
|
||||
mat_cards.append(read(join(cards_path, f)))
|
||||
return mat_cards
|
||||
|
||||
|
||||
def write_cards_to_path(cards_path, cards_data, write_group_section=True, write_template=False):
|
||||
from importFCMat import write
|
||||
from os.path import join
|
||||
for card_data in cards_data:
|
||||
if (card_data['CardName'] == 'TEMPLATE') and (write_template is False):
|
||||
continue
|
||||
else:
|
||||
card_path = join(cards_path, (card_data['CardName'] + '.FCMat'))
|
||||
print(card_path)
|
||||
if write_group_section is True:
|
||||
write(card_path, card_data, True)
|
||||
else:
|
||||
write(card_path, card_data, False)
|
||||
|
||||
|
||||
# ***** some code examples ***********************************************************************
|
||||
'''
|
||||
# cards, params, icons and resources **********
|
||||
from materialtools.cardutils import get_material_resources as getres
|
||||
from materialtools.cardutils import output_resources as outres
|
||||
outres(getres())
|
||||
|
||||
|
||||
from materialtools.cardutils import import_materials as getmats
|
||||
from materialtools.cardutils import output_materials as outmats
|
||||
from materialtools.cardutils import output_trio as outtrio
|
||||
|
||||
outmats(getmats()[0])
|
||||
|
||||
outtrio(getmats())
|
||||
|
||||
a,b,c=getmats()
|
||||
|
||||
|
||||
# param template, header, template card **********
|
||||
from materialtools.cardutils import get_material_template as gettemplate
|
||||
gettemplate()
|
||||
|
||||
from materialtools.cardutils import get_material_template as gettemplate
|
||||
template_data=gettemplate()
|
||||
for group in template_data:
|
||||
gname = list(group.keys())[0] # group dict has only one key
|
||||
for prop_name in group[gname]:
|
||||
#prop_dict = group[gname][prop_name]
|
||||
#print(prop_dict)
|
||||
#print(prop_dict['Description'])
|
||||
print(group[gname][prop_name]['Description'])
|
||||
|
||||
|
||||
from materialtools.cardutils import create_mat_tools_header as createheader
|
||||
createheader()
|
||||
|
||||
|
||||
from materialtools.cardutils import create_mat_template_card as createtemplate
|
||||
createtemplate()
|
||||
createtemplate(False)
|
||||
|
||||
|
||||
from materialtools.cardutils import get_source_path as getsrc
|
||||
getsrc()
|
||||
|
||||
|
||||
# generate all cards **********
|
||||
# run tools in source dir
|
||||
./make_ods.sh
|
||||
./make_FCMats.sh
|
||||
|
||||
# read cards
|
||||
from materialtools.cardutils import read_cards_from_path as readcards
|
||||
from materialtools.cardutils import get_source_path as getsrc
|
||||
cards_data = readcards(getsrc() + '/src/Mod/Material/StandardMaterial/')
|
||||
|
||||
# print cards
|
||||
for c in cards_data:
|
||||
print(c)
|
||||
|
||||
# write cards
|
||||
from materialtools.cardutils import write_cards_to_path as writecards
|
||||
from materialtools.cardutils import get_source_path as getsrc
|
||||
|
||||
# True writes sections ( method write_group_section is used =)
|
||||
writecards(getsrc() + '/src/Mod/Material/StandardMaterial/', cards_data, True)
|
||||
|
||||
writecards(getsrc() + '/src/Mod/Material/StandardMaterial/', cards_data, False)
|
||||
|
||||
# last True writes the TEMPLATE card which has no mat params because they have no values
|
||||
writecards(getsrc() + '/src/Mod/Material/StandardMaterial/', cards_data, True, True)
|
||||
|
||||
'''
|
||||
Reference in New Issue
Block a user