slice angled
This commit is contained in:
parent
083aa66436
commit
370a2d95cc
3 changed files with 21 additions and 10 deletions
|
|
@ -38,22 +38,28 @@ class SLICENODE_SliceShells(SliceNode):
|
||||||
def init(self, context):
|
def init(self, context):
|
||||||
self.add_input("SLICESOCK_Mesh")
|
self.add_input("SLICESOCK_Mesh")
|
||||||
self.add_input("SLICESOCK_Float", "Layer Height").value = 0.2
|
self.add_input("SLICESOCK_Float", "Layer Height").value = 0.2
|
||||||
|
self.add_input("SLICESOCK_VectorRotation", "Rotation")
|
||||||
self.add_output("SLICESOCK_Paths")
|
self.add_output("SLICESOCK_Paths")
|
||||||
|
|
||||||
def evaluate_output(self, socket_name: str, **_kwargs) -> SlicePaths:
|
def evaluate_output(self, socket_name: str, **_kwargs) -> SlicePaths:
|
||||||
if socket_name != "Paths": return SlicePaths()
|
if socket_name != "Paths": return SlicePaths()
|
||||||
|
|
||||||
slicing_collection: SlicingCollection | None = self.resolve("Mesh")
|
coll: SlicingCollection | None = self.resolve("Mesh")
|
||||||
layer_height: float = self.resolve("Layer Height")
|
layer_height: float = self.resolve("Layer Height")
|
||||||
|
rotation: Any = self.resolve("Rotation") or (0.0, 0.0, 0.0)
|
||||||
|
|
||||||
if not slicing_collection: return SlicePaths()
|
if not coll: return SlicePaths()
|
||||||
|
|
||||||
merged_object = SlicingObject()
|
merged_object = SlicingObject()
|
||||||
coll: SlicingCollection = self.resolve("Mesh")
|
|
||||||
if coll:
|
|
||||||
for obj in coll.objects:
|
for obj in coll.objects:
|
||||||
merged_object.mesh = np.concatenate([merged_object.mesh, obj.mesh], axis=0)
|
merged_object.mesh = np.concatenate([merged_object.mesh, obj.mesh], axis=0)
|
||||||
|
|
||||||
|
if rotation and any(rotation):
|
||||||
|
from mathutils import Euler
|
||||||
|
mat = np.array(Euler(rotation).to_matrix().inverted())
|
||||||
|
merged_object.mesh[:, :3, :] = merged_object.mesh[:, :3, :] @ mat.T
|
||||||
|
merged_object.mesh[:, 3:4, :] = merged_object.mesh[:, 3:4, :] @ mat.T
|
||||||
|
|
||||||
min_z = merged_object.mesh[:,0:3,2:3].min()
|
min_z = merged_object.mesh[:,0:3,2:3].min()
|
||||||
from math import floor
|
from math import floor
|
||||||
min_z = floor(min_z / layer_height) * layer_height
|
min_z = floor(min_z / layer_height) * layer_height
|
||||||
|
|
@ -63,9 +69,14 @@ class SLICENODE_SliceShells(SliceNode):
|
||||||
|
|
||||||
slices_group: list[list[np.ndarray]] | None = slice_at_range([merged_object.mesh], z_values)
|
slices_group: list[list[np.ndarray]] | None = slice_at_range([merged_object.mesh], z_values)
|
||||||
assert slices_group
|
assert slices_group
|
||||||
slices = slices_group[0]
|
slices = SlicePaths(slices_group[0])
|
||||||
|
|
||||||
return SlicePaths(slices)
|
if rotation and any(rotation):
|
||||||
|
from mathutils import Euler
|
||||||
|
mat_inv = np.array(Euler(rotation).to_matrix())
|
||||||
|
slices = slices.transform(mat_inv)
|
||||||
|
|
||||||
|
return slices
|
||||||
|
|
||||||
@register_class
|
@register_class
|
||||||
class SLICENODE_BufferShells(SliceNode):
|
class SLICENODE_BufferShells(SliceNode):
|
||||||
|
|
|
||||||
|
|
@ -57,7 +57,7 @@ All nodes are found in the **Add (Shift+A)** menu under the **SliceNodes** categ
|
||||||
- **Extrusion Multiplier Attribute**: Mesh attribute to use for per-segment extrusion rates.
|
- **Extrusion Multiplier Attribute**: Mesh attribute to use for per-segment extrusion rates.
|
||||||
- **Feedrate Attribute**: Mesh attribute to use for per-segment feedrates.
|
- **Feedrate Attribute**: Mesh attribute to use for per-segment feedrates.
|
||||||
- **Extra Attributes**: Dictionary mapping mesh attribute names to custom G-code prefixes (e.g., `opening_size` -> `S`).
|
- **Extra Attributes**: Dictionary mapping mesh attribute names to custom G-code prefixes (e.g., `opening_size` -> `S`).
|
||||||
- **Slice Shells**: Slices a `SlicingObject` into 2D `SlicePaths` at a given layer height.
|
- **Slice Shells**: Slices a `SlicingObject` into 2D `SlicePaths` at a given layer height. Supports rotation for slicing at an angle.
|
||||||
- **Buffer Shells**: Offsets/buffers 2D `SlicePaths`. Supports rotated offsetting and multiple miter types.
|
- **Buffer Shells**: Offsets/buffers 2D `SlicePaths`. Supports rotated offsetting and multiple miter types.
|
||||||
- **Infill**: Generates a cross-hatch grid or parallel lines clipped by boundary paths.
|
- **Infill**: Generates a cross-hatch grid or parallel lines clipped by boundary paths.
|
||||||
- **Infill Type**: Switch between **Grid** (cross-hatch) and **Rectilinear** (alternating parallel lines).
|
- **Infill Type**: Switch between **Grid** (cross-hatch) and **Rectilinear** (alternating parallel lines).
|
||||||
|
|
|
||||||
|
|
@ -67,5 +67,5 @@ Once you are happy with the preview:
|
||||||
|
|
||||||
## 5. Tips for Success
|
## 5. Tips for Success
|
||||||
* **Scale**: The slicer treats 1 Blender unit as 1 meter, but scales everything to **mm** for the G-code output.
|
* **Scale**: The slicer treats 1 Blender unit as 1 meter, but scales everything to **mm** for the G-code output.
|
||||||
* **Orientation**: The slicer currently assumes your object is oriented correctly for printing (Z is up).
|
* **Orientation**: The slicer currently assumes your object is oriented correctly for printing (Z is up). You can use the **Rotation** input on the **Slice Shells** node to slice at an angle if needed.
|
||||||
* **Performance**: For very complex meshes, the "Get Mesh" and "Slice Shells" nodes might take a moment to compute. The result is cached, so changing settings further down the chain (like Infill density) will be much faster.
|
* **Performance**: For very complex meshes, the "Get Mesh" and "Slice Shells" nodes might take a moment to compute. The result is cached, so changing settings further down the chain (like Infill density) will be much faster.
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue