Esempio n. 1
0
    /// <summary>
    /// Calculates the boolean difference between a closed planar curve, and a list of closed planar curves. 
    /// Note, curves must be co-planar.
    /// </summary>
    /// <param name="curveA">The first closed, planar curve.</param>
    /// <param name="subtractors">curves to subtract from the first closed curve.</param>
    /// <returns>Result curves on success, empty array if no difference could be calculated.</returns>
    public static Curve[] CreateBooleanDifference(Curve curveA, IEnumerable<Curve> subtractors)
    {
      if (null == curveA || null == subtractors)
        throw new ArgumentNullException(null == curveA ? "curveA" : "subtractors");

      List<Curve> curves = new List<Curve> { curveA };
      curves.AddRange(subtractors);
      SimpleArrayCurvePointer input = new SimpleArrayCurvePointer(curves);
      IntPtr inputPtr = input.ConstPointer();
      SimpleArrayCurvePointer output = new SimpleArrayCurvePointer();
      IntPtr outputPtr = output.NonConstPointer();
      int rc = UnsafeNativeMethods.ON_Curve_BooleanOperation(inputPtr, outputPtr, idxBooleanDifference);
      return rc < 1 ? new Curve[0] : output.ToNonConstArray();
    }
Esempio n. 2
0
    /// <summary>
    /// Projects a curve to a set of meshes using a direction and tolerance.
    /// </summary>
    /// <param name="curves">A list, an array or any enumerable of curves.</param>
    /// <param name="meshes">A list, an array or any enumerable of meshes.</param>
    /// <param name="direction">A direction vector.</param>
    /// <param name="tolerance">A tolerance value.</param>
    /// <returns>A curve array.</returns>
    public static Curve[] ProjectToMesh(IEnumerable<Curve> curves, IEnumerable<Mesh> meshes, Vector3d direction, double tolerance)
    {
      foreach (Curve crv in curves)
      {
        if (crv == null)
          throw new ArgumentNullException("curves");
      }
      List<GeometryBase> g = new List<GeometryBase>();
      foreach (Mesh msh in meshes)
      {
        if (msh == null)
          throw new ArgumentNullException("meshes");
        g.Add(msh);
      }

      using (SimpleArrayCurvePointer crv_array = new SimpleArrayCurvePointer(curves))
      using (Runtime.InteropWrappers.SimpleArrayGeometryPointer mesh_array = new Runtime.InteropWrappers.SimpleArrayGeometryPointer(g))
      using (SimpleArrayCurvePointer curves_out = new SimpleArrayCurvePointer())
      {
        IntPtr pCurvesIn = crv_array.ConstPointer();
        IntPtr pMeshes = mesh_array.ConstPointer();
        IntPtr pCurvesOut = curves_out.NonConstPointer();

        Curve[] rc = new Curve[0];
        if (UnsafeNativeMethods.RHC_RhinoProjectCurveToMesh(pMeshes, pCurvesIn, direction, tolerance, pCurvesOut))
          rc = curves_out.ToNonConstArray();
        return rc;
      }
    }
Esempio n. 3
0
    /// <summary>
    /// Calculates the boolean union of two or more closed, planar curves. 
    /// Note, curves must be co-planar.
    /// </summary>
    /// <param name="curves">The co-planar curves to union.</param>
    /// <returns>Result curves on success, empty array if no union could be calculated.</returns>
    public static Curve[] CreateBooleanUnion(IEnumerable<Curve> curves)
    {
      if (null == curves)
        throw new ArgumentNullException("curves");

      SimpleArrayCurvePointer input = new SimpleArrayCurvePointer(curves);
      IntPtr inputPtr = input.ConstPointer();
      SimpleArrayCurvePointer output = new SimpleArrayCurvePointer();
      IntPtr outputPtr = output.NonConstPointer();

      int rc = UnsafeNativeMethods.ON_Curve_BooleanOperation(inputPtr, outputPtr, idxBooleanUnion);
      return rc < 1 ? new Curve[0] : output.ToNonConstArray();
    }
