Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cut operation doesn't work #529

Open
RubenRubens opened this issue Dec 2, 2020 · 8 comments
Open

Cut operation doesn't work #529

RubenRubens opened this issue Dec 2, 2020 · 8 comments

Comments

@RubenRubens
Copy link
Contributor

Tested with the latest CQ version provided on conda

I'm working on a nut and the last cut operation fails, this is, there is no thread. The thing is that when using union instead of cut the operation is successfully performed. I cannot tell if it's my fault or a bug.

The code

import cadquery as cq
from math import sin, cos, tan, pi

# Parameters
d = 10
p = 1.50
da = 10.40
dw = 14.60
e = 17.77
m = 8.10
s = 16
angle = 30 * pi / 180

# Constant
H = 0.866 * p

# Gemetry
def cutting_hexagon():
	points = [
		(s/2, 0),
		(e, 0),
		(e, e * sin(angle))
	]

	a = (
		cq.Workplane('YZ')
		.polyline(points).close()
		.revolve()
	)

	b = a.mirror('XY', (0, 0, m/2))

	return a.union(b)

def internal_iso_thread():
	# Helix
	helix = cq.Workplane('XY').parametricCurve(
	lambda t : (
			d/2 * cos(t * 2 * pi),
			d/2 * sin(t * 2 * pi),
			p * t
		),
		start = 0,
		stop = m/p
	)

	# Face
	A = H/8 / tan(pi/3)
	B = A * tan(pi/6)
	C = A / cos(pi/6)
	face = (
		cq.Workplane('XZ')
		.center(d/2, 0)
		.moveTo(0, A)
		.threePointArc((C-B, 0), (0, -A))
		.lineTo(-7/8 * H, -H/2)
		.lineTo(-7/8 * H, H/2)
		.lineTo(0, A)
		.close()
	)

	return face.sweep(helix, isFrenet=True)

def core():
	def circumscribed(nSides, inscribedDiameter):
		angle = 1/(nSides * 2) * 2 * pi
		return inscribedDiameter / cos(angle)

	return (
		cq.Workplane('XY')
		.polygon(6, circumscribed(6, s))
		.circle(d / 2 - 3/8 * H)
		.extrude(m)
	)

result = (
	core()
	.cut(cutting_hexagon())
	.cut(internal_iso_thread())
)

result.val().exportStep('bug.step')

The result

result

The issue

cq_nut

@jmwright
Copy link
Member

jmwright commented Dec 3, 2020

We have run into kernel bugs fairly often with threads. For example: #407

I can confirm that the thread isn't cut in CQ-editor, so it's not an export issue. You could try a couple of things to see if they help, and then we can try to figure out how to work around whatever is going on.

  1. Increase the diameter of the thread coil so that more (or all) of the thread solid intersects with the nut core.
  2. Shorten the height of the coil so that it does not extend above (or below) the nut core.

@dcowden
Copy link
Member

dcowden commented Dec 3, 2020 via email

@adam-urbanczyk
Copy link
Member

Here is how you can make it work:
image

import cadquery as cq
from math import sin, cos, tan, pi

# Parameters
d = 10
p = 1.50
da = 10.40
dw = 14.60
e = 17.77
m = 8.10
s = 16
angle = 30 * pi / 180

# Constant
H = 0.866 * p

# Gemetry
def cutting_hexagon():
	points = [
		(s/2, 0),
		(e, 0),
		(e, e * sin(angle))
	]

	a = (
		cq.Workplane('YZ')
		.polyline(points).close()
		.revolve()
	)

	b = a.mirror('XY', (0, 0, m/2))

	return a.union(b)

def internal_iso_thread():
	# Helix
	helix = cq.Workplane('XY',origin=(0,0,-1)).parametricCurve(
	lambda t : (
			d/2 * cos(t * 2 * pi),
			d/2 * sin(t * 2 * pi),
			p * t
		),
		start = 0,
		stop = 2*m/p
	)

	# Face
	A = H/8 / tan(pi/3)
	B = A * tan(pi/6)
	C = A / cos(pi/6)
	face = (
		cq.Workplane('XZ')
		.center(d/2, 0)
		.moveTo(0, A)
		.threePointArc((C-B, 0), (0, -A))
		.lineTo(-7/8 * H, -H/2)
		.lineTo(-7/8 * H, H/2)
		.lineTo(0, A)
		.close()
	)

	return face.sweep(helix, isFrenet=True)

def core():
	def circumscribed(nSides, inscribedDiameter):
		angle = 1/(nSides * 2) * 2 * pi
		return inscribedDiameter / cos(angle)

	return (
		cq.Workplane('XY')
		.polygon(6, circumscribed(6, s))
		.circle(d / 2 - 3/8 * H)
		.extrude(m)
	)

thread = (
    internal_iso_thread()
    .transformed((-90,0,0))
    .split(True)
    .transformed((0,0,0),(0,0,m))
    .split(False, True)
    )

result = (
	core()
	.cut(cutting_hexagon())
	.cut(thread,clean=False)
)

@dcowden
Copy link
Member

dcowden commented Dec 3, 2020

wow @adam-urbanczyk nice!

@RubenRubens would you consider the idea of promoting this code to a core operation available as a convenience operation, similar to counterbores?

It wouldn't take much at all to convert the code above to automatically apply this code to a selected cylindrical face to create an internal or external thread, which would be immensely helpful when you need threads!

@RubenRubens
Copy link
Contributor Author

Cool! @dcowden you can do whatever makes you happy with the code above. I might consider to do a PR myself...

@jpoles1
Copy link
Contributor

jpoles1 commented Aug 5, 2022

Getting some very strange results using this with the latest version to try and make internal threads. Had similar results with twisted threads when using another example I found (when using specific sets of params for height and pitch in particular). Not sure what might be causing this:

image

@lorenzncode
Copy link
Member

It looks like there were changes to parametricCurve since these examples were created, see issue #682.

@lorenzncode
Copy link
Member

Had similar results with twisted threads when using another example I found (when using specific sets of params for height and pitch in particular).

@jpoles1 In my testing, specifying parametricCurve(..., smoothing=None) resolves the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants