Merge pull request #2758 from fieldOfView/feature_mesh_types

Improved mesh type UX (Per Model Settings)
This commit is contained in:
ChrisTerBeke 2017-11-29 13:24:38 +01:00 committed by GitHub
commit 0668f80792
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 168 additions and 42 deletions

View File

@ -52,6 +52,8 @@ class Arrange:
# Place all objects fixed nodes
for fixed_node in fixed_nodes:
vertices = fixed_node.callDecoration("getConvexHull")
if not vertices:
continue
points = copy.deepcopy(vertices._points)
shape_arr = ShapeArray.fromPolygon(points, scale = scale)
arranger.place(0, 0, shape_arr)

View File

@ -56,6 +56,11 @@ class ConvexHullDecorator(SceneNodeDecorator):
if self._node is None:
return None
if getattr(self._node, "_non_printing_mesh", False):
# infill_mesh, cutting_mesh and anti_overhang_mesh do not need a convex hull
# node._non_printing_mesh is set in SettingOverrideDecorator
return None
hull = self._compute2DConvexHull()
if self._global_stack and self._node:

View File

@ -22,6 +22,14 @@ class SettingOverrideDecorator(SceneNodeDecorator):
## Event indicating that the user selected a different extruder.
activeExtruderChanged = Signal()
## Non-printing meshes
#
# If these settings are True for any mesh, the mesh does not need a convex hull,
# and is sent to the slicer regardless of whether it fits inside the build volume.
# Note that Support Mesh is not in here because it actually generates
# g-code in the volume of the mesh.
_non_printing_mesh_settings = {"anti_overhang_mesh", "infill_mesh", "cutting_mesh"}
def __init__(self):
super().__init__()
self._stack = PerObjectContainerStack(stack_id = id(self))
@ -78,6 +86,8 @@ class SettingOverrideDecorator(SceneNodeDecorator):
Application.getInstance().getBackend().needsSlicing()
Application.getInstance().getBackend().tickle()
self._node._non_printing_mesh = any(self._stack.getProperty(setting, "value") for setting in self._non_printing_mesh_settings)
## Makes sure that the stack upon which the container stack is placed is
# kept up to date.
def _updateNextStack(self):

View File

@ -45,14 +45,6 @@ class GcodeStartEndFormatter(Formatter):
## Job class that builds up the message of scene data to send to CuraEngine.
class StartSliceJob(Job):
## Meshes that are sent to the engine regardless of being outside of the
# build volume.
#
# If these settings are True for any mesh, the build volume is ignored.
# Note that Support Mesh is not in here because it actually generates
# g-code in the volume of the mesh.
_not_printed_mesh_settings = {"anti_overhang_mesh", "infill_mesh", "cutting_mesh"}
def __init__(self, slice_message):
super().__init__()
@ -141,8 +133,7 @@ class StartSliceJob(Job):
temp_list = []
for node in DepthFirstIterator(self._scene.getRoot()):
if type(node) is SceneNode and node.getMeshData() and node.getMeshData().getVertices() is not None:
if not getattr(node, "_outside_buildarea", False)\
or (node.callDecoration("getStack") and any(node.callDecoration("getStack").getProperty(setting, "value") for setting in self._not_printed_mesh_settings)):
if not getattr(node, "_outside_buildarea", False) or getattr(node, "_non_printing_mesh", False):
temp_list.append(node)
Job.yieldThread()

View File

