Esempio n. 1
0
        /// <summary>
        /// Translate integeres to CornerStyle
        /// </summary>
        /// <param name="cornerStyleInInt"></param>
        /// <param name="cornerStyle"></param>
        private static void GetCornerStyleFromInt(ref int cornerStyleInInt, ref CurveOffsetCornerStyle cornerStyle)
        {
            if (cornerStyleInInt < 0)
            {
                cornerStyleInInt = 0;
            }
            if (cornerStyleInInt > 4)
            {
                cornerStyleInInt = 4;
            }
            switch (cornerStyleInInt)
            {
            case (0):
                cornerStyle = CurveOffsetCornerStyle.None;
                break;

            case (1):
                cornerStyle = CurveOffsetCornerStyle.Sharp;
                break;

            case (2):
                cornerStyle = CurveOffsetCornerStyle.Round;
                break;

            case (3):
                cornerStyle = CurveOffsetCornerStyle.Smooth;
                break;

            case (4):
                cornerStyle = CurveOffsetCornerStyle.Chamfer;
                break;
            }
        }
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <Curve> curveList = new List <Curve>();

            DA.GetDataList(0, curveList);
            //GH_Structure<GH_Activ> in_IDtree = new GH_Structure<Curve>();

            double width = new double();

            if (!DA.GetData(1, ref width))
            {
                width = .1;
            }
            double halfwidth = width / 2.0;

            CurveOffsetCornerStyle cornerstyle = new CurveOffsetCornerStyle();
            List <PolylineCurve>   plines      = new List <PolylineCurve>();
            Vector3d normal = new Vector3d(0.0, 0.0, 1.0);
            Point3d  origin = new Point3d(0.0, 0.0, 0.0);
            Plane    plane  = new Plane(origin, normal);

            foreach (Curve c in curveList)
            {
                Polyline pl = new Polyline();
                if (c.TryGetPolyline(out pl))
                {
                    int    segCount = pl.SegmentCount;
                    Line[] segments = pl.GetSegments();
                    foreach (Line l in segments)
                    {
                        l.Extend(halfwidth, halfwidth);
                        Curve     crv     = l.ToNurbsCurve();
                        Curve[]   offset1 = crv.Offset(plane, halfwidth, 0.0, cornerstyle);
                        Curve[]   offset2 = crv.Offset(plane, -halfwidth, 0.0, cornerstyle);
                        Point3d[] rect    = new Point3d[5] {
                            offset1[0].PointAtStart, offset1[0].PointAtEnd, offset2[0].PointAtEnd, offset2[0].PointAtStart, offset1[0].PointAtStart
                        };
                        PolylineCurve plc = new PolylineCurve(rect);
                        plines.Add(plc);
                    }
                }
            }

            // 2. Boolean Union
            Curve[] final = PolylineCurve.CreateBooleanUnion(plines);

            // 3. Set data back
            DA.SetDataList(0, final);
        }
Esempio n. 3
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. 4
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="plane">Offset solution 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(Plane plane, double distance, double tolerance, CurveOffsetCornerStyle cornerStyle)
    {
      // Create a bogus dir point
      Point3d direction_point = plane.Origin + plane.XAxis;

      Random rnd = new Random(1);

      // Try a hundred times to find a smooth place on the curve where the tangent 
      // is not (anti)parallel to the offset plane z-axis.
      // This is unbelievably foul, but the most consistent offset result I 
      // can come up with on short notice.
      for (int i = 0; i < 100; i++)
      {
        double t = Domain.ParameterAt(rnd.NextDouble());
        if (IsContinuous(Continuity.G1_continuous, t))
        {
          Point3d p = PointAt(t);
          Vector3d v = TangentAt(t);

          if (v.IsParallelTo(plane.ZAxis, RhinoMath.ToRadians(0.1)) == 0)
          {
            Vector3d perp = Vector3d.CrossProduct(v, plane.ZAxis);
            perp.Unitize();
            direction_point = p + 1e-3 * perp;
            break;
          }
        }
      }

      return Offset(direction_point, plane.Normal, distance, tolerance, cornerStyle);

      //IntPtr ptr = ConstPointer();
      //SimpleArrayCurvePointer offsetCurves = new SimpleArrayCurvePointer();
      //IntPtr pCurveArray = offsetCurves.NonConstPointer();
      //bool rc = UnsafeNativeMethods.RHC_RhinoOffsetCurve(ptr, plane.ZAxis, plane.Origin, distance, pCurveArray, tolerance, 0.015, (int)cornerStyle);
      //Curve[] curves = offsetCurves.ToNonConstArray();
      //offsetCurves.Dispose();
      //if (!rc)
      //  return null;
      //return curves;
    }
Esempio n. 5
0
        public Curve[] AfterOffset(Curve destination, double naN, Plane unset, int num2)
        {
            if (!RhinoMath.IsValidDouble(naN))
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "不是有效的数字");
                return(new Curve[] {});
            }
            else if (!unset.IsValid)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "不是有效的平面");
                return(new Curve[] { });
            }
            else
            {
                double num3      = Math.Abs(naN);
                double tolerance = Math.Min(GH_Component.DocumentTolerance(), 0.1 * num3);
                GH_Component.DocumentAngleTolerance();
                num2 = Math.Max(Math.Min(num2, 4), 0);
                if (naN == 0.0)
                {
                    return(new Curve[] { destination });
                }
                else
                {
                    CurveOffsetCornerStyle none = CurveOffsetCornerStyle.None;
                    switch (num2)
                    {
                    case 0:
                        none = CurveOffsetCornerStyle.None;
                        break;

                    case 1:
                        none = CurveOffsetCornerStyle.Sharp;
                        break;

                    case 2:
                        none = CurveOffsetCornerStyle.Round;
                        break;

                    case 3:
                        none = CurveOffsetCornerStyle.Smooth;
                        break;

                    case 4:
                        none = CurveOffsetCornerStyle.Chamfer;
                        break;
                    }
                    Curve[] inputCurves = null;
                    inputCurves = destination.Offset(unset, naN, tolerance, none);
                    if (inputCurves == null)
                    {
                        this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "不能偏移该曲线");
                        return(new Curve[] { });
                    }
                    else
                    {
                        Curve[] data = Curve.JoinCurves(inputCurves);
                        if (data == null)
                        {
                            return(inputCurves);
                        }
                        else
                        {
                            return(data);
                        }
                    }
                }
            }
        }
