Material: card utils, move card methods from material editor to card utils module
- isolate card tools for further use in other modules - possible use of card tools in cmd mode - add some methods for better card handling - add some output methods for better card debuging - editor, better names for methods - add preference to sort cards and add duplicate cards too - use icon in mat editor card combo box
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();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -32,6 +32,7 @@ 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
|
||||
|
||||
@@ -50,6 +51,9 @@ class MaterialEditor:
|
||||
self.internalprops = []
|
||||
self.groups = []
|
||||
self.directory = FreeCAD.getResourceDir() + "Mod/Material"
|
||||
self.materials = {}
|
||||
self.cards = {}
|
||||
self.icons = {}
|
||||
|
||||
# load the UI file from the same directory as this script
|
||||
self.widget = FreeCADGui.PySideUic.loadUi(
|
||||
@@ -75,7 +79,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 +88,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[str].connect(self.updateMatParamsInTree)
|
||||
buttonAddProperty.clicked.connect(self.addCustomProperty)
|
||||
buttonDeleteProperty.clicked.connect(self.deleteCustomProperty)
|
||||
treeView.clicked.connect(self.checkDeletable)
|
||||
@@ -103,7 +107,7 @@ class MaterialEditor:
|
||||
|
||||
self.implementModel()
|
||||
if d:
|
||||
self.updateContents(d)
|
||||
self.updateMatParamsInTree(d)
|
||||
|
||||
def implementModel(self):
|
||||
|
||||
@@ -146,7 +150,7 @@ 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
|
||||
@@ -191,66 +195,39 @@ class MaterialEditor:
|
||||
if k:
|
||||
if k in self.cards:
|
||||
|
||||
# be careful with reading from materials dict
|
||||
# the card could be updated the dict not
|
||||
from importFCMat import read
|
||||
d = read(self.cards[k])
|
||||
if d:
|
||||
self.updateContents(d)
|
||||
self.updateMatParamsInTree(d)
|
||||
|
||||
def getMaterialResources(self):
|
||||
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)
|
||||
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()
|
||||
|
||||
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]])
|
||||
|
||||
for mat in card_name_list:
|
||||
self.widget.ComboMaterial.addItem(QtGui.QIcon(mat[2]), mat[0])
|
||||
|
||||
def openProductURL(self):
|
||||
|
||||
@@ -441,7 +418,7 @@ class MaterialEditor:
|
||||
self.directory = os.path.dirname(filename)
|
||||
d = read(filename)
|
||||
if d:
|
||||
self.updateContents(d)
|
||||
self.updateMatParamsInTree(d)
|
||||
|
||||
def savefile(self):
|
||||
"Saves a FCMat file."
|
||||
@@ -472,7 +449,7 @@ class MaterialEditor:
|
||||
if d:
|
||||
from importFCMat import write
|
||||
write(filename, d)
|
||||
self.updateCards()
|
||||
self.updateCardsInCombo()
|
||||
|
||||
def show(self):
|
||||
return self.widget.show()
|
||||
|
||||
@@ -23,3 +23,159 @@ __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
|
||||
|
||||
|
||||
# ***** 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
|
||||
i = 1
|
||||
while card_name in cards.values():
|
||||
if i == 1:
|
||||
card_name += ('_' + str(i))
|
||||
else:
|
||||
card_name = card_name[:-1] + str(i)
|
||||
i += 1
|
||||
# print(card_name)
|
||||
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')
|
||||
|
||||
Reference in New Issue
Block a user