Esempio n. 4
0
    /// <summary>
    /// Calculates the boolean intersection of two closed, planar curves. 
    /// Note, curves must be co-planar.
    /// </summary>
    /// <param name="curveA">The first closed, planar curve.</param>
    /// <param name="curveB">The second closed, planar curve.</param>
    /// <returns>Result curves on success, empty array if no intersection could be calculated.</returns>
    public static Curve[] CreateBooleanIntersection(Curve curveA, Curve curveB)
    {
      if (null == curveA || null == curveB)
        throw new ArgumentNullException(null == curveA ? "curveA" : "curveB");

      SimpleArrayCurvePointer input = new SimpleArrayCurvePointer(new Curve[] { curveA, curveB });
      IntPtr inputPtr = input.ConstPointer();
      SimpleArrayCurvePointer output = new SimpleArrayCurvePointer();
      IntPtr outputPtr = output.NonConstPointer();
      int rc = UnsafeNativeMethods.ON_Curve_BooleanOperation(inputPtr, outputPtr, idxBooleanIntersection);
      return rc < 1 ? new Curve[0] : output.ToNonConstArray();
    }
Esempio n. 5
0
 /// <summary>
 /// Creates curves between two open or closed input curves. Use sample points method to make curves compatible.
 /// This is how the algorithm workd: Divides the two curves into an equal number of points, finds the midpoint between the 
 /// corresponding points on the curves and interpolates the tween curve through those points. There is no matching of curves
 /// direction. Caller must match input curves direction before calling the function.
 /// </summary>
 /// <param name="curve0">The first, or starting, curve.</param>
 /// <param name="curve1">The second, or ending, curve.</param>
 /// <param name="numCurves">Number of tween curves to create.</param>
 /// <param name="numSamples">Number of sample points along input curves.</param>
 /// <returns>>An array of joint curves. This array can be empty.</returns>
 public static Curve[] CreateTweenCurvesWithSampling(Curve curve0, Curve curve1, int numCurves, int numSamples)
 {
   IntPtr pConstCurve0 = curve0.ConstPointer();
   IntPtr pConstCurve1 = curve1.ConstPointer();
   SimpleArrayCurvePointer output = new SimpleArrayCurvePointer();
   IntPtr outputPtr = output.NonConstPointer();
   bool rc = UnsafeNativeMethods.RHC_RhinoTweenCurveWithSampling(pConstCurve0, pConstCurve1, numCurves, numSamples, outputPtr);
   return rc ? output.ToNonConstArray() : new Curve[0];
 }
Esempio n. 6
0
    /// <summary>
    /// Joins a collection of curve segments together.
    /// </summary>
    /// <param name="inputCurves">An array, a list or any enumerable set of curve segments to join.</param>
    /// <param name="joinTolerance">Joining tolerance, 
    /// i.e. the distance between segment end-points that is allowed.</param>
    /// <param name="preserveDirection">
    /// <para>If true, curve endpoints will be compared to curve startpoints.</para>
    /// <para>If false, all start and endpoints will be compared and copies of input curves may be reversed in output.</para>
    /// </param>
    /// <returns>An array of joint curves. This array can be empty.</returns>
    /// <exception cref="ArgumentNullException">If inputCurves is null.</exception>
    public static Curve[] JoinCurves(IEnumerable<Curve> inputCurves, double joinTolerance, bool preserveDirection)
    {
      // 1 March 2010 S. Baer
      // JoinCurves calls the unmanaged RhinoMergeCurves function which appears to be a "better"
      // implementation of ON_JoinCurves. We removed the wrapper for ON_JoinCurves for this reason.
      if (null == inputCurves)
        throw new ArgumentNullException("inputCurves");

      SimpleArrayCurvePointer input = new SimpleArrayCurvePointer(inputCurves);
      IntPtr inputPtr = input.ConstPointer();
      SimpleArrayCurvePointer output = new SimpleArrayCurvePointer();
      IntPtr outputPtr = output.NonConstPointer();

      bool rc = UnsafeNativeMethods.RHC_RhinoMergeCurves(inputPtr,
        outputPtr, joinTolerance, preserveDirection);

      return rc ? output.ToNonConstArray() : new Curve[0];
    }
