Hello,
I’ve noticed what I think is a strange behaviour in rhino3dm.js. I’ve already found a working solution, but I feel like it’s a bit unintuitive and not very elegant, so I’m posting here to let you know and/or to see if I’m missing something.
I’m trying to create an Extrusion from a geojson polygon. In geojson the first curve is always the boundary and if there are more curves, those are holes.
This was my original attempt at doing this:
type Coordinate = [number, number]
toExtrusion(coordinates: Coordinate[][], referencePoint: Coordinate, height: number) {
const [first, ...rest] = (await this.toPolylineList(coordinates, referencePoint)).map((p) => p.toNurbsCurve())
const extrusion = rhino.Extrusion.create(first, height, true)
if (rest.length === 0) return extrusion
for (const curve of rest) {
extrusion.addInnerProfile(curve)
}
return extrusion
}
but when I saved the geometry to a .3dm this is what I ended up with:
After some messing around I figured out that Extrusion.addInnerProfile()
uses the local plane of the extrusion rather than the worldXY plane as the reference plane. The plane defaults to the plane spanned by the tangent vector of the curve it’s created from and a 90-degree rotated vector in the same plane.
Anyway, the point is that since there is no create function in 3dmjs that takes a reference plane as an argument, I have to manually transform the holes to be in the same plane as the boundary like this:
toExtrusion(coordinates: Coordinate[][], referencePoint: Coordinate, height: number) {
const [first, ...rest] = (await this.toPolylineList(coordinates, referencePoint)).map((p) => p.toNurbsCurve())
const extrusion = rhino.Extrusion.create(first, height, true)
if (rest.length === 0) return extrusion
// Here I'm recreating the plane to make a transform for the hole-curve so it gets placed in the right place.
let plane = rhino.Plane.worldXY()
const tangent = first.tangentAt(0)
plane.xAxis = tangent
plane.yAxis = this.crossProduct(tangent, [0, 0, 1])
plane.origin = extrusion.pathStart
const pathXform = rhino.Transform.planeToPlane(plane, rhino.Plane.worldXY())
for (const curve of rest) {
curve.transform(pathXform)
extrusion.addInnerProfile(curve)
}
return extrusion
}
and I get this result (like the original gejson):
So my question is, would it be possible to include this version of the Create()
method that takes in a plane in the next release of 3dm
https://developer.rhino3d.com/api/rhinocommon/rhino.geometry.extrusion/create
or is there something I’m missing here?
Thanks a lot and sorry for a long post!
Erik