Sorry, I've had a tough day :-( But here's what I got, its a simpler case, another part of the same design which shows similar problems.
def visor():
v = cq.Workplane("XY").sphere(radius=HELMET_RADIUS+LINE_WIDTH)
v = v.cut(cq.Workplane("XY").sphere(radius=HELMET_RADIUS-LINE_WIDTH))
v = v.workplane().split(keepTop=True)
v = v.workplane().transformed(offset=(0,0,-HELMET_RADIUS/2), rotate=(VISOR_ANGLE,0,0)).split(keepBottom=True)
v = v.rotate(axisStartPoint=(0,0,0), axisEndPoint=(1,0,0), angleDegrees=VISOR_ANGLE_OFFSET)
v = v.cut(cq.Workplane("YZ").circle(radius=EAR_RADIUS).extrude(HELMET,both=True))
return v
def torus(outerRadius, innerRadius, z=0):
r = (outerRadius-innerRadius)/2;
t = cq.Workplane("XZ", origin=(0,0,-z)).moveTo(innerRadius+r).circle(r).revolve()
return t
def visor_torus(z):
return torus(HELMET_RADIUS+VISOR_BORDER_RADIUS,HELMET_RADIUS-VISOR_BORDER_RADIUS,z);
def visor_frame():
v1 = visor_torus(VISOR_BORDER_RADIUS)
v2 = (visor_torus(-VISOR_BORDER_RADIUS)
.rotate(axisStartPoint=(0,0,0), axisEndPoint=(1,0,0), angleDegrees=VISOR_ANGLE)
)
v = v1.add(v2).rotate(axisStartPoint=(0,0,0), axisEndPoint=(1,0,0), angleDegrees=VISOR_ANGLE_OFFSET)
return v.copyWorkplane(cq.Workplane("XZ", origin=(0,0,0))).split(keepBottom=True)
def helmet():
h = cq.Workplane("XY").sphere(radius=HELMET_RADIUS)
h = h.add(visor_frame())
h = h.cut(visor())
return h
h = helmet()
This code uses add() and produces the following geometry
:
Now, if I use union() in the following lines, the geometry simply does not work and produces an 'empty' solid without any warning.
def helmet():
h = cq.Workplane("XY").sphere(radius=HELMET_RADIUS)
h = h.union(visor_frame())
h = h.cut(visor())
return h
The visor() method alone generates this part, which is subtracted from the sphere:
The visor_frame() method generates two toruses which are rotated and translated along the normal axis so they end up exactly above and below the visor part that is subtracted.
There are other problems; if I subtract the inner sphere (commented in the code above but activated in the code below), and cut the bottom part, it kind of works with add() but generates strange geometry inside (with a plane that should not exist at all).
def helmet():
h = cq.Workplane("XY").sphere(radius=HELMET_RADIUS)
h = h.union(visor_frame())
h = h.cut(visor())
# cuts a slightly squished sphere to make the top part a bit thicker
h = h.cut(make_inner_sphere(HELMET_RADIUS))
# cuts down the bottom part; could be done with slice or other similar method.
h = h.cut(
cq.Workplane("XY",origin=(0,0,-(HELMET_RADIUS-HELMET_FLOOR/2))).
box(HELMET, HELMET, HELMET_FLOOR)
)
return h
These strange artifacts get increasingly cumbersome as I try to add more details inside the geometry. I managed to get to a point where I can add a lot more detail and correct lots of problems with Netfabb, but still, I can't add the visor_frame() in any other way. It just breaks and there's no way that even Netfabb can correct it.