Esempio n. 7
0
    /// <summary>
    /// Offset a curve on a brep face surface. This curve must lie on the surface.
    /// <para>This overload allows to specify different offsets for different curve parameters.</para>
    /// </summary>
    /// <param name="face">The brep face on which to offset.</param>
    /// <param name="curveParameters">Curve parameters corresponding to the offset distances.</param>
    /// <param name="offsetDistances">distances to offset (+)left, (-)right.</param>
    /// <param name="fittingTolerance">A fitting tolerance.</param>
    /// <returns>Offset curves on success, or null on failure.</returns>
    /// <exception cref="ArgumentNullException">If face, curveParameters or offsetDistances are null.</exception>
    public Curve[] OffsetOnSurface(BrepFace face, double[] curveParameters, double[] offsetDistances, double fittingTolerance)
    {
      if (face == null) throw new ArgumentNullException("face");
      if (curveParameters == null) throw new ArgumentNullException("curveParameters");
      if (offsetDistances == null) throw new ArgumentNullException("offsetDistances");

      int array_count = curveParameters.Length;
      if (offsetDistances.Length != array_count)
        throw new ArgumentException("curveParameters and offsetDistances must be the same length");

      int fid = face.m_index;
      IntPtr pConstBrep = face.m_brep.ConstPointer();
      SimpleArrayCurvePointer offsetCurves = new SimpleArrayCurvePointer();
      IntPtr pCurveArray = offsetCurves.NonConstPointer();
      IntPtr pConstCurve = ConstPointer();
      int count = UnsafeNativeMethods.RHC_RhinoOffsetCurveOnSrf3(pConstCurve, pConstBrep, fid, array_count, curveParameters, offsetDistances, fittingTolerance, pCurveArray);
      Curve[] curves = offsetCurves.ToNonConstArray();
      offsetCurves.Dispose();
      if (count < 1)
        return null;
      return curves;
    }
Esempio n. 8
0
    /// <summary>
    /// Pull a curve to a BrepFace using closest point projection.
    /// </summary>
    /// <param name="curve">Curve to pull.</param>
    /// <param name="face">Brepface that pulls.</param>
    /// <param name="tolerance">Tolerance to use for pulling.</param>
    /// <returns>An array of pulled curves, or an empty array on failure.</returns>
    public static Curve[] PullToBrepFace(Curve curve, BrepFace face, double tolerance)
    {
      IntPtr brep_ptr = face.m_brep.ConstPointer();
      IntPtr curve_ptr = curve.ConstPointer();

      using (SimpleArrayCurvePointer rc = new SimpleArrayCurvePointer())
      {
        IntPtr rc_ptr = rc.NonConstPointer();
        if (UnsafeNativeMethods.RHC_RhinoPullCurveToBrep(brep_ptr, face.FaceIndex, curve_ptr, tolerance, rc_ptr))
        {
          return rc.ToNonConstArray();
        }
        return new Curve[0];
      }
    }
Esempio n. 9
0
 /// <summary>
 /// Offsets this curve. If you have a nice offset, then there will be one entry in 
 /// the array. If the original curve had kinks or the offset curve had self 
 /// intersections, you will get multiple segments in the offset_curves[] array.
 /// </summary>
 /// <param name="directionPoint">A point that indicates the direction of the offset.</param>
 /// <param name="normal">The normal to the offset plane.</param>
 /// <param name="distance">The positive or negative distance to offset.</param>
 /// <param name="tolerance">The offset or fitting tolerance.</param>
 /// <param name="cornerStyle">Corner style for offset kinks.</param>
 /// <returns>Offset curves on success, null on failure.</returns>
 public Curve[] Offset(Point3d directionPoint, Vector3d normal, double distance, double tolerance, CurveOffsetCornerStyle cornerStyle)
 {
   IntPtr ptr = ConstPointer();
   SimpleArrayCurvePointer offsetCurves = new SimpleArrayCurvePointer();
   IntPtr pCurveArray = offsetCurves.NonConstPointer();
   bool rc = UnsafeNativeMethods.RHC_RhinoOffsetCurve2(ptr, distance, directionPoint, normal, (int)cornerStyle, tolerance, pCurveArray);
   Curve[] curves = offsetCurves.ToNonConstArray();
   offsetCurves.Dispose();
   if (!rc)
     return null;
   return curves;
 }
