I don't see the image I provided.
The first code block should include the 2 lines following it.
Post
Replies
Boosts
Views
Activity
Bill3D,
Thank you for your help. Unfortunately, the node is still not being rendered. Here is the modified code plus the bsplinePath function. I will be grateful if you would try it.
```func cabinetKnob() -> SCNNode {
let controlPoints: [(x: Float, y: Float)] = [
(0.728,-0.237), (0.176,-0.06), (0.202,0.475), (0.989,0.842),
(-0.066,1.093), (-0.726,0.787) ]
let pairs = bsplinePath(controlPoints)
var knobProfile = [SCNVector3]()
for (x,y) in pairs {
knobProfile += [ SCNVector3(x: CGFloat(x), y: CGFloat(y), z: 0)]
}
let nProfiles = 64
// create knob by rotating knobProfile about y-axis
let aIncrement: CGFloat = 2 * CGFloat.pi / CGFloat(nProfiles) // ~6 degrees
var angle: CGFloat = 0
var knobVertices = knobProfile.map( { $0 } )
angle = 0
for _ in 1...nProfiles {
angle += aIncrement
// rotate knobProfile about y-axis
knobVertices += knobProfile.map( { $0.rotate(about: .y, by: angle) } )
}
let source = SCNGeometrySource(vertices: knobVertices)
var indices = [[UInt16]]()
var i: UInt16 = 0
var j: UInt16 = UInt16(knobProfile.count) // 1st vertex of next profile
for k in 0...nProfiles {
var stripIndices = [UInt16]()
if k == nProfiles { j = 0 }
for _ in 0...knobProfile.count-1 {
stripIndices += [i, j]
i += 1; j += 1
}
indices += [stripIndices]
}
let elements: [SCNGeometryElement] = indices.map( {
SCNGeometryElement(indices: $0, primitiveType: .triangleStrip) } )
let surfaceGeometry = SCNGeometry(sources: [source], elements: elements)
let aluminum = SCNMaterial()
aluminum.lightingModel = SCNMaterial.LightingModel.physicallyBased
aluminum.diffuse.contents = NSColor(srgbRed: 0.95, green: 0.95, blue: 0.95, alpha: 1.0)
aluminum.roughness.contents = 0.2
aluminum.metalness.contents = 0.9
aluminum.isDoubleSided = true
let modelMesh = MDLMesh(scnGeometry: surfaceGeometry)
do{
try modelMesh.makeVerticesUniqueAndReturnError()
modelMesh.addNormals(withAttributeNamed: "normal", creaseThreshold: 0.9)
let flattenedGeom = SCNGeometry(mdlMesh: modelMesh)
let flattenedNode = SCNNode(geometry: flattenedGeom)
flattenedNode.geometry?.materials = [aluminum]
return flattenedNode
}catch{
fatalError("mesh vert error")
}
}
func bsplinePath(_ p: [(x: Float, y: Float)]) -> [(Float, Float)] {
var pairs = [(Float, Float)]()
let nSegements: Int = 10
let tIncr: Float = 1.0/Float(nSegements)
let bmat = simd_float4x4([ simd_float4(-1/6, 0.5, -0.5, 1/6),
simd_float4(0.5, -1, 0, 4/6),
simd_float4(-0.5, 0.5, 0.5, 1/6),
simd_float4(1/6, 0, 0, 0) ])
for i in 0...p.count-4 {
let px = simd_float4(p[i].x, p[i+1].x, p[i+2].x, p[i+3].x)
let py = simd_float4(p[i].y, p[i+1].y, p[i+2].y, p[i+3].y)
let vx: simd_float4 = simd_mul(bmat, px)
let vy: simd_float4 = simd_mul(bmat, py)
// print("bmat * P = (\(vx), \(vy))")
var t: Float = 0
let last: Int = (i == p.count-4) ? nSegements : nSegements-1
for _ in 0...last {
let qx = simd_dot(simd_float4(t*t*t, t*t, t, 1), vx)
let qy = simd_dot(simd_float4(t*t*t, t*t, t, 1), vy)
pairs += [(qx, qy)]
t += tIncr
}
}
return pairs
}