@ -26,17 +26,92 @@ Item {
spacing: UM.Theme.getSize("default_margin").height
Row
{
spacing: UM.Theme.getSize("default_margin").width
Label
{
text: catalog.i18nc("@label","Mesh Type")
font: UM.Theme.getFont("default")
color: UM.Theme.getColor("text")
height: UM.Theme.getSize("setting").height
verticalAlignment: Text.AlignVCenter
}
ComboBox
{
id: meshTypeSelection
style: UM.Theme.styles.combobox
onActivated: {
UM.ActiveTool.setProperty("MeshType", model.get(index).type)
}
model: ListModel
{
id: meshTypeModel
Component.onCompleted:
{
meshTypeModel.append({
type: "",
text: catalog.i18nc("@label", "Normal model")
});
meshTypeModel.append({
type: "support_mesh",
text: catalog.i18nc("@label", "Print as support")
});
meshTypeModel.append({
type: "anti_overhang_mesh",
text: catalog.i18nc("@label", "Don't support overlap with other models")
});
meshTypeModel.append({
type: "cutting_mesh",
text: catalog.i18nc("@label", "Modify settings for overlap with other models")
});
meshTypeModel.append({
type: "infill_mesh",
text: catalog.i18nc("@label", "Modify settings for infill of other models")
});
meshTypeSelection.updateCurrentIndex();
}
}
function updateCurrentIndex()
{
var mesh_type = UM.ActiveTool.properties.getValue("MeshType");
for(var index=0; index < meshTypeSelection.model.count; index++)
{
if(meshTypeSelection.model.get(index).type == mesh_type)
{
meshTypeSelection.currentIndex = index;
return;
}
}
meshTypeSelection.currentIndex = 0;
}
}
Connections
{
target: UM.Selection
onSelectionChanged: meshTypeSelection.updateCurrentIndex()
}
}
Column
{
// This is to ensure that the panel is first increasing in size up to 200 and then shows a scrollbar.
// It kinda looks ugly otherwise (big panel, no content on it)
id: currentSettings
property int maximumHeight: 200 * screenScaleFactor
height: Math.min(contents.count * (UM.Theme.getSize("section").height + UM.Theme.getSize("default_lining").height), maximumHeight)
visible: ["support_mesh", "anti_overhang_mesh"].indexOf(meshTypeSelection.model.get(meshTypeSelection.currentIndex).type) == -1
ScrollView
{
height: parent.height
width: UM.Theme.getSize("setting").width + UM.Theme.getSize("setting").height
width: UM.Theme.getSize("setting").width
style: UM.Theme.styles.scrollview
ListView
@ -49,6 +124,7 @@ Item {
id: addedSettingsModel;
containerId: Cura.MachineManager.activeDefinitionId
expanded: [ "*" ]
exclude: [ "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ]
visibilityHandler: Cura.PerObjectSettingVisibilityHandler
{
@ -58,6 +134,7 @@ Item {
delegate: Row
{
spacing: - UM.Theme.getSize("default_margin").width
Loader
{
id: settingLoader
@ -112,7 +189,7 @@ Item {
Button
{
width: (UM.Theme.getSize("setting").height / 2) | 0
width: Math.floor(UM.Theme.getSize("setting").height / 2)
height: UM.Theme.getSize("setting").height
onClicked: addedSettingsModel.setVisible(model.key, false)
@ -125,7 +202,7 @@ Item {
{
anchors.verticalCenter: parent.verticalCenter
width: parent.width
height: parent.height / 2
height: width
sourceSize.width: width
sourceSize.height: width
color: control.hovered ? UM.Theme.getColor("setting_control_button_hover") : UM.Theme.getColor("setting_control_button")
@ -201,9 +278,9 @@ Item {
Button
{
id: customise_settings_button;
height: UM.Theme.getSize("setting").height;
visible: parseInt(UM.Preferences.getValue("cura/active_mode")) == 1
id: customiseSettingsButton;
height: UM.Theme.getSize("setting_control").height;
visible: currentSettings.visible
text: catalog.i18nc("@action:button", "Select settings");
@ -223,21 +300,12 @@ Item {
{
text: control.text;
color: UM.Theme.getColor("setting_control_text");
font: UM.Theme.getFont("default")
anchors.centerIn: parent
}
}
onClicked: settingPickDialog.visible = true;
Connections
{
target: UM.Preferences;
onPreferenceChanged:
{
customise_settings_button.visible = parseInt(UM.Preferences.getValue("cura/active_mode"))
}
}
}
}
@ -325,7 +393,7 @@ Item {
}
visibilityHandler: UM.SettingPreferenceVisibilityHandler {}
expanded: [ "*" ]
exclude: [ "machine_settings", "command_line_settings" ]
exclude: [ "machine_settings", "command_line_settings", "support_mesh", "anti_overhang_mesh", "cutting_mesh", "infill_mesh" ]
}
delegate:Loader
{

View File

@ -8,6 +8,7 @@ from UM.Application import Application
from UM.Preferences import Preferences
from cura.Settings.SettingOverrideDecorator import SettingOverrideDecorator
from cura.Settings.ExtruderManager import ExtruderManager
from UM.Settings.SettingInstance import SettingInstance
from UM.Event import Event
@ -18,7 +19,7 @@ class PerObjectSettingsTool(Tool):
super().__init__()
self._model = None
self.setExposedProperties("SelectedObjectId", "ContainerID", "SelectedActiveExtruder")
self.setExposedProperties("SelectedObjectId", "ContainerID", "SelectedActiveExtruder", "MeshType")
self._advanced_mode = False
self._multi_extrusion = False
@ -70,6 +71,39 @@ class PerObjectSettingsTool(Tool):
selected_object.addDecorator(SettingOverrideDecorator())
selected_object.callDecoration("setActiveExtruder", extruder_stack_id)
def setMeshType(self, mesh_type):
selected_object = Selection.getSelectedObject(0)
stack = selected_object.callDecoration("getStack") #Don't try to get the active extruder since it may be None anyway.
if not stack:
selected_object.addDecorator(SettingOverrideDecorator())
stack = selected_object.callDecoration("getStack")
settings = stack.getTop()
for property_key in ["infill_mesh", "cutting_mesh", "support_mesh", "anti_overhang_mesh"]:
if property_key != mesh_type:
if settings.getInstance(property_key):
settings.removeInstance(property_key)
else:
if not (settings.getInstance(property_key) and settings.getProperty(property_key, "value")):
definition = stack.getSettingDefinition(property_key)
new_instance = SettingInstance(definition, settings)
new_instance.setProperty("value", True)
new_instance.resetState() # Ensure that the state is not seen as a user state.
settings.addInstance(new_instance)
def getMeshType(self):
selected_object = Selection.getSelectedObject(0)
stack = selected_object.callDecoration("getStack") #Don't try to get the active extruder since it may be None anyway.
if not stack:
return ""
settings = stack.getTop()
for property_key in ["infill_mesh", "cutting_mesh", "support_mesh", "anti_overhang_mesh"]:
if settings.getInstance(property_key) and settings.getProperty(property_key, "value"):
return property_key
return ""
def _onPreferenceChanged(self, preference):
if preference == "cura/active_mode":
self._advanced_mode = Preferences.getInstance().getValue(preference) == 1

View File

@ -27,25 +27,33 @@ class SolidView(View):
self._enabled_shader = None
self._disabled_shader = None
self._non_printing_shader = None
self._extruders_model = ExtrudersModel()
self._theme = None
def beginRendering(self):
scene = self.getController().getScene()
renderer = self.getRenderer()
if not self._theme:
self._theme = Application.getInstance().getTheme()
if not self._enabled_shader:
self._enabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "overhang.shader"))
theme = Application.getInstance().getTheme()
self._enabled_shader.setUniformValue("u_overhangColor", Color(*theme.getColor("model_overhang").getRgb()))
self._enabled_shader.setUniformValue("u_overhangColor", Color(*self._theme.getColor("model_overhang").getRgb()))
if not self._disabled_shader:
self._disabled_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "striped.shader"))
theme = Application.getInstance().getTheme()
self._disabled_shader.setUniformValue("u_diffuseColor1", Color(*theme.getColor("model_unslicable").getRgb()))
self._disabled_shader.setUniformValue("u_diffuseColor2", Color(*theme.getColor("model_unslicable_alt").getRgb()))
self._disabled_shader.setUniformValue("u_diffuseColor1", Color(*self._theme.getColor("model_unslicable").getRgb()))
self._disabled_shader.setUniformValue("u_diffuseColor2", Color(*self._theme.getColor("model_unslicable_alt").getRgb()))
self._disabled_shader.setUniformValue("u_width", 50.0)
if not self._non_printing_shader:
self._non_printing_shader = OpenGL.getInstance().createShaderProgram(Resources.getPath(Resources.Shaders, "transparent_object.shader"))
self._non_printing_shader.setUniformValue("u_diffuseColor", Color(*self._theme.getColor("model_non_printing").getRgb()))
self._non_printing_shader.setUniformValue("u_opacity", 0.6)
global_container_stack = Application.getInstance().getGlobalContainerStack()
if global_container_stack:
support_extruder_nr = global_container_stack.getProperty("support_extruder_nr", "value")
@ -68,11 +76,19 @@ class SolidView(View):
uniforms = {}
shade_factor = 1.0
per_mesh_stack = node.callDecoration("getStack")
# Get color to render this mesh in from ExtrudersModel
extruder_index = 0
extruder_id = node.callDecoration("getActiveExtruder")
if extruder_id:
extruder_index = max(0, self._extruders_model.find("id", extruder_id))
# Use the support extruder instead of the active extruder if this is a support_mesh
if per_mesh_stack:
if per_mesh_stack.getProperty("support_mesh", "value"):
extruder_index = int(global_container_stack.getProperty("support_extruder_nr", "value"))
try:
material_color = self._extruders_model.getItem(extruder_index)["color"]
except KeyError:
@ -94,19 +110,17 @@ class SolidView(View):
except ValueError:
pass
if hasattr(node, "_outside_buildarea"):
if node._outside_buildarea:
renderer.queueNode(node, shader = self._disabled_shader)
if getattr(node, "_non_printing_mesh", False):
if per_mesh_stack and (per_mesh_stack.getProperty("infill_mesh", "value") or per_mesh_stack.getProperty("cutting_mesh", "value")):
renderer.queueNode(node, shader = self._non_printing_shader, uniforms = uniforms, transparent = True)
else:
renderer.queueNode(node, shader = self._enabled_shader, uniforms = uniforms)
renderer.queueNode(node, shader = self._non_printing_shader, transparent = True)
elif getattr(node, "_outside_buildarea", False):
renderer.queueNode(node, shader = self._disabled_shader)
else:
renderer.queueNode(node, material = self._enabled_shader, uniforms = uniforms)
renderer.queueNode(node, shader = self._enabled_shader, uniforms = uniforms)
if node.callDecoration("isGroup") and Selection.isSelected(node):
renderer.queueNode(scene.getRoot(), mesh = node.getBoundingBoxMesh(), mode = RenderBatch.RenderMode.LineLoop)
def endRendering(self):
pass
#def _onPreferenceChanged(self, preference):
#if preference == "view/show_overhang": ## Todo: This a printer only setting. Should be removed from Uranium.
#self._enabled_material = None

View File

@ -111,6 +111,7 @@ u_modelMatrix = model_matrix
u_viewProjectionMatrix = view_projection_matrix
u_normalMatrix = normal_matrix
u_lightPosition = light_0_position
u_diffuseColor = diffuse_color
[attributes]
a_vertex = vertex

View File

@ -266,6 +266,7 @@
"model_unslicable": [122, 122, 122, 255],
"model_unslicable_alt": [172, 172, 127, 255],
"model_selection_outline": [12, 169, 227, 255],
"model_non_printing": [122, 122, 122, 255],
"xray": [26, 26, 62, 255],
"xray_error": [255, 0, 0, 255],