Esempio n. 10
0
    /// <summary>
    /// Offset a curve on a brep face surface. This curve must lie on the surface.
    /// <para>This overload allows to specify a surface point at which the offset will pass.</para>
    /// </summary>
    /// <param name="face">The brep face on which to offset.</param>
    /// <param name="throughPoint">2d point on the brep face to offset through.</param>
    /// <param name="fittingTolerance">A fitting tolerance.</param>
    /// <returns>Offset curves on success, or null on failure.</returns>
    /// <exception cref="ArgumentNullException">If face is null.</exception>
    public Curve[] OffsetOnSurface(BrepFace face, Point2d throughPoint, double fittingTolerance)
    {
      if (face == null)
        throw new ArgumentNullException("face");

      int fid = face.m_index;
      IntPtr pConstBrep = face.m_brep.ConstPointer();
      SimpleArrayCurvePointer offsetCurves = new SimpleArrayCurvePointer();
      IntPtr pCurveArray = offsetCurves.NonConstPointer();
      IntPtr pConstCurve = ConstPointer();
      int count = UnsafeNativeMethods.RHC_RhinoOffsetCurveOnSrf2(pConstCurve, pConstBrep, fid, throughPoint, fittingTolerance, pCurveArray);
      Curve[] curves = offsetCurves.ToNonConstArray();
      offsetCurves.Dispose();
      if (count < 1)
        return null;
      return curves;
    }
Esempio n. 11
0
 /// <summary>
 /// Splits a curve into pieces using a surface.
 /// </summary>
 /// <param name="cutter">A cutting surface or polysurface.</param>
 /// <param name="tolerance">A tolerance for computing intersections.</param>
 /// <returns>An array of curves. This array can be empty.</returns>
 public Curve[] Split(Surface cutter, double tolerance)
 {
   IntPtr pConstThis = ConstPointer();
   IntPtr pConstSurface = cutter.ConstPointer();
   using (Rhino.Runtime.InteropWrappers.SimpleArrayCurvePointer pieces = new SimpleArrayCurvePointer())
   {
     IntPtr pPieces = pieces.NonConstPointer();
     UnsafeNativeMethods.RHC_RhinoCurveSplit(pConstThis, pConstSurface, tolerance, pPieces);
     return pieces.ToNonConstArray();
   }
 }
Esempio n. 12
0
    /// <summary>
    /// Splits a curve into pieces using a polysurface.
    /// </summary>
    /// <param name="cutter">A cutting surface or polysurface.</param>
    /// <param name="tolerance">A tolerance for computing intersections.</param>
    /// <returns>An array of curves. This array can be empty.</returns>
    public Curve[] Split(Brep cutter, double tolerance)
    {
      if (cutter == null) throw new ArgumentNullException("cutter");

      IntPtr pConstThis = ConstPointer();
      IntPtr pConstBrep = cutter.ConstPointer();
      using (Rhino.Runtime.InteropWrappers.SimpleArrayCurvePointer pieces = new SimpleArrayCurvePointer())
      {
        IntPtr pPieces = pieces.NonConstPointer();
        UnsafeNativeMethods.RHC_RhinoCurveSplit(pConstThis, pConstBrep, tolerance, pPieces);
        return pieces.ToNonConstArray();
      }
    }
