mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-05-24 23:29:00 +08:00
Merge branch 'master' of github.com:Ultimaker/Cura
This commit is contained in:
commit
bae2193bfb
@ -59,7 +59,7 @@ class CrashHandler:
|
|||||||
self.data = dict()
|
self.data = dict()
|
||||||
self.data["time_stamp"] = time.time()
|
self.data["time_stamp"] = time.time()
|
||||||
|
|
||||||
Logger.log("c", "An uncaught exception has occurred!")
|
Logger.log("c", "An uncaught error has occurred!")
|
||||||
for line in traceback.format_exception(exception_type, value, tb):
|
for line in traceback.format_exception(exception_type, value, tb):
|
||||||
for part in line.rstrip("\n").split("\n"):
|
for part in line.rstrip("\n").split("\n"):
|
||||||
Logger.log("c", part)
|
Logger.log("c", part)
|
||||||
@ -90,7 +90,7 @@ class CrashHandler:
|
|||||||
|
|
||||||
def _messageWidget(self):
|
def _messageWidget(self):
|
||||||
label = QLabel()
|
label = QLabel()
|
||||||
label.setText(catalog.i18nc("@label crash message", """<p><b>A fatal exception has occurred. Please send us this Crash Report to fix the problem</p></b>
|
label.setText(catalog.i18nc("@label crash message", """<p><b>A fatal error has occurred. Please send us this Crash Report to fix the problem</p></b>
|
||||||
<p>Please use the "Send report" button to post a bug report automatically to our servers</p>
|
<p>Please use the "Send report" button to post a bug report automatically to our servers</p>
|
||||||
"""))
|
"""))
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ class CrashHandler:
|
|||||||
|
|
||||||
def _exceptionInfoWidget(self):
|
def _exceptionInfoWidget(self):
|
||||||
group = QGroupBox()
|
group = QGroupBox()
|
||||||
group.setTitle(catalog.i18nc("@title:groupbox", "Exception traceback"))
|
group.setTitle(catalog.i18nc("@title:groupbox", "Error traceback"))
|
||||||
layout = QVBoxLayout()
|
layout = QVBoxLayout()
|
||||||
|
|
||||||
text_area = QTextEdit()
|
text_area = QTextEdit()
|
||||||
|
@ -508,7 +508,7 @@ class CuraContainerStack(ContainerStack):
|
|||||||
def findDefaultQuality(self) -> Optional[ContainerInterface]:
|
def findDefaultQuality(self) -> Optional[ContainerInterface]:
|
||||||
definition = self._getMachineDefinition()
|
definition = self._getMachineDefinition()
|
||||||
registry = ContainerRegistry.getInstance()
|
registry = ContainerRegistry.getInstance()
|
||||||
material_container = self.material if self.material != self._empty_instance_container else None
|
material_container = self.material if self.material.getId() not in (self._empty_material.getId(), self._empty_instance_container.getId()) else None
|
||||||
|
|
||||||
search_criteria = {"type": "quality"}
|
search_criteria = {"type": "quality"}
|
||||||
|
|
||||||
@ -552,7 +552,7 @@ class CuraContainerStack(ContainerStack):
|
|||||||
material_search_criteria = {"type": "material", "material": material_container.getMetaDataEntry("material"), "color_name": "Generic"}
|
material_search_criteria = {"type": "material", "material": material_container.getMetaDataEntry("material"), "color_name": "Generic"}
|
||||||
if definition.getMetaDataEntry("has_machine_quality"):
|
if definition.getMetaDataEntry("has_machine_quality"):
|
||||||
if self.material != self._empty_instance_container:
|
if self.material != self._empty_instance_container:
|
||||||
material_search_criteria["definition"] = material_container.getDefinition().id
|
material_search_criteria["definition"] = material_container.getMetaDataEntry("definition")
|
||||||
|
|
||||||
if definition.getMetaDataEntry("has_variants"):
|
if definition.getMetaDataEntry("has_variants"):
|
||||||
material_search_criteria["variant"] = material_container.getMetaDataEntry("variant")
|
material_search_criteria["variant"] = material_container.getMetaDataEntry("variant")
|
||||||
|
@ -131,12 +131,21 @@ class StartSliceJob(Job):
|
|||||||
Logger.log("w", "No objects suitable for one at a time found, or no correct order found")
|
Logger.log("w", "No objects suitable for one at a time found, or no correct order found")
|
||||||
else:
|
else:
|
||||||
temp_list = []
|
temp_list = []
|
||||||
|
is_non_printing_mesh = False
|
||||||
for node in DepthFirstIterator(self._scene.getRoot()):
|
for node in DepthFirstIterator(self._scene.getRoot()):
|
||||||
if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None:
|
if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None:
|
||||||
if not getattr(node, "_outside_buildarea", False) or getattr(node, "_non_printing_mesh", False):
|
_non_printing_mesh = getattr(node, "_non_printing_mesh", False)
|
||||||
|
if not getattr(node, "_outside_buildarea", False) or _non_printing_mesh:
|
||||||
temp_list.append(node)
|
temp_list.append(node)
|
||||||
|
if _non_printing_mesh:
|
||||||
|
is_non_printing_mesh = True
|
||||||
Job.yieldThread()
|
Job.yieldThread()
|
||||||
|
|
||||||
|
#If list has one node and it has non printing settings then remove it from list
|
||||||
|
# otherwise CuraEngine will crash
|
||||||
|
if len(temp_list) == 1 and is_non_printing_mesh:
|
||||||
|
temp_list.clear()
|
||||||
|
|
||||||
if temp_list:
|
if temp_list:
|
||||||
object_groups.append(temp_list)
|
object_groups.append(temp_list)
|
||||||
|
|
||||||
|
@ -212,11 +212,12 @@ class XmlMaterialProfile(InstanceContainer):
|
|||||||
|
|
||||||
for definition_id, container in machine_container_map.items():
|
for definition_id, container in machine_container_map.items():
|
||||||
definition = container.getDefinition()
|
definition = container.getDefinition()
|
||||||
try:
|
|
||||||
product = UM.Dictionary.findKey(product_id_map, definition_id)
|
|
||||||
except ValueError:
|
|
||||||
# An unknown product id; export it anyway
|
|
||||||
product = definition_id
|
product = definition_id
|
||||||
|
for product_name, product_id_list in product_id_map.items():
|
||||||
|
if definition_id in product_id_list:
|
||||||
|
product = product_name
|
||||||
|
break
|
||||||
|
|
||||||
builder.start("machine")
|
builder.start("machine")
|
||||||
builder.start("machine_identifier", {
|
builder.start("machine_identifier", {
|
||||||
@ -530,16 +531,17 @@ class XmlMaterialProfile(InstanceContainer):
|
|||||||
|
|
||||||
identifiers = machine.iterfind("./um:machine_identifier", self.__namespaces)
|
identifiers = machine.iterfind("./um:machine_identifier", self.__namespaces)
|
||||||
for identifier in identifiers:
|
for identifier in identifiers:
|
||||||
machine_id = product_id_map.get(identifier.get("product"), None)
|
machine_id_list = product_id_map.get(identifier.get("product"), [])
|
||||||
if machine_id is None:
|
if not machine_id_list:
|
||||||
# Lets try again with some naive heuristics.
|
machine_id_list = self.getPossibleDefinitionIDsFromName(identifier.get("product"))
|
||||||
machine_id = identifier.get("product").replace(" ", "").lower()
|
|
||||||
|
|
||||||
|
for machine_id in machine_id_list:
|
||||||
definitions = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = machine_id)
|
definitions = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = machine_id)
|
||||||
if not definitions:
|
if not definitions:
|
||||||
Logger.log("w", "No definition found for machine ID %s", machine_id)
|
Logger.log("w", "No definition found for machine ID %s", machine_id)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
Logger.log("d", "Found definition for machine ID %s", machine_id)
|
||||||
definition = definitions[0]
|
definition = definitions[0]
|
||||||
|
|
||||||
machine_manufacturer = identifier.get("manufacturer", definition.get("manufacturer", "Unknown")) #If the XML material doesn't specify a manufacturer, use the one in the actual printer definition.
|
machine_manufacturer = identifier.get("manufacturer", definition.get("manufacturer", "Unknown")) #If the XML material doesn't specify a manufacturer, use the one in the actual printer definition.
|
||||||
@ -583,7 +585,7 @@ class XmlMaterialProfile(InstanceContainer):
|
|||||||
variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = hotend_id)
|
variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(id = hotend_id)
|
||||||
if not variant_containers:
|
if not variant_containers:
|
||||||
# It is not really properly defined what "ID" is so also search for variants by name.
|
# It is not really properly defined what "ID" is so also search for variants by name.
|
||||||
variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(definition = definition["id"], name = hotend_id)
|
variant_containers = ContainerRegistry.getInstance().findInstanceContainersMetadata(definition = machine_id, name = hotend_id)
|
||||||
|
|
||||||
if not variant_containers:
|
if not variant_containers:
|
||||||
continue
|
continue
|
||||||
@ -616,6 +618,7 @@ class XmlMaterialProfile(InstanceContainer):
|
|||||||
new_hotend_material.getMetaData()["id"] = new_hotend_id
|
new_hotend_material.getMetaData()["id"] = new_hotend_id
|
||||||
new_hotend_material.getMetaData()["name"] = self.getName()
|
new_hotend_material.getMetaData()["name"] = self.getName()
|
||||||
new_hotend_material.getMetaData()["variant"] = variant_containers[0]["id"]
|
new_hotend_material.getMetaData()["variant"] = variant_containers[0]["id"]
|
||||||
|
new_hotend_material.setDefinition(machine_id)
|
||||||
# Don't use setMetadata, as that overrides it for all materials with same base file
|
# Don't use setMetadata, as that overrides it for all materials with same base file
|
||||||
new_hotend_material.getMetaData()["compatible"] = hotend_compatibility
|
new_hotend_material.getMetaData()["compatible"] = hotend_compatibility
|
||||||
new_hotend_material.getMetaData()["machine_manufacturer"] = machine_manufacturer
|
new_hotend_material.getMetaData()["machine_manufacturer"] = machine_manufacturer
|
||||||
@ -631,6 +634,10 @@ class XmlMaterialProfile(InstanceContainer):
|
|||||||
if is_new_material:
|
if is_new_material:
|
||||||
containers_to_add.append(new_hotend_material)
|
containers_to_add.append(new_hotend_material)
|
||||||
|
|
||||||
|
# there is only one ID for a machine. Once we have reached here, it means we have already found
|
||||||
|
# a workable ID for that machine, so there is no need to continue
|
||||||
|
break
|
||||||
|
|
||||||
for container_to_add in containers_to_add:
|
for container_to_add in containers_to_add:
|
||||||
ContainerRegistry.getInstance().addContainer(container_to_add)
|
ContainerRegistry.getInstance().addContainer(container_to_add)
|
||||||
|
|
||||||
@ -720,14 +727,17 @@ class XmlMaterialProfile(InstanceContainer):
|
|||||||
machine_compatibility = cls._parseCompatibleValue(entry.text)
|
machine_compatibility = cls._parseCompatibleValue(entry.text)
|
||||||
|
|
||||||
for identifier in machine.iterfind("./um:machine_identifier", cls.__namespaces):
|
for identifier in machine.iterfind("./um:machine_identifier", cls.__namespaces):
|
||||||
machine_id = product_id_map.get(identifier.get("product"), None)
|
machine_id_list = product_id_map.get(identifier.get("product"), [])
|
||||||
if machine_id is None:
|
if not machine_id_list:
|
||||||
# Lets try again with some naive heuristics.
|
machine_id_list = cls.getPossibleDefinitionIDsFromName(identifier.get("product"))
|
||||||
machine_id = identifier.get("product").replace(" ", "").lower()
|
|
||||||
|
for machine_id in machine_id_list:
|
||||||
definition_metadata = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = machine_id)
|
definition_metadata = ContainerRegistry.getInstance().findDefinitionContainersMetadata(id = machine_id)
|
||||||
if not definition_metadata:
|
if not definition_metadata:
|
||||||
Logger.log("w", "No definition found for machine ID %s", machine_id)
|
Logger.log("w", "No definition found for machine ID %s", machine_id)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
|
Logger.log("d", "========= Found def for machine [%s]", machine_id)
|
||||||
definition_metadata = definition_metadata[0]
|
definition_metadata = definition_metadata[0]
|
||||||
|
|
||||||
machine_manufacturer = identifier.get("manufacturer", definition_metadata.get("manufacturer", "Unknown")) #If the XML material doesn't specify a manufacturer, use the one in the actual printer definition.
|
machine_manufacturer = identifier.get("manufacturer", definition_metadata.get("manufacturer", "Unknown")) #If the XML material doesn't specify a manufacturer, use the one in the actual printer definition.
|
||||||
@ -794,6 +804,10 @@ class XmlMaterialProfile(InstanceContainer):
|
|||||||
if len(found_materials) == 0:
|
if len(found_materials) == 0:
|
||||||
result_metadata.append(new_hotend_material_metadata)
|
result_metadata.append(new_hotend_material_metadata)
|
||||||
|
|
||||||
|
# there is only one ID for a machine. Once we have reached here, it means we have already found
|
||||||
|
# a workable ID for that machine, so there is no need to continue
|
||||||
|
break
|
||||||
|
|
||||||
return result_metadata
|
return result_metadata
|
||||||
|
|
||||||
def _addSettingElement(self, builder, instance):
|
def _addSettingElement(self, builder, instance):
|
||||||
@ -813,15 +827,41 @@ class XmlMaterialProfile(InstanceContainer):
|
|||||||
else:
|
else:
|
||||||
return material_name
|
return material_name
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def getPossibleDefinitionIDsFromName(cls, name):
|
||||||
|
name_parts = name.lower().split(" ")
|
||||||
|
merged_name_parts = []
|
||||||
|
for part in name_parts:
|
||||||
|
if len(part) == 0:
|
||||||
|
continue
|
||||||
|
if len(merged_name_parts) == 0:
|
||||||
|
merged_name_parts.append(part)
|
||||||
|
continue
|
||||||
|
if part.isdigit():
|
||||||
|
# for names with digit(s) such as Ultimaker 3 Extended, we generate an ID like
|
||||||
|
# "ultimaker3_extended", ignoring the space between "Ultimaker" and "3".
|
||||||
|
merged_name_parts[-1] = merged_name_parts[-1] + part
|
||||||
|
else:
|
||||||
|
merged_name_parts.append(part)
|
||||||
|
|
||||||
|
id_list = [name.lower().replace(" ", ""), # simply removing all spaces
|
||||||
|
name.lower().replace(" ", "_"), # simply replacing all spaces with underscores
|
||||||
|
"_".join(merged_name_parts),
|
||||||
|
]
|
||||||
|
|
||||||
|
return id_list
|
||||||
|
|
||||||
## Gets a mapping from product names in the XML files to their definition
|
## Gets a mapping from product names in the XML files to their definition
|
||||||
# IDs.
|
# IDs.
|
||||||
#
|
#
|
||||||
# This loads the mapping from a file.
|
# This loads the mapping from a file.
|
||||||
@classmethod
|
@classmethod
|
||||||
def getProductIdMap(cls) -> Dict[str, str]:
|
def getProductIdMap(cls) -> Dict[str, List[str]]:
|
||||||
product_to_id_file = os.path.join(os.path.dirname(sys.modules[cls.__module__].__file__), "product_to_id.json")
|
product_to_id_file = os.path.join(os.path.dirname(sys.modules[cls.__module__].__file__), "product_to_id.json")
|
||||||
with open(product_to_id_file) as f:
|
with open(product_to_id_file) as f:
|
||||||
return json.load(f)
|
product_to_id_map = json.load(f)
|
||||||
|
product_to_id_map = {key: [value] for key, value in product_to_id_map.items()}
|
||||||
|
return product_to_id_map
|
||||||
|
|
||||||
## Parse the value of the "material compatible" property.
|
## Parse the value of the "material compatible" property.
|
||||||
@classmethod
|
@classmethod
|
||||||
|
Loading…
x
Reference in New Issue
Block a user