function create_surface(p, [a, b], [c, d], opts = {}) {
let {
Nu = 100,
nu = 10,
Nv = 100,
nv = 10,
color = "#40bfbf",
transparency = 0,
show_mesh = true
} = opts;
let surface_strings = make_surface_strings(p, [a, b], [c, d], opts);
let surface_transform = d3.create("transform");
if (opts.id) {
surface_transform.attr("id", `${opts.id}`);
}
if (opts.class) {
surface_transform.attr("class", `${opts.class}`);
}
let surface_shape = surface_transform.append("shape");
let appearance = surface_shape.append("appearance");
if (opts.sortKey || opts.sortKey === 0) {
appearance.attr("sortKey", opts.sortKey);
}
let material = appearance
.append("material")
.attr("diffuseColor", color)
.attr("transparency", transparency);
let indexedFaceSet = surface_shape
.append("indexedFaceset")
.attr("coordIndex", surface_strings.face_index_string)
.attr("solid", "false")
.attr("creaseAngle", "3.14156");
indexedFaceSet
.append("coordinate")
.attr("point", surface_strings.coord_string);
if (show_mesh) {
let mesh = surface_transform.append("shape");
mesh
.append("appearance")
.append("material")
.attr("transparency", transparency);
mesh
.append("IndexedLineSet")
.attr("coordIndex", surface_strings.line_index_string)
.append("Coordinate")
.attr("point", surface_strings.coord_string);
}
let surface_node = surface_transform.node();
surface_node.extent = surface_strings.extent;
return surface_node;
}