Esempio n. 13
0
    /// <summary>
    /// Polylines will be exploded into line segments. ExplodeCurves will
    /// return the curves in topological order.
    /// </summary>
    /// <returns>
    /// An array of all the segments that make up this curve.
    /// </returns>
    public Curve[] DuplicateSegments()
    {
      IntPtr ptr = ConstPointer();
      SimpleArrayCurvePointer output = new SimpleArrayCurvePointer();
      IntPtr outputPtr = output.NonConstPointer();

      int rc = UnsafeNativeMethods.RHC_RhinoDuplicateCurveSegments(ptr, outputPtr);
      return rc < 1 ? new Curve[0] : output.ToNonConstArray();
    }
Esempio n. 14
0
    /// <summary>
    /// Projects a Curve onto a Brep along a given direction.
    /// </summary>
    /// <param name="curve">Curve to project.</param>
    /// <param name="brep">Brep to project onto.</param>
    /// <param name="direction">Direction of projection.</param>
    /// <param name="tolerance">Tolerance to use for projection.</param>
    /// <returns>An array of projected curves or empty array if the projection set is empty.</returns>
    public static Curve[] ProjectToBrep(Curve curve, Brep brep, Vector3d direction, double tolerance)
    {
      IntPtr brep_ptr = brep.ConstPointer();
      IntPtr curve_ptr = curve.ConstPointer();

      using (SimpleArrayCurvePointer rc = new SimpleArrayCurvePointer())
      {
        IntPtr rc_ptr = rc.NonConstPointer();
        return UnsafeNativeMethods.RHC_RhinoProjectCurveToBrep(brep_ptr, curve_ptr, direction, tolerance, rc_ptr) ? rc.ToNonConstArray() : new Curve[0];
      }
    }
Esempio n. 15
0
    /// <summary>
    /// Pulls this curve to a brep face and returns the result of that operation.
    /// </summary>
    /// <param name="face">A brep face.</param>
    /// <param name="tolerance">A tolerance value.</param>
    /// <returns>An array containing the resulting curves after pulling. This array could be empty.</returns>
    /// <exception cref="ArgumentNullException">If face is null.</exception>
    public Curve[] PullToBrepFace(BrepFace face, double tolerance)
    {
      if (face == null)
        throw new ArgumentNullException("face");

      IntPtr pConstCurve = ConstPointer();
      IntPtr pConstBrepFace = face.ConstPointer();
      using (Runtime.InteropWrappers.SimpleArrayCurvePointer curves = new SimpleArrayCurvePointer())
      {
        IntPtr pCurves = curves.NonConstPointer();
        UnsafeNativeMethods.RHC_RhinoPullCurveToFace(pConstCurve, pConstBrepFace, pCurves, tolerance);
        return curves.ToNonConstArray();
      }
    }
Esempio n. 16
0
    /// <summary>
    /// Projects a collection of Curves onto a collection of Breps along a given direction.
    /// </summary>
    /// <param name="curves">Curves to project.</param>
    /// <param name="breps">Breps to project onto.</param>
    /// <param name="direction">Direction of projection.</param>
    /// <param name="tolerance">Tolerance to use for projection.</param>
    /// <param name="curveIndices">Index of which curve in the input list was the source for a curve in the return array.</param>
    /// <param name="brepIndices">Index of which brep was used to generate a curve in the return array.</param>
    /// <returns>An array of projected curves. Array is empty if the projection set is empty.</returns>
    public static Curve[] ProjectToBrep(IEnumerable<Curve> curves, IEnumerable<Brep> breps, Vector3d direction, double tolerance, out int[] curveIndices, out int[] brepIndices)
    {
      curveIndices = null;
      brepIndices = null;

      foreach (Curve crv in curves) { if (crv == null) { throw new ArgumentNullException("curves"); } }
      foreach (Brep brp in breps) { if (brp == null) { throw new ArgumentNullException("breps"); } }

      SimpleArrayCurvePointer crv_array = new SimpleArrayCurvePointer(curves);
      Runtime.InteropWrappers.SimpleArrayBrepPointer brp_array = new Runtime.InteropWrappers.SimpleArrayBrepPointer();
      foreach (Brep brp in breps) { brp_array.Add(brp, true); }

      IntPtr ptr_crv_array = crv_array.ConstPointer();
      IntPtr ptr_brp_array = brp_array.ConstPointer();

      SimpleArrayInt brp_top = new SimpleArrayInt();
      SimpleArrayInt crv_top = new SimpleArrayInt();

      SimpleArrayCurvePointer rc = new SimpleArrayCurvePointer();
      IntPtr ptr_rc = rc.NonConstPointer();

      if (UnsafeNativeMethods.RHC_RhinoProjectCurveToBrepEx(ptr_brp_array,
                                                            ptr_crv_array,
                                                            direction,
                                                            tolerance,
                                                            ptr_rc,
                                                            brp_top.m_ptr,
                                                            crv_top.m_ptr))
      {
        brepIndices = brp_top.ToArray();
        curveIndices = crv_top.ToArray();
        return rc.ToNonConstArray();
      }
      return new Curve[0];
    }
