I believe this may be an iOS bug, and I've reported it to Apple via Bug Report. I'll post it here in case there's some workaround I can use, or explanation of the cause.
I'm wanting to draw the stroke of a UIBezierPath within SceneKit. I'm using the CGPath copyStrokingWithWidth
function, and then creating a SCNShape
using the given path.
This works fine for lines with 2 points, but on lines with 3 points, the SCNShape doesn't display anything. I've determined that this is only the case when the lineWidth
is more than 0.1. With lineWidth
set to 0.1, it displays perfectly.
let strokeBezierPath = UIBezierPath()
strokeBezierPath.lineWidth = 1
strokeBezierPath.move(to: CGPoint.zero)
strokeBezierPath.addLine(to: CGPoint(x: 10, y: 0))
strokeBezierPath.addLine(to: CGPoint(x: 10, y: 10))
let cgPath = strokeBezierPath.cgPath.copy(
strokingWithWidth: strokeBezierPath.lineWidth,
lineCap: strokeBezierPath.lineCapStyle,
lineJoin: strokeBezierPath.lineJoinStyle,
miterLimit: strokeBezierPath.miterLimit)
let bezierPath = UIBezierPath(cgPath: cgPath)
let shape = SCNShape(path: bezierPath, extrusionDepth: 1)
shape.firstMaterial?.diffuse.contents = UIColor.blue
let node = SCNNode(geometry: shape)
node.position.z = -40
sceneView.scene.rootNode.addChildNode(node)
This works fine with:
- Just the first 2 points
- Line width of 0.1
- A manually-drawn bezier path covering the same area
Printing the UIBezierPath for line width as 0.1 (does display):
<UIBezierPath: 0x1d00b12e0; <MoveTo {0, 0.050000000000000003}>,
<LineTo {10, 0.050000000000000003}>,
<LineTo {9.9499999999999993, 10}>,
<LineTo {10.050000000000001, 10}>,
<LineTo {10.050000000000001, 0}>,
<LineTo {0, -0.050000000000000003}>,
<LineTo {0, 0.050000000000000003}>,
<Close>
With line width as 0.2 (doesn't display):
<UIBezierPath: 0x1d00b7160; <MoveTo {0, 0.10000000000000001}>,
<LineTo {10, 0.10000000000000001}>,
<LineTo {9.9000000000000004, 0}>,
<LineTo {9.9000000000000004, 10}>,
<LineTo {10.1, 10}>,
<LineTo {10.1, 0}>,
<LineTo {10, -0.10000000000000001}>,
<LineTo {0, -0.10000000000000001}>,
<LineTo {0, 0.10000000000000001}>,
<Close>
You haven’t closed the path. You won’t be able to extrude two line segments that have not been closed... so nothing will appear. Close the path off with the following. This will bring up your geometry in the sceneView.
Edit: Scenekit units are in metres. So to work with a smaller object in front of you. Change your units, and linewidth to the following. This will put the object 1 metre in front... and much smaller so you can see whats going on better.