Esempio n. 6
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            InputChecker inputChecker = new InputChecker(this);

            #region get Input From GH Canvas
            GH_Structure <GH_Curve> inCurves = new GH_Structure <GH_Curve>();
            bool areCurvesOK = DA.GetDataTree(0, out inCurves);
            inputChecker.StopIfConversionIsFailed(areCurvesOK);
            GH_Structure <GH_Curve> ghCurves = new GH_Structure <GH_Curve>();
            ghCurves = inCurves.Duplicate();
            ghCurves.Graft(GH_GraftMode.GraftAll);
            ghCurves.Simplify(GH_SimplificationMode.CollapseAllOverlaps);

            GH_Structure <GH_Number> inDistances = new GH_Structure <GH_Number>();
            bool areDistancesOk = DA.GetDataTree(1, out inDistances);
            inputChecker.StopIfConversionIsFailed(areDistancesOk);
            GH_Structure <GH_Number> ghDistances = new GH_Structure <GH_Number>();
            ghDistances = ValuesAllocator.NumsDSFromCurves(ghCurves, inDistances, ghDistances);

            GH_Structure <GH_Plane> inPlanes = new GH_Structure <GH_Plane>();
            bool arePlanesOk = DA.GetDataTree(2, out inPlanes);
            inputChecker.StopIfConversionIsFailed(arePlanesOk);
            GH_Structure <GH_Plane> ghPlanes = new GH_Structure <GH_Plane>();
            ghPlanes = ValuesAllocator.PlanesDSFromCurves(ghCurves, inPlanes, ghPlanes);

            GH_Structure <GH_Integer> inCorners = new GH_Structure <GH_Integer>();
            bool areCornerssOk = DA.GetDataTree(3, out inCorners);
            inputChecker.StopIfConversionIsFailed(areCornerssOk);
            GH_Structure <GH_Integer> ghCorners = new GH_Structure <GH_Integer>();
            ghCorners = ValuesAllocator.IntegerDSFromCurves(ghCurves, inCorners, ghCorners);
            #endregion

            GH_Structure <GH_Curve> ghCurveOffset = new GH_Structure <GH_Curve>();
            double docTollerance = DocumentTolerance();

            int pathIndex = 0;
            foreach (GH_Path ghPath in ghCurves.Paths)
            {
                for (int i = 0; i < ghCurves.get_Branch(ghPath).Count; i++)
                {
                    CurveOffsetCornerStyle cornerStyle = CurveOffsetCornerStyle.None;
                    int cornerStyleInInt = ghCorners.get_DataItem(ghPath, i).Value;
                    GetCornerStyleFromInt(ref cornerStyleInInt, ref cornerStyle);

                    Curve  crv   = ghCurves.get_DataItem(ghPath, i).Value;
                    Plane  plane = ghPlanes.get_DataItem(ghPath, i).Value;
                    double dist  = ghDistances.get_DataItem(ghPath, i).Value;

                    List <Curve> resultingCurves = new List <Curve>();

                    resultingCurves.AddRange(crv.Offset(plane, dist, docTollerance, cornerStyle));
                    resultingCurves.AddRange(crv.Offset(plane, dist *= -1, docTollerance, cornerStyle));
                    foreach (Curve resultingCrv in resultingCurves)
                    {
                        GH_Curve ghResultingCrv = null;
                        if (GH_Convert.ToGHCurve(resultingCrv, GH_Conversion.Both, ref ghResultingCrv))
                        {
                            ghCurveOffset.Append(ghResultingCrv, ghPath);
                        }
                    }
                }
                pathIndex++;
            }

            DA.SetDataTree(0, ghCurveOffset);
        }
Esempio n. 7
0
        public static Curve OffsetOut(this Curve curve, double distance, Plane plane, CurveOffsetCornerStyle cornerStyle = CurveOffsetCornerStyle.Sharp)
        {
            if (distance == 0)
            {
                return(curve);
            }

            double original_area = AreaMassProperties.Compute(curve).Area;

            Curve[] offset_1 = curve.Offset(plane, distance, ObjectModel.Tolerance.Distance, cornerStyle);
            if (offset_1 != null)
            {
                double area_1 = AreaMassProperties.Compute(offset_1[0]).Area;
                if (area_1 > original_area)
                {
                    return(offset_1[0]);
                }
                else
                {
                    return(curve.Offset(plane, -distance, ObjectModel.Tolerance.Distance, cornerStyle)[0]);
                }
            }
            else
            {
                return(curve.Offset(plane, -distance, ObjectModel.Tolerance.Distance, cornerStyle)[0]);
            }
        }
Esempio n. 8
0
 //====================================================================//
 public static NotImplementedException OffsetIn(this Curve curve, double distance, Plane plane, CurveOffsetCornerStyle cornerStyle = CurveOffsetCornerStyle.Sharp)
 {
     return(new NotImplementedException());
 }