Esempio n. 17
0
 /// <summary>
 /// Creates a tangent arc between two curves and trims or extends the curves to the arc.
 /// </summary>
 /// <param name="curve0">The first curve to fillet.</param>
 /// <param name="point0">
 /// A point on the first curve that is near the end where the fillet will
 /// be created.
 /// </param>
 /// <param name="curve1">The second curve to fillet.</param>
 /// <param name="point1">
 /// A point on the second curve that is near the end where the fillet will
 /// be created.
 /// </param>
 /// <param name="radius">The radius of the fillet.</param>
 /// <param name="join">Join the output curves.</param>
 /// <param name="trim">
 /// Trim copies of the input curves to the output fillet curve.
 /// </param>
 /// <param name="arcExtension">
 /// Applies when arcs are filleted but need to be extended to meet the
 /// fillet curve or chamfer line. If true, then the arc is extended
 /// maintaining its validity. If false, then the arc is extended with a
 /// line segment, which is joined to the arc converting it to a polycurve.
 /// </param>
 /// <param name="tolerance">
 /// The tolerance, generally the document's absolute tolerance.
 /// </param>
 /// <param name="angleTolerance"></param>
 /// <returns>
 /// The results of the fillet operation. The number of output curves depends
 /// on the input curves and the values of the parameters that were used
 /// during the fillet operation. In most cases, the output array will contain
 /// either one or three curves, although two curves can be returned if the
 /// radius is zero and join = false.
 /// For example, if both join and trim = true, then the output curve
 /// will be a polycurve containing the fillet curve joined with trimmed copies
 /// of the input curves. If join = false and trim = true, then three curves,
 /// the fillet curve and trimmed copies of the input curves, will be returned.
 /// If both join and trim = false, then just the fillet curve is returned.
 /// </returns>
 /// <example>
 /// <code source='examples\vbnet\ex_filletcurves.vb' lang='vbnet'/>
 /// <code source='examples\cs\ex_filletcurves.cs' lang='cs'/>
 /// <code source='examples\py\ex_filletcurves.py' lang='py'/>
 /// </example>
 public static Curve[] CreateFilletCurves( Curve curve0, Point3d point0, Curve curve1, Point3d point1, double radius, bool join, bool trim, bool arcExtension, double tolerance, double angleTolerance)
 {
   IntPtr const_ptr_curve0 = curve0.ConstPointer();
   IntPtr const_ptr_curve1 = curve1.ConstPointer();
   using (var output_array = new SimpleArrayCurvePointer())
   {
     IntPtr ptr_output_array = output_array.NonConstPointer();
     UnsafeNativeMethods.RHC_RhFilletCurve(const_ptr_curve0, point0, const_ptr_curve1, point1, radius, join, trim, arcExtension, tolerance, angleTolerance, ptr_output_array);
     return output_array.ToNonConstArray();
   }
 }