Remove zip, format module, class and function

names to pep8 / Blender standards
pull/277/head^2
Rob 2024-12-12 14:18:05 -05:00
rodzic 35d065d828
commit 72bae15d7f
72 zmienionych plików z 1944 dodań i 1910 usunięć

Plik binarny nie jest wyświetlany.

Wyświetl plik

@ -22,13 +22,13 @@ from bpy.props import (
from bpy_extras.object_utils import object_data_add
# Relative Imports - from 'cam' module
from .basrelief import DoBasRelief, ProblemAreas
from .cam_operation import camOperation
from .bas_relief import DoBasRelief, ProblemAreas
from .cam_operation import CamOperation
from .chain import (
camChain,
opReference,
CamChain,
OpReference,
)
from .curvecamcreate import (
from .curve_cam_create import (
CamCurveDrawer,
CamCurveFlatCone,
CamCurveGear,
@ -38,13 +38,13 @@ from .curvecamcreate import (
CamCurvePlate,
CamCurvePuzzle,
)
from .curvecamequation import (
from .curve_cam_equation import (
CamCustomCurve,
CamHypotrochoidCurve,
CamLissajousCurve,
CamSineCurve,
)
from .curvecamtools import (
from .curve_cam_tools import (
CamCurveBoolean,
CamCurveConvexHull,
CamCurveIntarsion,
@ -59,7 +59,7 @@ from .engine import (
FABEX_ENGINE,
get_panels,
)
from .machine_settings import machineSettings
from .machine_settings import MachineSettings
from .ops import (
CalculatePath,
# bridges related
@ -106,7 +106,7 @@ from .ui import register as ui_register, unregister as ui_unregister
from .ui.panels.interface import CAM_INTERFACE_Properties
from .utils import (
check_operations_on_load,
updateOperation,
update_operation,
)
@ -115,8 +115,8 @@ classes = [
DoBasRelief,
ProblemAreas,
# .chain
opReference,
camChain,
OpReference,
CamChain,
# .curvecamcreate
CamCurveDrawer,
CamCurveFlatCone,
@ -144,7 +144,7 @@ classes = [
# .engine
FABEX_ENGINE,
# .machine_settings
machineSettings,
MachineSettings,
# .ops
CalculatePath,
# bridges related
@ -191,7 +191,7 @@ def register() -> None:
ui_register()
# .cam_operation - last to allow dependencies to register before it
bpy.utils.register_class(camOperation)
bpy.utils.register_class(CamOperation)
bpy.app.handlers.frame_change_pre.append(timer_update)
bpy.app.handlers.load_post.append(check_operations_on_load)
@ -206,20 +206,20 @@ def register() -> None:
scene.cam_active_operation = IntProperty(
name="CAM Active Operation",
description="The selected operation",
update=updateOperation,
update=update_operation,
)
scene.cam_chains = CollectionProperty(
type=camChain,
type=CamChain,
)
scene.gcode_output_type = StringProperty(
name="Gcode Output Type",
default="",
)
scene.cam_machine = PointerProperty(
type=machineSettings,
type=MachineSettings,
)
scene.cam_operations = CollectionProperty(
type=camOperation,
type=CamOperation,
)
scene.cam_text = StringProperty()
scene.interface = PointerProperty(
@ -249,7 +249,7 @@ def unregister() -> None:
ui_unregister()
bpy.utils.unregister_class(camOperation)
bpy.utils.unregister_class(CamOperation)
scene = bpy.types.Scene

Wyświetl plik

@ -46,7 +46,7 @@ def copy_compbuf_data(inbuf, outbuf):
outbuf[:] = inbuf[:]
def restrictbuf(inbuf, outbuf):
def restrict_buffer(inbuf, outbuf):
"""Restrict the resolution of an input buffer to match an output buffer.
This function scales down the input buffer `inbuf` to fit the dimensions
@ -288,7 +288,7 @@ def smooth(U, F, linbcgiterations, planar):
n = U.size
linbcg(n, F, U, 2, 0.001, linbcgiterations, iter, err, rows, cols, planar)
linear_bcg(n, F, U, 2, 0.001, linbcgiterations, iter, err, rows, cols, planar)
def calculate_defect(D, U, F):
@ -431,11 +431,11 @@ def solve_pde_multigrid(
VF[k + 1] = numpy.zeros((sx, sy), dtype=numpy.float64)
# restrict from level k to level k+1 (coarser-grid)
restrictbuf(PLANAR[k], PLANAR[k + 1])
restrict_buffer(PLANAR[k], PLANAR[k + 1])
PLANAR[k + 1] = PLANAR[k + 1] > 0
# numpytoimage(PLANAR[k+1],'planar')
# print(PLANAR[k+1])
restrictbuf(RHS[k], RHS[k + 1])
restrict_buffer(RHS[k], RHS[k + 1])
# numpytoimage(RHS[k+1],'rhs')
# 2. find exact sollution at the coarsest-grid (k=levels)
@ -490,7 +490,7 @@ def solve_pde_multigrid(
# 9. restrict deffect as target function for next coarser-grid
# def -> f[k2+1]
restrictbuf(D, VF[k2 + 1])
restrict_buffer(D, VF[k2 + 1])
# 10. solve on coarsest-grid (target function is the deffect)
# iu[levels] should contain sollution for
@ -598,7 +598,7 @@ def snrm(n, sx, itol):
# */
def linbcg(n, b, x, itol, tol, itmax, iter, err, rows, cols, planar):
def linear_bcg(n, b, x, itol, tol, itmax, iter, err, rows, cols, planar):
"""Solve a linear system using the Biconjugate Gradient Method.
This function implements the Biconjugate Gradient Method as described in
@ -718,7 +718,7 @@ def linbcg(n, b, x, itol, tol, itmax, iter, err, rows, cols, planar):
# --------------------------------------------------------------------
def numpysave(a, iname):
def numpy_save(a, iname):
"""Save a NumPy array as an image file in OpenEXR format.
This function takes a NumPy array and saves it as an image file using
@ -733,7 +733,7 @@ def numpysave(a, iname):
inamebase = bpy.path.basename(iname)
i = numpytoimage(a, inamebase)
i = numpy_to_image(a, inamebase)
r = bpy.context.scene.render
@ -744,7 +744,7 @@ def numpysave(a, iname):
i.save_render(iname)
def numpytoimage(a, iname):
def numpy_to_image(a, iname):
"""Convert a NumPy array to a Blender image.
This function takes a NumPy array and converts it into a Blender image.
@ -807,7 +807,7 @@ def numpytoimage(a, iname):
return i
def imagetonumpy(i):
def image_to_numpy(i):
"""Convert an image to a NumPy array.
This function takes an image object and converts its pixel data into a
@ -903,7 +903,7 @@ def vert(column, row, z, XYscaling, Zscaling):
return column * XYscaling, row * XYscaling, z * Zscaling
def buildMesh(mesh_z, br):
def build_mesh(mesh_z, br):
"""Build a 3D mesh from a height map and apply transformations.
This function constructs a 3D mesh based on the provided height map
@ -973,14 +973,14 @@ def buildMesh(mesh_z, br):
ob.select_set(True)
bpy.context.view_layer.objects.active = ob
bpy.context.active_object.dimensions = (
br.widthmm / 1000,
br.heightmm / 1000,
br.thicknessmm / 1000,
br.width_mm / 1000,
br.height_mm / 1000,
br.thickness_mm / 1000,
)
bpy.context.active_object.location = (
float(br.justifyx) * br.widthmm / 1000,
float(br.justifyy) * br.heightmm / 1000,
float(br.justifyz) * br.thicknessmm / 1000,
float(br.justify_x) * br.width_mm / 1000,
float(br.justify_y) * br.height_mm / 1000,
float(br.justify_z) * br.thickness_mm / 1000,
)
print("Faces:" + str(len(ob.data.polygons)))
@ -1000,7 +1000,7 @@ def buildMesh(mesh_z, br):
# Switches to cycles render to CYCLES to render the sceen then switches it back to FABEX_RENDER for basRelief
def renderScene(width, height, bit_diameter, passes_per_radius, make_nodes, view_layer):
def render_scene(width, height, bit_diameter, passes_per_radius, make_nodes, view_layer):
"""Render a scene using Blender's Cycles engine.
This function switches the rendering engine to Cycles, sets up the
@ -1066,7 +1066,7 @@ def renderScene(width, height, bit_diameter, passes_per_radius, make_nodes, view
print("Done Rendering")
def problemAreas(br):
def problem_areas(br):
"""Process image data to identify problem areas based on silhouette
thresholds.
@ -1131,10 +1131,10 @@ def problemAreas(br):
# if br.gradient_scaling_mask_use:
# m.scale(int(m.size[0]*br.scale_down_before),int(m.size[1]*br.scale_down_before))
nar = imagetonumpy(i)
nar = image_to_numpy(i)
# return
if br.gradient_scaling_mask_use:
mask = imagetonumpy(m)
mask = image_to_numpy(m)
# put image to scale
tonemap(nar, br.depth_exponent)
nar = 1 - nar # reverse z buffer+ add something
@ -1190,7 +1190,7 @@ def problemAreas(br):
atimes(divgp, divga)
divga = divgp
numpytoimage(divga, "problem")
numpy_to_image(divga, "problem")
def relief(br):
@ -1262,10 +1262,10 @@ def relief(br):
# if br.gradient_scaling_mask_use:
# m.scale(int(m.size[0]*br.scale_down_before),int(m.size[1]*br.scale_down_before))
nar = imagetonumpy(i)
nar = image_to_numpy(i)
# return
if br.gradient_scaling_mask_use:
mask = imagetonumpy(m)
mask = image_to_numpy(m)
# put image to scale
tonemap(nar, br.depth_exponent)
nar = 1 - nar # reverse z buffer+ add something
@ -1395,7 +1395,7 @@ def relief(br):
tonemap(target, 1)
buildMesh(target, br)
build_mesh(target, br)
# ipath=bpy.path.abspath(i.filepath)[:-len(bpy.path.basename(i.filepath))]+br.output_image_name+'.exr'
# numpysave(target,ipath)
@ -1446,31 +1446,31 @@ class DoBasRelief(bpy.types.Operator):
min=1,
max=10,
)
widthmm: IntProperty(
width_mm: IntProperty(
name="Desired Width in mm",
default=200,
min=5,
max=4000,
)
heightmm: IntProperty(
height_mm: IntProperty(
name="Desired Height in mm",
default=150,
min=5,
max=4000,
)
thicknessmm: IntProperty(
thickness_mm: IntProperty(
name="Thickness in mm",
default=15,
min=5,
max=100,
)
justifyx: EnumProperty(
justify_x: EnumProperty(
name="X",
items=[("1", "Left", "", 0), ("-0.5", "Centered", "", 1), ("-1", "Right", "", 2)],
default="-1",
)
justifyy: EnumProperty(
justify_y: EnumProperty(
name="Y",
items=[
("1", "Bottom", "", 0),
@ -1479,7 +1479,7 @@ class DoBasRelief(bpy.types.Operator):
],
default="-1",
)
justifyz: EnumProperty(
justify_z: EnumProperty(
name="Z",
items=[
("-1", "Below 0", "", 0),
@ -1643,9 +1643,9 @@ class DoBasRelief(bpy.types.Operator):
self.view_layer_name = bpy.context.view_layer.name
try:
renderScene(
self.widthmm,
self.heightmm,
render_scene(
self.width_mm,
self.height_mm,
self.bit_diameter,
self.pass_per_radius,
not self.use_image_source,
@ -1798,5 +1798,5 @@ class ProblemAreas(bpy.types.Operator):
s = bpy.context.scene
br = s.basreliefsettings
problemAreas(br)
problem_areas(br)
return {"FINISHED"}

Wyświetl plik

@ -21,7 +21,7 @@ from . import utils
from . import simple
def addBridge(x, y, rot, sizex, sizey):
def add_bridge(x, y, rot, size_x, size_y):
"""Add a bridge mesh object to the scene.
This function creates a bridge by adding a primitive plane to the
@ -42,7 +42,7 @@ def addBridge(x, y, rot, sizex, sizey):
"""
bpy.ops.mesh.primitive_plane_add(
size=sizey * 2,
size=size_y * 2,
calc_uvs=True,
enter_editmode=False,
align="WORLD",
@ -52,12 +52,12 @@ def addBridge(x, y, rot, sizex, sizey):
b = bpy.context.active_object
b.name = "bridge"
# b.show_name=True
b.dimensions.x = sizex
b.dimensions.x = size_x
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
bpy.ops.object.editmode_toggle()
bpy.ops.transform.translate(
value=(0, sizey / 2, 0),
value=(0, size_y / 2, 0),
constraint_axis=(False, True, False),
orient_type="GLOBAL",
mirror=False,
@ -73,7 +73,7 @@ def addBridge(x, y, rot, sizex, sizey):
return b
def addAutoBridges(o):
def add_auto_bridges(o):
"""Attempt to add auto bridges as a set of curves.
This function creates a collection of bridges based on the provided
@ -93,7 +93,7 @@ def addAutoBridges(o):
Blender context by adding bridge objects to the specified
collection.
"""
utils.getOperationSources(o)
utils.get_operation_sources(o)
bridgecollectionname = o.bridges_collection_name
if bridgecollectionname == "" or bpy.data.collections.get(bridgecollectionname) is None:
bridgecollectionname = "bridges_" + o.name
@ -104,35 +104,39 @@ def addAutoBridges(o):
for ob in o.objects:
if ob.type == "CURVE" or ob.type == "TEXT":
curve = utils.curveToShapely(ob)
curve = utils.curve_to_shapely(ob)
if ob.type == "MESH":
curve = utils.getObjectSilhouete("OBJECTS", [ob])
curve = utils.get_object_silhouette("OBJECTS", [ob])
for c in curve.geoms:
c = c.exterior
minx, miny, maxx, maxy = c.bounds
d1 = c.project(sgeometry.Point(maxx + 1000, (maxy + miny) / 2.0))
p = c.interpolate(d1)
bo = addBridge(p.x, p.y, -pi / 2, o.bridges_width, o.cutter_diameter * 1)
bo = add_bridge(p.x, p.y, -pi / 2, o.bridges_width, o.cutter_diameter * 1)
g.objects.link(bo)
bpy.context.collection.objects.unlink(bo)
d1 = c.project(sgeometry.Point(minx - 1000, (maxy + miny) / 2.0))
p = c.interpolate(d1)
bo = addBridge(p.x, p.y, pi / 2, o.bridges_width, o.cutter_diameter * 1)
bo = add_bridge(p.x, p.y, pi / 2, o.bridges_width, o.cutter_diameter * 1)
g.objects.link(bo)
bpy.context.collection.objects.unlink(bo)
d1 = c.project(sgeometry.Point((minx + maxx) / 2.0, maxy + 1000))
p = c.interpolate(d1)
bo = addBridge(p.x, p.y, 0, o.bridges_width, o.cutter_diameter * 1)
bo = add_bridge(p.x, p.y, 0, o.bridges_width, o.cutter_diameter * 1)
g.objects.link(bo)
bpy.context.collection.objects.unlink(bo)
d1 = c.project(sgeometry.Point((minx + maxx) / 2.0, miny - 1000))
p = c.interpolate(d1)
bo = addBridge(p.x, p.y, pi, o.bridges_width, o.cutter_diameter * 1)
bo = add_bridge(p.x, p.y, pi, o.bridges_width, o.cutter_diameter * 1)
g.objects.link(bo)
bpy.context.collection.objects.unlink(bo)
def getBridgesPoly(o):
def get_bridges_poly(o):
"""Generate and prepare bridge polygons from a Blender object.
This function checks if the provided object has an attribute for bridge
@ -159,7 +163,7 @@ def getBridgesPoly(o):
bpy.ops.object.duplicate()
bpy.ops.object.join()
ob = bpy.context.active_object
shapes = utils.curveToShapely(ob, o.use_bridge_modifiers)
shapes = utils.curve_to_shapely(ob, o.use_bridge_modifiers)
ob.select_set(state=True)
bpy.ops.object.delete(use_global=False)
bridgespoly = sops.unary_union(shapes)
@ -171,7 +175,7 @@ def getBridgesPoly(o):
o.bridgespoly = prepared.prep(o.bridgespolyorig)
def useBridges(ch, o):
def use_bridges(ch, o):
"""Add bridges to chunks using a collection of bridge objects.
This function takes a collection of bridge objects and uses the curves
@ -199,7 +203,7 @@ def useBridges(ch, o):
if len(bridgecollection.objects) > 0:
# get bridgepoly
getBridgesPoly(o)
get_bridges_poly(o)
####
@ -318,7 +322,7 @@ def useBridges(ch, o):
edgelength = hypot(x - x2, y - y2)
if edgelength > o.bridges_width:
# make new vertex
verts.append(((x + x2) / 2, (y + y2) / 2, o.minz))
verts.append(((x + x2) / 2, (y + y2) / 2, o.min_z))
isedge += 1
edge = [count - 2, count - 1]
@ -327,7 +331,7 @@ def useBridges(ch, o):
else:
x2 = x
y2 = y
verts.append((x, y, o.minz)) # make new vertex
verts.append((x, y, o.min_z)) # make new vertex
isedge += 1
if isedge > 1: # Two points make an edge
edge = [count - 2, count - 1]

Wyświetl plik

@ -23,14 +23,14 @@ from mathutils import Vector
from . import polygon_utils_cam
from .simple import (
activate,
dist2d,
distance_2d,
progress,
)
from .exception import CamException
from .numba_wrapper import jit
def Rotate_pbyp(originp, p, ang): # rotate point around another point with angle
def rotate_point_by_point(originp, p, ang): # rotate point around another point with angle
ox, oy, oz = originp
px, py, oz = p
@ -46,7 +46,7 @@ def Rotate_pbyp(originp, p, ang): # rotate point around another point with angl
@jit(nopython=True, parallel=True, fastmath=True, cache=True)
def _internalXyDistanceTo(ourpoints, theirpoints, cutoff):
def _internal_x_y_distance_to(ourpoints, theirpoints, cutoff):
v1 = ourpoints[0]
v2 = theirpoints[0]
minDistSq = (v1[0] - v2[0]) ** 2 + (v1[1] - v2[1]) ** 2
@ -61,7 +61,7 @@ def _internalXyDistanceTo(ourpoints, theirpoints, cutoff):
# for building points - stores points as lists for easy insert /append behaviour
class camPathChunkBuilder:
class CamPathChunkBuilder:
def __init__(self, inpoints=None, startpoints=None, endpoints=None, rotations=None):
if inpoints is None:
inpoints = []
@ -72,7 +72,7 @@ class camPathChunkBuilder:
self.depth = None
def to_chunk(self):
chunk = camPathChunk(self.points, self.startpoints, self.endpoints, self.rotations)
chunk = CamPathChunk(self.points, self.startpoints, self.endpoints, self.rotations)
if len(self.points) > 2 and np.array_equal(self.points[0], self.points[-1]):
chunk.closed = True
if self.depth is not None:
@ -84,7 +84,7 @@ class camPathChunkBuilder:
# an actual chunk - stores points as numpy arrays
class camPathChunk:
class CamPathChunk:
# parents=[]
# children=[]
# sorted=False
@ -144,7 +144,7 @@ class camPathChunk:
return len(self.points)
def copy(self):
nchunk = camPathChunk(
nchunk = CamPathChunk(
inpoints=self.points.copy(),
startpoints=self.startpoints,
endpoints=self.endpoints,
@ -164,45 +164,45 @@ class camPathChunk:
for i, p in enumerate(self.endpoints):
self.endpoints[i] = (p[0] + x, p[1] + y, p[2] + z)
def setZ(self, z, if_bigger=False):
def set_z(self, z, if_bigger=False):
if if_bigger:
self.points[:, 2] = z if z > self.points[:, 2] else self.points[:, 2]
else:
self.points[:, 2] = z
def offsetZ(self, z):
def offset_z(self, z):
self.points[:, 2] += z
def flipX(self, x_centre):
def flip_x(self, x_centre):
self.points[:, 0] = x_centre - self.points[:, 0]
def isbelowZ(self, z):
def is_below_z(self, z):
return np.any(self.points[:, 2] < z)
def clampZ(self, z):
def clamp_z(self, z):
np.clip(self.points[:, 2], z, None, self.points[:, 2])
def clampmaxZ(self, z):
def clamp_max_z(self, z):
np.clip(self.points[:, 2], None, z, self.points[:, 2])
def dist(self, pos, o):
def distance(self, pos, o):
if self.closed:
dist_sq = (pos[0] - self.points[:, 0]) ** 2 + (pos[1] - self.points[:, 1]) ** 2
return sqrt(np.min(dist_sq))
else:
if o.movement.type == "MEANDER":
d1 = dist2d(pos, self.points[0])
d2 = dist2d(pos, self.points[-1])
d1 = distance_2d(pos, self.points[0])
d2 = distance_2d(pos, self.points[-1])
# if d2<d1:
# ch.points.reverse()
return min(d1, d2)
else:
return dist2d(pos, self.points[0])
return distance_2d(pos, self.points[0])
def distStart(self, pos, o):
return dist2d(pos, self.points[0])
def distance_start(self, pos, o):
return distance_2d(pos, self.points[0])
def xyDistanceWithin(self, other, cutoff):
def x_y_distance_within(self, other, cutoff):
if self.poly is None:
self.update_poly()
if other.poly is None:
@ -210,10 +210,10 @@ class camPathChunk:
if not self.poly.is_empty and not other.poly.is_empty:
return self.poly.dwithin(other.poly, cutoff)
else:
return _internalXyDistanceTo(self.points, other.points, cutoff) < cutoff
return _internal_x_y_distance_to(self.points, other.points, cutoff) < cutoff
# if cutoff is set, then the first distance < cutoff is returned
def xyDistanceTo(self, other, cutoff=0):
def x_y_distance_to(self, other, cutoff=0):
if self.poly is None:
self.update_poly()
if other.poly is None:
@ -229,9 +229,9 @@ class camPathChunk:
else: # this is the old method, preferably should be replaced in most cases except parallel
# where this method works probably faster.
# print('warning, sorting will be slow due to bad parenting in parentChildDist')
return _internalXyDistanceTo(self.points, other.points, cutoff)
return _internal_x_y_distance_to(self.points, other.points, cutoff)
def adaptdist(self, pos, o):
def adapt_distance(self, pos, o):
# reorders chunk so that it starts at the closest point to pos.
if self.closed:
dist_sq = (pos[0] - self.points[:, 0]) ** 2 + (pos[1] - self.points[:, 1]) ** 2
@ -240,12 +240,12 @@ class camPathChunk:
self.points = new_points
else:
if o.movement.type == "MEANDER":
d1 = dist2d(pos, self.points[0])
d2 = dist2d(pos, self.points[-1])
d1 = distance_2d(pos, self.points[0])
d2 = distance_2d(pos, self.points[-1])
if d2 < d1:
self.points = np.flip(self.points, axis=0)
def getNextClosest(self, o, pos):
def get_next_closest(self, o, pos):
# finds closest chunk that can be milled, when inside sorting hierarchy.
mind = 100000000000
@ -280,7 +280,7 @@ class camPathChunk:
# print('returning none')
return None
def getLength(self):
def get_length(self):
# computes length of the chunk - in 3d
point_differences = self.points[0:-1, :] - self.points[1:, :]
@ -301,7 +301,7 @@ class camPathChunk:
self.endpoints.pop(index)
self.rotations.pop(index)
def dedupePoints(self):
def dedupe_points(self):
if len(self.points) > 1:
keep_points = np.empty(self.points.shape[0], dtype=bool)
keep_points[0] = True
@ -369,12 +369,12 @@ class camPathChunk:
)
self.points = self.points[included_values]
def rampContour(self, zstart, zend, o):
def ramp_contour(self, zstart, zend, o):
stepdown = zstart - zend
chunk_points = []
estlength = (zstart - zend) / tan(o.movement.ramp_in_angle)
self.getLength()
self.get_length()
ramplength = estlength # min(ch.length,estlength)
ltraveled = 0
endpoint = None
@ -389,11 +389,11 @@ class camPathChunk:
if i > 0:
s2 = self.points[i - 1]
ltraveled += dist2d(s, s2)
ltraveled += distance_2d(s, s2)
ratio = ltraveled / ramplength
elif rounds > 0 and i == 0:
s2 = self.points[-1]
ltraveled += dist2d(s, s2)
ltraveled += distance_2d(s, s2)
ratio = ltraveled / ramplength
else:
ratio = 0
@ -444,7 +444,7 @@ class camPathChunk:
z = zend
# i=endpoint
while z < o.maxz:
while z < o.max_z:
if i == len(self.points):
i = 0
s1 = self.points[i]
@ -452,10 +452,10 @@ class camPathChunk:
if i2 < 0:
i2 = len(self.points) - 1
s2 = self.points[i2]
l = dist2d(s1, s2)
l = distance_2d(s1, s2)
znew = z + tan(o.movement.ramp_out_angle) * l
if znew > o.maxz:
ratio = (z - o.maxz) / (z - znew)
if znew > o.max_z:
ratio = (z - o.max_z) / (z - znew)
v1 = Vector(chunk_points[-1])
v2 = Vector((s1[0], s1[1], znew))
v = v1 + ratio * (v2 - v1)
@ -469,7 +469,7 @@ class camPathChunk:
# TODO: convert to numpy properly
self.points = np.array(chunk_points)
def rampZigZag(self, zstart, zend, o):
def ramp_zig_zag(self, zstart, zend, o):
# TODO: convert to numpy properly
if zend == None:
zend = self.points[0][2]
@ -481,7 +481,7 @@ class camPathChunk:
stepdown = zstart - zend
estlength = (zstart - zend) / tan(o.movement.ramp_in_angle)
self.getLength()
self.get_length()
if self.length > 0: # for single point chunks..
ramplength = estlength
zigzaglength = ramplength / 2.000
@ -502,7 +502,7 @@ class camPathChunk:
# print(i,zigzaglength,zigzagtraveled)
p1 = ramppoints[-1]
p2 = self.points[i]
d = dist2d(p1, p2)
d = distance_2d(p1, p2)
zigzagtraveled += d
if zigzagtraveled >= zigzaglength or i + 1 == len(self.points):
ratio = 1 - (zigzagtraveled - zigzaglength) / d
@ -532,7 +532,7 @@ class camPathChunk:
for p in range(0, len(ramppoints)):
p1 = chunk_points[-1]
p2 = ramppoints[p]
d = dist2d(p1, p2)
d = distance_2d(p1, p2)
traveled += d
ratio = traveled / ramplength
znew = zstart - stepdown * ratio
@ -546,14 +546,14 @@ class camPathChunk:
######################################
# ramp out - this is the same thing, just on the other side..
if o.movement.ramp_out:
zstart = o.maxz
zstart = o.max_z
zend = self.points[-1][2]
# again, sometimes a chunk could theoretically end above the starting level.
if zend < zstart:
stepdown = zstart - zend
estlength = (zstart - zend) / tan(o.movement.ramp_out_angle)
self.getLength()
self.get_length()
if self.length > 0:
ramplength = estlength
zigzaglength = ramplength / 2.000
@ -582,7 +582,7 @@ class camPathChunk:
# print(i,zigzaglength,zigzagtraveled)
p1 = ramppoints[-1]
p2 = self.points[i]
d = dist2d(p1, p2)
d = distance_2d(p1, p2)
zigzagtraveled += d
if zigzagtraveled >= zigzaglength or i + 1 == len(self.points):
ratio = 1 - (zigzagtraveled - zigzaglength) / d
@ -609,7 +609,7 @@ class camPathChunk:
for p in range(0, len(ramppoints)):
p1 = chunk_points[-1]
p2 = ramppoints[p]
d = dist2d(p1, p2)
d = distance_2d(p1, p2)
traveled += d
ratio = 1 - (traveled / ramplength)
znew = zstart - stepdown * ratio
@ -618,14 +618,14 @@ class camPathChunk:
self.points = np.array(chunk_points)
# modify existing path start point
def changePathStart(self, o):
def change_path_start(self, o):
if o.profile_start > 0:
newstart = o.profile_start
chunkamt = len(self.points)
newstart = newstart % chunkamt
self.points = np.concatenate((self.points[newstart:], self.points[:newstart]))
def breakPathForLeadinLeadout(self, o):
def break_path_for_leadin_leadout(self, o):
iradius = o.lead_in
oradius = o.lead_out
if iradius + oradius > 0:
@ -654,7 +654,7 @@ class camPathChunk:
)
)
def leadContour(self, o):
def lead_contour(self, o):
perimeterDirection = 1 # 1 is clockwise, 0 is CCW
if o.movement.spindle_rotation == "CW":
if o.movement.type == "CONVENTIONAL":
@ -672,7 +672,7 @@ class camPathChunk:
oradius = o.lead_out
start = self.points[0]
nextp = self.points[1]
rpoint = Rotate_pbyp(start, nextp, pi / 2)
rpoint = rotate_point_by_point(start, nextp, pi / 2)
dx = rpoint[0] - start[0]
dy = rpoint[1] - start[1]
la = hypot(dx, dy)
@ -687,7 +687,7 @@ class camPathChunk:
if round(o.lead_in, 6) > 0.0:
for i in range(15):
iangle = -i * (pi / 2) / 15
arc_p = Rotate_pbyp(arc_c, start, iangle)
arc_p = rotate_point_by_point(arc_c, start, iangle)
chunk_points.insert(0, arc_p)
# glue rest of the path to the arc
@ -699,13 +699,13 @@ class camPathChunk:
if round(o.lead_in, 6) > 0.0:
for i in range(15):
iangle = i * (pi / 2) / 15
arc_p = Rotate_pbyp(arc_c, start, iangle)
arc_p = rotate_point_by_point(arc_c, start, iangle)
chunk_points.append(arc_p)
self.points = np.array(chunk_points)
def chunksCoherency(chunks):
def chunks_coherency(chunks):
# checks chunks for their stability, for pencil path.
# it checks if the vectors direction doesn't jump too much too quickly,
# if this happens it splits the chunk on such places,
@ -714,7 +714,7 @@ def chunksCoherency(chunks):
nchunks = []
for chunk in chunks:
if len(chunk.points) > 2:
nchunk = camPathChunkBuilder()
nchunk = CamPathChunkBuilder()
# doesn't check for 1 point chunks here, they shouldn't get here at all.
lastvec = Vector(chunk.points[1]) - Vector(chunk.points[0])
@ -726,7 +726,7 @@ def chunksCoherency(chunks):
if angle > 1.07: # 60 degrees is maximum toleration for pencil paths.
if len(nchunk.points) > 4: # this is a testing threshold
nchunks.append(nchunk.to_chunk())
nchunk = camPathChunkBuilder()
nchunk = CamPathChunkBuilder()
lastvec = vec
if len(nchunk.points) > 4: # this is a testing threshold
nchunk.points = np.array(nchunk.points)
@ -734,11 +734,11 @@ def chunksCoherency(chunks):
return nchunks
def setChunksZ(chunks, z):
def set_chunks_z(chunks, z):
newchunks = []
for ch in chunks:
chunk = ch.copy()
chunk.setZ(z)
chunk.set_z(z)
newchunks.append(chunk)
return newchunks
@ -809,7 +809,7 @@ def _optimize_internal(points, keep_points, e, protect_vertical, protect_vertica
prev_i = i
def optimizeChunk(chunk, operation):
def optimize_chunk(chunk, operation):
if len(chunk.points) > 2:
points = chunk.points
naxispoints = False
@ -845,13 +845,13 @@ def optimizeChunk(chunk, operation):
return chunk
def limitChunks(chunks, o, force=False): # TODO: this should at least add point on area border...
def limit_chunks(chunks, o, force=False): # TODO: this should at least add point on area border...
# but shouldn't be needed at all at the first place...
if o.use_limit_curve or force:
nchunks = []
for ch in chunks:
prevsampled = True
nch = camPathChunkBuilder()
nch = CamPathChunkBuilder()
nch1 = None
closed = True
for s in ch.points:
@ -862,7 +862,7 @@ def limitChunks(chunks, o, force=False): # TODO: this should at least add point
nchunks.append(nch.to_chunk())
if nch1 is None:
nch1 = nchunks[-1]
nch = camPathChunkBuilder()
nch = CamPathChunkBuilder()
elif sampled:
nch.points.append(s)
prevsampled = sampled
@ -890,7 +890,7 @@ def limitChunks(chunks, o, force=False): # TODO: this should at least add point
return chunks
def parentChildPoly(parents, children, o):
def parent_child_poly(parents, children, o):
# hierarchy based on polygons - a polygon inside another is his child.
# hierarchy works like this: - children get milled first.
@ -906,12 +906,12 @@ def parentChildPoly(parents, children, o):
child.parents.append(parent)
def parentChildDist(parents, children, o, distance=None):
def parent_child_distance(parents, children, o, distance=None):
# parenting based on x,y distance between chunks
# hierarchy works like this: - children get milled first.
if distance is None:
dlim = o.dist_between_paths * 2
dlim = o.distance_between_paths * 2
if (o.strategy == "PARALLEL" or o.strategy == "CROSS") and o.movement.parallel_step_back:
dlim = dlim * 2
else:
@ -921,12 +921,12 @@ def parentChildDist(parents, children, o, distance=None):
for parent in parents:
isrelation = False
if parent != child:
if parent.xyDistanceWithin(child, cutoff=dlim):
if parent.x_y_distance_within(child, cutoff=dlim):
parent.children.append(child)
child.parents.append(parent)
def parentChild(parents, children, o):
def parent_child(parents, children, o):
# connect all children to all parents. Useful for any type of defining hierarchy.
# hierarchy works like this: - children get milled first.
@ -938,7 +938,7 @@ def parentChild(parents, children, o):
# this does more cleve chunks to Poly with hierarchies... ;)
def chunksToShapely(chunks):
def chunks_to_shapely(chunks):
# print ('analyzing paths')
for ch in chunks: # first convert chunk to poly
if len(ch.points) > 2:
@ -1077,11 +1077,11 @@ def chunksToShapely(chunks):
return polys
def meshFromCurveToChunk(object):
def mesh_from_curve_to_chunk(object):
mesh = object.data
# print('detecting contours from curve')
chunks = []
chunk = camPathChunkBuilder()
chunk = CamPathChunkBuilder()
ek = mesh.edge_keys
d = {}
for e in ek:
@ -1110,11 +1110,11 @@ def meshFromCurveToChunk(object):
# add first point to end#originally the z was mesh.vertices[lastvi].co.z+z
lastvi = vi + 1
chunk = chunk.to_chunk()
chunk.dedupePoints()
chunk.dedupe_points()
if chunk.count() >= 1:
# dump single point chunks
chunks.append(chunk)
chunk = camPathChunkBuilder()
chunk = CamPathChunkBuilder()
progress("Processing Curve - FINISHED")
@ -1136,14 +1136,14 @@ def meshFromCurveToChunk(object):
)
)
chunk = chunk.to_chunk()
chunk.dedupePoints()
chunk.dedupe_points()
if chunk.count() >= 1:
# dump single point chunks
chunks.append(chunk)
return chunks
def makeVisible(o):
def make_visible(o):
storage = [True, []]
if not o.visible_get():
@ -1161,14 +1161,14 @@ def makeVisible(o):
return storage
def restoreVisibility(o, storage):
def restore_visibility(o, storage):
o.hide_viewport = storage[0]
# print(storage)
for i in range(0, 20):
o.layers[i] = storage[1][i]
def meshFromCurve(o, use_modifiers=False):
def mesh_from_curve(o, use_modifiers=False):
activate(o)
bpy.ops.object.duplicate()
@ -1209,9 +1209,9 @@ def meshFromCurve(o, use_modifiers=False):
return bpy.context.active_object
def curveToChunks(o, use_modifiers=False):
co = meshFromCurve(o, use_modifiers)
chunks = meshFromCurveToChunk(co)
def curve_to_chunks(o, use_modifiers=False):
co = mesh_from_curve(o, use_modifiers)
chunks = mesh_from_curve_to_chunk(co)
co = bpy.context.active_object
@ -1222,15 +1222,15 @@ def curveToChunks(o, use_modifiers=False):
return chunks
def shapelyToChunks(p, zlevel): #
def shapely_to_chunks(p, zlevel): #
chunk_builders = []
# p=sortContours(p)
seq = polygon_utils_cam.shapelyToCoords(p)
seq = polygon_utils_cam.shapely_to_coordinates(p)
i = 0
for s in seq:
# progress(p[i])
if len(s) > 1:
chunk = camPathChunkBuilder([])
chunk = CamPathChunkBuilder([])
for v in s:
if p.has_z:
chunk.points.append((v[0], v[1], v[2]))
@ -1243,12 +1243,12 @@ def shapelyToChunks(p, zlevel): #
return [c.to_chunk() for c in chunk_builders]
def chunkToShapely(chunk):
def chunk_to_shapely(chunk):
p = spolygon.Polygon(chunk.points)
return p
def chunksRefine(chunks, o):
def chunks_refine(chunks, o):
"""Add Extra Points in Between for Chunks"""
for ch in chunks:
# print('before',len(ch))
@ -1260,7 +1260,7 @@ def chunksRefine(chunks, o):
v1 = Vector(s)
v = v1 - v2
if v.length > o.dist_along_paths:
if v.length > o.distance_along_paths:
d = v.length
v.normalize()
i = 0
@ -1268,7 +1268,7 @@ def chunksRefine(chunks, o):
while vref.length < d:
i += 1
vref = v * o.dist_along_paths * i
vref = v * o.distance_along_paths * i
if vref.length < d:
p = v2 + vref
@ -1281,7 +1281,7 @@ def chunksRefine(chunks, o):
return chunks
def chunksRefineThreshold(chunks, distance, limitdistance):
def chunks_refine_threshold(chunks, distance, limitdistance):
"""Add Extra Points in Between for Chunks. for Medial Axis Strategy only!"""
for ch in chunks:
newchunk = []

Wyświetl plik

@ -22,18 +22,18 @@ from bpy.types import (
)
from . import constants
from .utils import (
getStrategyList,
operationValid,
get_strategy_list,
operation_valid,
update_operation,
updateBridges,
updateChipload,
updateCutout,
updateOffsetImage,
updateOperationValid,
updateRest,
updateRotation,
updateStrategy,
updateZbufferImage,
update_bridges,
update_chipload,
update_cutout,
update_offset_image,
update_operation_valid,
update_rest,
update_rotation,
update_strategy,
update_Z_buffer_image,
)
from .ui.panels.info import CAM_INFO_Properties
from .ui.panels.material import CAM_MATERIAL_Properties
@ -41,7 +41,7 @@ from .ui.panels.movement import CAM_MOVEMENT_Properties
from .ui.panels.optimisation import CAM_OPTIMISATION_Properties
class camOperation(PropertyGroup):
class CamOperation(PropertyGroup):
material: PointerProperty(type=CAM_MATERIAL_Properties)
info: PointerProperty(type=CAM_INFO_Properties)
@ -51,12 +51,12 @@ class camOperation(PropertyGroup):
name: StringProperty(
name="Operation Name",
default="Operation",
update=updateRest,
update=update_rest,
)
filename: StringProperty(
name="File Name",
default="Operation",
update=updateRest,
update=update_rest,
)
auto_export: BoolProperty(
name="Auto Export",
@ -68,7 +68,7 @@ class camOperation(PropertyGroup):
description="Remove redundant points sharing the same angle" " as the start vector",
default=False,
)
simplify_tol: IntProperty(
simplify_tolerance: IntProperty(
name="Tolerance",
description="lower number means more precise",
default=50,
@ -89,28 +89,28 @@ class camOperation(PropertyGroup):
object_name: StringProperty(
name="Object",
description="Object handled by this operation",
update=updateOperationValid,
update=update_operation_valid,
)
collection_name: StringProperty(
name="Collection",
description="Object collection handled by this operation",
update=updateOperationValid,
update=update_operation_valid,
)
curve_object: StringProperty(
curve_source: StringProperty(
name="Curve Source",
description="Curve which will be sampled along the 3D object",
update=operationValid,
update=operation_valid,
)
curve_object1: StringProperty(
curve_target: StringProperty(
name="Curve Target",
description="Curve which will serve as attractor for the "
"cutter when the cutter follows the curve",
update=operationValid,
update=operation_valid,
)
source_image_name: StringProperty(
name="Image Source",
description="image source",
update=operationValid,
update=operation_valid,
)
geometry_source: EnumProperty(
name="Data Source",
@ -121,7 +121,7 @@ class camOperation(PropertyGroup):
),
description="Geometry source",
default="OBJECT",
update=updateOperationValid,
update=update_operation_valid,
)
cutter_type: EnumProperty(
name="Cutter",
@ -138,14 +138,13 @@ class camOperation(PropertyGroup):
),
description="Type of cutter used",
default="END",
update=updateZbufferImage,
update=update_Z_buffer_image,
)
cutter_object_name: StringProperty(
name="Cutter Object",
description="Object used as custom cutter for this operation",
update=updateZbufferImage,
update=update_Z_buffer_image,
)
machine_axes: EnumProperty(
name="Number of Axes",
items=(
@ -155,16 +154,15 @@ class camOperation(PropertyGroup):
),
description="How many axes will be used for the operation",
default="3",
update=updateStrategy,
update=update_strategy,
)
strategy: EnumProperty(
name="Strategy",
items=getStrategyList,
items=get_strategy_list,
description="Strategy",
update=updateStrategy,
update=update_strategy,
)
strategy4axis: EnumProperty(
strategy_4_axis: EnumProperty(
name="4 Axis Strategy",
items=(
(
@ -183,16 +181,15 @@ class camOperation(PropertyGroup):
),
description="#Strategy",
default="PARALLEL",
update=updateStrategy,
update=update_strategy,
)
strategy5axis: EnumProperty(
strategy_5_axis: EnumProperty(
name="Strategy",
items=(("INDEXED", "Indexed 3-axis", "All 3 axis strategies, just rotated by 4+5th axes"),),
description="5 axis Strategy",
default="INDEXED",
update=updateStrategy,
update=update_strategy,
)
rotary_axis_1: EnumProperty(
name="Rotary Axis",
items=(
@ -202,7 +199,7 @@ class camOperation(PropertyGroup):
),
description="Around which axis rotates the first rotary axis",
default="X",
update=updateStrategy,
update=update_strategy,
)
rotary_axis_2: EnumProperty(
name="Rotary Axis 2",
@ -213,9 +210,8 @@ class camOperation(PropertyGroup):
),
description="Around which axis rotates the second rotary axis",
default="Z",
update=updateStrategy,
update=update_strategy,
)
skin: FloatProperty(
name="Skin",
description="Material to leave when roughing ",
@ -224,19 +220,19 @@ class camOperation(PropertyGroup):
default=0.0,
precision=constants.PRECISION,
unit="LENGTH",
update=updateOffsetImage,
update=update_offset_image,
)
inverse: BoolProperty(
name="Inverse Milling",
description="Male to female model conversion",
default=False,
update=updateOffsetImage,
update=update_offset_image,
)
array: BoolProperty(
name="Use Array",
description="Create a repetitive array for producing the " "same thing many times",
default=False,
update=updateRest,
update=update_rest,
)
array_x_count: IntProperty(
name="X Count",
@ -244,7 +240,7 @@ class camOperation(PropertyGroup):
default=1,
min=1,
max=32000,
update=updateRest,
update=update_rest,
)
array_y_count: IntProperty(
name="Y Count",
@ -252,7 +248,7 @@ class camOperation(PropertyGroup):
default=1,
min=1,
max=32000,
update=updateRest,
update=update_rest,
)
array_x_distance: FloatProperty(
name="X Distance",
@ -262,7 +258,7 @@ class camOperation(PropertyGroup):
default=0.01,
precision=constants.PRECISION,
unit="LENGTH",
update=updateRest,
update=update_rest,
)
array_y_distance: FloatProperty(
name="Y Distance",
@ -272,19 +268,17 @@ class camOperation(PropertyGroup):
default=0.01,
precision=constants.PRECISION,
unit="LENGTH",
update=updateRest,
update=update_rest,
)
# pocket options
pocket_option: EnumProperty(
name="Start Position",
items=(("INSIDE", "Inside", "a"), ("OUTSIDE", "Outside", "a")),
description="Pocket starting position",
default="INSIDE",
update=updateRest,
update=update_rest,
)
pocketType: EnumProperty(
pocket_type: EnumProperty(
name="pocket type",
items=(
("PERIMETER", "Perimeter", "a", "", 0),
@ -292,45 +286,42 @@ class camOperation(PropertyGroup):
),
description="Type of pocket",
default="PERIMETER",
update=updateRest,
update=update_rest,
)
parallelPocketAngle: FloatProperty(
parallel_pocket_angle: FloatProperty(
name="Parallel Pocket Angle",
description="Angle for parallel pocket",
min=-180,
max=180.0,
default=45.0,
precision=constants.PRECISION,
update=updateRest,
update=update_rest,
)
parallelPocketCrosshatch: BoolProperty(
parallel_pocket_crosshatch: BoolProperty(
name="Crosshatch #",
description="Crosshatch X finish",
default=False,
update=updateRest,
update=update_rest,
)
parallelPocketContour: BoolProperty(
parallel_pocket_contour: BoolProperty(
name="Contour Finish",
description="Contour path finish",
default=False,
update=updateRest,
update=update_rest,
)
pocketToCurve: BoolProperty(
pocket_to_curve: BoolProperty(
name="Pocket to Curve",
description="Generates a curve instead of a path",
default=False,
update=updateRest,
update=update_rest,
)
# Cutout
cut_type: EnumProperty(
name="Cut",
items=(("OUTSIDE", "Outside", "a"), ("INSIDE", "Inside", "a"), ("ONLINE", "On Line", "a")),
description="Type of cutter used",
default="OUTSIDE",
update=updateRest,
update=update_rest,
)
outlines_count: IntProperty(
name="Outlines Count",
@ -338,13 +329,13 @@ class camOperation(PropertyGroup):
default=1,
min=1,
max=32,
update=updateCutout,
update=update_cutout,
)
straight: BoolProperty(
name="Overshoot Style",
description="Use overshoot cutout instead of conventional rounded",
default=True,
update=updateRest,
update=update_rest,
)
# cutter
cutter_id: IntProperty(
@ -353,7 +344,7 @@ class camOperation(PropertyGroup):
min=0,
max=10000,
default=1,
update=updateRest,
update=update_rest,
)
cutter_diameter: FloatProperty(
name="Cutter Diameter",
@ -363,7 +354,7 @@ class camOperation(PropertyGroup):
default=0.003,
precision=constants.PRECISION,
unit="LENGTH",
update=updateOffsetImage,
update=update_offset_image,
)
cylcone_diameter: FloatProperty(
name="Bottom Diameter",
@ -373,7 +364,7 @@ class camOperation(PropertyGroup):
default=0.003,
precision=constants.PRECISION,
unit="LENGTH",
update=updateOffsetImage,
update=update_offset_image,
)
cutter_length: FloatProperty(
name="#Cutter Length",
@ -383,7 +374,7 @@ class camOperation(PropertyGroup):
default=25.0,
precision=constants.PRECISION,
unit="LENGTH",
update=updateOffsetImage,
update=update_offset_image,
)
cutter_flutes: IntProperty(
name="Cutter Flutes",
@ -391,7 +382,7 @@ class camOperation(PropertyGroup):
min=1,
max=20,
default=2,
update=updateChipload,
update=update_chipload,
)
cutter_tip_angle: FloatProperty(
name="Cutter V-carve Angle",
@ -400,7 +391,7 @@ class camOperation(PropertyGroup):
max=180.0,
default=60.0,
precision=constants.PRECISION,
update=updateOffsetImage,
update=update_offset_image,
)
ball_radius: FloatProperty(
name="Ball Radius",
@ -410,7 +401,7 @@ class camOperation(PropertyGroup):
default=0.001,
unit="LENGTH",
precision=constants.PRECISION,
update=updateOffsetImage,
update=update_offset_image,
)
# ball_cone_flute: FloatProperty(name="BallCone Flute Length", description="length of flute", min=0.0,
# max=0.1, default=0.017, unit="LENGTH", precision=constants.PRECISION, update=updateOffsetImage)
@ -422,69 +413,69 @@ class camOperation(PropertyGroup):
default=0.005,
unit="LENGTH",
precision=constants.PRECISION,
update=updateOffsetImage,
update=update_offset_image,
)
cutter_description: StringProperty(
name="Tool Description",
default="",
update=updateOffsetImage,
update=update_offset_image,
)
Laser_on: StringProperty(
laser_on: StringProperty(
name="Laser ON String",
default="M68 E0 Q100",
)
Laser_off: StringProperty(
laser_off: StringProperty(
name="Laser OFF String",
default="M68 E0 Q0",
)
Laser_cmd: StringProperty(
laser_cmd: StringProperty(
name="Laser Command",
default="M68 E0 Q",
)
Laser_delay: FloatProperty(
laser_delay: FloatProperty(
name="Laser ON Delay",
description="Time after fast move to turn on laser and " "let machine stabilize",
default=0.2,
)
Plasma_on: StringProperty(
plasma_on: StringProperty(
name="Plasma ON String",
default="M03",
)
Plasma_off: StringProperty(
plasma_off: StringProperty(
name="Plasma OFF String",
default="M05",
)
Plasma_delay: FloatProperty(
plasma_delay: FloatProperty(
name="Plasma ON Delay",
description="Time after fast move to turn on Plasma and " "let machine stabilize",
default=0.1,
)
Plasma_dwell: FloatProperty(
plasma_dwell: FloatProperty(
name="Plasma Dwell Time",
description="Time to dwell and warm up the torch",
default=0.0,
)
# steps
dist_between_paths: FloatProperty(
distance_between_paths: FloatProperty(
name="Distance Between Toolpaths",
default=0.001,
min=0.00001,
max=32,
precision=constants.PRECISION,
unit="LENGTH",
update=updateRest,
update=update_rest,
)
dist_along_paths: FloatProperty(
distance_along_paths: FloatProperty(
name="Distance Along Toolpaths",
default=0.0002,
min=0.00001,
max=32,
precision=constants.PRECISION,
unit="LENGTH",
update=updateRest,
update=update_rest,
)
parallel_angle: FloatProperty(
name="Angle of Paths",
@ -494,10 +485,10 @@ class camOperation(PropertyGroup):
precision=0,
subtype="ANGLE",
unit="ROTATION",
update=updateRest,
update=update_rest,
)
old_rotation_A: FloatProperty(
old_rotation_a: FloatProperty(
name="A Axis Angle",
description="old value of Rotate A axis\nto specified angle",
default=0,
@ -506,10 +497,10 @@ class camOperation(PropertyGroup):
precision=0,
subtype="ANGLE",
unit="ROTATION",
update=updateRest,
update=update_rest,
)
old_rotation_B: FloatProperty(
old_rotation_b: FloatProperty(
name="A Axis Angle",
description="old value of Rotate A axis\nto specified angle",
default=0,
@ -518,10 +509,10 @@ class camOperation(PropertyGroup):
precision=0,
subtype="ANGLE",
unit="ROTATION",
update=updateRest,
update=update_rest,
)
rotation_A: FloatProperty(
rotation_a: FloatProperty(
name="A Axis Angle",
description="Rotate A axis\nto specified angle",
default=0,
@ -530,22 +521,22 @@ class camOperation(PropertyGroup):
precision=0,
subtype="ANGLE",
unit="ROTATION",
update=updateRotation,
update=update_rotation,
)
enable_A: BoolProperty(
enable_a_axis: BoolProperty(
name="Enable A Axis",
description="Rotate A axis",
default=False,
update=updateRotation,
update=update_rotation,
)
A_along_x: BoolProperty(
a_along_x: BoolProperty(
name="A Along X ",
description="A Parallel to X",
default=True,
update=updateRest,
update=update_rest,
)
rotation_B: FloatProperty(
rotation_b: FloatProperty(
name="B Axis Angle",
description="Rotate B axis\nto specified angle",
default=0,
@ -554,13 +545,13 @@ class camOperation(PropertyGroup):
precision=0,
subtype="ANGLE",
unit="ROTATION",
update=updateRotation,
update=update_rotation,
)
enable_B: BoolProperty(
enable_b_axis: BoolProperty(
name="Enable B Axis",
description="Rotate B axis",
default=False,
update=updateRotation,
update=update_rotation,
)
# carve only
@ -571,7 +562,7 @@ class camOperation(PropertyGroup):
max=32,
precision=constants.PRECISION,
unit="LENGTH",
update=updateRest,
update=update_rest,
)
# drill only
@ -584,7 +575,7 @@ class camOperation(PropertyGroup):
),
description="Strategy to detect holes to drill",
default="MIDDLE_SYMETRIC",
update=updateRest,
update=update_rest,
)
# waterline only
slice_detail: FloatProperty(
@ -594,19 +585,19 @@ class camOperation(PropertyGroup):
max=32,
precision=constants.PRECISION,
unit="LENGTH",
update=updateRest,
update=update_rest,
)
waterline_fill: BoolProperty(
name="Fill Areas Between Slices",
description="Fill areas between slices in waterline mode",
default=True,
update=updateRest,
update=update_rest,
)
waterline_project: BoolProperty(
name="Project Paths - Not Recomended",
description="Project paths in areas between slices",
default=True,
update=updateRest,
update=update_rest,
)
# movement and ramps
@ -614,7 +605,7 @@ class camOperation(PropertyGroup):
name="Use Layers",
description="Use layers for roughing",
default=True,
update=updateRest,
update=update_rest,
)
stepdown: FloatProperty(
name="",
@ -624,7 +615,7 @@ class camOperation(PropertyGroup):
max=32,
precision=constants.PRECISION,
unit="LENGTH",
update=updateRest,
update=update_rest,
)
lead_in: FloatProperty(
name="Lead-in Radius",
@ -649,22 +640,22 @@ class camOperation(PropertyGroup):
description="Start point offset",
min=0,
default=0,
update=updateRest,
update=update_rest,
)
# helix_angle: FloatProperty(name="Helix ramp angle", default=3*pi/180, min=0.00001, max=pi*0.4999,precision=1, subtype="ANGLE" , unit="ROTATION" , update = updateRest)
minz: FloatProperty(
min_z: FloatProperty(
name="Operation Depth End",
default=-0.01,
min=-3,
max=3,
precision=constants.PRECISION,
unit="LENGTH",
update=updateRest,
update=update_rest,
)
minz_from: EnumProperty(
min_z_from: EnumProperty(
name="Max Depth From",
description="Set maximum operation depth",
items=(
@ -673,7 +664,7 @@ class camOperation(PropertyGroup):
("CUSTOM", "Custom", "Custom max depth"),
),
default="OBJECT",
update=updateRest,
update=update_rest,
)
start_type: EnumProperty(
@ -688,10 +679,10 @@ class camOperation(PropertyGroup):
),
description="Starting depth",
default="ZLEVEL",
update=updateStrategy,
update=update_strategy,
)
maxz: FloatProperty(
max_z: FloatProperty(
name="Operation Depth Start",
description="operation starting depth",
default=0,
@ -699,7 +690,7 @@ class camOperation(PropertyGroup):
max=10,
precision=constants.PRECISION,
unit="LENGTH",
update=updateRest,
update=update_rest,
) # EXPERIMENTAL
first_down: BoolProperty(
@ -720,7 +711,7 @@ class camOperation(PropertyGroup):
max=1,
precision=constants.PRECISION,
unit="LENGTH",
update=updateZbufferImage,
update=update_Z_buffer_image,
)
source_image_size_x: FloatProperty(
name="Image Source X Size",
@ -729,7 +720,7 @@ class camOperation(PropertyGroup):
max=10,
precision=constants.PRECISION,
unit="LENGTH",
update=updateZbufferImage,
update=update_Z_buffer_image,
)
source_image_offset: FloatVectorProperty(
name="Image Offset",
@ -737,7 +728,7 @@ class camOperation(PropertyGroup):
unit="LENGTH",
precision=constants.PRECISION,
subtype="XYZ",
update=updateZbufferImage,
update=update_Z_buffer_image,
)
source_image_crop: BoolProperty(
@ -746,7 +737,7 @@ class camOperation(PropertyGroup):
"is relative to the whole image, so it can be used for e.g. "
"finishing just a part of an image",
default=False,
update=updateZbufferImage,
update=update_Z_buffer_image,
)
source_image_crop_start_x: FloatProperty(
name="Crop Start X",
@ -755,7 +746,7 @@ class camOperation(PropertyGroup):
max=100,
precision=constants.PRECISION,
subtype="PERCENTAGE",
update=updateZbufferImage,
update=update_Z_buffer_image,
)
source_image_crop_start_y: FloatProperty(
name="Crop Start Y",
@ -764,7 +755,7 @@ class camOperation(PropertyGroup):
max=100,
precision=constants.PRECISION,
subtype="PERCENTAGE",
update=updateZbufferImage,
update=update_Z_buffer_image,
)
source_image_crop_end_x: FloatProperty(
name="Crop End X",
@ -773,7 +764,7 @@ class camOperation(PropertyGroup):
max=100,
precision=constants.PRECISION,
subtype="PERCENTAGE",
update=updateZbufferImage,
update=update_Z_buffer_image,
)
source_image_crop_end_y: FloatProperty(
name="Crop End Y",
@ -782,7 +773,7 @@ class camOperation(PropertyGroup):
max=100,
precision=constants.PRECISION,
subtype="PERCENTAGE",
update=updateZbufferImage,
update=update_Z_buffer_image,
)
#########################################################
@ -794,7 +785,7 @@ class camOperation(PropertyGroup):
items=(("ALL", "All", "a"), ("AROUND", "Around", "a")),
description="Handling ambient surfaces",
default="ALL",
update=updateZbufferImage,
update=update_Z_buffer_image,
)
ambient_radius: FloatProperty(
@ -805,26 +796,26 @@ class camOperation(PropertyGroup):
default=0.01,
precision=constants.PRECISION,
unit="LENGTH",
update=updateRest,
update=update_rest,
)
# ambient_cutter = EnumProperty(name='Borders',items=(('EXTRAFORCUTTER', 'Extra for cutter', "Extra space for cutter is cut around the segment"),('ONBORDER', "Cutter on edge", "Cutter goes exactly on edge of ambient with it's middle") ,('INSIDE', "Inside segment", 'Cutter stays within segment') ),description='handling of ambient and cutter size',default='INSIDE')
use_limit_curve: BoolProperty(
name="Use Limit Curve",
description="A curve limits the operation area",
default=False,
update=updateRest,
update=update_rest,
)
ambient_cutter_restrict: BoolProperty(
name="Cutter Stays in Ambient Limits",
description="Cutter doesn't get out from ambient limits otherwise "
"goes on the border exactly",
default=True,
update=updateRest,
update=update_rest,
) # restricts cutter inside ambient only
limit_curve: StringProperty(
name="Limit Curve",
description="Curve used to limit the area of the operation",
update=updateRest,
update=update_rest,
)
# feeds
@ -836,7 +827,7 @@ class camOperation(PropertyGroup):
default=1.0,
precision=constants.PRECISION,
unit="LENGTH",
update=updateChipload,
update=update_chipload,
)
plunge_feedrate: FloatProperty(
name="Plunge Speed",
@ -846,7 +837,7 @@ class camOperation(PropertyGroup):
default=50.0,
precision=1,
subtype="PERCENTAGE",
update=updateRest,
update=update_rest,
)
plunge_angle: FloatProperty(
name="Plunge Angle",
@ -857,7 +848,7 @@ class camOperation(PropertyGroup):
precision=0,
subtype="ANGLE",
unit="ROTATION",
update=updateRest,
update=update_rest,
)
spindle_rpm: FloatProperty(
name="Spindle RPM",
@ -865,7 +856,7 @@ class camOperation(PropertyGroup):
min=0,
max=60000,
default=12000,
update=updateChipload,
update=update_chipload,
)
# optimization and performance
@ -874,14 +865,14 @@ class camOperation(PropertyGroup):
name="Adjust Feedrates with Simulation EXPERIMENTAL",
description="Adjust feedrates with simulation",
default=False,
update=updateRest,
update=update_rest,
)
dont_merge: BoolProperty(
name="Don't Merge Outlines when Cutting",
description="this is usefull when you want to cut around everything",
default=False,
update=updateRest,
update=update_rest,
)
pencil_threshold: FloatProperty(
@ -891,62 +882,62 @@ class camOperation(PropertyGroup):
max=1,
precision=constants.PRECISION,
unit="LENGTH",
update=updateRest,
update=update_rest,
)
crazy_threshold1: FloatProperty(
crazy_threshold_1: FloatProperty(
name="Min Engagement",
default=0.02,
min=0.00000001,
max=100,
precision=constants.PRECISION,
update=updateRest,
update=update_rest,
)
crazy_threshold5: FloatProperty(
name="Optimal Engagement",
default=0.3,
min=0.00000001,
max=100,
precision=constants.PRECISION,
update=updateRest,
)
crazy_threshold2: FloatProperty(
crazy_threshold_2: FloatProperty(
name="Max Engagement",
default=0.5,
min=0.00000001,
max=100,
precision=constants.PRECISION,
update=updateRest,
update=update_rest,
)
crazy_threshold3: FloatProperty(
crazy_threshold_3: FloatProperty(
name="Max Angle",
default=2,
min=0.00000001,
max=100,
precision=constants.PRECISION,
update=updateRest,
update=update_rest,
)
crazy_threshold4: FloatProperty(
crazy_threshold_4: FloatProperty(
name="Test Angle Step",
default=0.05,
min=0.00000001,
max=100,
precision=constants.PRECISION,
update=updateRest,
update=update_rest,
)
crazy_threshold_5: FloatProperty(
name="Optimal Engagement",
default=0.3,
min=0.00000001,
max=100,
precision=constants.PRECISION,
update=update_rest,
)
# Add pocket operation to medial axis
add_pocket_for_medial: BoolProperty(
name="Add Pocket Operation",
description="Clean unremoved material after medial axis",
default=True,
update=updateRest,
update=update_rest,
)
add_mesh_for_medial: BoolProperty(
name="Add Medial mesh",
description="Medial operation returns mesh for editing and " "further processing",
default=False,
update=updateRest,
update=update_rest,
)
####
medial_axis_threshold: FloatProperty(
@ -956,7 +947,7 @@ class camOperation(PropertyGroup):
max=100,
precision=constants.PRECISION,
unit="LENGTH",
update=updateRest,
update=update_rest,
)
medial_axis_subdivision: FloatProperty(
name="Fine Subdivision",
@ -965,7 +956,7 @@ class camOperation(PropertyGroup):
max=100,
precision=constants.PRECISION,
unit="LENGTH",
update=updateRest,
update=update_rest,
)
# calculations
@ -974,14 +965,14 @@ class camOperation(PropertyGroup):
name="Use Bridges / Tabs",
description="Use bridges in cutout",
default=False,
update=updateBridges,
update=update_bridges,
)
bridges_width: FloatProperty(
name="Bridge / Tab Width",
default=0.002,
unit="LENGTH",
precision=constants.PRECISION,
update=updateBridges,
update=update_bridges,
)
bridges_height: FloatProperty(
name="Bridge / Tab Height",
@ -989,19 +980,19 @@ class camOperation(PropertyGroup):
default=0.0005,
unit="LENGTH",
precision=constants.PRECISION,
update=updateBridges,
update=update_bridges,
)
bridges_collection_name: StringProperty(
name="Bridges / Tabs Collection",
description="Collection of curves used as bridges",
update=operationValid,
update=operation_valid,
)
use_bridge_modifiers: BoolProperty(
name="Use Bridge / Tab Modifiers",
description="Include bridge curve modifiers using render level when "
"calculating operation, does not effect original bridge data",
default=True,
update=updateBridges,
update=update_bridges,
)
# commented this - auto bridges will be generated, but not as a setting of the operation
@ -1022,7 +1013,7 @@ class camOperation(PropertyGroup):
description="Include mesh modifiers using render level when "
"calculating operation, does not effect original mesh",
default=True,
update=operationValid,
update=operation_valid,
)
# optimisation panel
@ -1146,12 +1137,12 @@ class camOperation(PropertyGroup):
description="Mark for update",
default=False,
)
update_zbufferimage_tag: BoolProperty(
update_z_buffer_image_tag: BoolProperty(
name="Mark Z-Buffer Image for Update",
description="Mark for update",
default=True,
)
update_offsetimage_tag: BoolProperty(
update_offset_image_tag: BoolProperty(
name="Mark Offset Image for Update",
description="Mark for update",
default=True,
@ -1177,7 +1168,7 @@ class camOperation(PropertyGroup):
description="True if operation is ok for calculation",
default=True,
)
changedata: StringProperty(
change_data: StringProperty(
name="Changedata",
description="change data for checking if stuff changed.",
)
@ -1194,7 +1185,7 @@ class camOperation(PropertyGroup):
description="Background process id",
default=-1,
)
outtext: StringProperty(
out_text: StringProperty(
name="Outtext",
description="outtext",
default="",

Wyświetl plik

@ -13,7 +13,7 @@ from bpy.types import PropertyGroup
# this type is defined just to hold reference to operations for chains
class opReference(PropertyGroup):
class OpReference(PropertyGroup):
name: StringProperty(
name="Operation Name",
default="Operation",
@ -22,7 +22,7 @@ class opReference(PropertyGroup):
# chain is just a set of operations which get connected on export into 1 file.
class camChain(PropertyGroup):
class CamChain(PropertyGroup):
index: IntProperty(
name="Index",
description="Index in the hard-defined camChains",
@ -53,5 +53,5 @@ class camChain(PropertyGroup):
)
# this is to hold just operation names.
operations: CollectionProperty(
type=opReference,
type=OpReference,
)

Wyświetl plik

@ -24,12 +24,12 @@ from .constants import (
)
from .simple import (
activate,
delob,
delete_object,
progress,
)
def getCutterBullet(o):
def get_cutter_bullet(o):
"""Create a cutter for Rigidbody simulation collisions.
This function generates a 3D cutter object based on the specified cutter
@ -202,7 +202,7 @@ def getCutterBullet(o):
return cutter
def subdivideLongEdges(ob, threshold):
def subdivide_long_edges(ob, threshold):
"""Subdivide edges of a mesh object that exceed a specified length.
This function iteratively checks the edges of a given mesh object and
@ -263,7 +263,7 @@ def subdivideLongEdges(ob, threshold):
#
def prepareBulletCollision(o):
def prepare_bullet_collision(o):
"""Prepares all objects needed for sampling with Bullet collision.
This function sets up the Bullet physics simulation by preparing the
@ -324,7 +324,7 @@ def prepareBulletCollision(o):
# subdivide long edges here:
if o.optimisation.exact_subdivide_edges:
subdivideLongEdges(collisionob, o.cutter_diameter * 2)
subdivide_long_edges(collisionob, o.cutter_diameter * 2)
bpy.ops.rigidbody.object_add(type="ACTIVE")
# using active instead of passive because of performance.TODO: check if this works also with 4axis...
@ -349,7 +349,7 @@ def prepareBulletCollision(o):
if active_collection in collisionob.users_collection:
active_collection.objects.unlink(collisionob)
getCutterBullet(o)
get_cutter_bullet(o)
# machine objects scaling up to simulation scale
if bpy.data.objects.find("machine") > -1:
@ -374,7 +374,7 @@ def prepareBulletCollision(o):
progress(time.time() - t)
def cleanupBulletCollision(o):
def cleanup_bullet_collision(o):
"""Clean up bullet collision objects in the scene.
This function checks for the presence of a 'machine' object in the
@ -399,7 +399,7 @@ def cleanupBulletCollision(o):
if ob.rigid_body is not None and not (
machinepresent and ob.name in bpy.data.objects["machine"].objects
):
delob(ob)
delete_object(ob)
# machine objects scaling up to simulation scale
if machinepresent:
for ob in bpy.data.objects["machine"].objects:
@ -418,7 +418,7 @@ def cleanupBulletCollision(o):
ob.location = ob.location / BULLET_SCALE
def getSampleBullet(cutter, x, y, radius, startz, endz):
def get_sample_bullet(cutter, x, y, radius, startz, endz):
"""Perform a collision test for a 3-axis milling cutter.
This function simplifies the collision detection process compared to a
@ -455,7 +455,7 @@ def getSampleBullet(cutter, x, y, radius, startz, endz):
return endz - 10
def getSampleBulletNAxis(cutter, startpoint, endpoint, rotation, cutter_compensation):
def get_sample_bullet_n_axis(cutter, startpoint, endpoint, rotation, cutter_compensation):
"""Perform a fully 3D collision test for N-Axis milling.
This function computes the collision detection between a cutter and a

Wyświetl plik

@ -55,7 +55,7 @@ def generate_crosshatch(context, angle, distance, offset, pocket_shape, join, ob
bpy.ops.object.origin_set(type="ORIGIN_GEOMETRY", center="MEDIAN")
depth = ob.location[2]
shapes = utils.curveToShapely(ob)
shapes = utils.curve_to_shapely(ob)
if pocket_shape == "HULL":
shapes = shapes.convex_hull
@ -187,7 +187,7 @@ class CamCurveHatch(Operator):
self.pocket_shape,
join,
)
utils.shapelyToCurve("crosshatch_lines", xing, depth)
utils.shapely_to_curve("crosshatch_lines", xing, depth)
if self.xhatch:
simple.make_active(obname)
@ -199,7 +199,7 @@ class CamCurveHatch(Operator):
self.pocket_shape,
join,
)
utils.shapelyToCurve("crosshatch_lines_ra", xingra, depth)
utils.shapely_to_curve("crosshatch_lines_ra", xingra, depth)
bpy.ops.object.origin_set(type="ORIGIN_GEOMETRY", center="MEDIAN")
simple.join_multiple("crosshatch")
@ -400,7 +400,7 @@ class CamCurvePlate(Operator):
# select the circles for the four corners
simple.select_multiple("_circ")
# perform hull operation on the four corner circles
utils.polygonConvexHull(context)
utils.polygon_convex_hull(context)
simple.active_name("plate_base")
simple.remove_multiple("_circ") # remove corner circles
@ -568,7 +568,7 @@ class CamCurvePlate(Operator):
# select everything starting with _hole and perform a convex hull on them
simple.select_multiple("_hole")
utils.polygonConvexHull(context)
utils.polygon_convex_hull(context)
simple.active_name("plate_hole")
simple.move(y=-self.hole_vdist / 2)
simple.duplicate(y=self.hole_vdist)
@ -611,7 +611,7 @@ class CamCurvePlate(Operator):
# Make the plate base active
bpy.context.view_layer.objects.active = bpy.data.objects["plate_base"]
# Remove holes from the base
utils.polygonBoolean(context, "DIFFERENCE")
utils.polygon_boolean(context, "DIFFERENCE")
simple.remove_multiple("plate_") # Remove temporary base and holes
simple.remove_multiple("_")
@ -875,8 +875,8 @@ class CamCurveMortise(Operator):
# convert coordinates to shapely LineString datastructure
line = LineString(coords)
simple.remove_multiple("-converted")
utils.shapelyToCurve("-converted_curve", line, 0.0)
shapes = utils.curveToShapely(o1)
utils.shapely_to_curve("-converted_curve", line, 0.0)
shapes = utils.curve_to_shapely(o1)
for s in shapes.geoms:
if s.boundary.type == "LineString":
@ -1056,8 +1056,8 @@ class CamCurveInterlock(Operator):
# convert coordinates to shapely LineString datastructure
line = LineString(coords)
simple.remove_multiple("-converted")
utils.shapelyToCurve("-converted_curve", line, 0.0)
shapes = utils.curveToShapely(o1)
utils.shapely_to_curve("-converted_curve", line, 0.0)
shapes = utils.curve_to_shapely(o1)
for s in shapes.geoms:
if s.boundary.type == "LineString":
@ -1763,7 +1763,7 @@ class CamCurvePuzzle(Operator):
which=self.gender,
)
elif self.interlock_type == "CURVEBARCURVE":
puzzle_joinery.arcbararc(
puzzle_joinery.arc_bar_arc(
self.width,
self.radius,
self.height,
@ -1783,7 +1783,7 @@ class CamCurvePuzzle(Operator):
)
elif self.interlock_type == "CURVEBAR":
puzzle_joinery.arcbar(
puzzle_joinery.arc_bar(
self.width,
self.radius,
self.height,

Wyświetl plik

@ -63,7 +63,7 @@ class CamSineCurve(Operator):
precision=4,
unit="LENGTH",
)
beatperiod: FloatProperty(
beat_period: FloatProperty(
name="Beat Period Offset",
default=0.0,
min=0.0,
@ -93,7 +93,7 @@ class CamSineCurve(Operator):
min=50,
max=2000,
)
maxt: FloatProperty(
max_t: FloatProperty(
name="Wave Ends at X",
default=0.5,
min=-3.0,
@ -101,7 +101,7 @@ class CamSineCurve(Operator):
precision=4,
unit="LENGTH",
)
mint: FloatProperty(
min_t: FloatProperty(
name="Wave Starts at X",
default=0,
min=-3.0,
@ -135,27 +135,29 @@ class CamSineCurve(Operator):
def execute(self, context):
amp = self.amplitude
period = self.period
beatperiod = self.beatperiod
beatperiod = self.beat_period
offset = self.offset
shift = self.shift
# z=Asin(B(x+C))+D
if self.wave == "sine":
zstring = ssine(amp, period, dc_offset=offset, phase_shift=shift)
if self.beatperiod != 0:
zstring += f"+ {ssine(amp, period+beatperiod, dc_offset=offset, phase_shift=shift)}"
zstring = s_sine(amp, period, dc_offset=offset, phase_shift=shift)
if self.beat_period != 0:
zstring += (
f"+ {s_sine(amp, period+beatperiod, dc_offset=offset, phase_shift=shift)}"
)
# build triangle wave from fourier series
elif self.wave == "triangle":
zstring = f"{round(offset, 6) + triangle(80, period, amp)}"
if self.beatperiod != 0:
if self.beat_period != 0:
zstring += f"+ {triangle(80, period+beatperiod, amp)}"
elif self.wave == "cycloid":
zstring = f"abs({ssine(amp, period, dc_offset=offset, phase_shift=shift)})"
zstring = f"abs({s_sine(amp, period, dc_offset=offset, phase_shift=shift)})"
elif self.wave == "invcycloid":
zstring = f"-1 * abs({ssine(amp, period, dc_offset=offset, phase_shift=shift)})"
zstring = f"-1 * abs({s_sine(amp, period, dc_offset=offset, phase_shift=shift)})"
print(zstring)
# make equation from string
@ -180,8 +182,8 @@ class CamSineCurve(Operator):
parametric.create_parametric_curve(
f,
offset=self.wave_distance * i,
min=self.mint,
max=self.maxt,
min=self.min_t,
max=self.max_t,
use_cubic=True,
iterations=self.iteration,
angle_offset=angle_off,
@ -197,7 +199,7 @@ class CamLissajousCurve(Operator):
bl_label = "Lissajous Figure"
bl_options = {"REGISTER", "UNDO", "PRESET"}
amplitude_A: FloatProperty(
amplitude_a: FloatProperty(
name="Amplitude A",
default=0.1,
min=0,
@ -205,13 +207,13 @@ class CamLissajousCurve(Operator):
precision=4,
unit="LENGTH",
)
waveA: EnumProperty(
wave_a: EnumProperty(
name="Wave X",
items=(("sine", "Sine Wave", "Sine Wave"), ("triangle", "Triangle Wave", "triangle wave")),
default="sine",
)
amplitude_B: FloatProperty(
amplitude_b: FloatProperty(
name="Amplitude B",
default=0.1,
min=0,
@ -219,12 +221,12 @@ class CamLissajousCurve(Operator):
precision=4,
unit="LENGTH",
)
waveB: EnumProperty(
wave_b: EnumProperty(
name="Wave Y",
items=(("sine", "Sine Wave", "Sine Wave"), ("triangle", "Triangle Wave", "triangle wave")),
default="sine",
)
period_A: FloatProperty(
period_a: FloatProperty(
name="Period A",
default=1.1,
min=0.001,
@ -232,7 +234,7 @@ class CamLissajousCurve(Operator):
precision=4,
unit="LENGTH",
)
period_B: FloatProperty(
period_b: FloatProperty(
name="Period B",
default=1.0,
min=0.001,
@ -240,7 +242,7 @@ class CamLissajousCurve(Operator):
precision=4,
unit="LENGTH",
)
period_Z: FloatProperty(
period_z: FloatProperty(
name="Period Z",
default=1.0,
min=0.001,
@ -248,7 +250,7 @@ class CamLissajousCurve(Operator):
precision=4,
unit="LENGTH",
)
amplitude_Z: FloatProperty(
amplitude_z: FloatProperty(
name="Amplitude Z",
default=0.0,
min=0,
@ -271,7 +273,7 @@ class CamLissajousCurve(Operator):
min=50,
max=10000,
)
maxt: FloatProperty(
max_t: FloatProperty(
name="Wave Ends at X",
default=11,
min=-3.0,
@ -279,7 +281,7 @@ class CamLissajousCurve(Operator):
precision=4,
unit="LENGTH",
)
mint: FloatProperty(
min_t: FloatProperty(
name="Wave Starts at X",
default=0,
min=-10.0,
@ -291,17 +293,17 @@ class CamLissajousCurve(Operator):
def execute(self, context):
# x=Asin(at+delta ),y=Bsin(bt)
if self.waveA == "sine":
xstring = ssine(self.amplitude_A, self.period_A, phase_shift=self.shift)
elif self.waveA == "triangle":
xstring = f"{triangle(100, self.period_A, self.amplitude_A)}"
if self.wave_a == "sine":
xstring = s_sine(self.amplitude_a, self.period_a, phase_shift=self.shift)
elif self.wave_a == "triangle":
xstring = f"{triangle(100, self.period_a, self.amplitude_a)}"
if self.waveB == "sine":
ystring = ssine(self.amplitude_B, self.period_B)
elif self.waveB == "triangle":
ystring = f"{triangle(100, self.period_B, self.amplitude_B)}"
if self.wave_b == "sine":
ystring = s_sine(self.amplitude_b, self.period_b)
elif self.wave_b == "triangle":
ystring = f"{triangle(100, self.period_b, self.amplitude_b)}"
zstring = ssine(self.amplitude_Z, self.period_Z)
zstring = s_sine(self.amplitude_z, self.period_z)
# make equation from string
def x(t):
@ -322,7 +324,7 @@ class CamLissajousCurve(Operator):
return c
parametric.create_parametric_curve(
f, offset=0.0, min=self.mint, max=self.maxt, use_cubic=True, iterations=self.iteration
f, offset=0.0, min=self.min_t, max=self.max_t, use_cubic=True, iterations=self.iteration
)
return {"FINISHED"}
@ -431,17 +433,17 @@ class CamCustomCurve(Operator):
bl_label = "Custom Curve"
bl_options = {"REGISTER", "UNDO", "PRESET"}
xstring: StringProperty(
x_string: StringProperty(
name="X Equation",
description="Equation x=F(t)",
default="t",
)
ystring: StringProperty(
y_string: StringProperty(
name="Y Equation",
description="Equation y=F(t)",
default="0",
)
zstring: StringProperty(
z_string: StringProperty(
name="Z Equation",
description="Equation z=F(t)",
default="0.05*sin(2*pi*4*t)",
@ -453,7 +455,7 @@ class CamCustomCurve(Operator):
min=50,
max=2000,
)
maxt: FloatProperty(
max_t: FloatProperty(
name="Wave Ends at X",
default=0.5,
min=-3.0,
@ -461,7 +463,7 @@ class CamCustomCurve(Operator):
precision=4,
unit="LENGTH",
)
mint: FloatProperty(
min_t: FloatProperty(
name="Wave Starts at X",
default=0,
min=-3.0,
@ -471,19 +473,19 @@ class CamCustomCurve(Operator):
)
def execute(self, context):
print("x= " + self.xstring)
print("y= " + self.ystring)
print("z= " + self.zstring)
print("x= " + self.x_string)
print("y= " + self.y_string)
print("z= " + self.z_string)
# make equation from string
def ex(t):
return eval(self.xstring)
return eval(self.x_string)
def ey(t):
return eval(self.ystring)
return eval(self.y_string)
def ez(t):
return eval(self.zstring)
return eval(self.z_string)
# build function to be passed to create parametric curve ()
def f(t, offset: float = 0.0):
@ -491,7 +493,7 @@ class CamCustomCurve(Operator):
return c
parametric.create_parametric_curve(
f, offset=0.0, min=self.mint, max=self.maxt, use_cubic=True, iterations=self.iteration
f, offset=0.0, min=self.min_t, max=self.max_t, use_cubic=True, iterations=self.iteration
)
return {"FINISHED"}
@ -511,7 +513,7 @@ def triangle(i, T, A):
return s
def ssine(A, T, dc_offset=0, phase_shift=0):
def s_sine(A, T, dc_offset=0, phase_shift=0):
args = [dc_offset, phase_shift, A, T]
for arg in args:
arg = round(arg, 6)

Wyświetl plik

@ -49,7 +49,7 @@ class CamCurveBoolean(Operator):
def execute(self, context):
if len(context.selected_objects) > 1:
utils.polygonBoolean(context, self.boolean_type)
utils.polygon_boolean(context, self.boolean_type)
return {"FINISHED"}
else:
self.report({"ERROR"}, "at least 2 curves must be selected")
@ -71,7 +71,7 @@ class CamCurveConvexHull(Operator):
return context.active_object is not None and context.active_object.type in ["CURVE", "FONT"]
def execute(self, context):
utils.polygonConvexHull(context)
utils.polygon_convex_hull(context)
return {"FINISHED"}
@ -158,12 +158,12 @@ class CamCurveIntarsion(Operator):
# make the diameter 5% larger and compensate for backlight
diam = self.diameter * 1.05 + self.backlight * 2
utils.silhoueteOffset(context, -diam / 2)
utils.silhouette_offset(context, -diam / 2)
o1 = bpy.context.active_object
utils.silhoueteOffset(context, diam)
utils.silhouette_offset(context, diam)
o2 = bpy.context.active_object
utils.silhoueteOffset(context, -diam / 2)
utils.silhouette_offset(context, -diam / 2)
o3 = bpy.context.active_object
o1.select_set(True)
o2.select_set(True)
@ -174,7 +174,7 @@ class CamCurveIntarsion(Operator):
bpy.context.object.location[2] = -self.intarsion_thickness
if self.perimeter_cut > 0.0:
utils.silhoueteOffset(context, self.perimeter_cut)
utils.silhouette_offset(context, self.perimeter_cut)
bpy.context.active_object.name = "intarsion_perimeter"
bpy.context.object.location[2] = -self.base_thickness
bpy.ops.object.select_all(action="DESELECT") # deselect new curve
@ -183,14 +183,14 @@ class CamCurveIntarsion(Operator):
context.view_layer.objects.active = o3
# intarsion profile is the inside piece of the intarsion
# make smaller curve for material profile
utils.silhoueteOffset(context, -self.tolerance / 2)
utils.silhouette_offset(context, -self.tolerance / 2)
bpy.context.object.location[2] = self.intarsion_thickness
o4 = bpy.context.active_object
bpy.context.active_object.name = "intarsion_profil"
o4.select_set(False)
if self.backlight > 0.0: # Make a smaller curve for backlighting purposes
utils.silhoueteOffset(context, (-self.tolerance / 2) - self.backlight)
utils.silhouette_offset(context, (-self.tolerance / 2) - self.backlight)
bpy.context.active_object.name = "intarsion_backlight"
bpy.context.object.location[2] = (
-self.backlight_depth_from_top - self.intarsion_thickness
@ -246,7 +246,7 @@ class CamCurveOvercuts(Operator):
def execute(self, context):
bpy.ops.object.curve_remove_doubles()
o1 = bpy.context.active_object
shapes = utils.curveToShapely(o1)
shapes = utils.curve_to_shapely(o1)
negative_overcuts = []
positive_overcuts = []
diameter = self.diameter * 1.001
@ -289,7 +289,7 @@ class CamCurveOvercuts(Operator):
v.normalize()
p = p - v * diameter / 2
if abs(a) < pi / 2:
shape = polygon_utils_cam.Circle(diameter / 2, 64)
shape = polygon_utils_cam.circle(diameter / 2, 64)
shape = shapely.affinity.translate(shape, p.x, p.y)
else:
l = tan(a / 2) * diameter / 2
@ -308,7 +308,7 @@ class CamCurveOvercuts(Operator):
fs = shapely.ops.unary_union(shapes)
fs = fs.union(positive_overcuts)
fs = fs.difference(negative_overcuts)
utils.shapelyToCurve(o1.name + "_overcuts", fs, o1.location.z)
utils.shapely_to_curve(o1.name + "_overcuts", fs, o1.location.z)
return {"FINISHED"}
@ -363,7 +363,7 @@ class CamCurveOvercutsB(Operator):
description="invert overcut operation on all curves",
default=True,
)
otherEdge: BoolProperty(
other_edge: BoolProperty(
name="Other Edge",
description="change to the other edge for the overcut to be on",
default=False,
@ -376,7 +376,7 @@ class CamCurveOvercutsB(Operator):
def execute(self, context):
bpy.ops.object.curve_remove_doubles()
o1 = bpy.context.active_object
shapes = utils.curveToShapely(o1)
shapes = utils.curve_to_shapely(o1)
negative_overcuts = []
positive_overcuts = []
# count all the corners including inside and out
@ -395,14 +395,14 @@ class CamCurveOvercutsB(Operator):
# indexes in insideCorner tuple
POS, V1, V2, A, IDX = range(5)
def addOvercut(a):
def add_overcut(a):
nonlocal pos, centerv, radius, extendedv, sign, negative_overcuts, positive_overcuts
# move the overcut shape center position 1 radius in direction v
pos -= centerv * radius
print("abs(a)", abs(a))
if abs(a) <= pi / 2 + 0.0001:
print("<=pi/2")
shape = polygon_utils_cam.Circle(radius, 64)
shape = polygon_utils_cam.circle(radius, 64)
shape = shapely.affinity.translate(shape, pos.x, pos.y)
else: # elongate overcut circle to make sure tool bit can fit into slot
print(">pi/2")
@ -415,31 +415,31 @@ class CamCurveOvercutsB(Operator):
else:
positive_overcuts.append(shape)
def setOtherEdge(v1, v2, a):
def set_other_edge(v1, v2, a):
nonlocal centerv, extendedv
if self.otherEdge:
if self.other_edge:
centerv = v1
extendedv = v2
else:
centerv = -v2
extendedv = -v1
addOvercut(a)
add_overcut(a)
def setCenterOffset(a):
def set_center_offset(a):
nonlocal centerv, extendedv, sign
centerv = v1 - v2
centerv.normalize()
extendedv = centerv * tan(a / 2) * -sign
addOvercut(a)
add_overcut(a)
def getCorner(idx, offset):
def get_corner(idx, offset):
nonlocal insideCorners
idx += offset
if idx >= len(insideCorners):
idx -= len(insideCorners)
return insideCorners[idx]
def getCornerDelta(curidx, nextidx):
def get_corner_delta(curidx, nextidx):
nonlocal cornerCnt
delta = nextidx - curidx
if delta < 0:
@ -508,10 +508,10 @@ class CamCurveOvercutsB(Operator):
# processing of corners for T-Bone are done after all points are processed
continue
setOtherEdge(v1, v2, a)
set_other_edge(v1, v2, a)
else: # DOGBONE style
setCenterOffset(a)
set_center_offset(a)
elif isTBone and outsideCornerFound:
# add an outside corner to the list
@ -527,47 +527,47 @@ class CamCurveOvercutsB(Operator):
# figure out which side of the corner to do overcut
# if prev corner is outside corner
# calc index distance between current corner and prev
prevCorner = getCorner(i, -1)
prevCorner = get_corner(i, -1)
print("first:", i, idx, prevCorner[IDX])
if getCornerDelta(prevCorner[IDX], idx) == 1:
if get_corner_delta(prevCorner[IDX], idx) == 1:
# make sure there is an outside corner
print(getCornerDelta(getCorner(i, -2)[IDX], idx))
if getCornerDelta(getCorner(i, -2)[IDX], idx) > 2:
setOtherEdge(v1, v2, a)
print(get_corner_delta(get_corner(i, -2)[IDX], idx))
if get_corner_delta(get_corner(i, -2)[IDX], idx) > 2:
set_other_edge(v1, v2, a)
print("first won")
continue
nextCorner = getCorner(i, 1)
nextCorner = get_corner(i, 1)
print("second:", i, idx, nextCorner[IDX])
if getCornerDelta(idx, nextCorner[IDX]) == 1:
if get_corner_delta(idx, nextCorner[IDX]) == 1:
# make sure there is an outside corner
print(getCornerDelta(idx, getCorner(i, 2)[IDX]))
if getCornerDelta(idx, getCorner(i, 2)[IDX]) > 2:
print(get_corner_delta(idx, get_corner(i, 2)[IDX]))
if get_corner_delta(idx, get_corner(i, 2)[IDX]) > 2:
print("second won")
setOtherEdge(-v2, -v1, a)
set_other_edge(-v2, -v1, a)
continue
print("third")
if getCornerDelta(prevCorner[IDX], idx) == 3:
if get_corner_delta(prevCorner[IDX], idx) == 3:
# check if they share the same edge
a1 = v1.angle_signed(prevCorner[V2]) * 180.0 / pi
print("third won", a1)
if a1 < -135 or a1 > 135:
setOtherEdge(-v2, -v1, a)
set_other_edge(-v2, -v1, a)
continue
print("fourth")
if getCornerDelta(idx, nextCorner[IDX]) == 3:
if get_corner_delta(idx, nextCorner[IDX]) == 3:
# check if they share the same edge
a1 = v2.angle_signed(nextCorner[V1]) * 180.0 / pi
print("fourth won", a1)
if a1 < -135 or a1 > 135:
setOtherEdge(v1, v2, a)
set_other_edge(v1, v2, a)
continue
print("***No Win***")
# the default if no other rules pass
setCenterOffset(a)
set_center_offset(a)
negative_overcuts = shapely.ops.unary_union(negative_overcuts)
positive_overcuts = shapely.ops.unary_union(positive_overcuts)
@ -575,7 +575,7 @@ class CamCurveOvercutsB(Operator):
fs = fs.union(positive_overcuts)
fs = fs.difference(negative_overcuts)
utils.shapelyToCurve(o1.name + "_overcuts", fs, o1.location.z)
utils.shapely_to_curve(o1.name + "_overcuts", fs, o1.location.z)
return {"FINISHED"}
def invoke(self, context, event):
@ -660,7 +660,7 @@ class CamMeshGetPockets(Operator):
max=1.0,
precision=4,
)
zlimit: FloatProperty(
z_limit: FloatProperty(
name="Z Limit",
description="Maximum z height considered for pocket operation, " "default is 0.0",
default=0.0,
@ -696,7 +696,7 @@ class CamMeshGetPockets(Operator):
if n.z > self.threshold:
face.select = True
z = (mw @ mesh.vertices[face.vertices[0]].co).z
if z < self.zlimit:
if z < self.z_limit:
if pockets.get(z) is None:
pockets[z] = [i]
else:
@ -767,7 +767,7 @@ class CamOffsetSilhouete(Operator):
precision=4,
unit="LENGTH",
)
mitrelimit: FloatProperty(
mitre_limit: FloatProperty(
name="Mitre Limit",
default=2,
min=0.00000001,
@ -787,7 +787,7 @@ class CamOffsetSilhouete(Operator):
name="Alignment",
items=(("worldxy", "World XY", ""), ("bottom", "Base Bottom", ""), ("top", "Base Top", "")),
)
opentype: EnumProperty(
open_type: EnumProperty(
name="Curve Type",
items=(
("dilate", "Dilate open curve", ""),
@ -805,7 +805,7 @@ class CamOffsetSilhouete(Operator):
or context.active_object.type == "MESH"
)
def isStraight(self, geom):
def is_straight(self, geom):
assert geom.geom_type == "LineString", geom.geom_type
length = geom.length
start_pt = geom.interpolate(0)
@ -872,7 +872,7 @@ class CamOffsetSilhouete(Operator):
line = LineString(coords)
# if curve is a straight segment, change offset type to dilate
if self.isStraight(line) and self.opentype != "leaveopen":
if self.is_straight(line) and self.opentype != "leaveopen":
self.opentype = "dilate"
# make the dilate or open curve offset
@ -897,12 +897,12 @@ class CamOffsetSilhouete(Operator):
cap_style=self.caps,
resolution=16,
join_style=style,
mitre_limit=self.mitrelimit,
mitre_limit=self.mitre_limit,
) # use shapely to expand, closing the curve
name = "Dilation: " + "%.2f" % round(self.offset * 1000) + "mm - " + ob.name
# create the actual offset object based on the Shapely offset
polygon_utils_cam.shapelyToCurve(name, new_shape, 0, self.opentype != "leaveopen")
polygon_utils_cam.shapely_to_curve(name, new_shape, 0, self.opentype != "leaveopen")
# position the object according to the calculated point
bpy.context.object.location.z = point
@ -910,7 +910,7 @@ class CamOffsetSilhouete(Operator):
# if curve is not a straight line and neither dilate or leave open are selected, create a normal offset
else:
bpy.context.view_layer.objects.active = ob
utils.silhoueteOffset(context, self.offset, int(self.style), self.mitrelimit)
utils.silhouette_offset(context, self.offset, int(self.style), self.mitre_limit)
return {"FINISHED"}
def draw(self, context):
@ -949,11 +949,11 @@ class CamObjectSilhouete(Operator):
# this is almost same as getobjectoutline, just without the need of operation data
def execute(self, context):
ob = bpy.context.active_object
self.silh = utils.getObjectSilhouete("OBJECTS", objects=bpy.context.selected_objects)
self.silh = utils.get_object_silhouette("OBJECTS", objects=bpy.context.selected_objects)
bpy.context.scene.cursor.location = (0, 0, 0)
# smp=sgeometry.asMultiPolygon(self.silh)
for smp in self.silh.geoms:
polygon_utils_cam.shapelyToCurve(ob.name + "_silhouette", smp, 0) #
polygon_utils_cam.shapely_to_curve(ob.name + "_silhouette", smp, 0) #
# bpy.ops.object.convert(target='CURVE')
simple.join_multiple(ob.name + "_silhouette")
bpy.context.scene.cursor.location = ob.location

Wyświetl plik

@ -41,11 +41,11 @@ def import_gcode(self, context, filepath):
then = time.time()
parse = GcodeParser()
model = parse.parseFile(filepath)
model = parse.parse_file(filepath)
if mytool.subdivide:
model.subdivide(mytool.max_segment_size)
model.classifySegments()
model.classify_segments()
if mytool.split_layers:
model.draw(split_layers=True)
else:
@ -179,7 +179,7 @@ class GcodeParser:
def __init__(self):
self.model = GcodeModel(self)
def parseFile(self, path):
def parse_file(self, path):
"""Parse a G-code file and update the model.
This function reads a G-code file line by line, increments a line
@ -206,10 +206,10 @@ class GcodeParser:
# remove trailing linefeed
self.line = line.rstrip()
# parse a line
self.parseLine()
self.parse_line()
return self.model
def parseLine(self):
def parse_line(self):
"""Parse a line of G-code and execute the corresponding command.
This method processes a line of G-code by stripping comments, cleaning
@ -264,12 +264,12 @@ class GcodeParser:
# if code doesn't start with a G but starts with a coordinate add the last command to the line
elif code[0] == "X" or code[0] == "Y" or code[0] == "Z":
self.line = self.last_command + " " + self.line
self.parseLine() # parse this line again with the corrections
self.parse_line() # parse this line again with the corrections
else:
pass
print("Unsupported gcode " + str(code))
def parseArgs(self, args):
def parse_args(self, args):
"""Parse command-line arguments into a dictionary.
This function takes a string of arguments, splits it into individual
@ -300,23 +300,23 @@ class GcodeParser:
def parse_G1(self, args, type="G1"):
# G1: Controlled move
self.model.do_G1(self.parseArgs(args), type)
self.model.do_G1(self.parse_args(args), type)
def parse_G0(self, args, type="G0"):
# G1: Controlled move
self.model.do_G1(self.parseArgs(args), type)
self.model.do_G1(self.parse_args(args), type)
def parse_G90(self, args):
# G90: Set to Absolute Positioning
self.model.setRelative(False)
self.model.set_relative(False)
def parse_G91(self, args):
# G91: Set to Relative Positioning
self.model.setRelative(True)
self.model.set_relative(True)
def parse_G92(self, args):
# G92: Set Position
self.model.do_G92(self.parseArgs(args))
self.model.do_G92(self.parse_args(args))
def warn(self, msg):
print("[WARN] Line %d: %s (Text:'%s')" % (self.lineNb, msg, self.line))
@ -421,7 +421,7 @@ class GcodeModel:
or seg.coords["Y"] != self.relative["Y"] + self.offset["Y"]
or seg.coords["Z"] != self.relative["Z"] + self.offset["Z"]
):
self.addSegment(seg)
self.add_segment(seg)
# update model coords
self.relative = coords
@ -493,10 +493,10 @@ class GcodeModel:
RGB = comment[:3]
self.color[:3] = RGB
def setRelative(self, isRelative):
def set_relative(self, isRelative):
self.isRelative = isRelative
def addSegment(self, segment):
def add_segment(self, segment):
self.segments.append(segment)
def warn(self, msg):
@ -505,7 +505,7 @@ class GcodeModel:
def error(self, msg):
self.parser.error(msg)
def classifySegments(self):
def classify_segments(self):
"""Classify segments into layers based on their coordinates and extrusion
style.
@ -745,4 +745,4 @@ if __name__ == "__main__":
path = "test.gcode"
parser = GcodeParser()
model = parser.parseFile(path)
model = parser.parse_file(path)

Wyświetl plik

@ -15,41 +15,41 @@ from mathutils import Euler, Vector
from . import strategy
from .async_op import progress_async
from .bridges import useBridges
from .bridges import use_bridges
from .cam_chunk import (
curveToChunks,
chunksRefine,
limitChunks,
chunksCoherency,
shapelyToChunks,
parentChildDist,
curve_to_chunks,
chunks_refine,
limit_chunks,
chunks_coherency,
shapely_to_chunks,
parent_child_distance,
)
from .image_utils import (
crazyStrokeImageBinary,
getOffsetImageCavities,
imageToShapely,
prepareArea,
crazy_stroke_image_binary,
get_offset_image_cavities,
image_to_shapely,
prepare_area,
)
from .nc import iso
from .opencamlib.opencamlib import oclGetWaterline
from .pattern import getPathPattern, getPathPattern4axis
from .simple import progress, safeFileName, strInUnits
from .pattern import get_path_pattern, get_path_pattern_4_axis
from .simple import progress, safe_filename, unit_value_to_string
from .utils import (
cleanupIndexed,
connectChunksLow,
getAmbient,
getBounds,
getOperationSilhouete,
getOperationSources,
prepareIndexed,
sampleChunks,
sampleChunksNAxis,
sortChunks,
cleanup_indexed,
connect_chunks_low,
get_ambient,
get_bounds,
get_operation_silhouette,
get_operation_sources,
prepare_indexed,
sample_chunks,
sample_chunks_n_axis,
sort_chunks,
USE_PROFILER,
)
def pointonline(a, b, c, tolerence):
def point_on_line(a, b, c, tolerance):
"""Determine if the angle between two vectors is within a specified
tolerance.
@ -78,13 +78,13 @@ def pointonline(a, b, c, tolerence):
norms = numpy.linalg.norm(b) * numpy.linalg.norm(c) # find norms
# find angle between the two vectors
angle = numpy.rad2deg(numpy.arccos(dot_pr / norms))
if angle > tolerence:
if angle > tolerance:
return False
else:
return True
def exportGcodePath(filename, vertslist, operations):
def export_gcode_path(filename, vertslist, operations):
"""Exports G-code using the Heeks NC Adopted Library.
This function generates G-code from a list of vertices and operations
@ -127,7 +127,7 @@ def exportGcodePath(filename, vertslist, operations):
print("File Will Be Separated Into %i Files" % filesnum)
print("1")
basefilename = bpy.data.filepath[: -len(bpy.path.basename(bpy.data.filepath))] + safeFileName(
basefilename = bpy.data.filepath[: -len(bpy.path.basename(bpy.data.filepath))] + safe_filename(
filename
)
@ -182,7 +182,7 @@ def exportGcodePath(filename, vertslist, operations):
unitcorr = 1
rotcorr = 180.0 / pi
def startNewFile():
def start_new_file():
"""Start a new file for G-code generation.
This function initializes a new file for G-code output based on the
@ -237,7 +237,7 @@ def exportGcodePath(filename, vertslist, operations):
return c
c = startNewFile()
c = start_new_file()
# [o.cutter_id,o.cutter_dameter,o.cutter_type,o.cutter_flutes]
last_cutter = None
@ -281,7 +281,7 @@ def exportGcodePath(filename, vertslist, operations):
if m.output_tool_definitions:
c.comment(
"Tool: D = %s type %s flutes %s"
% (strInUnits(o.cutter_diameter, 4), o.cutter_type, o.cutter_flutes)
% (unit_value_to_string(o.cutter_diameter, 4), o.cutter_type, o.cutter_flutes)
)
c.flush_nc()
@ -323,15 +323,15 @@ def exportGcodePath(filename, vertslist, operations):
fmh = round(free_height * unitcorr, 2)
if o.cutter_type not in ["LASER", "PLASMA"]:
c.write("G00 Z" + str(fmh) + "\n")
if o.enable_A:
if o.rotation_A == 0:
o.rotation_A = 0.0001
c.rapid(a=o.rotation_A * 180 / pi)
if o.enable_a_axis:
if o.rotation_a == 0:
o.rotation_a = 0.0001
c.rapid(a=o.rotation_a * 180 / pi)
if o.enable_B:
if o.rotation_B == 0:
o.rotation_B = 0.0001
c.rapid(a=o.rotation_B * 180 / pi)
if o.enable_b_axis:
if o.rotation_b == 0:
o.rotation_b = 0.0001
c.rapid(a=o.rotation_b * 180 / pi)
c.write("\n")
c.flush_nc()
@ -389,7 +389,7 @@ def exportGcodePath(filename, vertslist, operations):
elif ii == 1:
middlev = v
else:
if pointonline(firstv, middlev, nextv, o.simplify_tol / 1000):
if point_on_line(firstv, middlev, nextv, o.simplify_tolerance / 1000):
middlev = nextv
online += 1
continue
@ -450,15 +450,15 @@ def exportGcodePath(filename, vertslist, operations):
if not cut:
if o.cutter_type == "LASER":
c.write("(*************dwell->laser on)\n")
c.write("G04 P" + str(round(o.Laser_delay, 2)) + "\n")
c.write(o.Laser_on + "\n")
c.write("G04 P" + str(round(o.laser_delay, 2)) + "\n")
c.write(o.laser_on + "\n")
elif o.cutter_type == "PLASMA":
c.write("(*************dwell->PLASMA on)\n")
plasma_delay = round(o.Plasma_delay, 5)
plasma_delay = round(o.plasma_delay, 5)
if plasma_delay > 0:
c.write("G04 P" + str(plasma_delay) + "\n")
c.write(o.Plasma_on + "\n")
plasma_dwell = round(o.Plasma_dwell, 5)
c.write(o.plasma_on + "\n")
plasma_dwell = round(o.plasma_dwell, 5)
if plasma_dwell > 0:
c.write("G04 P" + str(plasma_dwell) + "\n")
cut = True
@ -478,10 +478,10 @@ def exportGcodePath(filename, vertslist, operations):
if cut:
if o.cutter_type == "LASER":
c.write("(**************laser off)\n")
c.write(o.Laser_off + "\n")
c.write(o.laser_off + "\n")
elif o.cutter_type == "PLASMA":
c.write("(**************Plasma off)\n")
c.write(o.Plasma_off + "\n")
c.write(o.plasma_off + "\n")
cut = False
c.rapid(x=vx, y=vy)
@ -520,11 +520,11 @@ def exportGcodePath(filename, vertslist, operations):
c.program_end()
findex += 1
c.file_close()
c = startNewFile()
c = start_new_file()
c.flush_nc()
c.comment(
"Tool change - D = %s type %s flutes %s"
% (strInUnits(o.cutter_diameter, 4), o.cutter_type, o.cutter_flutes)
% (unit_value_to_string(o.cutter_diameter, 4), o.cutter_type, o.cutter_flutes)
)
c.tool_change(o.cutter_id)
c.spindle(o.spindle_rpm, spdir_clockwise)
@ -579,7 +579,7 @@ def exportGcodePath(filename, vertslist, operations):
print(time.time() - t)
async def getPath(context, operation):
async def get_path(context, operation):
"""Calculate the path for a given operation in a specified context.
This function performs various calculations to determine the path based
@ -602,22 +602,22 @@ async def getPath(context, operation):
# these tags are for caching of some of the results. Not working well still
# - although it can save a lot of time during calculation...
chd = getChangeData(operation)
chd = get_change_data(operation)
# print(chd)
# print(o.changedata)
if operation.changedata != chd: # or 1:
operation.update_offsetimage_tag = True
operation.update_zbufferimage_tag = True
operation.changedata = chd
# print(o.change_data)
if operation.change_data != chd: # or 1:
operation.update_offset_image_tag = True
operation.update_z_buffer_image_tag = True
operation.change_data = chd
operation.update_silhouete_tag = True
operation.update_ambient_tag = True
operation.update_bullet_collision_tag = True
getOperationSources(operation)
get_operation_sources(operation)
operation.info.warnings = ""
checkMemoryLimit(operation)
check_memory_limit(operation)
print(operation.machine_axes)
@ -629,38 +629,38 @@ async def getPath(context, operation):
pr = cProfile.Profile()
pr.enable()
await getPath3axis(context, operation)
await get_path_3_axis(context, operation)
pr.disable()
pr.dump_stats(time.strftime("Fabex_%Y%m%d_%H%M.prof"))
else:
await getPath3axis(context, operation)
await get_path_3_axis(context, operation)
elif (operation.machine_axes == "5" and operation.strategy5axis == "INDEXED") or (
operation.machine_axes == "4" and operation.strategy4axis == "INDEXED"
elif (operation.machine_axes == "5" and operation.strategy_5_axis == "INDEXED") or (
operation.machine_axes == "4" and operation.strategy_4_axis == "INDEXED"
):
# 5 axis operations are now only 3 axis operations that get rotated...
operation.orientation = prepareIndexed(operation) # TODO RENAME THIS
operation.orientation = prepare_indexed(operation) # TODO RENAME THIS
await getPath3axis(context, operation) # TODO RENAME THIS
await get_path_3_axis(context, operation) # TODO RENAME THIS
cleanupIndexed(operation) # TODO RENAME THIS
cleanup_indexed(operation) # TODO RENAME THIS
# transform5axisIndexed
elif operation.machine_axes == "4":
await getPath4axis(context, operation)
await get_path_4_axis(context, operation)
# export gcode if automatic.
if operation.auto_export:
if bpy.data.objects.get("cam_path_{}".format(operation.name)) is None:
return
p = bpy.data.objects["cam_path_{}".format(operation.name)]
exportGcodePath(operation.filename, [p.data], [operation])
export_gcode_path(operation.filename, [p.data], [operation])
operation.changed = False
t1 = time.process_time() - t
progress("total time", t1)
def getChangeData(o):
def get_change_data(o):
"""Check if object properties have changed to determine if image updates
are needed.
@ -692,7 +692,7 @@ def getChangeData(o):
return changedata
def checkMemoryLimit(o):
def check_memory_limit(o):
"""Check and adjust the memory limit for an object.
This function calculates the resolution of an object based on its
@ -729,7 +729,7 @@ def checkMemoryLimit(o):
# this is the main function.
# FIXME: split strategies into separate file!
async def getPath3axis(context, operation):
async def get_path_3_axis(context, operation):
"""Generate a machining path based on the specified operation strategy.
This function evaluates the provided operation's strategy and generates
@ -755,7 +755,7 @@ async def getPath3axis(context, operation):
s = bpy.context.scene
o = operation
getBounds(o)
get_bounds(o)
tw = time.time()
if o.strategy == "CUTOUT":
@ -765,7 +765,7 @@ async def getPath3axis(context, operation):
await strategy.curve(o)
elif o.strategy == "PROJECTED_CURVE":
await strategy.proj_curve(s, o)
await strategy.project_curve(s, o)
elif o.strategy == "POCKET":
await strategy.pocket(o)
@ -784,95 +784,95 @@ async def getPath3axis(context, operation):
if o.strategy == "CARVE":
pathSamples = []
ob = bpy.data.objects[o.curve_object]
pathSamples.extend(curveToChunks(ob))
ob = bpy.data.objects[o.curve_source]
pathSamples.extend(curve_to_chunks(ob))
# sort before sampling
pathSamples = await sortChunks(pathSamples, o)
pathSamples = chunksRefine(pathSamples, o)
pathSamples = await sort_chunks(pathSamples, o)
pathSamples = chunks_refine(pathSamples, o)
elif o.strategy == "PENCIL":
await prepareArea(o)
getAmbient(o)
pathSamples = getOffsetImageCavities(o, o.offset_image)
pathSamples = limitChunks(pathSamples, o)
await prepare_area(o)
get_ambient(o)
pathSamples = get_offset_image_cavities(o, o.offset_image)
pathSamples = limit_chunks(pathSamples, o)
# sort before sampling
pathSamples = await sortChunks(pathSamples, o)
pathSamples = await sort_chunks(pathSamples, o)
elif o.strategy == "CRAZY":
await prepareArea(o)
await prepare_area(o)
# pathSamples = crazyStrokeImage(o)
# this kind of worked and should work:
millarea = o.zbuffer_image < o.minz + 0.000001
avoidarea = o.offset_image > o.minz + 0.000001
millarea = o.zbuffer_image < o.min_z + 0.000001
avoidarea = o.offset_image > o.min_z + 0.000001
pathSamples = crazyStrokeImageBinary(o, millarea, avoidarea)
pathSamples = crazy_stroke_image_binary(o, millarea, avoidarea)
#####
pathSamples = await sortChunks(pathSamples, o)
pathSamples = chunksRefine(pathSamples, o)
pathSamples = await sort_chunks(pathSamples, o)
pathSamples = chunks_refine(pathSamples, o)
else:
if o.strategy == "OUTLINEFILL":
getOperationSilhouete(o)
get_operation_silhouette(o)
pathSamples = getPathPattern(o)
pathSamples = get_path_pattern(o)
if o.strategy == "OUTLINEFILL":
pathSamples = await sortChunks(pathSamples, o)
pathSamples = await sort_chunks(pathSamples, o)
# have to be sorted once before, because of the parenting inside of samplechunks
if o.strategy in ["BLOCK", "SPIRAL", "CIRCLES"]:
pathSamples = await connectChunksLow(pathSamples, o)
pathSamples = await connect_chunks_low(pathSamples, o)
# print (minz)
chunks = []
layers = strategy.getLayers(o, o.maxz, o.min.z)
layers = strategy.get_layers(o, o.max_z, o.min.z)
print("SAMPLE", o.name)
chunks.extend(await sampleChunks(o, pathSamples, layers))
chunks.extend(await sample_chunks(o, pathSamples, layers))
print("SAMPLE OK")
if o.strategy == "PENCIL": # and bpy.app.debug_value==-3:
chunks = chunksCoherency(chunks)
chunks = chunks_coherency(chunks)
print("coherency check")
# and not o.movement.parallel_step_back:
if o.strategy in ["PARALLEL", "CROSS", "PENCIL", "OUTLINEFILL"]:
print("sorting")
chunks = await sortChunks(chunks, o)
chunks = await sort_chunks(chunks, o)
if o.strategy == "OUTLINEFILL":
chunks = await connectChunksLow(chunks, o)
chunks = await connect_chunks_low(chunks, o)
if o.movement.ramp:
for ch in chunks:
ch.rampZigZag(ch.zstart, None, o)
ch.ramp_zig_zag(ch.zstart, None, o)
# print(chunks)
if o.strategy == "CARVE":
for ch in chunks:
ch.offsetZ(-o.carve_depth)
ch.offset_z(-o.carve_depth)
# for vi in range(0, len(ch.points)):
# ch.points[vi] = (ch.points[vi][0], ch.points[vi][1], ch.points[vi][2] - o.carve_depth)
if o.use_bridges:
print(chunks)
for bridge_chunk in chunks:
useBridges(bridge_chunk, o)
use_bridges(bridge_chunk, o)
strategy.chunksToMesh(chunks, o)
strategy.chunks_to_mesh(chunks, o)
elif o.strategy == "WATERLINE" and o.optimisation.use_opencamlib:
getAmbient(o)
get_ambient(o)
chunks = []
await oclGetWaterline(o, chunks)
chunks = limitChunks(chunks, o)
chunks = limit_chunks(chunks, o)
if (o.movement.type == "CLIMB" and o.movement.spindle_rotation == "CW") or (
o.movement.type == "CONVENTIONAL" and o.movement.spindle_rotation == "CCW"
):
for ch in chunks:
ch.reverse()
strategy.chunksToMesh(chunks, o)
strategy.chunks_to_mesh(chunks, o)
elif o.strategy == "WATERLINE" and not o.optimisation.use_opencamlib:
topdown = True
chunks = []
await progress_async("retrieving object slices")
await prepareArea(o)
await prepare_area(o)
layerstep = 1000000000
if o.use_layers:
layerstep = floor(o.stepdown / o.slice_detail)
@ -884,32 +884,32 @@ async def getPath3axis(context, operation):
layerend = o.min.z #
layers = [[layerstart, layerend]]
#######################
nslices = ceil(abs((o.minz - o.maxz) / o.slice_detail))
nslices = ceil(abs((o.min_z - o.max_z) / o.slice_detail))
lastslice = spolygon.Polygon() # polyversion
layerstepinc = 0
slicesfilled = 0
getAmbient(o)
get_ambient(o)
for h in range(0, nslices):
layerstepinc += 1
slicechunks = []
z = o.minz + h * o.slice_detail
z = o.min_z + h * o.slice_detail
if h == 0:
z += 0.0000001
# if people do mill flat areas, this helps to reach those...
# otherwise first layer would actually be one slicelevel above min z.
islice = o.offset_image > z
slicepolys = imageToShapely(o, islice, with_border=True)
slicepolys = image_to_shapely(o, islice, with_border=True)
poly = spolygon.Polygon() # polygversion
lastchunks = []
for p in slicepolys.geoms:
poly = poly.union(p) # polygversion TODO: why is this added?
nchunks = shapelyToChunks(p, z)
nchunks = limitChunks(nchunks, o, force=True)
nchunks = shapely_to_chunks(p, z)
nchunks = limit_chunks(nchunks, o, force=True)
lastchunks.extend(nchunks)
slicechunks.extend(nchunks)
if len(slicepolys.geoms) > 0:
@ -917,7 +917,7 @@ async def getPath3axis(context, operation):
#
if o.waterline_fill:
layerstart = min(o.maxz, z + o.slice_detail) #
layerstart = min(o.max_z, z + o.slice_detail) #
layerend = max(o.min.z, z - o.slice_detail) #
layers = [[layerstart, layerend]]
#####################################
@ -938,26 +938,26 @@ async def getPath3axis(context, operation):
restpoly = lastslice
restpoly = restpoly.buffer(
-o.dist_between_paths, resolution=o.optimisation.circle_detail
-o.distance_between_paths, resolution=o.optimisation.circle_detail
)
fillz = z
i = 0
while not restpoly.is_empty:
nchunks = shapelyToChunks(restpoly, fillz)
nchunks = shapely_to_chunks(restpoly, fillz)
# project paths TODO: path projection during waterline is not working
if o.waterline_project:
nchunks = chunksRefine(nchunks, o)
nchunks = await sampleChunks(o, nchunks, layers)
nchunks = chunks_refine(nchunks, o)
nchunks = await sample_chunks(o, nchunks, layers)
nchunks = limitChunks(nchunks, o, force=True)
nchunks = limit_chunks(nchunks, o, force=True)
#########################
slicechunks.extend(nchunks)
parentChildDist(lastchunks, nchunks, o)
parent_child_distance(lastchunks, nchunks, o)
lastchunks = nchunks
# slicechunks.extend(polyToChunks(restpoly,z))
restpoly = restpoly.buffer(
-o.dist_between_paths, resolution=o.optimisation.circle_detail
-o.distance_between_paths, resolution=o.optimisation.circle_detail
)
i += 1
@ -979,21 +979,21 @@ async def getPath3axis(context, operation):
restpoly = bound_rectangle.difference(lastslice)
restpoly = restpoly.buffer(
-o.dist_between_paths, resolution=o.optimisation.circle_detail
-o.distance_between_paths, resolution=o.optimisation.circle_detail
)
i = 0
# 'GeometryCollection':#len(restpoly.boundary.coords)>0:
while not restpoly.is_empty:
# print(i)
nchunks = shapelyToChunks(restpoly, fillz)
nchunks = shapely_to_chunks(restpoly, fillz)
#########################
nchunks = limitChunks(nchunks, o, force=True)
nchunks = limit_chunks(nchunks, o, force=True)
slicechunks.extend(nchunks)
parentChildDist(lastchunks, nchunks, o)
parent_child_distance(lastchunks, nchunks, o)
lastchunks = nchunks
restpoly = restpoly.buffer(
-o.dist_between_paths, resolution=o.optimisation.circle_detail
-o.distance_between_paths, resolution=o.optimisation.circle_detail
)
i += 1
@ -1006,7 +1006,7 @@ async def getPath3axis(context, operation):
):
for chunk in slicechunks:
chunk.reverse()
slicechunks = await sortChunks(slicechunks, o)
slicechunks = await sort_chunks(slicechunks, o)
if topdown:
slicechunks.reverse()
# project chunks in between
@ -1014,7 +1014,7 @@ async def getPath3axis(context, operation):
chunks.extend(slicechunks)
if topdown:
chunks.reverse()
strategy.chunksToMesh(chunks, o)
strategy.chunks_to_mesh(chunks, o)
elif o.strategy == "DRILL":
await strategy.drill(o)
@ -1024,7 +1024,7 @@ async def getPath3axis(context, operation):
await progress_async(f"Done", time.time() - tw, "s")
async def getPath4axis(context, operation):
async def get_path_4_axis(context, operation):
"""Generate a path for a specified axis based on the given operation.
This function retrieves the bounds of the operation and checks the
@ -1045,14 +1045,14 @@ async def getPath4axis(context, operation):
"""
o = operation
getBounds(o)
if o.strategy4axis in ["PARALLELR", "PARALLEL", "HELIX", "CROSS"]:
path_samples = getPathPattern4axis(o)
get_bounds(o)
if o.strategy_4_axis in ["PARALLELR", "PARALLEL", "HELIX", "CROSS"]:
path_samples = get_path_pattern_4_axis(o)
depth = path_samples[0].depth
chunks = []
layers = strategy.getLayers(o, 0, depth)
layers = strategy.get_layers(o, 0, depth)
chunks.extend(await sampleChunksNAxis(o, path_samples, layers))
strategy.chunksToMesh(chunks, o)
chunks.extend(await sample_chunks_n_axis(o, path_samples, layers))
strategy.chunks_to_mesh(chunks, o)

Wyświetl plik

@ -33,13 +33,13 @@ from mathutils import (
from .simple import (
progress,
getCachePath,
get_cache_path,
)
from .cam_chunk import (
parentChildDist,
camPathChunkBuilder,
camPathChunk,
chunksToShapely,
parent_child_distance,
CamPathChunkBuilder,
CamPathChunk,
chunks_to_shapely,
)
from .async_op import progress_async
from .numba_wrapper import (
@ -48,7 +48,7 @@ from .numba_wrapper import (
)
def numpysave(a, iname):
def numpy_save(a, iname):
"""Save a NumPy array as an image file in OpenEXR format.
This function converts a NumPy array into an image and saves it using
@ -63,7 +63,7 @@ def numpysave(a, iname):
inamebase = bpy.path.basename(iname)
i = numpytoimage(a, inamebase)
i = numpy_to_image(a, inamebase)
r = bpy.context.scene.render
@ -74,7 +74,7 @@ def numpysave(a, iname):
i.save_render(iname)
def getCircle(r, z):
def get_circle(r, z):
"""Generate a 2D array representing a circle.
This function creates a 2D NumPy array filled with a specified value for
@ -106,7 +106,7 @@ def getCircle(r, z):
return car
def getCircleBinary(r):
def get_circle_binary(r):
"""Generate a binary representation of a circle in a 2D grid.
This function creates a 2D boolean array where the elements inside a
@ -139,7 +139,7 @@ def getCircleBinary(r):
# get cutters for the z-buffer image method
def numpytoimage(a, iname):
def numpy_to_image(a, iname):
"""Convert a NumPy array to a Blender image.
This function takes a NumPy array and converts it into a Blender image.
@ -199,7 +199,7 @@ def numpytoimage(a, iname):
return i
def imagetonumpy(i):
def image_to_numpy(i):
"""Convert a Blender image to a NumPy array.
This function takes a Blender image object and converts its pixel data
@ -265,7 +265,7 @@ def _offset_inner_loop(y1, y2, cutterArrayNan, cwidth, sourceArray, width, heigh
)
async def offsetArea(o, samples):
async def offset_area(o, samples):
"""Offsets the whole image with the cutter and skin offsets.
This function modifies the offset image based on the provided cutter and
@ -276,18 +276,18 @@ async def offsetArea(o, samples):
asynchronously during processing.
Args:
o: An object containing properties such as `update_offsetimage_tag`,
o: An object containing properties such as `update_offset_image_tag`,
`min`, `max`, `inverse`, and `offset_image`.
samples (numpy.ndarray): A 2D array representing the source image data.
Returns:
numpy.ndarray: The updated offset image after applying the cutter and skin offsets.
"""
if o.update_offsetimage_tag:
if o.update_offset_image_tag:
minx, miny, minz, maxx, maxy, maxz = o.min.x, o.min.y, o.min.z, o.max.x, o.max.y, o.max.z
sourceArray = samples
cutterArray = getCutterArray(o, o.optimisation.pixsize)
cutterArray = get_cutter_array(o, o.optimisation.pixsize)
# progress('image size', sourceArray.shape)
@ -318,11 +318,11 @@ async def offsetArea(o, samples):
print("\nOffset Image Time " + str(time.time() - t))
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
return o.offset_image
def dilateAr(ar, cycles):
def dilate_array(ar, cycles):
"""Dilate a binary array using a specified number of cycles.
This function performs a dilation operation on a 2D binary array. For
@ -346,7 +346,7 @@ def dilateAr(ar, cycles):
ar[:, 1:-1] = numpy.logical_or(ar[:, 1:-1], ar[:, :-2])
def getOffsetImageCavities(o, i): # for pencil operation mainly
def get_offset_image_cavities(o, i): # for pencil operation mainly
"""Detects areas in the offset image which are 'cavities' due to curvature
changes.
@ -376,10 +376,10 @@ def getOffsetImageCavities(o, i): # for pencil operation mainly
if 1: # this is newer strategy, finds edges nicely, but pff.going exacty on edge,
# it has tons of spikes and simply is not better than the old one
iname = getCachePath(o) + "_pencilthres.exr"
iname = get_cache_path(o) + "_pencilthres.exr"
# numpysave(ar,iname)#save for comparison before
chunks = imageEdgeSearch_online(o, ar, i)
iname = getCachePath(o) + "_pencilthres_comp.exr"
chunks = image_edge_search_on_line(o, ar, i)
iname = get_cache_path(o) + "_pencilthres_comp.exr"
print("new pencil strategy")
# ##crop pixels that are on outer borders
@ -396,7 +396,7 @@ def getOffsetImageCavities(o, i): # for pencil operation mainly
# search edges for pencil strategy, another try.
def imageEdgeSearch_online(o, ar, zimage):
def image_edge_search_on_line(o, ar, zimage):
"""Search for edges in an image using a pencil strategy.
This function implements an edge detection algorithm that simulates a
@ -433,7 +433,7 @@ def imageEdgeSearch_online(o, ar, zimage):
chunk_builders = []
xs = indices[0][0]
ys = indices[1][0]
nchunk = camPathChunkBuilder([(xs, ys, zimage[xs, ys])]) # startposition
nchunk = CamPathChunkBuilder([(xs, ys, zimage[xs, ys])]) # startposition
dindex = 0 # index in the directions list
last_direction = directions[dindex]
test_direction = directions[dindex]
@ -493,11 +493,11 @@ def imageEdgeSearch_online(o, ar, zimage):
if len(indices[0] > 0):
xs = indices[0][0]
ys = indices[1][0]
nchunk = camPathChunkBuilder([(xs, ys, zimage[xs, ys])]) # startposition
nchunk = CamPathChunkBuilder([(xs, ys, zimage[xs, ys])]) # startposition
ar[xs, ys] = False
else:
nchunk = camPathChunkBuilder([])
nchunk = CamPathChunkBuilder([])
test_direction = directions[3]
last_direction = directions[3]
@ -546,7 +546,7 @@ def imageEdgeSearch_online(o, ar, zimage):
return [c.to_chunk() for c in chunk_builders]
async def crazyPath(o):
async def crazy_path(o):
"""Execute a greedy adaptive algorithm for path planning.
This function prepares an area based on the provided object `o`,
@ -566,7 +566,7 @@ async def crazyPath(o):
# TODO: try to do something with this stuff, it's just a stub. It should be a greedy adaptive algorithm.
# started another thing below.
await prepareArea(o)
await prepare_area(o)
sx = o.max.x - o.min.x
sy = o.max.y - o.min.y
@ -575,10 +575,10 @@ async def crazyPath(o):
o.millimage = numpy.full(shape=(resx, resy), fill_value=0.0, dtype=numpy.float)
# getting inverted cutter
o.cutterArray = -getCutterArray(o, o.optimisation.simulation_detail)
o.cutterArray = -get_cutter_array(o, o.optimisation.simulation_detail)
def buildStroke(start, end, cutterArray):
def build_stroke(start, end, cutterArray):
"""Build a stroke array based on start and end points.
This function generates a 2D stroke array that represents a stroke from
@ -618,19 +618,19 @@ def buildStroke(start, end, cutterArray):
return strokeArray
def testStroke():
def test_stroke():
pass
def applyStroke():
def apply_stroke():
pass
def testStrokeBinary(img, stroke):
def test_stroke_binary(img, stroke):
pass # buildstroke()
def crazyStrokeImage(o):
def crazy_stroke_image(o):
"""Generate a toolpath for a milling operation using a crazy stroke
strategy.
@ -663,13 +663,13 @@ def crazyStrokeImage(o):
maxarx = ar.shape[0]
maxary = ar.shape[1]
cutterArray = getCircleBinary(r)
cutterArray = get_circle_binary(r)
cutterArrayNegative = -cutterArray
cutterimagepix = cutterArray.sum()
# a threshold which says if it is valuable to cut in a direction
satisfypix = cutterimagepix * o.crazy_threshold1
toomuchpix = cutterimagepix * o.crazy_threshold2
satisfypix = cutterimagepix * o.crazy_threshold_1
toomuchpix = cutterimagepix * o.crazy_threshold_2
indices = ar.nonzero() # first get white pixels
startpix = ar.sum() #
totpix = startpix
@ -680,7 +680,7 @@ def crazyStrokeImage(o):
ys = indices[1][0] - r
if ys < r:
ys = r
nchunk = camPathChunkBuilder([(xs, ys)]) # startposition
nchunk = CamPathChunkBuilder([(xs, ys)]) # startposition
print(indices)
print(indices[0][0], indices[1][0])
# vector is 3d, blender somehow doesn't rotate 2d vectors with angles.
@ -777,7 +777,7 @@ def crazyStrokeImage(o):
else: # climb/conv.
testangle += angleincrement
if abs(testangle) > o.crazy_threshold3: # /testlength
if abs(testangle) > o.crazy_threshold_3: # /testlength
testangle = testangleinit
testlength += r / 4.0
if nchunk.points[-1][0] + testvect.x < r:
@ -811,7 +811,7 @@ def crazyStrokeImage(o):
ys = indices[1][0] - r
if ys < r:
ys = r
nchunk = camPathChunkBuilder([(xs, ys)]) # startposition
nchunk = CamPathChunkBuilder([(xs, ys)]) # startposition
ar[xs - r : xs - r + d, ys - r : ys - r + d] = (
ar[xs - r : xs - r + d, ys - r : ys - r + d] * cutterArrayNegative
)
@ -841,7 +841,7 @@ def crazyStrokeImage(o):
return [c.to_chunk() for c in chunk_builders]
def crazyStrokeImageBinary(o, ar, avoidar):
def crazy_stroke_image_binary(o, ar, avoidar):
"""Perform a milling operation using a binary image representation.
This function implements a strategy for milling by navigating through a
@ -883,17 +883,17 @@ def crazyStrokeImageBinary(o, ar, avoidar):
maxarx = ar.shape[0]
maxary = ar.shape[1]
cutterArray = getCircleBinary(r)
cutterArray = get_circle_binary(r)
cutterArrayNegative = -cutterArray
cutterimagepix = cutterArray.sum()
anglelimit = o.crazy_threshold3
anglelimit = o.crazy_threshold_3
# a threshold which says if it is valuable to cut in a direction
satisfypix = cutterimagepix * o.crazy_threshold1
toomuchpix = cutterimagepix * o.crazy_threshold2 # same, but upper limit
satisfypix = cutterimagepix * o.crazy_threshold_1
toomuchpix = cutterimagepix * o.crazy_threshold_2 # same, but upper limit
# (satisfypix+toomuchpix)/2.0# the ideal eating ratio
optimalpix = cutterimagepix * o.crazy_threshold5
optimalpix = cutterimagepix * o.crazy_threshold_5
indices = ar.nonzero() # first get white pixels
startpix = ar.sum() #
@ -909,7 +909,7 @@ def crazyStrokeImageBinary(o, ar, avoidar):
if ys < r:
ys = r
nchunk = camPathChunkBuilder([(xs, ys)]) # startposition
nchunk = CamPathChunkBuilder([(xs, ys)]) # startposition
print(indices)
print(indices[0][0], indices[1][0])
# vector is 3d, blender somehow doesn't rotate 2d vectors with angles.
@ -933,7 +933,7 @@ def crazyStrokeImageBinary(o, ar, avoidar):
# range for angle of toolpath vector versus material vector -
# probably direction negative to the force applied on cutter by material.
testangleinit = 0
angleincrement = o.crazy_threshold4
angleincrement = o.crazy_threshold_4
if (o.movement.type == "CLIMB" and o.movement.spindle_rotation == "CCW") or (
o.movement.type == "CONVENTIONAL" and o.movement.spindle_rotation == "CW"
@ -1042,7 +1042,7 @@ def crazyStrokeImageBinary(o, ar, avoidar):
else: # climb/conv.
testangle += angleincrement
if (abs(testangle) > o.crazy_threshold3 and len(nchunk.points) > 1) or abs(
if (abs(testangle) > o.crazy_threshold_3 and len(nchunk.points) > 1) or abs(
testangle
) > 2 * pi: # /testlength
testangle = testangleinit
@ -1075,7 +1075,7 @@ def crazyStrokeImageBinary(o, ar, avoidar):
andar = numpy.logical_and(ar, numpy.logical_not(avoidar))
indices = andar.nonzero()
if len(nchunk.points) > 1:
parentChildDist([nchunk], chunks, o, distance=r)
parent_child_distance([nchunk], chunks, o, distance=r)
chunk_builders.append(nchunk)
if totpix > startpix * 0.001:
@ -1110,7 +1110,7 @@ def crazyStrokeImageBinary(o, ar, avoidar):
found = True
# print(xs,ys,indices[0][index],indices[1][index])
nchunk = camPathChunk([(xs, ys)]) # startposition
nchunk = CamPathChunk([(xs, ys)]) # startposition
ar[xs - r : xs + r, ys - r : ys + r] = (
ar[xs - r : xs + r, ys - r : ys + r] * cutterArrayNegative
)
@ -1137,7 +1137,7 @@ def crazyStrokeImageBinary(o, ar, avoidar):
print(totaltests)
i = 0
if len(nchunk.points) > 1:
parentChildDist([nchunk], chunks, o, distance=r)
parent_child_distance([nchunk], chunks, o, distance=r)
chunk_builders.append(nchunk)
for ch in chunk_builders:
@ -1146,13 +1146,13 @@ def crazyStrokeImageBinary(o, ar, avoidar):
ch[i] = (
(ch[i][0] + coef - o.borderwidth) * o.optimisation.pixsize + minx,
(ch[i][1] + coef - o.borderwidth) * o.optimisation.pixsize + miny,
o.minz,
o.min_z,
)
return [c.to_chunk for c in chunk_builders]
def imageToChunks(o, image, with_border=False):
def image_to_chunks(o, image, with_border=False):
"""Convert an image into chunks based on detected edges.
This function processes a given image to identify edges and convert them
@ -1348,7 +1348,7 @@ def imageToChunks(o, image, with_border=False):
s = curve_simplify.simplify_RDP(ch, soptions)
# print(s)
nch = camPathChunkBuilder([])
nch = CamPathChunkBuilder([])
for i in range(0, len(s)):
nch.points.append((ch[s[i]].x, ch[s[i]].y))
@ -1360,7 +1360,7 @@ def imageToChunks(o, image, with_border=False):
return []
def imageToShapely(o, i, with_border=False):
def image_to_shapely(o, i, with_border=False):
"""Convert an image to Shapely polygons.
This function takes an image and converts it into a series of Shapely
@ -1379,13 +1379,13 @@ def imageToShapely(o, i, with_border=False):
image chunks.
"""
polychunks = imageToChunks(o, i, with_border)
polys = chunksToShapely(polychunks)
polychunks = image_to_chunks(o, i, with_border)
polys = chunks_to_shapely(polychunks)
return polys
def getSampleImage(s, sarray, minz):
def get_sample_image(s, sarray, minz):
"""Get a sample image value from a 2D array based on given coordinates.
This function retrieves a value from a 2D array by performing bilinear
@ -1428,7 +1428,7 @@ def getSampleImage(s, sarray, minz):
return z
def getResolution(o):
def get_resolution(o):
"""Calculate the resolution based on the dimensions of an object.
This function computes the resolution in both x and y directions by
@ -1520,7 +1520,7 @@ def _restore_render_settings(pairs, properties):
setattr(owner, struct_name, obj_value)
def renderSampleImage(o):
def render_sample_image(o):
"""Render a sample image based on the provided object settings.
This function generates a Z-buffer image for a given object by either
@ -1540,7 +1540,7 @@ def renderSampleImage(o):
t = time.time()
progress("Getting Z-Buffer")
# print(o.zbuffer_image)
o.update_offsetimage_tag = True
o.update_offset_image_tag = True
if o.geometry_source == "OBJECT" or o.geometry_source == "COLLECTION":
pixsize = o.optimisation.pixsize
@ -1551,7 +1551,7 @@ def renderSampleImage(o):
resy = ceil(sy / o.optimisation.pixsize) + 2 * o.borderwidth
if (
not o.update_zbufferimage_tag
not o.update_z_buffer_image_tag
and len(o.zbuffer_image) == resx
and len(o.zbuffer_image[0]) == resy
):
@ -1559,18 +1559,18 @@ def renderSampleImage(o):
# print('has zbuffer')
return o.zbuffer_image
# ###setup image name
iname = getCachePath(o) + "_z.exr"
if not o.update_zbufferimage_tag:
iname = get_cache_path(o) + "_z.exr"
if not o.update_z_buffer_image_tag:
try:
i = bpy.data.images.load(iname)
if i.size[0] != resx or i.size[1] != resy:
print("Z buffer size changed:", i.size, resx, resy)
o.update_zbufferimage_tag = True
o.update_z_buffer_image_tag = True
except:
o.update_zbufferimage_tag = True
if o.update_zbufferimage_tag:
o.update_z_buffer_image_tag = True
if o.update_z_buffer_image_tag:
s = bpy.context.scene
s.use_nodes = True
vl = bpy.context.view_layer
@ -1670,11 +1670,11 @@ def renderSampleImage(o):
i = bpy.data.images.load(iname)
bpy.context.scene.render.engine = "FABEX_RENDER"
a = imagetonumpy(i)
a = image_to_numpy(i)
a = 10.0 * a
a = 1.0 - a
o.zbuffer_image = a
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
else:
i = bpy.data.images[o.source_image_name]
@ -1694,7 +1694,7 @@ def renderSampleImage(o):
o.optimisation.pixsize = o.source_image_size_x / i.size[0]
progress("Pixel Size in the Image Source", o.optimisation.pixsize)
rawimage = imagetonumpy(i)
rawimage = image_to_numpy(i)
maxa = numpy.max(rawimage)
mina = numpy.min(rawimage)
neg = o.source_image_scale_z < 0
@ -1729,7 +1729,7 @@ def renderSampleImage(o):
a += o.source_image_offset.z # after that, image gets offset.
o.minz = numpy.min(a) # TODO: I really don't know why this is here...
o.min_z = numpy.min(a) # TODO: I really don't know why this is here...
o.min.z = numpy.min(a)
print("min z ", o.min.z)
print("max z ", o.max.z)
@ -1740,14 +1740,14 @@ def renderSampleImage(o):
progress(time.time() - t)
# progress(a)
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
return o.zbuffer_image
# return numpy.array([])
async def prepareArea(o):
async def prepare_area(o):
"""Prepare the area for rendering by processing the offset image.
This function handles the preparation of the area by rendering a sample
@ -1764,27 +1764,27 @@ async def prepareArea(o):
"""
# if not o.use_exact:
renderSampleImage(o)
render_sample_image(o)
samples = o.zbuffer_image
iname = getCachePath(o) + "_off.exr"
iname = get_cache_path(o) + "_off.exr"
if not o.update_offsetimage_tag:
if not o.update_offset_image_tag:
progress("Loading Offset Image")
try:
o.offset_image = imagetonumpy(bpy.data.images.load(iname))
o.offset_image = image_to_numpy(bpy.data.images.load(iname))
except:
o.update_offsetimage_tag = True
o.update_offset_image_tag = True
if o.update_offsetimage_tag:
if o.update_offset_image_tag:
if o.inverse:
samples = numpy.maximum(samples, o.min.z - 0.00001)
await offsetArea(o, samples)
numpysave(o.offset_image, iname)
await offset_area(o, samples)
numpy_save(o.offset_image, iname)
def getCutterArray(operation, pixsize):
def get_cutter_array(operation, pixsize):
"""Generate a cutter array based on the specified operation and pixel size.
This function calculates a 2D array representing the cutter shape based

Wyświetl plik

@ -171,7 +171,7 @@ def gear(
gear_polar(r, -k if r < b else pi / number_of_teeth),
]
)
utils.shapelyToCurve("tooth", shapely_gear, 0.0)
utils.shapely_to_curve("tooth", shapely_gear, 0.0)
i = number_of_teeth
while i > 1:
simple.duplicate()
@ -321,7 +321,7 @@ def rack(
]
)
utils.shapelyToCurve("_tooth", shapely_gear, 0.0)
utils.shapely_to_curve("_tooth", shapely_gear, 0.0)
i = number_of_teeth
while i > 1:
simple.duplicate(x=mm_per_tooth)

Wyświetl plik

@ -183,7 +183,7 @@ def twist_separator_slot(length, thickness, finger_play=0.00005, percentage=0.5)
simple.add_rectangle(thickness + finger_play / 2, length, center_y=False)
simple.move(y=((length * percentage - finger_play / 2) / 2))
simple.duplicate()
simple.mirrory()
simple.mirror_y()
simple.join_multiple("simple_rectangle")
simple.active_name("_separator_slot")
@ -592,12 +592,12 @@ def slope_array(loop):
oldp = p
derivative = LineString(sarray)
dderivative = LineString(dsarray)
utils.shapelyToCurve("-derivative", derivative, 0.0)
utils.shapelyToCurve("-doublederivative", dderivative, 0.0)
utils.shapely_to_curve("-derivative", derivative, 0.0)
utils.shapely_to_curve("-doublederivative", dderivative, 0.0)
return sarray
def dslope_array(loop, resolution=0.001):
def d_slope_array(loop, resolution=0.001):
"""Returns a double derivative array or slope of the slope
Args:
@ -625,7 +625,7 @@ def dslope_array(loop, resolution=0.001):
dsarray.append((distance, slope * -0.1))
oldp = p
dderivative = LineString(dsarray)
utils.shapelyToCurve("doublederivative", dderivative, 0.0)
utils.shapely_to_curve("doublederivative", dderivative, 0.0)
return sarray

Wyświetl plik

@ -1,5 +1,6 @@
"""Fabex 'machine_settings.py'
All CAM machine properties.
"""
@ -13,10 +14,10 @@ from bpy.props import (
from bpy.types import PropertyGroup
from . import constants
from .utils import updateMachine
from .utils import update_machine
class machineSettings(PropertyGroup):
class MachineSettings(PropertyGroup):
"""stores all data for machines"""
# name = StringProperty(name="Machine Name", default="Machine")
@ -56,7 +57,7 @@ class machineSettings(PropertyGroup):
unit="LENGTH",
precision=constants.PRECISION,
subtype="XYZ",
update=updateMachine,
update=update_machine,
)
mtc_position: FloatVectorProperty(
name="MTC Position",
@ -64,7 +65,7 @@ class machineSettings(PropertyGroup):
unit="LENGTH",
precision=constants.PRECISION,
subtype="XYZ",
update=updateMachine,
update=update_machine,
)
ending_position: FloatVectorProperty(
name="End Position",
@ -72,7 +73,7 @@ class machineSettings(PropertyGroup):
unit="LENGTH",
precision=constants.PRECISION,
subtype="XYZ",
update=updateMachine,
update=update_machine,
)
working_area: FloatVectorProperty(
@ -81,7 +82,7 @@ class machineSettings(PropertyGroup):
unit="LENGTH",
precision=constants.PRECISION,
subtype="XYZ",
update=updateMachine,
update=update_machine,
)
feedrate_min: FloatProperty(
name="Feedrate Minimum /min",
@ -147,12 +148,13 @@ class machineSettings(PropertyGroup):
precision=1,
)
axis4: BoolProperty(
axis_4: BoolProperty(
name="4th Axis",
description="Machine has 4th axis",
default=0,
)
axis5: BoolProperty(
axis_5: BoolProperty(
name="5th Axis",
description="Machine has 5th axis",
default=0,
@ -222,7 +224,7 @@ class machineSettings(PropertyGroup):
default=True,
)
output_g43_on_tool_change: BoolProperty(
output_G43_on_tool_change: BoolProperty(
name="Output G43 on Tool Change",
description="Output G43 on tool change line",
default=False,

Wyświetl plik

@ -5,6 +5,7 @@
#
import recreator
try:
import ocl
import ocl_funcs
@ -25,7 +26,7 @@ class Creator(recreator.Redirector):
self.stl = None
self.cutter = None
self.minz = None
self.min_z = None
self.path = None
self.pdcf = None
self.material_allowance = 0.0
@ -39,36 +40,36 @@ class Creator(recreator.Redirector):
self.pdcf.setSTL(self.stl)
self.pdcf.setCutter(self.cutter)
self.pdcf.setSampling(0.1)
self.pdcf.setZ(self.minz/units)
self.pdcf.setZ(self.min_z / units)
def z2(self, z):
path = ocl.Path()
# use a line with no length
path.append(ocl.Line(ocl.Point(self.x, self.y, self.z), ocl.Point(self.x, self.y, self.z)))
self.setPdcfIfNotSet()
if (self.z > self.minz):
if self.z > self.min_z:
# Adjust Z if we have gotten a higher limit (Fix pocketing loosing steps when using attach?)
self.pdcf.setZ(self.z)
else:
self.pdcf.setZ(self.minz/units) # Else use minz
self.pdcf.setZ(self.min_z / units) # Else use minz
self.pdcf.setPath(path)
self.pdcf.run()
plist = self.pdcf.getCLPoints()
p = plist[0]
return p.z + self.material_allowance/units
return p.z + self.material_allowance / units
def cut_path(self):
if self.path == None:
return
self.setPdcfIfNotSet()
if (self.z > self.minz):
if self.z > self.min_z:
# Adjust Z if we have gotten a higher limit (Fix pocketing loosing steps when using attach?)
self.pdcf.setZ(self.z)
else:
self.pdcf.setZ(self.minz/units) # Else use minz
self.pdcf.setZ(self.min_z / units) # Else use minz
# get the points on the surface
# get the points on the surface
self.pdcf.setPath(self.path)
self.pdcf.run()
@ -85,7 +86,9 @@ class Creator(recreator.Redirector):
i = 0
for p in plist:
if i > 0:
self.original.feed(p.x/units, p.y/units, p.z/units + self.material_allowance/units)
self.original.feed(
p.x / units, p.y / units, p.z / units + self.material_allowance / units
)
i = i + 1
self.path = ocl.Path()
@ -120,12 +123,16 @@ class Creator(recreator.Redirector):
# add an arc to the path
if self.path == None:
self.path = ocl.Path()
self.path.append(ocl.Arc(ocl.Point(px, py, pz), ocl.Point(
self.x, self.y, self.z), ocl.Point(i, j, pz), ccw))
self.path.append(
ocl.Arc(
ocl.Point(px, py, pz), ocl.Point(self.x, self.y, self.z), ocl.Point(i, j, pz), ccw
)
)
def set_ocl_cutter(self, cutter):
self.cutter = cutter
################################################################################

Wyświetl plik

@ -117,7 +117,7 @@ async def ocl_sample(operation, chunks, use_cached_mesh=False):
op_cutter_type = operation.cutter_type
op_cutter_diameter = operation.cutter_diameter
op_minz = operation.minz
op_minz = operation.min_z
op_cutter_tip_angle = radians(operation.cutter_tip_angle) / 2
if op_cutter_type == "VCARVE":
cutter_length = (op_cutter_diameter / tan(op_cutter_tip_angle)) / 2

Wyświetl plik

@ -278,9 +278,9 @@ def oclWaterlineLayerHeights(operation):
list: A list of waterline layer heights from maximum to minimum.
"""
layers = []
l_last = operation.minz
l_last = operation.min_z
l_step = operation.stepdown
l_first = operation.maxz - l_step
l_first = operation.max_z - l_step
l_depth = l_first
while l_depth > (l_last + 0.0000001):
layers.append(l_depth)
@ -320,7 +320,7 @@ async def oclGetWaterline(operation, chunks):
op_cutter_type = operation.cutter_type
op_cutter_diameter = operation.cutter_diameter
op_minz = operation.minz
op_minz = operation.min_z
if op_cutter_type == "VCARVE":
op_cutter_tip_angle = operation["cutter_tip_angle"]

Wyświetl plik

@ -32,7 +32,7 @@ from mathutils import Euler, Vector
from . import (
bridges,
gcodepath,
gcode_path,
pack,
polygon_utils_cam,
simple,
@ -46,14 +46,14 @@ from .async_op import (
)
from .constants import PRECISION
from .exception import CamException
from .pack import packCurves
from .pack import pack_curves
from .utils import (
addMachineAreaObject,
getBoundsWorldspace,
isChainValid,
isValid,
add_machine_area_object,
get_bounds_worldspace,
chain_valid,
source_valid,
reload_paths,
silhoueteOffset,
silhouette_offset,
was_hidden_dict,
)
@ -61,12 +61,12 @@ from .utils import (
class threadCom: # object passed to threads to read background process stdout info
def __init__(self, o, proc):
self.opname = o.name
self.outtext = ""
self.out_text = ""
self.proc = proc
self.lasttext = ""
def threadread(tcom):
def thread_read(tcom):
"""Reads the standard output of a background process in a non-blocking
manner.
@ -90,7 +90,7 @@ def threadread(tcom):
s = inline.find("progress{")
if s > -1:
e = inline.find("}")
tcom.outtext = inline[s + 9 : e]
tcom.out_text = inline[s + 9 : e]
@bpy.app.handlers.persistent
@ -119,10 +119,10 @@ def timer_update(context):
if not readthread.is_alive():
readthread.join()
# readthread.
tcom.lasttext = tcom.outtext
if tcom.outtext != "":
print(tcom.opname, tcom.outtext)
tcom.outtext = ""
tcom.lasttext = tcom.out_text
if tcom.out_text != "":
print(tcom.opname, tcom.out_text)
tcom.out_text = ""
if "finished" in tcom.lasttext:
processes.remove(p)
@ -130,14 +130,14 @@ def timer_update(context):
o = s.cam_operations[tcom.opname]
o.computing = False
reload_paths(o)
update_zbufferimage_tag = False
update_offsetimage_tag = False
update_z_buffer_image_tag = False
update_offset_image_tag = False
else:
readthread = threading.Thread(target=threadread, args=([tcom]), daemon=True)
readthread = threading.Thread(target=thread_read, args=([tcom]), daemon=True)
readthread.start()
p[0] = readthread
o = s.cam_operations[tcom.opname] # changes
o.outtext = tcom.lasttext # changes
o.out_text = tcom.lasttext # changes
class PathsBackground(Operator):
@ -185,7 +185,7 @@ class PathsBackground(Operator):
)
tcom = threadCom(o, proc)
readthread = threading.Thread(target=threadread, args=([tcom]), daemon=True)
readthread = threading.Thread(target=thread_read, args=([tcom]), daemon=True)
readthread.start()
# self.__class__.cam_processes=[]
if not hasattr(bpy.ops.object.calculate_cam_paths_background.__class__, "cam_processes"):
@ -269,7 +269,7 @@ async def _calc_path(operator, context):
for ob in obc.objects:
ob.hide_set(False)
if o.strategy == "CARVE":
curvob = bpy.data.objects[o.curve_object]
curvob = bpy.data.objects[o.curve_source]
curvob.hide_set(False)
"""if o.strategy == 'WATERLINE':
ob = bpy.data.objects[o.object_name]
@ -290,7 +290,7 @@ async def _calc_path(operator, context):
return {"FINISHED", False}
# check for free movement height < maxz and return with error
if o.movement.free_height < o.maxz:
if o.movement.free_height < o.max_z:
operator.report(
{"ERROR_INVALID_INPUT"},
"Free Movement Height Is Less than Operation Depth Start \n Correct and Try Again.",
@ -307,7 +307,7 @@ async def _calc_path(operator, context):
if o.use_layers:
o.movement.parallel_step_back = False
try:
await gcodepath.getPath(context, o)
await gcode_path.get_path(context, o)
print("Got Path Okay")
except CamException as e:
traceback.print_tb(e.__traceback__)
@ -357,7 +357,7 @@ class CalculatePath(Operator, AsyncOperatorMixin):
s = context.scene
o = s.cam_operations[s.cam_active_operation]
if o is not None:
if isValid(o, context):
if source_valid(o, context):
return True
return False
@ -507,7 +507,7 @@ class CamPackObjects(Operator):
"""Execute the operation in the given context.
This function sets the Blender object mode to 'OBJECT', retrieves the
currently selected objects, and calls the `packCurves` function from the
currently selected objects, and calls the `pack_curves` function from the
`pack` module. It is typically used to finalize operations on selected
objects in Blender.
@ -542,8 +542,8 @@ class CamPackObjects(Operator):
bpy.ops.object.location_clear()
bpy.ops.object.rotation_clear()
chunks = utils.curveToChunks(ob)
npolys = utils.chunksToShapely(chunks)
chunks = utils.curve_to_chunks(ob)
npolys = utils.chunks_to_shapely(chunks)
# add all polys in silh to one poly
poly = shapely.ops.unary_union(npolys)
@ -663,7 +663,7 @@ class CamPackObjects(Operator):
i += 1
t = time.time() - t
polygon_utils_cam.shapelyToCurve("test", sgeometry.MultiPolygon(placedpolys), 0)
polygon_utils_cam.shapely_to_curve("test", sgeometry.MultiPolygon(placedpolys), 0)
print(t)
# layout.
return {"FINISHED"}
@ -711,7 +711,7 @@ class CamSliceObjects(Operator):
precision=PRECISION,
unit="LENGTH",
)
slice_above0: BoolProperty(
slice_above_0: BoolProperty(
name="Slice Above 0",
description="only slice model above 0",
default=False,
@ -745,7 +745,7 @@ class CamSliceObjects(Operator):
ob (bpy.types.Object): The 3D object to be sliced.
"""
from .slice import slicing2d, slicing3d
from .slice import slicing_2d, slicing_3d
ob = bpy.context.active_object
@ -754,7 +754,7 @@ class CamSliceObjects(Operator):
thickness = self.slice_distance
slice3d = self.slice_3d
indexes = self.indexes
above0 = self.slice_above0
above0 = self.slice_above_0
# setup the collections
scollection = bpy.data.collections.new("Slices")
bpy.context.scene.collection.children.link(scollection)
@ -763,7 +763,7 @@ class CamSliceObjects(Operator):
bpy.context.scene.collection.children.link(tcollection)
bpy.ops.object.mode_set(mode="OBJECT") # force object mode
minx, miny, minz, maxx, maxy, maxz = utils.getBoundsWorldspace([ob])
minx, miny, minz, maxx, maxy, maxz = utils.get_bounds_worldspace([ob])
start_height = minz
if above0 and minz < 0:
@ -790,10 +790,10 @@ class CamSliceObjects(Operator):
scollection.objects.link(obslice) # link obslice to scollecton
if slice3d:
# slice 3d at desired height and stop at desired height
slicesuccess = slicing3d(obslice, height, height + thickness)
slicesuccess = slicing_3d(obslice, height, height + thickness)
else:
# slice object at desired height
slicesuccess = slicing2d(obslice, height)
slicesuccess = slicing_2d(obslice, height)
if indexes and slicesuccess:
# text objects
@ -819,12 +819,12 @@ class CamSliceObjects(Operator):
col = layout.column(align=True)
col.prop(self, "slice_distance")
col.prop(self, "slice_above0")
col.prop(self, "slice_above_0")
col.prop(self, "slice_3d")
col.prop(self, "indexes")
def getChainOperations(chain):
def get_chain_operations(chain):
"""Return chain operations associated with a given chain object.
This function iterates through the operations of the provided chain
@ -872,7 +872,7 @@ class PathsChain(Operator, AsyncOperatorMixin):
s = context.scene
if len(s.cam_chains) > 0:
chain = s.cam_chains[s.cam_active_chain]
return isChainValid(chain, context)[0]
return chain_valid(chain, context)[0]
else:
return False
@ -896,7 +896,7 @@ class PathsChain(Operator, AsyncOperatorMixin):
s = context.scene
bpy.ops.object.mode_set(mode="OBJECT") # force object mode
chain = s.cam_chains[s.cam_active_chain]
chainops = getChainOperations(chain)
chainops = get_chain_operations(chain)
meshes = []
try:
for i in range(0, len(chainops)):
@ -913,7 +913,7 @@ class PathsChain(Operator, AsyncOperatorMixin):
for o in chainops:
meshes.append(bpy.data.objects["cam_path_{}".format(o.name)].data)
gcodepath.exportGcodePath(chain.filename, meshes, chainops)
gcode_path.export_gcode_path(chain.filename, meshes, chainops)
return {"FINISHED"}
@ -942,7 +942,7 @@ class PathExportChain(Operator):
s = context.scene
chain = s.cam_chains[s.cam_active_chain]
return isChainValid(chain, context)[0]
return chain_valid(chain, context)[0]
def execute(self, context):
"""Execute the camera path export process.
@ -964,7 +964,7 @@ class PathExportChain(Operator):
s = bpy.context.scene
chain = s.cam_chains[s.cam_active_chain]
chainops = getChainOperations(chain)
chainops = get_chain_operations(chain)
meshes = []
# if len(chainops)<4:
@ -972,7 +972,7 @@ class PathExportChain(Operator):
for o in chainops:
# bpy.ops.object.calculate_cam_paths_background()
meshes.append(bpy.data.objects["cam_path_{}".format(o.name)].data)
gcodepath.exportGcodePath(chain.filename, meshes, chainops)
gcode_path.export_gcode_path(chain.filename, meshes, chainops)
return {"FINISHED"}
@ -1010,7 +1010,7 @@ class PathExport(Operator):
operation,
)
gcodepath.exportGcodePath(
gcode_path.export_gcode_path(
operation.filename,
[bpy.data.objects["cam_path_{}".format(operation.name)].data],
[operation],
@ -1059,7 +1059,7 @@ class CAMSimulate(Operator, AsyncOperatorMixin):
if operation_name in bpy.data.objects:
try:
await simulation.doSimulation(operation_name, [operation])
await simulation.do_simulation(operation_name, [operation])
except AsyncCancelledException as e:
return {"CANCELLED"}
else:
@ -1111,7 +1111,7 @@ class CAMSimulateChain(Operator, AsyncOperatorMixin):
s = context.scene
if len(s.cam_chains) > 0:
chain = s.cam_chains[s.cam_active_chain]
return isChainValid(chain, context)[0]
return chain_valid(chain, context)[0]
else:
return False
@ -1141,7 +1141,7 @@ class CAMSimulateChain(Operator, AsyncOperatorMixin):
s = bpy.context.scene
chain = s.cam_chains[s.cam_active_chain]
chainops = getChainOperations(chain)
chainops = get_chain_operations(chain)
canSimulate = True
for operation in chainops:
@ -1150,7 +1150,7 @@ class CAMSimulateChain(Operator, AsyncOperatorMixin):
print("operation name " + str(operation.name))
if canSimulate:
try:
await simulation.doSimulation(chain.name, chainops)
await simulation.do_simulation(chain.name, chainops)
except AsyncCancelledException as e:
return {"CANCELLED"}
else:
@ -1394,7 +1394,7 @@ class CamChainOperationRemove(Operator):
return {"FINISHED"}
def fixUnits():
def fix_units():
"""Set up units for Fabex.
This function configures the unit settings for the current Blender
@ -1440,18 +1440,18 @@ class CamOperationAdd(Operator):
view3d.spaces[0].show_region_ui = True
s = bpy.context.scene
fixUnits()
fix_units()
ob = bpy.context.active_object
if ob is None:
self.report({"ERROR_INVALID_INPUT"}, "Please Add an Object to Base the Operation on.")
return {"CANCELLED"}
minx, miny, minz, maxx, maxy, maxz = getBoundsWorldspace([ob])
minx, miny, minz, maxx, maxy, maxz = get_bounds_worldspace([ob])
s.cam_operations.add()
o = s.cam_operations[-1]
o.object_name = ob.name
o.minz = minz
o.min_z = minz
s.cam_active_operation = len(s.cam_operations) - 1
@ -1459,7 +1459,7 @@ class CamOperationAdd(Operator):
o.filename = o.name
if s.objects.get("CAM_machine") is None:
addMachineAreaObject()
add_machine_area_object()
return {"FINISHED"}
@ -1498,7 +1498,7 @@ class CamOperationCopy(Operator):
# main(context)
scene = bpy.context.scene
fixUnits()
fix_units()
scene = bpy.context.scene
if len(scene.cam_operations) == 0:
@ -1687,7 +1687,7 @@ class CamOrientationAdd(Operator):
oriob = bpy.context.active_object
oriob.empty_draw_size = 0.02 # 2 cm
simple.addToGroup(oriob, gname)
simple.add_to_group(oriob, gname)
oriob.name = "ori_" + o.name + "." + str(len(bpy.data.collections[gname].objects)).zfill(3)
return {"FINISHED"}
@ -1723,5 +1723,5 @@ class CamBridgesAdd(Operator):
s = bpy.context.scene
a = s.cam_active_operation
o = s.cam_operations[a]
bridges.addAutoBridges(o)
bridges.add_auto_bridges(o)
return {"FINISHED"}

Wyświetl plik

@ -32,7 +32,7 @@ from . import (
)
def srotate(s, r, x, y):
def s_rotate(s, r, x, y):
"""Rotate a polygon's coordinates around a specified point.
This function takes a polygon and rotates its exterior coordinates
@ -63,7 +63,7 @@ def srotate(s, r, x, y):
return sgeometry.Polygon(ncoords)
def packCurves():
def pack_curves():
"""Pack selected curves into a defined area based on specified settings.
This function organizes selected curve objects in Blender by packing
@ -104,8 +104,8 @@ def packCurves():
bpy.ops.object.location_clear()
bpy.ops.object.rotation_clear()
chunks = utils.curveToChunks(ob)
npolys = utils.chunksToShapely(chunks)
chunks = utils.curve_to_chunks(ob)
npolys = utils.chunks_to_shapely(chunks)
# add all polys in silh to one poly
poly = shapely.ops.unary_union(npolys)
@ -225,5 +225,5 @@ def packCurves():
i += 1
t = time.time() - t
polygon_utils_cam.shapelyToCurve("test", sgeometry.MultiPolygon(placedpolys), 0)
polygon_utils_cam.shapely_to_curve("test", sgeometry.MultiPolygon(placedpolys), 0)
print(t)

Wyświetl plik

@ -12,16 +12,16 @@ import bpy
from mathutils import Euler, Vector
from .cam_chunk import (
camPathChunk,
camPathChunkBuilder,
chunksRefine,
parentChildDist,
shapelyToChunks,
CamPathChunk,
CamPathChunkBuilder,
chunks_refine,
parent_child_distance,
shapely_to_chunks,
)
from .simple import progress
def getPathPatternParallel(o, angle):
def get_path_pattern_parallel(o, angle):
"""Generate path chunks for parallel movement based on object dimensions
and angle.
@ -43,8 +43,8 @@ def getPathPatternParallel(o, angle):
"""
zlevel = 1
pathd = o.dist_between_paths
pathstep = o.dist_along_paths
pathd = o.distance_between_paths
pathstep = o.distance_along_paths
pathchunks = []
xm = (o.max.x + o.min.x) / 2
@ -64,7 +64,7 @@ def getPathPatternParallel(o, angle):
for a in range(
int(-dim / pathd), int(dim / pathd)
): # this is highly ineffective, computes path2x the area needed...
chunk = camPathChunkBuilder([])
chunk = CamPathChunkBuilder([])
v = Vector((a * pathd, int(-dim / pathstep) * pathstep, 0))
v.rotate(e)
# shifting for the rotation, so pattern rotates around middle...
@ -152,12 +152,12 @@ def getPathPatternParallel(o, angle):
print("WOO")
for ch in chunks:
ch = ch.tolist()
pathchunks.append(camPathChunk(ch))
pathchunks.append(CamPathChunk(ch))
# print (ch)
return pathchunks
def getPathPattern(operation):
def get_path_pattern(operation):
"""Generate a path pattern based on the specified operation strategy.
This function constructs a path pattern for a given operation by
@ -186,16 +186,16 @@ def getPathPattern(operation):
zlevel = 1 # minz#this should do layers...
if o.strategy == "PARALLEL":
pathchunks = getPathPatternParallel(o, o.parallel_angle)
pathchunks = get_path_pattern_parallel(o, o.parallel_angle)
elif o.strategy == "CROSS":
pathchunks.extend(getPathPatternParallel(o, o.parallel_angle))
pathchunks.extend(getPathPatternParallel(o, o.parallel_angle - pi / 2.0))
pathchunks.extend(get_path_pattern_parallel(o, o.parallel_angle))
pathchunks.extend(get_path_pattern_parallel(o, o.parallel_angle - pi / 2.0))
elif o.strategy == "BLOCK":
pathd = o.dist_between_paths
pathstep = o.dist_along_paths
pathd = o.distance_between_paths
pathstep = o.distance_along_paths
maxxp = maxx
maxyp = maxy
minxp = minx
@ -204,7 +204,7 @@ def getPathPattern(operation):
y = 0.0
incx = 1
incy = 0
chunk = camPathChunkBuilder([])
chunk = CamPathChunkBuilder([])
i = 0
while maxxp - minxp > 0 and maxyp - minyp > 0:
@ -254,9 +254,9 @@ def getPathPattern(operation):
pathchunks = [chunk.to_chunk()]
elif o.strategy == "SPIRAL":
chunk = camPathChunkBuilder([])
pathd = o.dist_between_paths
pathstep = o.dist_along_paths
chunk = CamPathChunkBuilder([])
pathd = o.distance_between_paths
pathstep = o.distance_along_paths
midx = (o.max.x + o.min.x) / 2
midy = (o.max.y + o.min.y) / 2
x = pathd / 4
@ -280,7 +280,7 @@ def getPathPattern(operation):
chunk.points.append((midx + v.x, midy + v.y, zlevel))
else:
pathchunks.append(chunk.to_chunk())
chunk = camPathChunkBuilder([])
chunk = CamPathChunkBuilder([])
if len(chunk.points) > 0:
pathchunks.append(chunk.to_chunk())
if o.movement.insideout == "OUTSIDEIN":
@ -293,15 +293,15 @@ def getPathPattern(operation):
o.movement.type == "CLIMB" and o.movement.spindle_rotation == "CCW"
):
# TODO
chunk.flipX(o.max.x + o.min.x)
chunk.flip_x(o.max.x + o.min.x)
# for si in range(0, len(chunk.points)):
# s = chunk.points[si]
# chunk.points[si] = (o.max.x + o.min.x - s[0], s[1], s[2])
elif o.strategy == "CIRCLES":
pathd = o.dist_between_paths
pathstep = o.dist_along_paths
pathd = o.distance_between_paths
pathstep = o.distance_along_paths
midx = (o.max.x + o.min.x) / 2
midy = (o.max.y + o.min.y) / 2
rx = o.max.x - o.min.x
@ -311,14 +311,14 @@ def getPathPattern(operation):
# progress(x,y,midx,midy)
e = Euler((0, 0, 0))
# pi = pi
chunk = camPathChunkBuilder([])
chunk = CamPathChunkBuilder([])
chunk.points.append((midx, midy, zlevel))
pathchunks.append(chunk.to_chunk())
r = 0
while r < maxr:
r += pathd
chunk = camPathChunkBuilder([])
chunk = CamPathChunkBuilder([])
firstchunk = chunk
v = Vector((-r, 0, 0))
steps = 2 * pi * r / pathstep
@ -337,7 +337,7 @@ def getPathPattern(operation):
chunk = chunk.to_chunk()
pathchunks.append(chunk)
currentstepchunks.append(chunk)
chunk = camPathChunkBuilder([])
chunk = CamPathChunkBuilder([])
v.rotate(e)
if len(chunk.points) > 0:
@ -347,10 +347,10 @@ def getPathPattern(operation):
chunk = chunk.to_chunk()
pathchunks.append(chunk)
currentstepchunks.append(chunk)
chunk = camPathChunkBuilder([])
chunk = CamPathChunkBuilder([])
for ch in laststepchunks:
for p in currentstepchunks:
parentChildDist(p, ch, o)
parent_child_distance(p, ch, o)
if o.movement.insideout == "OUTSIDEIN":
pathchunks.reverse()
@ -368,30 +368,30 @@ def getPathPattern(operation):
pathchunks = []
chunks = []
for p in polys:
p = p.buffer(-o.dist_between_paths / 10, o.optimisation.circle_detail)
p = p.buffer(-o.distance_between_paths / 10, o.optimisation.circle_detail)
# first, move a bit inside, because otherwise the border samples go crazy very often changin between
# hit/non hit and making too many jumps in the path.
chunks.extend(shapelyToChunks(p, 0))
chunks.extend(shapely_to_chunks(p, 0))
pathchunks.extend(chunks)
lastchunks = chunks
firstchunks = chunks
approxn = (min(maxx - minx, maxy - miny) / o.dist_between_paths) / 2
approxn = (min(maxx - minx, maxy - miny) / o.distance_between_paths) / 2
i = 0
for porig in polys:
p = porig
while not p.is_empty:
p = p.buffer(-o.dist_between_paths, o.optimisation.circle_detail)
p = p.buffer(-o.distance_between_paths, o.optimisation.circle_detail)
if not p.is_empty:
nchunks = shapelyToChunks(p, zlevel)
nchunks = shapely_to_chunks(p, zlevel)
if o.movement.insideout == "INSIDEOUT":
parentChildDist(lastchunks, nchunks, o)
parent_child_distance(lastchunks, nchunks, o)
else:
parentChildDist(nchunks, lastchunks, o)
parent_child_distance(nchunks, lastchunks, o)
pathchunks.extend(nchunks)
lastchunks = nchunks
percent = int(i / approxn * 100)
@ -401,11 +401,11 @@ def getPathPattern(operation):
if not o.inverse: # dont do ambient for inverse milling
lastchunks = firstchunks
for p in polys:
d = o.dist_between_paths
steps = o.ambient_radius / o.dist_between_paths
d = o.distance_between_paths
steps = o.ambient_radius / o.distance_between_paths
for a in range(0, int(steps)):
dist = d
if a == int(o.cutter_diameter / 2 / o.dist_between_paths):
if a == int(o.cutter_diameter / 2 / o.distance_between_paths):
if o.optimisation.use_exact:
dist += o.optimisation.pixsize * 0.85
# this is here only because silhouette is still done with zbuffer method,
@ -414,11 +414,11 @@ def getPathPattern(operation):
dist += o.optimisation.pixsize * 2.5
p = p.buffer(dist, o.optimisation.circle_detail)
if not p.is_empty:
nchunks = shapelyToChunks(p, zlevel)
nchunks = shapely_to_chunks(p, zlevel)
if o.movement.insideout == "INSIDEOUT":
parentChildDist(nchunks, lastchunks, o)
parent_child_distance(nchunks, lastchunks, o)
else:
parentChildDist(lastchunks, nchunks, o)
parent_child_distance(lastchunks, nchunks, o)
pathchunks.extend(nchunks)
lastchunks = nchunks
@ -433,12 +433,12 @@ def getPathPattern(operation):
):
chunk.reverse()
chunksRefine(pathchunks, o)
chunks_refine(pathchunks, o)
progress(time.time() - t)
return pathchunks
def getPathPattern4axis(operation):
def get_path_pattern_4_axis(operation):
"""Generate path patterns for a specified operation along a rotary axis.
This function constructs a series of path chunks based on the provided
@ -477,13 +477,13 @@ def getPathPattern4axis(operation):
a2 = 0
a3 = 1
o.max.z = o.maxz
o.max.z = o.max_z
# set radius for all types of operation
radius = max(o.max.z, 0.0001)
radiusend = o.min.z
mradius = max(radius, radiusend)
circlesteps = (mradius * pi * 2) / o.dist_along_paths
circlesteps = (mradius * pi * 2) / o.distance_along_paths
circlesteps = max(4, circlesteps)
anglestep = 2 * pi / circlesteps
# generalized rotation
@ -493,18 +493,18 @@ def getPathPattern4axis(operation):
# generalized length of the operation
maxl = o.max[a1]
minl = o.min[a1]
steps = (maxl - minl) / o.dist_between_paths
steps = (maxl - minl) / o.distance_between_paths
# set starting positions for cutter e.t.c.
cutterstart = Vector((0, 0, 0))
cutterend = Vector((0, 0, 0)) # end point for casting
if o.strategy4axis == "PARALLELR":
if o.strategy_4_axis == "PARALLELR":
for a in range(0, floor(steps) + 1):
chunk = camPathChunkBuilder([])
chunk = CamPathChunkBuilder([])
cutterstart[a1] = o.min[a1] + a * o.dist_between_paths
cutterstart[a1] = o.min[a1] + a * o.distance_between_paths
cutterend[a1] = cutterstart[a1]
cutterstart[a2] = 0 # radius
@ -532,9 +532,9 @@ def getPathPattern4axis(operation):
pathchunks.append(chunk.to_chunk())
if o.strategy4axis == "PARALLEL":
circlesteps = (mradius * pi * 2) / o.dist_between_paths
steps = (maxl - minl) / o.dist_along_paths
if o.strategy_4_axis == "PARALLEL":
circlesteps = (mradius * pi * 2) / o.distance_between_paths
steps = (maxl - minl) / o.distance_along_paths
anglestep = 2 * pi / circlesteps
# generalized rotation
@ -544,7 +544,7 @@ def getPathPattern4axis(operation):
reverse = False
for b in range(0, floor(circlesteps) + 1):
chunk = camPathChunkBuilder([])
chunk = CamPathChunkBuilder([])
cutterstart[a2] = 0
cutterstart[a3] = radius
@ -557,7 +557,7 @@ def getPathPattern4axis(operation):
cutterend.rotate(e)
for a in range(0, floor(steps) + 1):
cutterstart[a1] = o.min[a1] + a * o.dist_along_paths
cutterstart[a1] = o.min[a1] + a * o.distance_along_paths
cutterend[a1] = cutterstart[a1]
chunk.startpoints.append(cutterstart.to_tuple())
chunk.endpoints.append(cutterend.to_tuple())
@ -578,16 +578,16 @@ def getPathPattern4axis(operation):
reverse = not reverse
if o.strategy4axis == "HELIX":
if o.strategy_4_axis == "HELIX":
print("helix")
a1step = o.dist_between_paths / circlesteps
a1step = o.distance_between_paths / circlesteps
chunk = camPathChunkBuilder([]) # only one chunk, init here
chunk = CamPathChunkBuilder([]) # only one chunk, init here
for a in range(0, floor(steps) + 1):
cutterstart[a1] = o.min[a1] + a * o.dist_between_paths
cutterstart[a1] = o.min[a1] + a * o.distance_between_paths
cutterend[a1] = cutterstart[a1]
cutterstart[a2] = 0
cutterstart[a3] = radius
@ -614,5 +614,5 @@ def getPathPattern4axis(operation):
# print(chunk.startpoints)
# print(pathchunks)
# sprint(len(pathchunks))
# print(o.strategy4axis)
# print(o.strategy_4_axis)
return pathchunks

Wyświetl plik

@ -20,7 +20,7 @@ except ImportError:
SHAPELY = True
def Circle(r, np):
def circle(r, np):
"""Generate a circle defined by a given radius and number of points.
This function creates a polygon representing a circle by generating a
@ -48,7 +48,7 @@ def Circle(r, np):
return p
def shapelyRemoveDoubles(p, optimize_threshold):
def shapely_remove_doubles(p, optimize_threshold):
"""Remove duplicate points from the boundary of a shape.
This function simplifies the boundary of a given shape by removing
@ -86,7 +86,7 @@ def shapelyRemoveDoubles(p, optimize_threshold):
return pnew
def shapelyToMultipolygon(anydata):
def shapely_to_multipolygon(anydata):
"""Convert a Shapely geometry to a MultiPolygon.
This function takes a Shapely geometry object and converts it to a
@ -119,7 +119,7 @@ def shapelyToMultipolygon(anydata):
return sgeometry.MultiPolygon()
def shapelyToCoords(anydata):
def shapely_to_coordinates(anydata):
"""Convert a Shapely geometry object to a list of coordinates.
This function takes a Shapely geometry object and extracts its
@ -187,7 +187,7 @@ def shapelyToCoords(anydata):
return seq
def shapelyToCurve(name, p, z, cyclic=True):
def shapely_to_curve(name, p, z, cyclic=True):
"""Create a 3D curve object in Blender from a Shapely geometry.
This function takes a Shapely geometry and converts it into a 3D curve
@ -217,7 +217,7 @@ def shapelyToCurve(name, p, z, cyclic=True):
# for c in p.exterior.coords:
# print(p.type)
seq = shapelyToCoords(p)
seq = shapely_to_coordinates(p)
w = 1 # weight
curvedata = bpy.data.curves.new(name=name, type="CURVE")

Wyświetl plik

@ -121,23 +121,23 @@ class AddPresetCamOperation(AddPresetBase, Operator):
"o.cutter_length",
"o.ambient_behaviour",
"o.ambient_radius",
"o.curve_object",
"o.curve_object1",
"o.curve_source",
"o.curve_target",
"o.limit_curve",
"o.use_limit_curve",
"o.feedrate",
"o.plunge_feedrate",
"o.dist_along_paths",
"o.dist_between_paths",
"o.distance_along_paths",
"o.distance_between_paths",
"o.max",
"o.min",
"o.minz_from",
"o.minz",
"o.min_z_from",
"o.min_z",
"o.skin",
"o.spindle_rpm",
"o.use_layers",
"o.carve_depth",
"o.update_offsetimage_tag",
"o.update_offset_image_tag",
"o.slice_detail",
"o.drill_type",
"o.dont_merge",
@ -145,7 +145,7 @@ class AddPresetCamOperation(AddPresetBase, Operator):
"o.inverse",
"o.waterline_fill",
"o.strategy",
"o.update_zbufferimage_tag",
"o.update_z_buffer_image_tag",
"o.stepdown",
"o.path_object_name",
"o.pencil_threshold",
@ -157,11 +157,11 @@ class AddPresetCamOperation(AddPresetBase, Operator):
"o.output_trailer",
"o.gcode_trailer",
"o.use_modifiers",
"o.enable_A",
"o.enable_B",
"o.A_along_x",
"o.rotation_A",
"o.rotation_B",
"o.enable_a_axis",
"o.enable_b_axis",
"o.a_along_x",
"o.rotation_a",
"o.rotation_b",
"o.straight",
]

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.00015
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.00015
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 3.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.009999999776482582
o.strategy = 'BLOCK'
o.strategy = "BLOCK"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'AROUND'
o.ambient_behaviour = "AROUND"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.004
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.00015
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.00015
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 3.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.009999999776482582
o.strategy = 'BLOCK'
o.strategy = "BLOCK"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.00015
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.00015
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 3.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.009999999776482582
o.strategy = 'CIRCLES'
o.strategy = "CIRCLES"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'AROUND'
o.ambient_behaviour = "AROUND"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.00015
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.00015
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 3.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.009999999776482582
o.strategy = 'CIRCLES'
o.strategy = "CIRCLES"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.00015
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.00015
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 3.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.009999999776482582
o.strategy = 'CROSS'
o.strategy = "CROSS"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'AROUND'
o.ambient_behaviour = "AROUND"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.00015
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.00015
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 3.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.009999999776482582
o.strategy = 'CROSS'
o.strategy = "CROSS"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.00015
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.00015
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 3.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.009999999776482582
o.strategy = 'CUTOUT'
o.strategy = "CUTOUT"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.00015
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.00015
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 3.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.009999999776482582
o.strategy = 'OUTLINEFILL'
o.strategy = "OUTLINEFILL"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.00015
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.00015
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 3.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.009999999776482582
o.strategy = 'PARALLEL'
o.strategy = "PARALLEL"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'AROUND'
o.ambient_behaviour = "AROUND"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.00015
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.00015
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 3.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.009999999776482582
o.strategy = 'PARALLEL'
o.strategy = "PARALLEL"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.00015
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.00015
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 3.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.009999999776482582
o.strategy = 'PENCIL'
o.strategy = "PENCIL"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.00015
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.00015
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 3.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.009999999776482582
o.strategy = 'POCKET'
o.strategy = "POCKET"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.00015
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.00015
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 3.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.009999999776482582
o.strategy = 'SPIRAL'
o.strategy = "SPIRAL"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'AROUND'
o.ambient_behaviour = "AROUND"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.00015
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.00015
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 3.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.009999999776482582
o.strategy = 'SPIRAL'
o.strategy = "SPIRAL"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'AROUND'
o.ambient_behaviour = "AROUND"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003000000026077032
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.00019999999494757503
o.dist_between_paths = 0.0005000000237487257
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.00019999999494757503
o.distance_between_paths = 0.0005000000237487257
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.009999999776482582
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.019999999552965164
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = False
o.render_all = True
o.skin = 0.0
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = False
o.stepdown = 0.009999999776482582
o.strategy = 'CROSS'
o.strategy = "CROSS"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = False
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.0024
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.0024
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0003
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.003
o.strategy = 'BLOCK'
o.strategy = "BLOCK"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = True
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'AROUND'
o.ambient_behaviour = "AROUND"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.0024
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.0024
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0003
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.003
o.strategy = 'BLOCK'
o.strategy = "BLOCK"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = True
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.0024
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.0024
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0003
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.003
o.strategy = 'CIRCLES'
o.strategy = "CIRCLES"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = True
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'AROUND'
o.ambient_behaviour = "AROUND"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.0024
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.0024
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0003
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.003
o.strategy = 'CIRCLES'
o.strategy = "CIRCLES"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = True
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.0024
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.0024
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0003
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.003
o.strategy = 'CROSS'
o.strategy = "CROSS"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = True
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'AROUND'
o.ambient_behaviour = "AROUND"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.0024
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.0024
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0003
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.003
o.strategy = 'CROSS'
o.strategy = "CROSS"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = True
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.0024
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.0024
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0003
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.003
o.strategy = 'CUTOUT'
o.strategy = "CUTOUT"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = True
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.0024
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.0024
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0003
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.003
o.strategy = 'OUTLINEFILL'
o.strategy = "OUTLINEFILL"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = True
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.0024
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.0024
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0003
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.003
o.strategy = 'PARALLEL'
o.strategy = "PARALLEL"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = True
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'AROUND'
o.ambient_behaviour = "AROUND"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.0024
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.0024
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0003
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.003
o.strategy = 'PARALLEL'
o.strategy = "PARALLEL"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = True
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.0024
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.0024
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0003
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.003
o.strategy = 'PENCIL'
o.strategy = "PENCIL"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = True
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.0024
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.0024
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0003
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.003
o.strategy = 'POCKET'
o.strategy = "POCKET"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = True
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'ALL'
o.ambient_behaviour = "ALL"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.0024
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.0024
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0003
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.003
o.strategy = 'SPIRAL'
o.strategy = "SPIRAL"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = True
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -6,37 +6,37 @@ bpy.ops.scene.cam_operation_add()
scene = bpy.context.scene
o = scene.cam_operations[scene.cam_active_operation]
o.ambient_behaviour = 'AROUND'
o.ambient_behaviour = "AROUND"
o.ambient_radius = 0.009999999776482582
o.auto_nest = False
o.borderwidth = 50
o.carve_depth = 0.0010000000474974513
o.circle_detail = 64
o.curve_object = ''
o.cut_type = 'OUTSIDE'
o.curve_source = ""
o.cut_type = "OUTSIDE"
o.cutter_diameter = 0.003
o.cutter_length = 25.0
o.cutter_tip_angle = 60.0
o.cutter_type = 'BALLNOSE'
o.dist_along_paths = 0.0002
o.dist_between_paths = 0.0024
o.cutter_type = "BALLNOSE"
o.distance_along_paths = 0.0002
o.distance_between_paths = 0.0024
o.dont_merge = False
o.duration = 96.3156509399414
o.feedrate = 1.0
o.filename = o.name = f'OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}'
o.filename = o.name = f"OP_{o.object_name}_{scene.cam_active_operation + 1}_{Path(__file__).stem}"
o.free_movement_height = 0.01
o.geometry_source = 'OBJECT'
o.geometry_source = "OBJECT"
o.inverse = False
o.limit_curve = ''
o.limit_curve = ""
o.material_from_model = True
o.material_origin = (0.0, 0.0, 0.0)
o.material_radius_around_model = 0.003
o.material_size = (0.20000000298023224, 0.20000000298023224, 0.10000000149011612)
o.max = (0.1325458288192749, 0.14115460216999054, -0.041229985654354095)
o.min = (0.02779383957386017, 0.014265235513448715, -0.1281193494796753)
o.minz = -0.1281193494796753
o.minz_from_ob = True
o.movement_type = 'MEANDER'
o.min_z = -0.1281193494796753
o.min_z_from_ob = True
o.movement_type = "MEANDER"
o.object = None
o.optimize = True
o.optimize_threshold = 4.999999873689376e-05
@ -47,18 +47,18 @@ o.protect_vertical = True
o.render_all = True
o.skin = 0.0003
o.slice_detail = 0.0010000000474974513
o.source_image_name = ''
o.source_image_name = ""
o.source_image_offset = (0.0, 0.0, 0.0)
o.source_image_scale_z = 1.0
o.source_image_size_x = 0.10000000149011612
o.spindle = 30000.0
o.stay_low = True
o.stepdown = 0.003
o.strategy = 'SPIRAL'
o.strategy = "SPIRAL"
o.testing = 0
o.update_offsetimage_tag = False
o.update_offset_image_tag = False
o.update_silhouete_tag = True
o.update_zbufferimage_tag = False
o.update_z_buffer_image_tag = False
o.use_layers = True
o.use_limit_curve = False
o.waterline_fill = True

Wyświetl plik

@ -42,9 +42,7 @@ def finger(diameter, stem=2):
None: This function does not return any value.
"""
# diameter = diameter of the tool for joint creation
# DT = Bit diameter tolerance
# stem = amount of radius the stem or neck of the joint will have
global DT
RESOLUTION = 12 # Data resolution
cube_sx = diameter * DT * (2 + stem - 1)
@ -87,7 +85,7 @@ def finger(diameter, stem=2):
bpy.ops.object.origin_set(type="ORIGIN_CURSOR", center="MEDIAN")
simple.duplicate()
simple.mirrorx()
simple.mirror_x()
simple.union("ftmp")
simple.rename("ftmp", "_sum")
@ -112,7 +110,7 @@ def finger(diameter, stem=2):
bpy.ops.object.origin_set(type="ORIGIN_CURSOR", center="MEDIAN")
simple.duplicate()
simple.mirrorx()
simple.mirror_x()
simple.union("_circ")
simple.difference("_", "_sum")
@ -137,11 +135,7 @@ def fingers(diameter, inside, amount=1, stem=1):
to 1.
"""
# diameter = diameter of the tool for joint creation
# inside = Tolerance in the joint receptacle
global DT # Bit diameter tolerance
# stem = amount of radius the stem or neck of the joint will have
# amount = the amount of fingers
xtranslate = -(4 + 2 * (stem - 1)) * (amount - 1) * diameter * DT / 2
finger(diameter, stem=stem) # generate male finger
@ -167,7 +161,7 @@ def fingers(diameter, inside, amount=1, stem=1):
simple.move(y=-inside)
def twistf(name, length, diameter, tolerance, twist, tneck, tthick, twist_keep=False):
def twist_female(name, length, diameter, tolerance, twist, tneck, tthick, twist_keep=False):
"""Add a twist lock to a receptacle.
This function modifies the receptacle by adding a twist lock feature if
@ -205,7 +199,7 @@ def twistf(name, length, diameter, tolerance, twist, tneck, tthick, twist_keep=F
simple.active_name(name)
def twistm(
def twist_male(
name, length, diameter, tolerance, twist, tneck, tthick, angle, twist_keep=False, x=0, y=0
):
"""Add a twist lock to a male connector.
@ -302,17 +296,6 @@ def bar(
model in Blender.
"""
# width = length of the bar
# thick = thickness of the bar
# diameter = diameter of the tool for joint creation
# tolerance = Tolerance in the joint
# amount = amount of fingers in the joint 0 means auto generate
# stem = amount of radius the stem or neck of the joint will have
# twist = twist lock addition
# tneck = percentage the twist neck will have compared to thick
# tthick = thicknest of the twist material
# Which M,F, MF, MM, FF
global DT
if amount == 0:
amount = round(thick / ((4 + 2 * (stem - 1)) * diameter * DT)) - 1
@ -337,7 +320,7 @@ def bar(
simple.rename("tmprect", "_tmprect")
simple.union("_tmp")
simple.active_name("tmprect")
twistm(
twist_male(
"tmprect",
thick,
diameter,
@ -350,7 +333,9 @@ def bar(
twist_keep=twist_keep,
)
twistf("receptacle", thick, diameter, tolerance, twist, tneck, tthick, twist_keep=twist_keep)
twist_female(
"receptacle", thick, diameter, tolerance, twist, tneck, tthick, twist_keep=twist_keep
)
simple.rename("receptacle", "_tmpreceptacle")
if which == "FF" or which == "F" or which == "MF":
simple.rotate(-pi / 2)
@ -421,18 +406,6 @@ def arc(
directly.
"""
# radius = radius of the curve
# thick = thickness of the bar
# angle = angle of the arc
# diameter = diameter of the tool for joint creation
# tolerance = Tolerance in the joint
# amount = amount of fingers in the joint 0 means auto generate
# stem = amount of radius the stem or neck of the joint will have
# twist = twist lock addition
# tneck = percentage the twist neck will have compared to thick
# tthick = thicknest of the twist material
# which = which joint to generate, Male Female MaleFemale M, F, MF
global DT # diameter tolerance for diameter of finger creation
if angle == 0: # angle cannot be 0
@ -447,8 +420,10 @@ def arc(
amount = round(thick / ((4 + 2 * (stem - 1)) * diameter * DT)) - 1
fingers(diameter, tolerance, amount, stem=stem)
twistf("receptacle", thick, diameter, tolerance, twist, tneck, tthick, twist_keep=twist_keep)
twistf("testing", thick, diameter, tolerance, twist, tneck, tthick, twist_keep=twist_keep)
twist_female(
"receptacle", thick, diameter, tolerance, twist, tneck, tthick, twist_keep=twist_keep
)
twist_female("testing", thick, diameter, tolerance, twist, tneck, tthick, twist_keep=twist_keep)
print("generating arc")
# generate arc
bpy.ops.curve.simple(
@ -476,11 +451,11 @@ def arc(
if which == "MF" or which == "M":
simple.union("_tmp")
simple.active_name("base")
twistm("base", thick, diameter, tolerance, twist, tneck, tthick, pi, x=radius)
twist_male("base", thick, diameter, tolerance, twist, tneck, tthick, pi, x=radius)
simple.rename("base", "_tmparc")
simple.rename("receptacle", "_tmpreceptacle")
simple.mirrory()
simple.mirror_y()
simple.move(x=radius)
bpy.ops.object.origin_set(type="ORIGIN_CURSOR", center="MEDIAN")
simple.rotate(angle)
@ -494,13 +469,13 @@ def arc(
simple.make_active("PUZZLE_arc")
if which == "M":
simple.rotate(-angle)
simple.mirrory()
simple.mirror_y()
bpy.ops.object.transform_apply(location=True, rotation=True, scale=False)
simple.rotate(-pi / 2)
simple.move(y=radius)
simple.rename("PUZZLE_arc", "PUZZLE_arc_male")
elif which == "F":
simple.mirrorx()
simple.mirror_x()
simple.move(x=radius)
simple.rotate(pi / 2)
simple.rename("PUZZLE_arc", "PUZZLE_arc_receptacle")
@ -509,12 +484,12 @@ def arc(
# bpy.ops.object.transform_apply(location=True, rotation=False, scale=False, properties=False)
#
if negative: # mirror if angle is negative
simple.mirrory()
simple.mirror_y()
#
# bpy.ops.object.curve_remove_doubles()
def arcbararc(
def arc_bar_arc(
length,
radius,
thick,
@ -567,20 +542,6 @@ def arcbararc(
directly.
"""
# length is the total width of the segments including 2 * radius and thick
# radius = radius of the curve
# thick = thickness of the bar
# angle = angle of the female part
# angleb = angle of the male part
# diameter = diameter of the tool for joint creation
# tolerance = Tolerance in the joint
# amount = amount of fingers in the joint 0 means auto generate
# stem = amount of radius the stem or neck of the joint will have
# twist = twist lock addition
# tneck = percentage the twist neck will have compared to thick
# tthick = thicknest of the twist material
# which = which joint to generate, Male Female MaleFemale M, F, MF
# adjust length to include 2x radius + thick
length -= radius * 2 + thick
@ -651,7 +612,7 @@ def arcbararc(
simple.make_active("arcBarArc")
def arcbar(
def arc_bar(
length,
radius,
thick,
@ -698,18 +659,6 @@ def arcbar(
twist_line_amount (int?): Amount of twist line. Defaults to 2.
"""
# length is the total width of the segments including 2 * radius and thick
# radius = radius of the curve
# thick = thickness of the bar
# angle = angle of the female part
# diameter = diameter of the tool for joint creation
# tolerance = Tolerance in the joint
# amount = amount of fingers in the joint 0 means auto generate
# stem = amount of radius the stem or neck of the joint will have
# twist = twist lock addition
# tneck = percentage the twist neck will have compared to thick
# tthick = thicknest of the twist material
# which = which joint to generate, Male Female MaleFemale M, F, MF
if which == "M":
which = "MM"
elif which == "F":
@ -913,7 +862,7 @@ def multiangle(
simple.active_name("tmp_arc")
if combination == "MFF":
simple.duplicate()
simple.mirrorx()
simple.mirror_x()
elif combination == "MMF":
arc(
radius,
@ -929,7 +878,7 @@ def multiangle(
which="M",
)
simple.active_name("tmp_arc")
simple.mirrory()
simple.mirror_y()
simple.rotate(pi / 2)
simple.union("tmp_")
simple.difference("tmp", "tmp_")
@ -1011,7 +960,7 @@ def t(
if combination == "M":
simple.make_active("fingers")
simple.mirrory()
simple.mirror_y()
simple.active_name("tmp")
simple.union("tmp")
@ -1024,7 +973,7 @@ def t(
if combination == "F":
simple.make_active("receptacle")
simple.mirrory()
simple.mirror_y()
simple.active_name("tmp")
simple.difference("tmp", "tmp")
@ -1134,11 +1083,11 @@ def curved_t(
which="F",
)
simple.move(radius)
simple.mirrory()
simple.mirror_y()
simple.active_name("tmp_arc")
simple.union("tmp_arc")
simple.duplicate()
simple.mirrorx()
simple.mirror_x()
simple.union("tmp_arc")
simple.difference("tmp_", "tmp_arc")
else:
@ -1162,7 +1111,7 @@ def curved_t(
else:
simple.move(radius)
simple.duplicate()
simple.mirrorx()
simple.mirror_x()
simple.union("tmp")
simple.active_name("curved_t")
@ -1267,7 +1216,7 @@ def mitre(
simple.move(x=2 * thick)
simple.rotate(angleb)
simple.move(x=length / 2)
simple.mirrorx()
simple.mirror_x()
simple.active_name("tmpmitreleft")
simple.difference("tmp", "tmprect")
simple.make_active("tmprect")
@ -1289,7 +1238,7 @@ def mitre(
h = thick / cos(angleb)
h /= 2
simple.move(x=length / 2 + h * sin(angleb), y=-thick / 2)
simple.mirrorx()
simple.mirror_x()
simple.union("tmp")
simple.active_name("tmprect")
@ -1297,14 +1246,14 @@ def mitre(
# Generate female section and join to base
if which == "MF" or which == "F":
simple.make_active("receptacle")
simple.mirrory()
simple.mirror_y()
simple.duplicate()
simple.active_name("tmpreceptacle")
simple.rotate(angleb - pi / 2)
h = thick / cos(angleb)
h /= 2
simple.move(x=length / 2 + h * sin(angleb), y=-thick / 2)
simple.mirrorx()
simple.mirror_x()
if which == "F":
simple.rename("receptacle", "tmpreceptacle2")
simple.rotate(angle - pi / 2)
@ -1413,7 +1362,7 @@ def open_curve(
simple.move(x=p_end[0], y=p_end[1])
simple.union("tmprect")
dilated = line.buffer(thick / 2) # expand shapely object to thickness
utils.shapelyToCurve("tmp_curve", dilated, 0.0)
utils.shapely_to_curve("tmp_curve", dilated, 0.0)
# truncate curve at both ends with the rectangles
simple.difference("tmp", "tmp_curve")
@ -1424,7 +1373,7 @@ def open_curve(
simple.active_name("tmp_fingers")
simple.union("tmp_")
simple.active_name("tmp_curve")
twistm(
twist_male(
"tmp_curve",
thick,
diameter,
@ -1438,7 +1387,9 @@ def open_curve(
twist_keep=twist_keep,
)
twistf("receptacle", thick, diameter, tolerance, twist, t_neck, t_thick, twist_keep=twist_keep)
twist_female(
"receptacle", thick, diameter, tolerance, twist, t_neck, t_thick, twist_keep=twist_keep
)
simple.rename("receptacle", "tmp")
simple.rotate(start_angle + pi)
simple.move(x=p_start[0], y=p_start[1])

Wyświetl plik

@ -39,7 +39,7 @@ def tuple_add(t, t1): # add two tuples as Vectors
return t[0] + t1[0], t[1] + t1[1], t[2] + t1[2]
def tuple_sub(t, t1): # sub two tuples as Vectors
def tuple_subtract(t, t1): # sub two tuples as Vectors
"""Subtract two tuples element-wise.
This function takes two tuples of three elements each and performs an
@ -57,7 +57,7 @@ def tuple_sub(t, t1): # sub two tuples as Vectors
return t[0] - t1[0], t[1] - t1[1], t[2] - t1[2]
def tuple_mul(t, c): # multiply two tuples with a number
def tuple_multiply(t, c): # multiply two tuples with a number
"""Multiply each element of a tuple by a given number.
This function takes a tuple containing three elements and a numeric
@ -92,7 +92,7 @@ def tuple_length(t): # get length of vector, but passed in as tuple.
# timing functions for optimisation purposes...
def timinginit():
def timing_init():
"""Initialize timing metrics.
This function sets up the initial state for timing functions by
@ -107,7 +107,7 @@ def timinginit():
return [0, 0]
def timingstart(tinf):
def timing_start(tinf):
"""Start timing by recording the current time.
This function updates the second element of the provided list with the
@ -122,7 +122,7 @@ def timingstart(tinf):
tinf[1] = t
def timingadd(tinf):
def timing_add(tinf):
"""Update the timing information.
This function updates the first element of the `tinf` list by adding the
@ -136,7 +136,7 @@ def timingadd(tinf):
tinf[0] += t - tinf[1]
def timingprint(tinf):
def timing_print(tinf):
"""Print the timing information.
This function takes a tuple containing timing information and prints it
@ -202,7 +202,7 @@ def activate(o):
bpy.context.view_layer.objects.active = o
def dist2d(v1, v2):
def distance_2d(v1, v2):
"""Calculate the distance between two points in 2D space.
This function computes the Euclidean distance between two points
@ -220,7 +220,7 @@ def dist2d(v1, v2):
return hypot((v1[0] - v2[0]), (v1[1] - v2[1]))
def delob(ob):
def delete_object(ob):
"""Delete an object in Blender for multiple uses.
This function activates the specified object and then deletes it using
@ -235,7 +235,7 @@ def delob(ob):
bpy.ops.object.delete(use_global=False)
def dupliob(o, pos):
def duplicate_object(o, pos):
"""Helper function for visualizing cutter positions in bullet simulation.
This function duplicates the specified object and resizes it according
@ -265,7 +265,7 @@ def dupliob(o, pos):
o.location = pos
def addToGroup(ob, groupname):
def add_to_group(ob, groupname):
"""Add an object to a specified group in Blender.
This function activates the given object and checks if the specified
@ -318,7 +318,7 @@ def compare(v1, v2, vmiddle, e):
return False
def isVerticalLimit(v1, v2, limit):
def is_vertical_limit(v1, v2, limit):
"""Test Path Segment on Verticality Threshold for protect_vertical option.
This function evaluates the verticality of a path segment defined by two
@ -360,7 +360,7 @@ def isVerticalLimit(v1, v2, limit):
return v1, v2
def getCachePath(o):
def get_cache_path(o):
"""Get the cache path for a given object.
This function constructs a cache path based on the current Blender
@ -385,7 +385,7 @@ def getCachePath(o):
return iname
def getSimulationPath():
def get_simulation_path():
"""Get the simulation path for temporary camera files.
This function retrieves the file path of the current Blender project and
@ -402,7 +402,7 @@ def getSimulationPath():
return iname
def safeFileName(name): # for export gcode
def safe_filename(name): # for export gcode
"""Generate a safe file name from the given string.
This function takes a string input and removes any characters that are
@ -422,7 +422,7 @@ def safeFileName(name): # for export gcode
return filename
def strInUnits(x, precision=5):
def unit_value_to_string(x, precision=5):
"""Convert a value to a string representation in the current unit system.
This function takes a numeric value and converts it to a string
@ -656,7 +656,7 @@ def duplicate(x=0.0, y=0.0):
# Mirror active object along the x axis
def mirrorx():
def mirror_x():
"""Mirror the active object along the x-axis.
This function utilizes Blender's operator to mirror the currently active
@ -673,7 +673,7 @@ def mirrorx():
# mirror active object along y axis
def mirrory():
def mirror_y():
"""Mirror the active object along the Y axis.
This function uses Blender's operator to perform a mirror transformation

Wyświetl plik

@ -1,5 +1,4 @@
"""Fabex 'simulation.py' © 2012 Vilem Novak
Functions to generate a mesh simulation from CAM Chain / Operation data.
"""
@ -13,31 +12,30 @@ from mathutils import Vector
from .async_op import progress_async
from .image_utils import (
getCutterArray,
numpysave,
get_cutter_array,
numpy_save,
)
from .simple import getSimulationPath
from .simple import get_simulation_path
from .utils import (
getBoundsMultiple,
getOperationSources,
get_bounds_multiple,
get_operation_sources,
)
def createSimulationObject(name, operations, i):
def create_simulation_object(name, operations, i):
"""Create a simulation object in Blender.
This function creates a simulation object in Blender with the specified
name and operations. If an object with the given name already exists, it
retrieves that object; otherwise, it creates a new plane object and
applies several modifiers to it. The function also sets the object's
location and scale based on the provided operations and assigns a
texture to the object.
Args:
name (str): The name of the simulation object to be created.
operations (list): A list of operation objects that contain bounding box information.
i: The image to be used as a texture for the simulation object.
"""
oname = "csim_" + name
o = operations[0]
@ -95,38 +93,38 @@ def createSimulationObject(name, operations, i):
bpy.ops.object.shade_smooth()
async def doSimulation(name, operations):
async def do_simulation(name, operations):
"""Perform simulation of operations for a 3-axis system.
This function iterates through a list of operations, retrieves the
necessary sources for each operation, and computes the bounds for the
operations. It then generates a simulation image based on the operations
and their limits, saves the image to a specified path, and finally
creates a simulation object in Blender using the generated image.
Args:
name (str): The name to be used for the simulation object.
operations (list): A list of operations to be simulated.
"""
for o in operations:
getOperationSources(o)
limits = getBoundsMultiple(
get_operation_sources(o)
limits = get_bounds_multiple(
operations
) # this is here because some background computed operations still didn't have bounds data
i = await generateSimulationImage(operations, limits)
i = await generate_simulation_image(operations, limits)
# cp = getCachePath(operations[0])[:-len(operations[0].name)] + name
cp = getSimulationPath() + name
cp = get_simulation_path() + name
print("cp=", cp)
iname = cp + "_sim.exr"
numpysave(i, iname)
numpy_save(i, iname)
i = bpy.data.images.load(iname)
createSimulationObject(name, operations, i)
create_simulation_object(name, operations, i)
async def generateSimulationImage(operations, limits):
async def generate_simulation_image(operations, limits):
"""Generate a simulation image based on provided operations and limits.
This function creates a 2D simulation image by processing a series of
operations that define how the simulation should be conducted. It uses
the limits provided to determine the boundaries of the simulation area.
@ -187,7 +185,8 @@ async def generateSimulationImage(operations, limits):
totalvolume = 0.0
cutterArray = getCutterArray(o, simulation_detail)
cutterArray = get_cutter_array(o, simulation_detail)
cutterArray = -cutterArray
lasts = verts[1].co
perc = -1
@ -238,7 +237,7 @@ async def generateSimulationImage(operations, limits):
z = lasts.z + v.z
# print(z)
if lastxs != xs or lastys != ys:
volume_partial = simCutterSpot(
volume_partial = sim_cutter_spot(
xs, ys, z, cutterArray, si, o.do_simulation_feedrate
)
if o.do_simulation_feedrate:
@ -256,7 +255,7 @@ async def generateSimulationImage(operations, limits):
ys = int(
(s.y - miny) / simulation_detail + borderwidth + simulation_detail / 2
) # -middle
volume_partial = simCutterSpot(
volume_partial = sim_cutter_spot(
xs, ys, s.z, cutterArray, si, o.do_simulation_feedrate
)
if o.do_simulation_feedrate: # compute volumes and write data into shapekey.
@ -338,7 +337,7 @@ async def generateSimulationImage(operations, limits):
return si
def simCutterSpot(xs, ys, z, cutterArray, si, getvolume=False):
def sim_cutter_spot(xs, ys, z, cutterArray, si, getvolume=False):
"""Simulates a cutter cutting into stock and optionally returns the volume
removed.

Wyświetl plik

@ -17,7 +17,7 @@ from . import (
)
def slicing2d(ob, height):
def slicing_2d(ob, height):
"""Slice a 3D object at a specified height and convert it to a curve.
This function applies transformations to the given object, switches to
@ -63,7 +63,7 @@ def slicing2d(ob, height):
return True
def slicing3d(ob, start, end):
def slicing_3d(ob, start, end):
"""Slice a 3D object along specified planes.
This function applies transformations to a given object and slices it in

Wyświetl plik

@ -24,42 +24,53 @@ import bpy
from bpy_extras import object_utils
from mathutils import Euler, Vector
from .bridges import useBridges
from .bridges import use_bridges
from .cam_chunk import (
camPathChunk,
chunksRefine,
chunksRefineThreshold,
curveToChunks,
limitChunks,
optimizeChunk,
parentChildDist,
parentChildPoly,
setChunksZ,
shapelyToChunks,
CamPathChunk,
chunks_refine,
chunks_refine_threshold,
curve_to_chunks,
limit_chunks,
optimize_chunk,
parent_child_distance,
parent_child_poly,
set_chunks_z,
shapely_to_chunks,
)
from .collision import cleanupBulletCollision
from .collision import cleanup_bullet_collision
from .exception import CamException
from .polygon_utils_cam import Circle, shapelyToCurve
from .polygon_utils_cam import circle, shapely_to_curve
from .simple import (
activate,
delob,
delete_object,
join_multiple,
progress,
remove_multiple,
subdivide_short_lines,
)
from .utils import (
Add_Pocket,
checkEqual,
extendChunks5axis,
getObjectOutline,
getObjectSilhouete,
getOperationSilhouete,
getOperationSources,
Helix,
add_pocket,
check_equal,
extend_chunks_5_axis,
get_object_outline,
get_object_silhouette,
get_operation_silhouette,
get_operation_sources,
helix,
# Point,
sampleChunksNAxis,
sortChunks,
sample_chunks_n_axis,
sort_chunks,
unique,
)
from .curvecamcreate import generate_crosshatch
@ -88,7 +99,7 @@ async def cutout(o):
on the provided object.
"""
max_depth = checkminz(o)
max_depth = check_min_z(o)
cutter_angle = radians(o.cutter_tip_angle / 2)
c_offset = o.cutter_diameter / 2 # cutter offset
print("cuttertype:", o.cutter_type, "max_depth:", max_depth)
@ -128,31 +139,34 @@ async def cutout(o):
print("separate")
chunksFromCurve = []
for ob in o.objects:
chunksFromCurve.extend(curveToChunks(ob, o.use_modifiers))
chunksFromCurve.extend(curve_to_chunks(ob, o.use_modifiers))
# chunks always have polys now
# for ch in chunksFromCurve:
# # print(ch.points)
# if len(ch.points) > 2:
# ch.poly = chunkToShapely(ch)
# ch.poly = chunk_to_shapely(ch)
# p.addContour(ch.poly)
else:
chunksFromCurve = []
if o.cut_type == "ONLINE":
p = getObjectOutline(0, o, True)
p = get_object_outline(0, o, True)
else:
offset = True
if o.cut_type == "INSIDE":
offset = False
p = getObjectOutline(c_offset, o, offset)
p = get_object_outline(c_offset, o, offset)
if o.outlines_count > 1:
for i in range(1, o.outlines_count):
chunksFromCurve.extend(shapelyToChunks(p, -1))
path_distance = o.dist_between_paths
chunksFromCurve.extend(shapely_to_chunks(p, -1))
path_distance = o.distance_between_paths
if o.cut_type == "INSIDE":
path_distance *= -1
p = p.buffer(
@ -162,16 +176,21 @@ async def cutout(o):
mitre_limit=2,
)
chunksFromCurve.extend(shapelyToChunks(p, -1))
chunksFromCurve.extend(shapely_to_chunks(p, -1))
if o.outlines_count > 1 and o.movement.insideout == "OUTSIDEIN":
chunksFromCurve.reverse()
# parentChildPoly(chunksFromCurve,chunksFromCurve,o)
chunksFromCurve = limitChunks(chunksFromCurve, o)
chunksFromCurve = limit_chunks(chunksFromCurve, o)
if not o.dont_merge:
parentChildPoly(chunksFromCurve, chunksFromCurve, o)
parent_child_poly(chunksFromCurve, chunksFromCurve, o)
if o.outlines_count == 1:
chunksFromCurve = await sortChunks(chunksFromCurve, o)
chunksFromCurve = await sort_chunks(chunksFromCurve, o)
if (o.movement.type == "CLIMB" and o.movement.spindle_rotation == "CCW") or (
o.movement.type == "CONVENTIONAL" and o.movement.spindle_rotation == "CW"
@ -184,7 +203,7 @@ async def cutout(o):
for ch in chunksFromCurve:
ch.reverse()
layers = getLayers(o, o.maxz, checkminz(o))
layers = get_layers(o, o.max_z, check_min_z(o))
extendorder = []
if o.first_down: # each shape gets either cut all the way to bottom,
@ -209,7 +228,7 @@ async def cutout(o):
chunk = chl[0]
layer = chl[1]
print(layer[1])
chunk.setZ(layer[1])
chunk.set_z(layer[1])
chunks = []
@ -224,14 +243,15 @@ async def cutout(o):
chunk = chl[0]
layer = chl[1]
if layer[1] < bridgeheight:
useBridges(chunk, o)
use_bridges(chunk, o)
if o.profile_start > 0:
print("Cutout Change Profile Start")
for chl in extendorder:
chunk = chl[0]
if chunk.closed:
chunk.changePathStart(o)
chunk.change_path_start(o)
# Lead in
if o.lead_in > 0.0 or o.lead_out > 0:
@ -239,24 +259,24 @@ async def cutout(o):
for chl in extendorder:
chunk = chl[0]
if chunk.closed:
chunk.breakPathForLeadinLeadout(o)
chunk.leadContour(o)
chunk.break_path_for_leadin_leadout(o)
chunk.lead_contour(o)
if o.movement.ramp: # add ramps or simply add chunks
for chl in extendorder:
chunk = chl[0]
layer = chl[1]
if chunk.closed:
chunk.rampContour(layer[0], layer[1], o)
chunk.ramp_contour(layer[0], layer[1], o)
chunks.append(chunk)
else:
chunk.rampZigZag(layer[0], layer[1], o)
chunk.ramp_zig_zag(layer[0], layer[1], o)
chunks.append(chunk)
else:
for chl in extendorder:
chunks.append(chl[0])
chunksToMesh(chunks, o)
chunks_to_mesh(chunks, o)
async def curve(o):
@ -283,7 +303,7 @@ async def curve(o):
print("Operation: Curve")
pathSamples = []
getOperationSources(o)
get_operation_sources(o)
if not o.onlycurves:
raise CamException("All Objects Must Be Curves for This Operation.")
@ -291,14 +311,17 @@ async def curve(o):
# make sure all polylines are at least three points long
subdivide_short_lines(ob)
# make the chunks from curve here
pathSamples.extend(curveToChunks(ob))
pathSamples.extend(curve_to_chunks(ob))
# sort before sampling
pathSamples = await sortChunks(pathSamples, o)
pathSamples = chunksRefine(pathSamples, o) # simplify
pathSamples = await sort_chunks(pathSamples, o)
pathSamples = chunks_refine(pathSamples, o) # simplify
# layers here
if o.use_layers:
layers = getLayers(o, o.maxz, round(checkminz(o), 6))
layers = get_layers(o, o.max_z, round(check_min_z(o), 6))
# layers is a list of lists [[0.00,l1],[l1,l2],[l2,l3]] containg the start and end of each layer
extendorder = []
chunks = []
@ -311,27 +334,27 @@ async def curve(o):
chunk = chl[0]
layer = chl[1]
print("layer: " + str(layer[1]))
chunk.offsetZ(o.maxz * 2 - o.minz + layer[1])
chunk.clampZ(o.minz) # safety to not cut lower than minz
chunk.offset_z(o.max_z * 2 - o.min_z + layer[1])
chunk.clamp_z(o.min_z) # safety to not cut lower than minz
# safety, not higher than free movement height
chunk.clampmaxZ(o.movement.free_height)
chunk.clamp_max_z(o.movement.free_height)
for (
chl
) in extendorder: # strip layer information from extendorder and transfer them to chunks
chunks.append(chl[0])
chunksToMesh(chunks, o) # finish by converting to mesh
chunks_to_mesh(chunks, o) # finish by converting to mesh
else: # no layers, old curve
for ch in pathSamples:
ch.clampZ(o.minz) # safety to not cut lower than minz
ch.clamp_z(o.min_z) # safety to not cut lower than minz
# safety, not higher than free movement height
ch.clampmaxZ(o.movement.free_height)
chunksToMesh(pathSamples, o)
ch.clamp_max_z(o.movement.free_height)
chunks_to_mesh(pathSamples, o)
async def proj_curve(s, o):
async def project_curve(s, o):
"""Project a curve onto another curve object.
This function takes a source object and a target object, both of which
@ -356,10 +379,11 @@ async def proj_curve(s, o):
print("Operation: Projected Curve")
pathSamples = []
chunks = []
ob = bpy.data.objects[o.curve_object]
pathSamples.extend(curveToChunks(ob))
ob = bpy.data.objects[o.curve_source]
targetCurve = s.objects[o.curve_object1]
pathSamples.extend(curve_to_chunks(ob))
targetCurve = s.objects[o.curve_target]
from cam import cam_chunk
@ -369,7 +393,9 @@ async def proj_curve(s, o):
if 1:
extend_up = 0.1
extend_down = 0.04
tsamples = curveToChunks(targetCurve)
tsamples = curve_to_chunks(targetCurve)
for chi, ch in enumerate(pathSamples):
cht = tsamples[chi].get_points()
ch.depth = 0
@ -398,10 +424,10 @@ async def proj_curve(s, o):
ch.depth = min(ch.depth, -vec.length)
ch_points[i] = sp.copy()
ch.set_points(ch_points)
layers = getLayers(o, 0, ch.depth)
layers = get_layers(o, 0, ch.depth)
chunks.extend(sampleChunksNAxis(o, pathSamples, layers))
chunksToMesh(chunks, o)
chunks.extend(sample_chunks_n_axis(o, pathSamples, layers))
chunks_to_mesh(chunks, o)
async def pocket(o):
@ -421,6 +447,7 @@ async def pocket(o):
None: The function modifies the scene and generates geometry
based on the pocketing operation.
"""
if o.straight:
join = 2
else:
@ -430,7 +457,7 @@ async def pocket(o):
remove_multiple("3D_poc")
max_depth = checkminz(o) + o.skin
max_depth = check_min_z(o) + o.skin
cutter_angle = radians(o.cutter_tip_angle / 2)
c_offset = o.cutter_diameter / 2
if o.cutter_type == "VCARVE":
@ -454,38 +481,44 @@ async def pocket(o):
else:
bpy.ops.object.curve_remove_doubles()
chunksFromCurve = []
angle = radians(o.parallelPocketAngle)
distance = o.dist_between_paths
angle = radians(o.parallel_pocket_angle)
distance = o.distance_between_paths
offset = -c_offset
pocket_shape = ""
n_angle = angle - pi / 2
pr = getObjectOutline(0, o, False)
if o.pocketType == "PARALLEL":
if o.parallelPocketContour:
pr = get_object_outline(0, o, False)
if o.pocket_type == "PARALLEL":
if o.parallel_pocket_contour:
offset = -(c_offset + distance / 2)
p = pr.buffer(
-c_offset, resolution=o.optimisation.circle_detail, join_style=join, mitre_limit=2
)
nchunks = shapelyToChunks(p, o.min.z)
nchunks = shapely_to_chunks(p, o.min.z)
chunksFromCurve.extend(nchunks)
crosshatch_result = generate_crosshatch(
bpy.context, angle, distance, offset, pocket_shape, join, c_ob
)
nchunks = shapelyToChunks(crosshatch_result, o.min.z)
nchunks = shapely_to_chunks(crosshatch_result, o.min.z)
chunksFromCurve.extend(nchunks)
if o.parallelPocketCrosshatch:
if o.parallel_pocket_crosshatch:
crosshatch_result = generate_crosshatch(
bpy.context, n_angle, distance, offset, pocket_shape, join, c_ob
)
nchunks = shapelyToChunks(crosshatch_result, o.min.z)
nchunks = shapely_to_chunks(crosshatch_result, o.min.z)
chunksFromCurve.extend(nchunks)
else:
p = pr.buffer(
-c_offset, resolution=o.optimisation.circle_detail, join_style=join, mitre_limit=2
)
approxn = (min(o.max.x - o.min.x, o.max.y - o.min.y) / o.dist_between_paths) / 2
approxn = (min(o.max.x - o.min.x, o.max.y - o.min.y) / o.distance_between_paths) / 2
print("Approximative:" + str(approxn))
print(o)
@ -497,14 +530,19 @@ async def pocket(o):
prest = p.buffer(-c_offset, o.optimisation.circle_detail)
while not p.is_empty:
if o.pocketToCurve:
if o.pocket_to_curve:
# make a curve starting with _3dpocket
shapelyToCurve("3dpocket", p, 0.0)
nchunks = shapelyToChunks(p, o.min.z)
shapely_to_curve("3dpocket", p, 0.0)
nchunks = shapely_to_chunks(p, o.min.z)
# print("nchunks")
pnew = p.buffer(
-o.dist_between_paths, o.optimisation.circle_detail, join_style=join, mitre_limit=2
-o.distance_between_paths,
o.optimisation.circle_detail,
join_style=join,
mitre_limit=2,
)
if pnew.is_empty:
@ -516,9 +554,12 @@ async def pocket(o):
pnew = pt
# print("pnew")
nchunks = limitChunks(nchunks, o)
nchunks = limit_chunks(nchunks, o)
chunksFromCurve.extend(nchunks)
parentChildDist(lastchunks, nchunks, o)
parent_child_distance(lastchunks, nchunks, o)
lastchunks = nchunks
percent = int(i / approxn * 100)
@ -534,13 +575,15 @@ async def pocket(o):
for ch in chunksFromCurve:
ch.reverse()
chunksFromCurve = await sortChunks(chunksFromCurve, o)
chunksFromCurve = await sort_chunks(chunksFromCurve, o)
chunks = []
layers = getLayers(o, o.maxz, checkminz(o))
layers = get_layers(o, o.max_z, check_min_z(o))
for l in layers:
lchunks = setChunksZ(chunksFromCurve, l[1])
lchunks = set_chunks_z(chunksFromCurve, l[1])
if o.movement.ramp:
for ch in lchunks:
ch.zstart = l[0]
@ -559,7 +602,9 @@ async def pocket(o):
# TODO:intercept closest next point when it should stay low
p = ch.get_point(0)
# first thing to do is to check if helix enter can really enter.
checkc = Circle(helix_radius + c_offset, o.optimisation.circle_detail)
checkc = circle(helix_radius + c_offset, o.optimisation.circle_detail)
checkc = affinity.translate(checkc, p[0], p[1])
covers = False
for poly in o.silhouete.geoms:
@ -570,7 +615,7 @@ async def pocket(o):
if covers:
revolutions = (l[0] - p[2]) / revheight
# print(revolutions)
h = Helix(helix_radius, o.optimisation.circle_detail, l[0], p, revolutions)
h = helix(helix_radius, o.optimisation.circle_detail, l[0], p, revolutions)
# invert helix if not the typical direction
if (
o.movement.type == "CONVENTIONAL"
@ -586,7 +631,7 @@ async def pocket(o):
else:
o.info.warnings += "Helix entry did not fit! \n "
ch.closed = True
ch.rampZigZag(l[0], l[1], o)
ch.ramp_zig_zag(l[0], l[1], o)
# Arc retract here first try:
# TODO: check for entry and exit point before actual computing... will be much better.
if o.movement.retract_tangential:
@ -615,7 +660,7 @@ async def pocket(o):
p = (p.x, p.y, p.z)
# progress(str((v1,v,p)))
h = Helix(
h = helix(
o.movement.retract_radius,
o.optimisation.circle_detail,
p[2] + o.movement.retract_height,
@ -660,18 +705,18 @@ async def pocket(o):
if o.movement.ramp:
for ch in chunks:
ch.rampZigZag(ch.zstart, ch.get_point(0)[2], o)
ch.ramp_zig_zag(ch.zstart, ch.get_point(0)[2], o)
if o.first_down:
if o.pocket_option == "OUTSIDE":
chunks.reverse()
chunks = await sortChunks(chunks, o)
chunks = await sort_chunks(chunks, o)
if o.pocketToCurve: # make curve instead of a path
if o.pocket_to_curve: # make curve instead of a path
join_multiple("3dpocket")
else:
chunksToMesh(chunks, o) # make normal pocket path
chunks_to_mesh(chunks, o) # make normal pocket path
async def drill(o):
@ -741,7 +786,9 @@ async def drill(o):
maxx, minx, maxy, miny, maxz, minz = -10000, 10000, -10000, 10000, -10000, 10000
for p in c.points:
if o.drill_type == "ALL_POINTS":
chunks.append(camPathChunk([(p.co.x + l.x, p.co.y + l.y, p.co.z + l.z)]))
chunks.append(CamPathChunk([(p.co.x + l.x, p.co.y + l.y, p.co.z + l.z)]))
minx = min(p.co.x, minx)
maxx = max(p.co.x, maxx)
miny = min(p.co.y, miny)
@ -750,7 +797,9 @@ async def drill(o):
maxz = max(p.co.z, maxz)
for p in c.bezier_points:
if o.drill_type == "ALL_POINTS":
chunks.append(camPathChunk([(p.co.x + l.x, p.co.y + l.y, p.co.z + l.z)]))
chunks.append(CamPathChunk([(p.co.x + l.x, p.co.y + l.y, p.co.z + l.z)]))
minx = min(p.co.x, minx)
maxx = max(p.co.x, maxx)
miny = min(p.co.y, miny)
@ -766,38 +815,41 @@ async def drill(o):
if (
1.3 > aspect > 0.7 and o.drill_type == "MIDDLE_SYMETRIC"
) or o.drill_type == "MIDDLE_ALL":
chunks.append(camPathChunk([(center[0] + l.x, center[1] + l.y, cz + l.z)]))
chunks.append(CamPathChunk([(center[0] + l.x, center[1] + l.y, cz + l.z)]))
elif ob.type == "MESH":
for v in ob.data.vertices:
chunks.append(camPathChunk([(v.co.x + l.x, v.co.y + l.y, v.co.z + l.z)]))
delob(ob) # delete temporary object with applied transforms
layers = getLayers(o, o.maxz, checkminz(o))
chunks.append(CamPathChunk([(v.co.x + l.x, v.co.y + l.y, v.co.z + l.z)]))
delete_object(ob) # delete temporary object with applied transforms
layers = get_layers(o, o.max_z, check_min_z(o))
chunklayers = []
for layer in layers:
for chunk in chunks:
# If using object for minz then use z from points in object
if o.minz_from == "OBJECT":
if o.min_z_from == "OBJECT":
z = chunk.get_point(0)[2]
else: # using operation minz
z = o.minz
z = o.min_z
# only add a chunk layer if the chunk z point is in or lower than the layer
if z <= layer[0]:
if z <= layer[1]:
z = layer[1]
# perform peck drill
newchunk = chunk.copy()
newchunk.setZ(z)
newchunk.set_z(z)
chunklayers.append(newchunk)
# retract tool to maxz (operation depth start in ui)
newchunk = chunk.copy()
newchunk.setZ(o.maxz)
newchunk.set_z(o.max_z)
chunklayers.append(newchunk)
chunklayers = await sortChunks(chunklayers, o)
chunksToMesh(chunklayers, o)
chunklayers = await sort_chunks(chunklayers, o)
chunks_to_mesh(chunklayers, o)
async def medial_axis(o):
@ -829,7 +881,7 @@ async def medial_axis(o):
remove_multiple("medialMesh")
from .voronoi import Site, computeVoronoiDiagram
from .voronoi import Site, compute_voronoi_diagram
chunks = []
@ -842,15 +894,15 @@ async def medial_axis(o):
if o.cutter_type == "VCARVE":
angle = o.cutter_tip_angle
# start the max depth calc from the "start depth" of the operation.
maxdepth = o.maxz - slope * o.cutter_diameter / 2 - o.skin
maxdepth = o.max_z - slope * o.cutter_diameter / 2 - o.skin
# don't cut any deeper than the "end depth" of the operation.
if maxdepth < o.minz:
maxdepth = o.minz
if maxdepth < o.min_z:
maxdepth = o.min_z
# the effective cutter diameter can be reduced from it's max
# since we will be cutting shallower than the original maxdepth
# without this, the curve is calculated as if the diameter was at the original maxdepth and we get the bit
# pulling away from the desired cut surface
new_cutter_diameter = (maxdepth - o.maxz) / (-slope) * 2
new_cutter_diameter = (maxdepth - o.max_z) / (-slope) * 2
elif o.cutter_type == "BALLNOSE":
maxdepth = -new_cutter_diameter / 2 - o.skin
else:
@ -873,7 +925,7 @@ async def medial_axis(o):
if ob.data.resolution_u < 64:
ob.data.resolution_u = 64
polys = getOperationSilhouete(o)
polys = get_operation_silhouette(o)
if isinstance(polys, list):
if len(polys) == 1 and isinstance(polys[0], shapely.MultiPolygon):
mpoly = polys[0]
@ -889,10 +941,12 @@ async def medial_axis(o):
ipol = 0
for poly in mpoly.geoms:
ipol = ipol + 1
schunks = shapelyToChunks(poly, -1)
schunks = chunksRefineThreshold(
schunks = shapely_to_chunks(poly, -1)
schunks = chunks_refine_threshold(
schunks, o.medial_axis_subdivision, o.medial_axis_threshold
) # chunksRefine(schunks,o)
) # chunks_refine(schunks,o)
verts = []
for ch in schunks:
@ -911,7 +965,7 @@ async def medial_axis(o):
# Check colinear
xValues = [pt[0] for pt in verts]
yValues = [pt[1] for pt in verts]
if checkEqual(xValues) or checkEqual(yValues):
if check_equal(xValues) or check_equal(yValues):
print("Points Are Colinear")
return {"FINISHED"}
# Create diagram
@ -921,7 +975,7 @@ async def medial_axis(o):
vertsPts = [Point(vert[0], vert[1], vert[2]) for vert in verts]
# vertsPts= [Point(vert[0], vert[1]) for vert in verts]
pts, edgesIdx = computeVoronoiDiagram(
pts, edgesIdx = compute_voronoi_diagram(
vertsPts, xbuff, ybuff, polygonsOutput=False, formatOutput=True
)
@ -954,7 +1008,7 @@ async def medial_axis(o):
vertr.append((False, newIdx))
if o.cutter_type == "VCARVE":
# start the z depth calc from the "start depth" of the operation.
z = o.maxz - mpoly.boundary.distance(sgeometry.Point(p)) * slope
z = o.max_z - mpoly.boundary.distance(sgeometry.Point(p)) * slope
if z < maxdepth:
z = maxdepth
elif o.cutter_type == "BALL" or o.cutter_type == "BALLNOSE":
@ -998,12 +1052,16 @@ async def medial_axis(o):
if bufpoly.type == "Polygon" or bufpoly.type == "MultiPolygon":
lines = lines.difference(bufpoly)
chunks.extend(shapelyToChunks(bufpoly, maxdepth))
chunks.extend(shapelyToChunks(lines, 0))
chunks.extend(shapely_to_chunks(bufpoly, maxdepth))
chunks.extend(shapely_to_chunks(lines, 0))
# generate a mesh from the medial calculations
if o.add_mesh_for_medial:
shapelyToCurve("medialMesh", lines, 0.0)
shapely_to_curve("medialMesh", lines, 0.0)
bpy.ops.object.convert(target="MESH")
oi = 0
@ -1013,34 +1071,36 @@ async def medial_axis(o):
oi += 1
# bpy.ops.object.join()
chunks = await sortChunks(chunks, o)
chunks = await sort_chunks(chunks, o)
layers = getLayers(o, o.maxz, o.min.z)
layers = get_layers(o, o.max_z, o.min.z)
chunklayers = []
for layer in layers:
for chunk in chunks:
if chunk.isbelowZ(layer[0]):
if chunk.is_below_z(layer[0]):
newchunk = chunk.copy()
newchunk.clampZ(layer[1])
newchunk.clamp_z(layer[1])
chunklayers.append(newchunk)
if o.first_down:
chunklayers = await sortChunks(chunklayers, o)
chunklayers = await sort_chunks(chunklayers, o)
if o.add_mesh_for_medial: # make curve instead of a path
join_multiple("medialMesh")
chunksToMesh(chunklayers, o)
chunks_to_mesh(chunklayers, o)
# add pocket operation for medial if add pocket checked
if o.add_pocket_for_medial:
# o.add_pocket_for_medial = False
# export medial axis parameter to pocket op
Add_Pocket(maxdepth, m_o_ob, new_cutter_diameter)
add_pocket(maxdepth, m_o_ob, new_cutter_diameter)
def getLayers(operation, startdepth, enddepth):
def get_layers(operation, startdepth, enddepth):
"""Returns a list of layers bounded by start depth and end depth.
This function calculates the layers between the specified start and end
@ -1064,18 +1124,21 @@ def getLayers(operation, startdepth, enddepth):
Raises:
CamException: If the start depth is lower than the end depth.
"""
if startdepth < enddepth:
raise CamException(
"Start Depth Is Lower than End Depth. "
"if You Have Set a Custom Depth End, It Must Be Lower than Depth Start, "
"and Should Usually Be Negative. Set This in the CAM Operation Area Panel."
)
if operation.use_layers:
layers = []
n = ceil((startdepth - enddepth) / operation.stepdown)
print("Start " + str(startdepth) + " End " + str(enddepth) + " n " + str(n))
layerstart = operation.maxz
layerstart = operation.max_z
for x in range(0, n):
layerend = round(max(startdepth - ((x + 1) * operation.stepdown), enddepth), 6)
if int(layerstart * 10**8) != int(layerend * 10**8):
@ -1089,7 +1152,7 @@ def getLayers(operation, startdepth, enddepth):
return layers
def chunksToMesh(chunks, o):
def chunks_to_mesh(chunks, o):
"""Convert sampled chunks into a mesh path for a given optimization object.
This function takes a list of sampled chunks and converts them into a
@ -1107,6 +1170,7 @@ def chunksToMesh(chunks, o):
None: The function creates a mesh in the Blender context but does not return a
value.
"""
t = time.time()
s = bpy.context.scene
m = s.cam_machine
@ -1123,10 +1187,10 @@ def chunksToMesh(chunks, o):
verts = [origin]
if o.machine_axes != "3":
verts_rotations = [] # (0,0,0)
if (o.machine_axes == "5" and o.strategy5axis == "INDEXED") or (
o.machine_axes == "4" and o.strategy4axis == "INDEXED"
if (o.machine_axes == "5" and o.strategy_5_axis == "INDEXED") or (
o.machine_axes == "4" and o.strategy_4_axis == "INDEXED"
):
extendChunks5axis(chunks, o)
extend_chunks_5_axis(chunks, o)
if o.array:
nchunks = []
@ -1153,7 +1217,8 @@ def chunksToMesh(chunks, o):
# print(len(ch.points))
nverts = []
if o.optimisation.optimize:
ch = optimizeChunk(ch, o)
ch = optimize_chunk(ch, o)
# lift and drop
@ -1162,8 +1227,8 @@ def chunksToMesh(chunks, o):
): # did the cutter lift before? if yes, put a new position above of the first point of next chunk.
if (
o.machine_axes == "3"
or (o.machine_axes == "5" and o.strategy5axis == "INDEXED")
or (o.machine_axes == "4" and o.strategy4axis == "INDEXED")
or (o.machine_axes == "5" and o.strategy_5_axis == "INDEXED")
or (o.machine_axes == "4" and o.strategy_4_axis == "INDEXED")
):
v = (ch.get_point(0)[0], ch.get_point(0)[1], free_height)
else: # otherwise, continue with the next chunk without lifting/dropping
@ -1189,8 +1254,8 @@ def chunksToMesh(chunks, o):
o.machine_axes == "3"
and (o.strategy == "PARALLEL" or o.strategy == "CROSS")
and vect.z == 0
and vect.length < o.dist_between_paths * 2.5
) or (o.machine_axes == "4" and vect.length < o.dist_between_paths * 2.5):
and vect.length < o.distance_between_paths * 2.5
) or (o.machine_axes == "4" and vect.length < o.distance_between_paths * 2.5):
# case of neighbouring paths
lift = False
# case of stepdown by cutting.
@ -1200,8 +1265,8 @@ def chunksToMesh(chunks, o):
if lift:
if (
o.machine_axes == "3"
or (o.machine_axes == "5" and o.strategy5axis == "INDEXED")
or (o.machine_axes == "4" and o.strategy4axis == "INDEXED")
or (o.machine_axes == "5" and o.strategy_5_axis == "INDEXED")
or (o.machine_axes == "4" and o.strategy_4_axis == "INDEXED")
):
v = (ch.get_point(-1)[0], ch.get_point(-1)[1], free_height)
else:
@ -1211,7 +1276,9 @@ def chunksToMesh(chunks, o):
lifted = lift
# print(verts_rotations)
if o.optimisation.use_exact and not o.optimisation.use_opencamlib:
cleanupBulletCollision(o)
cleanup_bullet_collision(o)
print(time.time() - t)
t = time.time()
@ -1261,7 +1328,7 @@ def chunksToMesh(chunks, o):
ob.select_set(state=True, view_layer=None)
def checkminz(o):
def check_min_z(o):
"""Check the minimum value based on the specified condition.
This function evaluates the 'minz_from' attribute of the input object
@ -1272,10 +1339,10 @@ def checkminz(o):
o (object): An object that has attributes 'minz_from', 'min', and 'minz'.
Returns:
The minimum value, which can be either 'o.min.z' or 'o.minz' depending
The minimum value, which can be either 'o.min.z' or 'o.min_z' depending
on the condition.
"""
if o.minz_from == "MATERIAL":
if o.min_z_from == "MATERIAL":
return o.min.z
else:
return o.minz
return o.min_z

Wyświetl plik

@ -17,7 +17,7 @@ from bpy.types import (
PropertyGroup,
)
from ..gcodeimportparser import import_gcode
from ..gcode_import_parser import import_gcode
class CAM_UL_orientations(UIList):

Wyświetl plik

@ -7,7 +7,7 @@ import bpy
from bpy.types import Panel
from .buttons_panel import CAMButtonsPanel
from ...simple import strInUnits
from ...simple import unit_value_to_string
class CAM_AREA_Panel(CAMButtonsPanel, Panel):
@ -32,7 +32,7 @@ class CAM_AREA_Panel(CAMButtonsPanel, Panel):
col = box.column(align=True)
col.label(text="Z Clearance", icon="CON_FLOOR")
col.prop(self.op.movement, "free_height")
if self.op.maxz > self.op.movement.free_height:
if self.op.max_z > self.op.movement.free_height:
box = col.box()
col = box.column(align=True)
col.alert = True
@ -46,7 +46,7 @@ class CAM_AREA_Panel(CAMButtonsPanel, Panel):
col.label(text="Operation Depth")
col.prop(self.op, "maxz", text="Start")
# col.prop(self.op.movement, "free_height")
if self.op.maxz > self.op.movement.free_height:
if self.op.max_z > self.op.movement.free_height:
box = col.box()
box.alert = True
sub = box.column(align=True)
@ -61,7 +61,7 @@ class CAM_AREA_Panel(CAMButtonsPanel, Panel):
box = col.box()
box.alert = True
box.label(text="Cannot Use Depth from Object Using Curves", icon="ERROR")
depth = self.op.minz_from
depth = self.op.min_z_from
if depth == "MATERIAL":
icon = depth
elif depth == "OBJECT":
@ -69,7 +69,7 @@ class CAM_AREA_Panel(CAMButtonsPanel, Panel):
else:
icon = "USER"
col.prop(self.op, "minz_from", text="Max", icon=icon)
if self.op.minz_from == "CUSTOM":
if self.op.min_z_from == "CUSTOM":
col.prop(self.op, "minz")
else:
@ -80,7 +80,7 @@ class CAM_AREA_Panel(CAMButtonsPanel, Panel):
if i is not None:
size_x = self.op.source_image_size_x / i.size[0]
size_y = int(x_size * i.size[1] * 1000000) / 1000
col.label(text="Image Size on Y Axis: " + strInUnits(size_y, 8))
col.label(text="Image Size on Y Axis: " + unit_value_to_string(size_y, 8))
col.separator()
col.prop(self.op, "source_image_offset")
col.prop(self.op, "source_image_crop", text="Crop Source Image")

Wyświetl plik

@ -7,7 +7,7 @@ import bpy
from bpy.types import UIList, Panel
from .buttons_panel import CAMButtonsPanel
from ...utils import isChainValid
from ...utils import chain_valid
class CAM_UL_operations(UIList):
@ -18,7 +18,7 @@ class CAM_UL_operations(UIList):
layout.label(text=item.name, translate=False, icon_value=icon)
icon = "LOCKED" if operation.computing else "UNLOCKED"
if operation.computing:
layout.label(text=operation.outtext) # "computing" )
layout.label(text=operation.out_text) # "computing" )
elif self.layout_type in {"GRID"}:
layout.alignment = "CENTER"
layout.label(text="", icon_value=icon)
@ -105,7 +105,7 @@ class CAM_CHAINS_Panel(CAMButtonsPanel, Panel):
icon="RESTRICT_INSTANCED_OFF",
)
valid, reason = isChainValid(chain, context)
valid, reason = chain_valid(chain, context)
if not valid:
col.alert = True
col.label(icon="ERROR", text=f"Can't Compute Chain!")

Wyświetl plik

@ -107,9 +107,11 @@ class CAM_CUTTER_Panel(CAMButtonsPanel, Panel):
col = box.column(align=True)
# Warns if cutter engagement is greater than 50%
if self.op.cutter_type in ["BALLCONE"]:
engagement = round(100 * self.op.dist_between_paths / self.op.ball_radius, 1)
engagement = round(100 * self.op.distance_between_paths / self.op.ball_radius, 1)
else:
engagement = round(100 * self.op.dist_between_paths / self.op.cutter_diameter, 1)
engagement = round(
100 * self.op.distance_between_paths / self.op.cutter_diameter, 1
)
if engagement > 50:
col.alert = True

Wyświetl plik

@ -23,7 +23,7 @@ from ...constants import (
CHIPLOAD_PRECISION,
MAX_OPERATION_TIME,
)
from ...simple import strInUnits
from ...simple import unit_value_to_string
from ...version import __version__ as cam_version
# Info panel
@ -104,10 +104,12 @@ class CAM_INFO_Panel(CAMButtonsPanel, Panel):
col = box.column(align=True)
# Warns if cutter engagement is greater than 50%
if self.op.cutter_type in ["BALLCONE"]:
engagement = round(100 * self.op.dist_between_paths / self.op.ball_radius, 1)
engagement = round(
100 * self.op.distance_between_paths / self.op.ball_radius, 1
)
else:
engagement = round(
100 * self.op.dist_between_paths / self.op.cutter_diameter, 1
100 * self.op.distance_between_paths / self.op.cutter_diameter, 1
)
if engagement > 50:
@ -138,7 +140,7 @@ class CAM_INFO_Panel(CAMButtonsPanel, Panel):
if not self.op.info.chipload > 0:
pass
else:
chipload = f"Chipload: {strInUnits(self.op.info.chipload, 4)}/tooth"
chipload = f"Chipload: {unit_value_to_string(self.op.info.chipload, 4)}/tooth"
col.label(text=chipload, icon="DRIVER_ROTATIONAL_DIFFERENCE")
# Operation Money Cost

Wyświetl plik

@ -18,7 +18,7 @@ from bpy.types import (
from .buttons_panel import CAMButtonsPanel
from ...utils import (
positionObject,
position_object,
update_material,
)
from ...constants import PRECISION
@ -112,7 +112,7 @@ class CAM_MATERIAL_PositionObject(Operator):
scene = context.scene
operation = scene.cam_operations[scene.cam_active_operation]
if operation.object_name in bpy.data.objects:
positionObject(operation)
position_object(operation)
else:
print("No Object Assigned")
return {"FINISHED"}

Wyświetl plik

@ -264,7 +264,7 @@ class CAM_MOVEMENT_Panel(CAMButtonsPanel, Panel):
boxcol = box.column(align=True)
boxcol.label(text="Z Clearance", icon="CON_FLOOR")
boxcol.prop(self.op.movement, "free_height")
if self.op.maxz > self.op.movement.free_height:
if self.op.max_z > self.op.movement.free_height:
box = boxcol.box()
subcol = box.column(align=True)
subcol.alert = True

Wyświetl plik

@ -41,13 +41,13 @@ class CAM_OPERATION_PROPERTIES_Panel(CAMButtonsPanel, Panel):
# Strategy
if self.op.machine_axes == "4":
col.prop(self.op, "strategy4axis")
if self.op.strategy4axis == "INDEXED":
col.prop(self.op, "strategy_4_axis")
if self.op.strategy_4_axis == "INDEXED":
col.prop(self.op, "strategy")
col.prop(self.op, "rotary_axis_1")
elif self.op.machine_axes == "5":
col.prop(self.op, "strategy5axis")
if self.op.strategy5axis == "INDEXED":
col.prop(self.op, "strategy_5_axis")
if self.op.strategy_5_axis == "INDEXED":
col.prop(self.op, "strategy")
col.prop(self.op, "rotary_axis_1")
col.prop(self.op, "rotary_axis_2")
@ -97,7 +97,7 @@ class CAM_OPERATION_PROPERTIES_Panel(CAMButtonsPanel, Panel):
box = subcol.box()
sub = box.column(align=True)
sub.label(text="Toolpath Distance")
sub.prop(self.op, "dist_between_paths", text="Between")
sub.prop(self.op, "distance_between_paths", text="Between")
# self.draw_cutter_engagement(col=col)
# Waterline Options
@ -125,7 +125,7 @@ class CAM_OPERATION_PROPERTIES_Panel(CAMButtonsPanel, Panel):
box = col.box()
sub = box.column(align=True)
sub.label(text="Toolpath Distance")
sub.prop(self.op, "dist_between_paths", text="Between")
sub.prop(self.op, "distance_between_paths", text="Between")
# Carve Options
if self.op.strategy in ["CARVE"]:
@ -135,7 +135,7 @@ class CAM_OPERATION_PROPERTIES_Panel(CAMButtonsPanel, Panel):
box = col.box()
sub = box.column(align=True)
sub.label(text="Toolpath Distance")
sub.prop(self.op, "dist_along_paths", text="Along")
sub.prop(self.op, "distance_along_paths", text="Along")
# Medial Axis Options
if self.op.strategy in ["MEDIAL_AXIS"]:
@ -161,28 +161,28 @@ class CAM_OPERATION_PROPERTIES_Panel(CAMButtonsPanel, Panel):
if self.op.strategy in ["POCKET"]:
# box = layout.box()
col = box.column(align=True)
if self.op.pocketType == "PARALLEL":
if self.op.pocket_type == "PARALLEL":
warnbox = col.box()
warnbox.alert = True
warnbox.label(text="! Warning ! Experimental !", icon="ERROR")
col.prop(self.op, "pocketType", text="Type")
if self.op.pocketType == "PARALLEL":
col.prop(self.op, "parallelPocketAngle", text="Angle")
col.prop(self.op, "pocket_type", text="Type")
if self.op.pocket_type == "PARALLEL":
col.prop(self.op, "parallel_pocket_angle", text="Angle")
subcol = col.column(align=True)
subcol.use_property_split = False
subcol.prop(self.op, "parallelPocketCrosshatch", text="Crosshatch")
subcol.prop(self.op, "parallelPocketContour")
subcol.prop(self.op, "parallel_pocket_crosshatch", text="Crosshatch")
subcol.prop(self.op, "parallel_pocket_contour")
else:
col.prop(self.op, "pocket_option")
self.draw_overshoot(col=col)
row = col.row()
row.use_property_split = False
row.prop(self.op, "pocketToCurve")
row.prop(self.op, "pocket_to_curve")
box = col.box()
sub = box.column(align=True)
sub.label(text="Toolpath Distance")
sub.prop(self.op, "dist_between_paths", text="Between")
sub.prop(self.op, "distance_between_paths", text="Between")
# Default Options
if self.op.strategy not in [
@ -205,8 +205,8 @@ class CAM_OPERATION_PROPERTIES_Panel(CAMButtonsPanel, Panel):
box = col.box()
col = box.column(align=True)
col.label(text="Toolpath Distance")
col.prop(self.op, "dist_between_paths", text="Between")
col.prop(self.op, "dist_along_paths", text="Along")
col.prop(self.op, "distance_between_paths", text="Between")
col.prop(self.op, "distance_along_paths", text="Along")
# A & B, Array, Bridges Options
if self.level >= 1:
@ -227,23 +227,23 @@ class CAM_OPERATION_PROPERTIES_Panel(CAMButtonsPanel, Panel):
subheader, subpanel = panel.panel("a_axis", default_closed=True)
subheader.prop(self.op, "enable_A", text="A Axis")
if subpanel:
subpanel.enabled = self.op.enable_A
subpanel.enabled = self.op.enable_a_axis
col = subpanel.column(align=True)
row = col.row()
row.use_property_split = True
row.prop(self.op, "rotation_A")
row.prop(self.op, "rotation_a")
col.prop(self.op, "A_along_x")
if self.op.A_along_x:
if self.op.a_along_x:
col.label(text="Ⓐ || Ⓧ - Ⓑ || Ⓨ")
else:
col.label(text="Ⓐ || Ⓨ - Ⓑ || Ⓧ")
subheader, subpanel = panel.panel("b_axis", default_closed=True)
subheader.prop(self.op, "enable_B", text="B Axis")
if subpanel:
subpanel.enabled = self.op.enable_B
subpanel.enabled = self.op.enable_b_axis
col = subpanel.column(align=True)
col.use_property_split = True
col.prop(self.op, "rotation_B")
col.prop(self.op, "rotation_b")
# Array
if self.op.machine_axes == "3":

Wyświetl plik

@ -69,7 +69,7 @@ class CAM_OPERATIONS_Panel(CAMButtonsPanel, Panel):
return
# Calculate Path
if self.op.maxz > self.op.movement.free_height:
if self.op.max_z > self.op.movement.free_height:
box = layout.box()
col = box.column(align=True)
col.alert = True
@ -118,10 +118,10 @@ class CAM_OPERATIONS_Panel(CAMButtonsPanel, Panel):
else:
if self.op.geometry_source == "OBJECT":
col.prop_search(self.op, "object_name", bpy.data, "objects")
if self.op.enable_A:
col.prop(self.op, "rotation_A")
if self.op.enable_B:
col.prop(self.op, "rotation_B")
if self.op.enable_a_axis:
col.prop(self.op, "rotation_a")
if self.op.enable_b_axis:
col.prop(self.op, "rotation_b")
elif self.op.geometry_source == "COLLECTION":
col.prop_search(self.op, "collection_name", bpy.data, "collections")

Wyświetl plik

@ -31,7 +31,7 @@ class CAM_SLICE_Panel(CAMButtonsPanel, Panel):
settings = scene.cam_slice
col = layout.column(align=True)
col.prop(settings, "slice_distance")
col.prop(settings, "slice_above0")
col.prop(settings, "slice_above_0")
col.prop(settings, "slice_3d")
col.prop(settings, "indexes")

Wyświetl plik

@ -38,7 +38,7 @@ class VIEW3D_MT_PIE_Chains(Menu):
# Top
box = pie.box()
column = box.column(align=True)
if operation.maxz > operation.movement.free_height:
if operation.max_z > operation.movement.free_height:
column.label(text="!ERROR! COLLISION!")
column.label(text="Depth Start > Free Movement Height")
column.label(text="!ERROR! COLLISION!")

Wyświetl plik

@ -87,7 +87,7 @@ class Context(object):
self.polygons = {} # a dict of site:[edges] pairs
########Clip functions########
def getClipEdges(self):
def get_clip_edges(self):
"""Get the clipped edges based on the current extent.
This function iterates through the edges of a geometric shape and
@ -110,14 +110,14 @@ class Context(object):
x1, y1 = self.vertices[edge[1]][0], self.vertices[edge[1]][1]
x2, y2 = self.vertices[edge[2]][0], self.vertices[edge[2]][1]
pt1, pt2 = (x1, y1), (x2, y2)
inExtentP1, inExtentP2 = self.inExtent(x1, y1), self.inExtent(x2, y2)
inExtentP1, inExtentP2 = self.in_extent(x1, y1), self.in_extent(x2, y2)
if inExtentP1 and inExtentP2:
clipEdges.append((pt1, pt2))
elif inExtentP1 and not inExtentP2:
pt2 = self.clipLine(x1, y1, equation, leftDir=False)
pt2 = self.clip_line(x1, y1, equation, leftDir=False)
clipEdges.append((pt1, pt2))
elif not inExtentP1 and inExtentP2:
pt1 = self.clipLine(x2, y2, equation, leftDir=True)
pt1 = self.clip_line(x2, y2, equation, leftDir=True)
clipEdges.append((pt1, pt2))
else: # infinite line
if edge[1] != -1:
@ -126,13 +126,13 @@ class Context(object):
else:
x1, y1 = self.vertices[edge[2]][0], self.vertices[edge[2]][1]
leftDir = True
if self.inExtent(x1, y1):
if self.in_extent(x1, y1):
pt1 = (x1, y1)
pt2 = self.clipLine(x1, y1, equation, leftDir)
pt2 = self.clip_line(x1, y1, equation, leftDir)
clipEdges.append((pt1, pt2))
return clipEdges
def getClipPolygons(self, closePoly):
def get_clip_polygons(self, closePoly):
"""Get clipped polygons based on the provided edges.
This function processes a set of polygons defined by their edges and
@ -161,14 +161,14 @@ class Context(object):
x1, y1 = self.vertices[edge[1]][0], self.vertices[edge[1]][1]
x2, y2 = self.vertices[edge[2]][0], self.vertices[edge[2]][1]
pt1, pt2 = (x1, y1), (x2, y2)
inExtentP1, inExtentP2 = self.inExtent(x1, y1), self.inExtent(x2, y2)
inExtentP1, inExtentP2 = self.in_extent(x1, y1), self.in_extent(x2, y2)
if inExtentP1 and inExtentP2:
clipEdges.append((pt1, pt2))
elif inExtentP1 and not inExtentP2:
pt2 = self.clipLine(x1, y1, equation, leftDir=False)
pt2 = self.clip_line(x1, y1, equation, leftDir=False)
clipEdges.append((pt1, pt2))
elif not inExtentP1 and inExtentP2:
pt1 = self.clipLine(x2, y2, equation, leftDir=True)
pt1 = self.clip_line(x2, y2, equation, leftDir=True)
clipEdges.append((pt1, pt2))
else: # infinite line
if edge[1] != -1:
@ -177,12 +177,12 @@ class Context(object):
else:
x1, y1 = self.vertices[edge[2]][0], self.vertices[edge[2]][1]
leftDir = True
if self.inExtent(x1, y1):
if self.in_extent(x1, y1):
pt1 = (x1, y1)
pt2 = self.clipLine(x1, y1, equation, leftDir)
pt2 = self.clip_line(x1, y1, equation, leftDir)
clipEdges.append((pt1, pt2))
# create polygon definition from edges and check if polygon is completely closed
polyPts, complete = self.orderPts(clipEdges)
polyPts, complete = self.order_points(clipEdges)
if not complete:
startPt = polyPts[0]
endPt = polyPts[-1]
@ -215,7 +215,7 @@ class Context(object):
poly[inPtsIdx] = polyPts
return poly
def clipLine(self, x1, y1, equation, leftDir):
def clip_line(self, x1, y1, equation, leftDir):
"""Clip a line segment defined by its endpoints against a bounding box.
This function calculates the intersection points of a line defined by
@ -270,7 +270,7 @@ class Context(object):
pt = max(intersectPts)
return pt
def inExtent(self, x, y):
def in_extent(self, x, y):
"""Check if a point is within the defined extent.
This function determines whether the given coordinates (x, y) fall
@ -289,7 +289,7 @@ class Context(object):
xmin, xmax, ymin, ymax = self.extent
return x >= xmin and x <= xmax and y >= ymin and y <= ymax
def orderPts(self, edges):
def order_points(self, edges):
"""Order points to form a polygon.
This function takes a list of edges, where each edge is represented as a
@ -346,7 +346,7 @@ class Context(object):
del edges[i]
return poly, complete
def setClipBuffer(self, xpourcent, ypourcent):
def set_clip_buffer(self, xpourcent, ypourcent):
"""Set the clipping buffer based on percentage adjustments.
This function modifies the clipping extent of an object by adjusting its
@ -374,7 +374,7 @@ class Context(object):
# End clip functions########
def outSite(self, s):
def out_site(self, s):
"""Handle output for a site object.
This function processes the output based on the current settings of the
@ -396,7 +396,7 @@ class Context(object):
elif self.doPrint:
print("s %f %f" % (s.x, s.y))
def outVertex(self, s):
def out_vertex(self, s):
"""Add a vertex to the list of vertices.
This function appends the coordinates of a given vertex to the internal
@ -420,7 +420,7 @@ class Context(object):
elif self.doPrint:
print("v %f %f" % (s.x, s.y))
def outTriple(self, s1, s2, s3):
def out_triple(self, s1, s2, s3):
"""Add a triangle defined by three site numbers to the list of triangles.
This function takes three site objects, extracts their site numbers, and
@ -445,7 +445,7 @@ class Context(object):
elif self.triangulate and self.doPrint:
print("%d %d %d" % (s1.sitenum, s2.sitenum, s3.sitenum))
def outBisector(self, edge):
def out_bisector(self, edge):
"""Process and log the outbisector of a given edge.
This function appends the parameters of the edge (a, b, c) to the lines
@ -470,7 +470,7 @@ class Context(object):
elif self.doPrint:
print("l %f %f %f" % (edge.a, edge.b, edge.c))
def outEdge(self, edge):
def out_edge(self, edge):
"""Process an edge and update the associated polygons and edges.
This function takes an edge as input and retrieves the site numbers
@ -536,26 +536,26 @@ def voronoi(siteList, context):
siteIter = siteList.iterator()
bottomsite = siteIter.next()
context.outSite(bottomsite)
context.out_site(bottomsite)
newsite = siteIter.next()
minpt = Site(-BIG_FLOAT, -BIG_FLOAT)
while True:
if not priorityQ.isEmpty():
minpt = priorityQ.getMinPt()
if not priorityQ.is_empty():
minpt = priorityQ.get_min_point()
if newsite and (priorityQ.isEmpty() or newsite < minpt):
if newsite and (priorityQ.is_empty() or newsite < minpt):
# newsite is smallest - this is a site event
context.outSite(newsite)
context.out_site(newsite)
# get first Halfedge to the LEFT and RIGHT of the new site
lbnd = edgeList.leftbnd(newsite)
lbnd = edgeList.left_bnd(newsite)
rbnd = lbnd.right
# if this halfedge has no edge, bot = bottom site (whatever that is)
# create a new edge that bisects
bot = lbnd.rightreg(bottomsite)
edge = Edge.bisect(bot, newsite)
context.outBisector(edge)
context.out_bisector(edge)
# create a new Halfedge, setting its pm field to 0 and insert
# this new bisector edge between the left and right vectors in
@ -584,13 +584,13 @@ def voronoi(siteList, context):
newsite = siteIter.next()
elif not priorityQ.isEmpty():
elif not priorityQ.is_empty():
# intersection is smallest - this is a vector (circle) event
# pop the Halfedge with the lowest vector off the ordered list of
# vectors. Get the Halfedge to the left and right of the above HE
# and also the Halfedge to the right of the right HE
lbnd = priorityQ.popMinHalfedge()
lbnd = priorityQ.pop_min_halfedge()
llbnd = lbnd.left
rbnd = lbnd.right
rrbnd = rbnd.right
@ -602,20 +602,20 @@ def voronoi(siteList, context):
# output the triple of sites, stating that a circle goes through them
mid = lbnd.rightreg(bottomsite)
context.outTriple(bot, top, mid)
context.out_triple(bot, top, mid)
# get the vertex that caused this event and set the vertex number
# couldn't do this earlier since we didn't know when it would be processed
v = lbnd.vertex
siteList.setSiteNumber(v)
context.outVertex(v)
siteList.set_site_number(v)
context.out_vertex(v)
# set the endpoint of the left and right Halfedge to be this vector
if lbnd.edge.setEndpoint(lbnd.pm, v):
context.outEdge(lbnd.edge)
context.out_edge(lbnd.edge)
if rbnd.edge.setEndpoint(rbnd.pm, v):
context.outEdge(rbnd.edge)
context.out_edge(rbnd.edge)
# delete the lowest HE, remove all vertex events to do with the
# right HE and delete the right HE
@ -633,7 +633,7 @@ def voronoi(siteList, context):
# Create an Edge (or line) that is between the two Sites. This
# creates the formula of the line, and assigns a line number to it
edge = Edge.bisect(bot, top)
context.outBisector(edge)
context.out_bisector(edge)
# create a HE from the edge
bisector = Halfedge(edge, pm)
@ -644,7 +644,7 @@ def voronoi(siteList, context):
# Site, then this endpoint is put in position 0; otherwise in pos 1
edgeList.insert(llbnd, bisector)
if edge.setEndpoint(Edge.RE - pm, v):
context.outEdge(edge)
context.out_edge(edge)
# if left HE and the new bisector don't intersect, then delete
# the left HE, and reinsert it
@ -662,13 +662,13 @@ def voronoi(siteList, context):
he = edgeList.leftend.right
while he is not edgeList.rightend:
context.outEdge(he.edge)
context.out_edge(he.edge)
he = he.right
Edge.EDGE_NUM = 0 # CF
# ------------------------------------------------------------------
def isEqual(a, b, relativeError=TOLERANCE):
def is_equal(a, b, relativeError=TOLERANCE):
"""Check if two values are nearly equal within a specified relative error.
This function determines if the absolute difference between two values
@ -809,7 +809,7 @@ class Edge(object):
print("ep", self.ep)
print("reg", self.reg)
def setEndpoint(self, lrFlag, site):
def set_endpoint(self, lrFlag, site):
"""Set the endpoint for a given flag.
This function assigns a site to the specified endpoint flag. It checks
@ -961,7 +961,7 @@ class Halfedge(object):
if self.ystar == other.ystar and self.vertex.x == other.vertex.x:
return True
def leftreg(self, default):
def left_reg(self, default):
"""Retrieve the left registration value based on the edge state.
This function checks the state of the edge attribute. If the edge is not
@ -982,7 +982,7 @@ class Halfedge(object):
else:
return self.edge.reg[Edge.RE]
def rightreg(self, default):
def right_reg(self, default):
"""Retrieve the appropriate registration value based on the edge state.
This function checks if the current edge is set. If it is not set, it
@ -1006,7 +1006,7 @@ class Halfedge(object):
return self.edge.reg[Edge.LE]
# returns True if p is to right of halfedge self
def isPointRightOf(self, pt):
def is_point_right_of(self, pt):
"""Determine if a point is to the right of a half-edge.
This function checks whether the given point `pt` is located to the
@ -1093,7 +1093,7 @@ class Halfedge(object):
return None
d = e1.a * e2.b - e1.b * e2.a
if isEqual(d, 0.0):
if is_equal(d, 0.0):
return None
xint = (e1.c * e2.b - e2.c * e1.b) / d
@ -1164,7 +1164,7 @@ class EdgeList(object):
he.edge = Edge.DELETED
# Get entry from hash table, pruning any deleted nodes
def gethash(self, b):
def get_hash(self, b):
"""Retrieve an entry from the hash table, ignoring deleted nodes.
This function checks if the provided index is within the valid range of
@ -1189,7 +1189,7 @@ class EdgeList(object):
self.hash[b] = None
return None
def leftbnd(self, pt):
def left_bnd(self, pt):
"""Find the left boundary half-edge for a given point.
This function computes the appropriate half-edge that is to the left of
@ -1216,14 +1216,14 @@ class EdgeList(object):
if bucket >= self.hashsize:
bucket = self.hashsize - 1
he = self.gethash(bucket)
he = self.get_hash(bucket)
if he is None:
i = 1
while True:
he = self.gethash(bucket - i)
he = self.get_hash(bucket - i)
if he is not None:
break
he = self.gethash(bucket + i)
he = self.get_hash(bucket + i)
if he is not None:
break
i += 1
@ -1270,7 +1270,7 @@ class PriorityQueue(object):
"""
return self.count
def isEmpty(self):
def is_empty(self):
"""Check if the object is empty.
This method determines whether the object contains any elements by
@ -1303,7 +1303,7 @@ class PriorityQueue(object):
"""
he.vertex = site
he.ystar = site.y + offset
last = self.hash[self.getBucket(he)]
last = self.hash[self.get_bucket(he)]
next = last.qnext
while (next is not None) and he > next:
last = next
@ -1326,14 +1326,14 @@ class PriorityQueue(object):
he (Element): The element to be deleted from the data structure.
"""
if he.vertex is not None:
last = self.hash[self.getBucket(he)]
last = self.hash[self.get_bucket(he)]
while last.qnext is not he:
last = last.qnext
last.qnext = he.qnext
self.count -= 1
he.vertex = None
def getBucket(self, he):
def get_bucket(self, he):
"""Get the appropriate bucket index for a given value.
This function calculates the bucket index based on the provided value
@ -1360,7 +1360,7 @@ class PriorityQueue(object):
self.minidx = bucket
return bucket
def getMinPt(self):
def get_min_point(self):
"""Retrieve the minimum point from a hash table.
This function iterates through the hash table starting from the current
@ -1378,7 +1378,7 @@ class PriorityQueue(object):
y = he.ystar
return Site(x, y)
def popMinHalfedge(self):
def pop_min_halfedge(self):
"""Remove and return the minimum half-edge from the data structure.
This function retrieves the minimum half-edge from a hash table, updates
@ -1413,7 +1413,7 @@ class SiteList(object):
self.__sites.append(Site(pt.x, pt.y, i))
self.__sites.sort()
def setSiteNumber(self, site):
def set_site_number(self, site):
"""Set the site number for a given site.
This function assigns a unique site number to the provided site object.
@ -1577,7 +1577,7 @@ class SiteList(object):
# ------------------------------------------------------------------
def computeVoronoiDiagram(
def compute_voronoi_diagram(
points, xBuff=0, yBuff=0, polygonsOutput=False, formatOutput=False, closePoly=True
):
"""Compute the Voronoi diagram for a set of points.
@ -1619,24 +1619,24 @@ def computeVoronoiDiagram(
siteList = SiteList(points)
context = Context()
voronoi(siteList, context)
context.setClipBuffer(xBuff, yBuff)
context.set_clip_buffer(xBuff, yBuff)
if not polygonsOutput:
clipEdges = context.getClipEdges()
clipEdges = context.get_clip_edges()
if formatOutput:
vertices, edgesIdx = formatEdgesOutput(clipEdges)
vertices, edgesIdx = format_edges_output(clipEdges)
return vertices, edgesIdx
else:
return clipEdges
else:
clipPolygons = context.getClipPolygons(closePoly)
clipPolygons = context.get_clip_polygons(closePoly)
if formatOutput:
vertices, polyIdx = formatPolygonsOutput(clipPolygons)
vertices, polyIdx = format_polygons_output(clipPolygons)
return vertices, polyIdx
else:
return clipPolygons
def formatEdgesOutput(edges):
def format_edges_output(edges):
"""Format edges output for a list of edges.
This function takes a list of edges, where each edge is represented as a
@ -1668,7 +1668,7 @@ def formatEdgesOutput(edges):
return list(pts), edgesIdx
def formatPolygonsOutput(polygons):
def format_polygons_output(polygons):
"""Format the output of polygons into a standardized structure.
This function takes a dictionary of polygons, where each polygon is
@ -1707,7 +1707,7 @@ def formatPolygonsOutput(polygons):
# ------------------------------------------------------------------
def computeDelaunayTriangulation(points):
def compute_delaunay_triangulation(points):
"""Compute the Delaunay triangulation for a set of points.
This function takes a list of point objects, each of which must have 'x'
@ -1743,4 +1743,4 @@ def computeDelaunayTriangulation(points):
# points = MultiPoint(rcoord)
# voronoi = shapely.ops.voronoi_diagram(points, tolerance=0, edges=False)
#
# utils.shapelyToCurve('voronoi', voronoi, 0)
# utils.shapely_to_curve('voronoi', voronoi, 0)