def from_points(cls, points, u_degree=3, v_degree=3): """Construct a NURBS surface from control points. Parameters ---------- points : list[list[:class:`compas.geometry.Point`]] The control points. u_degree : int Degree in the U direction. v_degree : int Degree in the V direction. Returns ------- :class:`~compas_rhino.geometry.RhinoNurbsSurface` """ points = list(zip(*points)) u_count = len(points[0]) v_count = len(points) points[:] = [point_to_rhino(point) for row in points for point in row] surface = cls() surface.rhino_surface = Rhino.Geometry.NurbsSurface.CreateFromPoints( points, v_count, u_count, u_degree, v_degree) return surface
def closest_point(self, point, return_parameters=False): """Compute the closest point on the curve to a given point. Parameters ---------- point : :class:`compas.geometry.Point` The test point. return_parameters : bool, optional If True, return the UV parameters of the closest point as tuple in addition to the point location. Returns ------- :class:`compas.geometry.Point` If `return_parameters` is False. :class:`compas.geometry.Point`, (float, float) If `return_parameters` is True. """ result, u, v = self.rhino_surface.ClosestPoint(point_to_rhino(point)) if not result: return point = self.point_at(u, v) if return_parameters: return point, (u, v) return point
def rhino_curve_from_parameters(points, weights, knots, multiplicities, degree): rhino_curve = Rhino.Geometry.NurbsCurve(3, True, degree + 1, len(points)) for index, (point, weight) in enumerate(zip(points, weights)): rhino_curve.Points.SetPoint(index, point_to_rhino(point), weight) knotvector = [knot for knot, mult in zip(knots, multiplicities) for _ in range(mult)] # account for superfluous knots # https://developer.rhino3d.com/guides/opennurbs/superfluous-knots/ p = len(points) o = degree + 1 k = p + o if len(knotvector) == k: knotvector[:] = knotvector[1:-1] for index, knot in enumerate(knotvector): rhino_curve.Knots[index] = knot return rhino_curve
def from_interpolation(cls, points, precision=1e-3): """Construct a NURBS curve by interpolating a set of points. Parameters ---------- points : list[:class:`compas.geometry.Point`] The control points. precision : float, optional The required precision of the interpolation. This parameter is currently not supported. Returns ------- :class:`compas_rhino.geometry.RhinoNurbsCurve` """ curve = cls() curve.rhino_curve = Rhino.Geometry.NurbsCurve.CreateHSpline([point_to_rhino(point) for point in points]) return curve
def rhino_surface_from_parameters(points, weights, u_knots, v_knots, u_mults, v_mults, u_degree, v_degree, is_u_periodic=False, is_v_periodic=False): rhino_surface = Rhino.Geometry.NurbsSurface.Create(3, True, u_degree + 1, v_degree + 1, len(points[0]), len(points)) u_knotvector = [ knot for knot, mult in zip(u_knots, u_mults) for _ in range(mult) ] v_knotvector = [ knot for knot, mult in zip(v_knots, v_mults) for _ in range(mult) ] u_count = len(points[0]) v_count = len(points) u_order = u_degree + 1 v_order = v_degree + 1 # account for superfluous knots # https://developer.rhino3d.com/guides/opennurbs/superfluous-knots/ if len(u_knotvector) == u_count + u_order: u_knotvector[:] = u_knotvector[1:-1] if len(v_knotvector) == v_count + v_order: v_knotvector[:] = v_knotvector[1:-1] # add knots for index, knot in enumerate(u_knotvector): rhino_surface.KnotsU[index] = knot for index, knot in enumerate(v_knotvector): rhino_surface.KnotsV[index] = knot # add control points for i in range(v_count): for j in range(u_count): rhino_surface.Points.SetPoint(i, j, point_to_rhino(points[i][j]), weights[i][j]) return rhino_surface
def from_points(cls, points, degree=3, is_periodic=False): """Construct a NURBS curve from control points. Parameters ---------- points : list[:class:`compas.geometry.Point`] The control points. degree : int, optional The degree of the curve. is_periodic : bool, optional Flag indicating whether the curve is periodic or not. Returns ------- :class:`compas_rhino.geometry.RhinoNurbsCurve` """ points[:] = [point_to_rhino(point) for point in points] curve = cls() curve.rhino_curve = Rhino.Geometry.NurbsCurve.Create(is_periodic, degree, points) return curve
def closest_point(self, point, return_parameter=False): """Compute the closest point on the curve to a given point. Parameters ---------- point : :class:`compas.geometry.Point` The test point. return_parameter : bool, optional If True, the parameter corresponding to the closest point should be returned in addition to the point. Returns ------- :class:`compas.geometry.Point` | tuple[:class:`compas.geometry.Point`, float] If `return_parameter` is False, only the closest point is returned. If `return_parameter` is True, the closest point and the corresponding parameter are returned. """ result, t = self.rhino_curve.ClosestPoint(point_to_rhino(point)) if not result: return point = self.point_at(t) if return_parameter: return point, t return point
def __setitem__(self, index, point): u, v = index self.rhino_surface.Points.SetControlPoint( u, v, Rhino.Geometry.ControlPoint(point_to_rhino(point)))