Exemplo n.º 1
0
 public void AddIntersections(KeyValuePair <Guid, Curve> curveBData, CurveIntersections intersections)
 {
     foreach (var inter in intersections)
     {
         var fryIntersection = new FryIntersection(inter, myCurveData, curveBData);
         this.myIntersections.Add(fryIntersection);
     }
 }
Exemplo n.º 2
0
        DataTree <Point3d> findAllAxisPoints(Point3d startP, List <Vector3d> directions)
        {
            /// 'Walk out' from the center using a list of directions to find all points in this surface 'axis'
            /// Will output a tree with as many branches as directions where input

            /// MAIN BEHAVIOUR
            /// Create an arc using the normal, the direction and the negative normal of size DesiredLength
            /// Intersect the arc with the surface to find next point.
            /// After finding the next point, update current u,v values and current Direction
            /// If no intersections are found BREAK: You have reached the limit of the surface

            DataTree <Point3d> axis = new DataTree <Point3d>(); //Create an empty array of List<Point3d>

            for (int i = 0; i < _axisNum; i++)
            { // Iterate for every axis
                List <Point3d> pts = new List <Point3d>();
                double         u0, v0;
                Vector3d       d = directions[i];              // Set direction to starting dir

                _surface.ClosestPoint(startP, out u0, out v0); // Get U,V of the startingPoint

                double u = u0;
                double v = v0;

                for (int j = 0; j < _MAXITERATIONS; j++)
                { // Iterate until no intersections or maxIterations is reached
                    // Get the current point and normal
                    Point3d  pt = _surface.PointAt(u, v);
                    Vector3d n  = _surface.NormalAt(u, v);

                    pts.Add(pt);         // Add the point to the list
                    n *= _desiredLength; // Set n length to desired
                    d.Unitize();         // Make shure d is unitary
                    d *= _desiredLength; // Set d lenght to desired

                    Arc intArc = new Arc(pt + n, pt + d, pt - n);

                    CurveIntersections cvint =
                        Intersection.CurveSurface(intArc.ToNurbsCurve(), _surface, 0.01, 0.01); // Intersect arc with geometry

                    if (cvint.Count > 0)
                    {
                        cvint[0].SurfacePointParameter(out u, out v); // Find u,v of intersection point
                    }
                    else
                    {
                        break;                       // Break if no intersections are found
                    }
                    d = _surface.PointAt(u, v) - pt; // Update direction
                }

                axis.AddRange(pts, new GH_Path(i)); // Add axis points list to branch
            }
            return(axis);                           //Return the axis points of the grid
        }
 private Point3d FindMaxMTemp(Curve c, Plane p)
 {
     CurveIntersections ci = Intersection.CurvePlane(c, p, RhinoDoc.ActiveDoc.ModelAbsoluteTolerance);
     if (ci == null) return new Point3d(0.1, 0.1, 0);
     List<Point3d> points = new List<Point3d>();
     foreach (IntersectionEvent ie in ci)
     {
         points.Add(ie.PointA);
     }
     return points.Max();
 }
 private double FindMaxM(Curve c, Plane p, Axis direction)
 {
     
     CurveIntersections ci = Intersection.CurvePlane(c,p, RhinoDoc.ActiveDoc.ModelAbsoluteTolerance);
     if (ci == null) return 0.1;
     List<Point3d> points = new List<Point3d>();
     foreach (IntersectionEvent ie in ci)
     {
         points.Add(ie.PointA);
     }
     return (direction == Axis.ZAxis?  points.Select(o => o.Z).Max() : points.Select(o => o.Y).Max());
 }
Exemplo n.º 5
0
        /// <summary>
        /// Basic collision detection routine for single item placement.
        /// </summary>
        /// <param name="room">Room currently being populated.</param>
        /// <param name="candidate">PlacementPackaged being checked for fidelity.</param>
        /// <param name="pm"></param>
        /// <returns></returns>
        public static bool PlacementIsValid(RoomPackage room, PlacementPackage candidate, ProgramManifest pm)
        {
            //Verify placed item does not clash with previously placed items.
            foreach (PlacementPackage placedItem in room.PlacedItems)
            {
                if (Confirm.CurvesIntersect(placedItem.Bounds, candidate.Bounds, true))
                {
                    if (Confirm.CurvesIntersect(placedItem.Bounds, candidate.Bounds, false))
                    {
                        return(false);
                    }

                    CurveIntersections ccx = Intersection.CurveCurve(placedItem.Bounds, candidate.Bounds, 0.1, 0.1);

                    if (ccx.Count(x => x.IsOverlap) > 1)
                    {
                        return(false);
                    }
                }

                PointContainment insideCheck = placedItem.Bounds.Contains(candidate.Bounds.GetBoundingBox(Plane.WorldXY).Center);

                if (insideCheck == PointContainment.Inside || insideCheck == PointContainment.Coincident)
                {
                    return(false);
                }
            }

            //Verify item is completely within boundary of room.
            foreach (Curve edgeCurve in room.AllEdgeCurves)
            {
                if (Confirm.CurvesIntersect(candidate.Bounds, edgeCurve, false))
                {
                    return(false);
                }

                /*
                 * if (!Confirm.PointInRegion(room.Region, new CurveBounds(candidate.Bounds).Center))
                 * {
                 *  return false;
                 * }
                 */
            }

            //Verify program area is not larger than total room area.
            if (room.Region.GetArea() < pm.ProgramPackages[candidate.ProgramIndex].OccupationArea)
            {
                return(false);
            }

            return(true);
        }
Exemplo n.º 6
0
        // Find the best fitting geodesic curve for a set of
        public double ComputeError(int n, double[] x)
        {
            double   alpha  = x[0];
            Curve    curve  = perpGeodesics[startIndex];
            Point3d  pt     = curve.PointAt(perpParameters[startIndex]);
            Vector3d vector = curve.TangentAt(perpParameters[startIndex]);

            MeshPoint mPt    = mesh.ClosestMeshPoint(pt, 0.0);
            Vector3d  normal = mesh.NormalAt(mPt);
            Vector3d  cP     = Vector3d.CrossProduct(vector, normal);

            cP.Rotate(alpha, normal);

            Curve newG = MeshGeodesicMethods.getGeodesicCurveOnMesh(mesh, pt, cP, maxIter).ToNurbsCurve();

            if (bothDir)
            {
                Curve newG2 = MeshGeodesicMethods.getGeodesicCurveOnMesh(mesh, pt, -cP, maxIter).ToNurbsCurve();
                newG = Curve.JoinCurves(new List <Curve> {
                    newG, newG2
                })[0];
            }

            // Assign resulting geodesic to global property for output.
            selectedGeodesic = newG;

            // Calculate error
            double error = 0;

            for (int i = 0; i < perpGeodesics.Count - 1; i++)
            {
                Curve g = perpGeodesics[i];
                CurveIntersections cvInt = Intersection.CurveCurve(newG, g, 0.00001, 0.00001);
                if (cvInt.Count > 0)
                {
                    // Compute distance if intersection is found
                    double   param    = cvInt[0].ParameterB;
                    Interval domain   = new Interval(param, perpParameters[i]);
                    double   distance = g.GetLength(domain);
                    // Add squared distance to error
                    error += Math.Pow(distance, 2);
                }
                else
                {
                    // Penalize if no intersection is found on this perp geodesic
                    error += 10;
                }
            }
            return(error);
        }
Exemplo n.º 7
0
        internal Plane LocationPlane(double tol)
        {
            Tuple <IfcGridAxis, IfcGridAxis> axes = IntersectingAxes;

#if (RHINO || GH)
            Curve c1 = axes.Item1.Curve(tol), c2 = axes.Item2.Curve(tol);
            CurveIntersections ci = Intersection.CurveCurve(c1, c2, tol, tol);
            if (ci != null && ci.Count > 0)
            {
                return(new Plane(ci[0].PointA + OffsetVector, Vector3d.ZAxis));
            }
#endif
            return(Plane.WorldXY);
        }
Exemplo n.º 8
0
        }//eof

        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            List <Curve> curves = new List <Curve>();
            double       tlr    = 0;

            if (!DA.GetDataList(0, curves))
            {
                return;
            }
            DA.GetData(1, ref tlr);

            List <List <double> > intersectPoints = new List <List <double> >();

            for (int i = 0; i < curves.Count; ++i)
            {
                intersectPoints.Add(new List <double>());
            }
            List <Curve> outputCurves = new List <Curve>();

            for (int i = 0; i < curves.Count - 1; ++i)
            {
                for (int j = i + 1; j < curves.Count; ++j)
                {
                    CurveIntersections cis = Intersection.CurveCurve(curves[i], curves[j], tlr, 0);
                    for (int k = 0; k < cis.Count; ++k)
                    {
                        intersectPoints[i].Add(cis[k].ParameterA);
                        intersectPoints[j].Add(cis[k].ParameterB);
                    }
                }
            }

            for (int i = 0; i < curves.Count; ++i)
            {
                Curve[] crvI = curves[i].DuplicateCurve().Split(intersectPoints[i]);
                for (int j = 0; j < crvI.Length; ++j)
                {
                    outputCurves.Add(crvI[j]);
                }
            }

            DA.SetDataList(0, outputCurves);
        }//eof
Exemplo n.º 9
0
        private (Point3d, int, bool) GetNewMovePt(Polyline pline, List <Point3d> linePts, RhinoDoc doc, int tempDirPtIndex)
        {
            Point3d randomPt = new Point3d();
            int     tryCounter = 0;
            bool    isIntersecting = false, stuckPt = false;

            do
            {
                tryCounter++;
                if (tryCounter == 10000)
                {
                    stuckPt = true; break;
                }
                isIntersecting = false;
                int recentDirIndex;
                (randomPt, recentDirIndex) = GetRandomPt(linePts.Last());
                Line newLinePart = new Line(linePts.Last(), randomPt);
                if (pline.Count == 0)
                {
                    continue;                   // first entrance
                }
                CurveIntersections intersections = Intersection.CurveCurve(newLinePart.ToNurbsCurve(), pline.ToNurbsCurve(), doc.ModelAbsoluteTolerance, doc.ModelAbsoluteTolerance);
                if (intersections.Count != 1)
                {
                    isIntersecting = true;
                }
                if (tempDirPtIndex == recentDirIndex)
                {
                    isIntersecting = true;
                }
                if (linePts.Contains(randomPt))
                {
                    isIntersecting = true;
                }
                tempDirPtIndex = recentDirIndex;
            } while (isIntersecting);
            return(randomPt, tempDirPtIndex, stuckPt);
        }
        public static ZOffsetAtIntersection OffsetAtIntersection(List <Curve> crvs, double LayerWidth, double LayerHeight, double ResolutionMultiplier)
        {
            List <Curve> _crvs = new List <Curve>()
            {
                crvs[0]
            };

            for (int i = 1; i < crvs.Count; i++)
            {
                CurveIntersections ci = Intersection.CurveCurve(crvs[i], crvs[j], 0.01, 0.01);

                crvs[i].DivideByLength(LayerWidth, true, out Point3d[] pts);
                foreach (Curve c in _crvs)
                {
                    c.ClosestPoint
                }
                foreach (Point3d p in pts)
                {
                    p.dis
                }
            }
            return(null);
        }
Exemplo n.º 11
0
        // Find the best fitting geodesic curve for a set of
        public new double ComputeError(int n, double[] x)
        {
            double alpha = x[0];

            bestFitInterval = new int[] { };
            Curve    curve  = perpGeodesics[startIndex];
            Point3d  pt     = curve.PointAt(perpParameters[startIndex]);
            Vector3d vector = curve.TangentAt(perpParameters[startIndex]);

            MeshPoint mPt    = mesh.ClosestMeshPoint(pt, 0.0);
            Vector3d  normal = mesh.NormalAt(mPt);
            Vector3d  cP     = Vector3d.CrossProduct(vector, normal);

            cP.Rotate(alpha, normal);

            if (refDir == Vector3d.Unset)
            {
                refDir = cP;
            }
            double angle = Vector3d.VectorAngle(cP, refDir);

            if (angle >= 0.1 * Math.PI)
            {
                cP = -cP;
            }

            Vector3d.VectorAngle(cP, refDir);
            Curve newG = MeshGeodesicMethods.getGeodesicCurveOnMesh(mesh, pt, cP, maxIter).ToNurbsCurve();

            if (bothDir)
            {
                Curve newG2 = MeshGeodesicMethods.getGeodesicCurveOnMesh(mesh, pt, -cP, maxIter).ToNurbsCurve();
                newG = Curve.JoinCurves(new List <Curve> {
                    newG, newG2
                })[0];
            }

            // Assign resulting geodesic to global property for output.
            selectedGeodesic = newG;

            // Calculate error
            double        error           = 0;
            List <double> distances       = new List <double>();
            List <double> signedDistances = new List <double>();

            for (int i = 0; i < perpGeodesics.Count - 1; i++)
            {
                Curve g = perpGeodesics[i];
                CurveIntersections cvInt          = Intersection.CurveCurve(newG, g, 0.00001, 0.00001);
                double             signedDistance = g.GetLength(new Interval(0, perpParameters[i]));
                signedDistances.Add(signedDistance);
                if (cvInt.Count > 0)
                {
                    // Compute distance if intersection is found
                    double param    = cvInt[0].ParameterB;
                    double distance = g.GetLength(new Interval(0, param));
                    distances.Add(distance);
                    // Add squared distance to error
                    error += Math.Pow(signedDistance - distance, 2);
                }
                else
                {
                    // Penalize if no intersection is found on this perp geodesic
                    distances.Add(1000);
                    error += 1000;
                }
            }

            //Calculate longest interval within threshold.
            for (int k = (distances.Count - 1); k >= 2; k--)
            {
                for (int i = 0; i < (distances.Count - k); i++)
                {
                    //Check if interval i->k is within bounds
                    bool flag = true;
                    for (int j = i; j < i + k; j++)
                    {
                        double Lbound = signedDistances[j] * (1 - threshold);
                        double Ubound = signedDistances[j] * (1 + threshold);
                        if (Lbound > distances[j] || distances[j] > Ubound)
                        {
                            flag = false;
                            break;
                        }
                    }
                    if (flag && bestFitInterval.Length == 0)
                    {
                        bestFitInterval = new int[] { i, i + k };
                    }
                }
            }
            if (bestFitInterval.Length == 0)
            {
                error += 1000000;
                return(error);
            }
            error = error / (bestFitInterval[1] - bestFitInterval[0]);

            //if (invertDir) selectedGeodesic.Reverse();

            return(error);
        }
Exemplo n.º 12
0
        /// <summary>
        /// Test for a curve that is a polyline (or looks like a polyline).
        /// </summary>
        bool IsPolyline(Curve curve, ref int point_count, ref bool bClosed, ref bool bPlanar, ref bool bLength, ref bool bAngle, ref bool bIntersect)
        {
            if (null == curve)
            {
                return(false);
            }

            List <Point3d> points = new List <Point3d>();

            // Is the curve a polyline curve?
            PolylineCurve polyline_curve = curve as PolylineCurve;

            if (null != polyline_curve)
            {
                if (polyline_curve.PointCount <= 2)
                {
                    return(false);
                }

                for (int i = 0; i < polyline_curve.PointCount; i++)
                {
                    points.Add(polyline_curve.Point(i));
                }
            }

            // Is the curve a polycurve that looks like an polyline?
            PolyCurve poly_curve = curve as PolyCurve;

            if (null != poly_curve)
            {
                Polyline polyline;
                if (poly_curve.TryGetPolyline(out polyline))
                {
                    if (polyline.Count <= 2)
                    {
                        return(false);
                    }

                    for (int i = 0; i < polyline.Count; i++)
                    {
                        points.Add(polyline[i]);
                    }
                }
            }

            // Is the curve a NURBS curve that looks like an polyline?
            NurbsCurve nurbs_curve = curve as NurbsCurve;

            if (null != nurbs_curve)
            {
                Polyline polyline;
                if (nurbs_curve.TryGetPolyline(out polyline))
                {
                    if (polyline.Count <= 2)
                    {
                        return(false);
                    }

                    for (int i = 0; i < polyline.Count; i++)
                    {
                        points.Add(polyline[i]);
                    }
                }
            }

            if (0 == points.Count)
            {
                return(false);
            }

            // Is the curve closed?
            bClosed = curve.IsClosed;

            // Is the curve planar?
            bPlanar = curve.IsPlanar();

            // Get the point (vertex) count.
            point_count = (bClosed ? points.Count - 1 : points.Count);

            // Test for self-intersection.
            CurveIntersections intesections = Intersection.CurveSelf(curve, m_tolerance);

            bIntersect = (intesections.Count > 0) ? true : false;

            // If the curve is not closed, no reason to continue...
            if (!bClosed)
            {
                return(true);
            }

            // Test if the distance between each point is identical.
            double distance = 0.0;

            for (int i = 1; i < points.Count; i++)
            {
                Point3d  p0 = points[i - 1];
                Point3d  p1 = points[i];
                Vector3d v  = p0 - p1;

                double d = v.Length;
                if (i == 1)
                {
                    distance = d;
                    continue;
                }
                else if (Math.Abs(distance - d) < m_tolerance)
                {
                    continue;
                }
                else
                {
                    distance = RhinoMath.UnsetValue;
                    break;
                }
            }

            // Set return value.
            bLength = RhinoMath.IsValidDouble(distance);

            // Test if the angle between each point is identical.
            double angle = 0.0;

            for (int i = 1; i < points.Count - 1; i++)
            {
                Point3d p0 = points[i - 1];
                Point3d p1 = points[i];
                Point3d p2 = points[i + 1];

                Vector3d v0 = p1 - p0;
                Vector3d v1 = p1 - p2;

                v0.Unitize();
                v1.Unitize();

                double a = Vector3d.VectorAngle(v0, v1);
                if (i == 1)
                {
                    angle = a;
                    continue;
                }
                else if (Math.Abs(angle - a) < m_angle_tolerance)
                {
                    continue;
                }
                else
                {
                    angle = RhinoMath.UnsetValue;
                    break;
                }
            }

            // Set return value.
            bAngle = RhinoMath.IsValidDouble(angle);

            return(true);
        }
Exemplo n.º 13
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)
        {
            Surface S = null;

            if (!DA.GetData(0, ref S))
            {
                return;
            }

            Point3d P = Point3d.Unset;

            if (!DA.GetData(1, ref P))
            {
                P = S.PointAt(S.Domain(0).Mid, S.Domain(1).Mid);
            }

            double R = Rhino.RhinoMath.UnsetValue;

            if (!DA.GetData(2, ref R))
            {
                return;
            }

            double A = Rhino.RhinoMath.UnsetValue;

            if (!DA.GetData(3, ref A))
            {
                return;
            }

            int max = 0;

            if (!DA.GetData(4, ref max))
            {
                return;
            }

            Boolean extend = false;

            if (!DA.GetData(5, ref extend))
            {
                return;
            }

            if (R <= 0)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Mesh edge length must be a positive, non-zero number.");
                return;
            }

            // Extend surface beyond boundaries to get a better coverage from the net
            if (extend)
            {
                S = S.Extend(IsoStatus.North, R, true);
                S = S.Extend(IsoStatus.East, R, true);
                S = S.Extend(IsoStatus.South, R, true);
                S = S.Extend(IsoStatus.West, R, true);
            }


            // starting point
            double u0, v0;

            S.ClosestPoint(P, out u0, out v0);
            // get two (four) orthogonal directions (in plane of surface at starting point)
            Plane plane = new Plane(S.PointAt(u0, v0), S.NormalAt(u0, v0));

            plane.Rotate(Rhino.RhinoMath.ToRadians(A), S.NormalAt(u0, v0));
            Vector3d[] dir = new Vector3d[] {
                plane.XAxis *  R,
                plane.YAxis *  R,
                plane.XAxis * -R,
                       plane.YAxis * -R
            };


            // for each direction, walk out (and store list of points)
            double u, v;

            List <Point3d>[] axis = new List <Point3d> [4];
            for (int i = 0; i < 4; i++)
            {
                // set u and v to starting point
                u = u0;
                v = v0;
                List <Point3d> pts = new List <Point3d>();
                for (int j = 0; j < max + 1; j++)
                {
                    // get point and normal for uv
                    Point3d  pt = S.PointAt(u, v);
                    Vector3d n  = S.NormalAt(u, v);
                    n *= R;
                    // add point to list
                    pts.Add(pt);
                    // create forward facing arc and find intersection point with surface (as uv)
                    Arc arc = new Arc(pt + n, pt + dir[i], pt - n);
                    CurveIntersections isct =
                        Intersection.CurveSurface(arc.ToNurbsCurve(), S, 0.01, 0.01);
                    if (isct.Count > 0)
                    {
                        isct[0].SurfacePointParameter(out u, out v);
                    }
                    else
                    {
                        break;
                    }
                    // adjust direction vector (new position - old position)
                    dir[i] = S.PointAt(u, v) - pt;
                }
                axis[i] = pts;
            }


            // now that we have the axes, start to build up the mesh quads in between
            GH_PreviewUtil preview = new GH_PreviewUtil(GetValue("Animate", false));

            Rhino.Geometry.Mesh mesh = new Rhino.Geometry.Mesh(); // target mesh
            for (int k = 0; k < 4; k++)
            {
                int k0      = (k + 1) % 4;
                int padding = 10;
                Rhino.Geometry.Mesh qmesh = new Rhino.Geometry.Mesh();                            // local mesh for quadrant
                Point3d[,] quad = new Point3d[axis[k].Count + padding, axis[k0].Count + padding]; // 2d array of points
                int[,] qindex   = new int[axis[k].Count + padding, axis[k0].Count + padding];     // 2d array of points' indices in local mesh
                int count = 0;
                for (int i = 0; i < axis[k0].Count; i++)
                {
                    // add axis vertex to mesh and store point and index in corresponding 2d arrays
                    quad[0, i] = axis[k0][i];
                    qmesh.Vertices.Add(axis[k0][i]);
                    qindex[0, i] = count++;
                }

                for (int i = 1; i < quad.GetLength(0); i++)
                {
                    if (i < axis[k].Count)
                    {
                        // add axis vertex
                        quad[i, 0] = axis[k][i];
                        qmesh.Vertices.Add(axis[k][i]);
                        qindex[i, 0] = count++;
                    }
                    // for each column attempt to locate a new vertex in the grid
                    for (int j = 1; j < quad.GetLength(1); j++)
                    {
                        // if quad[i - 1, j] doesn't exist, try to add it and continue (or else break the current row)
                        if (quad[i - 1, j] == new Point3d())
                        {
                            if (j < 2)
                            {
                                break;
                            }
                            CurveIntersections isct = this.ArcIntersect(S, quad[i - 1, j - 1], quad[i - 1, j - 2], R);
                            if (isct.Count > 0)
                            {
                                quad[i - 1, j] = isct[0].PointB;
                                qmesh.Vertices.Add(quad[i - 1, j]);
                                qindex[i - 1, j] = count++;
                            }
                            else
                            {
                                break;
                            }
                        }
                        // if quad[i, j - 1] doesn't exist, try to create quad[i, j] by projection and skip mesh face creation
                        if (quad[i, j - 1] == new Point3d())
                        {
                            if (i < 2)
                            {
                                break;
                            }
                            CurveIntersections isct = this.ArcIntersect(S, quad[i - 1, j], quad[i - 2, j], R);
                            if (isct.Count > 0)
                            {
                                quad[i, j] = isct[0].PointB;
                                qmesh.Vertices.Add(quad[i, j]);
                                qindex[i, j] = count++;
                                continue;
                            }
                        }
                        // construct a sphere at each neighbouring vertex ([i,j-1] and [i-1,j]) and intersect
                        Sphere sph1 = new Sphere(quad[i, j - 1], R);
                        Sphere sph2 = new Sphere(quad[i - 1, j], R);
                        Circle cir;
                        if (Intersection.SphereSphere(sph1, sph2, out cir) == SphereSphereIntersection.Circle)
                        {
                            // intersect circle with surface
                            CurveIntersections cin =
                                Intersection.CurveSurface(NurbsCurve.CreateFromCircle(cir), S, 0.01, 0.01);
                            // attempt to find the new vertex (i.e not [i-1,j-1])
                            foreach (IntersectionEvent ie in cin)
                            {
                                if ((ie.PointA - quad[i - 1, j - 1]).Length > 0.2 * R) // compare with a tolerance, rather than exact comparison
                                {
                                    quad[i, j] = ie.PointA;
                                    qmesh.Vertices.Add(quad[i, j]);
                                    qindex[i, j] = count++;
                                    // create quad-face
                                    qmesh.Faces.AddFace(qindex[i, j], qindex[i - 1, j], qindex[i - 1, j - 1], qindex[i, j - 1]);
                                    break;
                                }
                            }
                            if (preview.Enabled)
                            {
                                preview.Clear();
                                preview.AddMesh(mesh);
                                preview.AddMesh(qmesh);
                                preview.Redraw();
                            }
                        }
                    }
                }
                // add local mesh to target
                mesh.Append(qmesh);
            }

            // weld mesh to remove duplicate vertices along axes
            mesh.Weld(Math.PI);
            mesh.Compact();
            mesh.Normals.ComputeNormals();


            DA.SetData(0, mesh);

            preview.Clear();
        }
Exemplo n.º 14
0
        public static void Make3d(string schemeName)
        {
            string inputLayerPath  = schemeName + "::EJLT Shapes";
            string outputLayerPath = schemeName + "::Walls";
            string doorsLayerPath  = schemeName + "::Doors";

            List <int>       layerIndexs;
            List <Curve>     curves   = LayerHelper.GetCurvesFromChild(inputLayerPath, out layerIndexs);
            List <Curve>     doors    = LayerHelper.GetCurvesFrom(doorsLayerPath);
            List <LineCurve> afterCut = new List <LineCurve>();

            List <Line> exploded = new List <Line>();

            foreach (Curve c in curves)
            {
                Polyline poly;
                c.TryGetPolyline(out poly);

                exploded.AddRange(poly.GetSegments());
            }

            List <Line> lineSegDoor = new List <Line>();
            List <List <LineCurve> > doorsPerSeg = new List <List <LineCurve> >();

            foreach (Line lineSeg in exploded)
            {
                List <LineCurve> doorsThisSeg = new List <LineCurve>();
                foreach (Curve door in doors)
                {
                    CurveIntersections inter = Intersection.CurveLine(door, lineSeg, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance, 0.0);
                    if (inter.Count == 2)
                    {
                        LineCurve l1;

                        Point3d p1 = inter.First().PointA;
                        Point3d p2 = inter[1].PointA;
                        l1 = new LineCurve(p1, p2);
                        doorsThisSeg.Add(l1);
                    }
                }
                if (doorsThisSeg.Count > 0)
                {
                    lineSegDoor.Add(lineSeg);
                    doorsPerSeg.Add(doorsThisSeg);
                }
                else
                {
                    // no intersection, add to after cut
                    afterCut.Add(new LineCurve(lineSeg));
                }
            }

            for (int i = 0; i < lineSegDoor.Count; i++)
            {
                // points from all intersection points
                List <Point3d> intersectionPts = new List <Point3d>();
                intersectionPts.Add(lineSegDoor[i].From);
                intersectionPts.Add(lineSegDoor[i].To);
                foreach (LineCurve doorLine in doorsPerSeg[i])
                {
                    intersectionPts.Add(doorLine.PointAtStart);
                    intersectionPts.Add(doorLine.PointAtEnd);
                }
                List <Point3d> sortedPoints = intersectionPts.OrderBy(pnt => pnt.Y).ThenBy(pnt => pnt.X).ToList();

                // construct line segments
                for (int pi = 0; pi < sortedPoints.Count; pi = pi + 2)
                {
                    LineCurve cuttedSegment = new LineCurve(sortedPoints[pi], sortedPoints[pi + 1]);
                    bool      indoor        = false;
                    foreach (Curve door in doors)
                    {
                        if (door.Contains(cuttedSegment.PointAt(0.5), Plane.WorldXY, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance) == PointContainment.Inside)
                        {
                            indoor = true;
                            break;
                        }
                    }
                    if (!indoor)
                    {
                        afterCut.Add(cuttedSegment);
                    }
                }
            }
            UnitSystem currentDocUnits  = RhinoDoc.ActiveDoc.ModelUnitSystem;
            double     unitSystemScaler = RhinoMath.UnitScale(UnitSystem.Feet, currentDocUnits);

            foreach (LineCurve wallLine in afterCut)
            {
                LayerHelper.BakeObjectToLayer(Extrusion.Create(wallLine, 8 * unitSystemScaler, false).ToBrep(), "Walls", schemeName);
            }
            Rhino.RhinoDoc.ActiveDoc.Views.Redraw();
        }
Exemplo n.º 15
0
        public static List <Curve> BestSplitterCurves(List <Brep> zones, List <Curve> circ, Curve core)
        {
            int numZones      = zones.Count;
            int numCircCurves = circ.Count;

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

            for (int i = 0; i < numZones; i++)
            {
                int validCircCurves = 0;

                List <bool>   intersects           = new List <bool>();
                List <double> intersectionInterval = new List <double>();

                //RhinoApp.WriteLine("---");

                for (int j = 0; j < numCircCurves; j++)
                {
                    if (Confirm.CurveRegionIntersection(circ[j], zones[i]) && circ[j].Degree == 1)
                    {
                        //RhinoApp.WriteLine("Region intersection exists.");

                        validCircCurves++;
                        intersects.Add(true);

                        CurveIntersections csx = Intersection.CurveSurface(circ[j], zones[i].Surfaces[0], 0.1, 0.1);

                        //RhinoApp.WriteLine("--{0} csx event(s). (Overlap: {1})", csx.Count, csx[0].OverlapA.ToString());

                        intersectionInterval.Add(csx[0].OverlapA.T1 - csx[0].OverlapB.T0);
                    }
                    else
                    {
                        //RhinoApp.WriteLine("Region intersection does not exist.");

                        intersects.Add(false);

                        intersectionInterval.Add(0);
                    }
                }

                if (validCircCurves == 0)
                {
                    //RhinoApp.WriteLine("No circulation options.");

                    Curve newSplitCurve = Select.GenerateSplitCurve(zones[i], core);

                    splitterCurves.Add(newSplitCurve);
                }
                if (validCircCurves == 1)
                {
                    //RhinoApp.WriteLine("Only one option.");
                    splitterCurves.Add(circ[intersects.IndexOf(true)]);
                }
                else if (validCircCurves > 1)
                {
                    //RhinoApp.WriteLine(validCircCurves.ToString() + " options.");
                    splitterCurves.Add(circ[intersectionInterval.IndexOf(intersectionInterval.Max())]);
                }

                intersects.Clear();
                intersectionInterval.Clear();
            }

            return(splitterCurves);
        }
Exemplo n.º 16
0
        DataTree <Point3d> getAllGridPoints(DataTree <Point3d> axisPoints)
        { // Assigns to '_grid' a tree with as many ranches as items contained in the gridAxisList
            DataTree <Point3d> resultingPoints = new DataTree <Point3d>();

            for (int i = 0; i < axisPoints.BranchCount; i++)
            { // Iterate on all axises
                DataTree <Point3d> quarterGrid = new DataTree <Point3d>();
                List <Point3d>     xAxis;
                List <Point3d>     yAxis;

                if (i % 2 == 0)
                {
                    xAxis = axisPoints.Branch(new GH_Path(i + 1));
                    yAxis = axisPoints.Branch(new GH_Path(i));
                    if (i == axisPoints.BranchCount - 1)
                    {
                        xAxis = axisPoints.Branch(new GH_Path(0));
                        yAxis = axisPoints.Branch(new GH_Path(i));
                    }
                }
                else
                {
                    xAxis = axisPoints.Branch(new GH_Path(i));
                    yAxis = axisPoints.Branch(new GH_Path(i + 1));
                    if (i == axisPoints.BranchCount - 1)
                    {
                        xAxis = axisPoints.Branch(new GH_Path(i));
                        yAxis = axisPoints.Branch(new GH_Path(0));
                    }
                }


                // Fill x and y axis list and wrap in the last index


                int[] complexPath = new int[] { i, 0 };
                quarterGrid.AddRange(xAxis, new GH_Path(complexPath)); //Add xAxis to path 0 of the quarter

                for (int j = 1; j < yAxis.Count; j++)
                { // Iterate on all yAxis Points EXCEPT the first one
                    complexPath = new int[] { i, j };
                    Point3d lastPoint = yAxis[j];
                    quarterGrid.Add(lastPoint, new GH_Path(complexPath)); //Add yAxis Point to list

                    for (int k = 1; k < xAxis.Count; k++)
                    { // Iterate on all xAxis Points EXCEPT the first one
                        //Intersection!!!
                        Sphere sphere1 = new Sphere(lastPoint, _desiredLength);
                        Sphere sphere2 = new Sphere(xAxis[k], _desiredLength);
                        Circle cir1;
                        Intersection.SphereSphere(sphere1, sphere2, out cir1);
                        CurveIntersections crvint = Intersection.CurveSurface(cir1.ToNurbsCurve(), _surface, 0.001, 0.001);

                        if (crvint.Count <= 1)
                        { // If  one or 0 intersections are found BREAK
                            break;
                        }
                        else
                        { // If 2 points are found, filter by distance to diagonal point
                            double u, v;
                            foreach (IntersectionEvent iE in crvint)
                            {
                                iE.SurfacePointParameter(out u, out v);

                                Point3d tmpPt = _surface.PointAt(u, v);
                                //int[] diagPath = new int[] { i, j - 1 };
                                //Point3d diagPt = quarterGrid[new GH_Path(diagPath), k - 1];
                                double dist = tmpPt.DistanceTo(xAxis[k - 1]);
                                if (dist < 0.02)
                                {
                                    // Do nothing
                                }
                                else
                                {
                                    quarterGrid.Add(tmpPt, new GH_Path(complexPath));
                                    lastPoint = tmpPt;
                                    break;
                                }
                            }
                        }
                    }
                    xAxis = quarterGrid.Branch(complexPath);
                }
                resultingPoints.MergeTree(quarterGrid);
                // Generate net using Grid
                createNetFromPoints(quarterGrid);
            }
            return(resultingPoints);
        }
Exemplo n.º 17
0
        //public VariableDivide() { }
        public static VariableDivide Divide(Curve crv, List <double> distanceList, int rep)
        {
            VariableDivide vd = new VariableDivide();

            if (distanceList.Count == 0)
            {
                return(null);
            }

            if (rep > 2 | rep < 0)
            {
                rep = 0;
            }
            //Dictionary<int, List<double>>.ValueCollection values = dictDistances.Values;

            crv.Domain = new Interval(0, crv.GetLength());
            double t1  = crv.Domain.T1;
            double tol = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;

            int i, j;

            i = j = -1;

            List <Curve>   crvList = new List <Curve>();
            List <Point3d> ptList  = new List <Point3d>()
            {
                crv.PointAtStart
            };
            List <Vector3d> vecList = new List <Vector3d>()
            {
                crv.TangentAtStart
            };
            List <double> paramList = new List <double>()
            {
                0.0
            };
            bool tolBool    = false;
            bool endPtsBool = false;

            //warning message
            if (crv.PointAtStart.DistanceTo(crv.PointAtEnd) < distanceList.Max())
            {
                endPtsBool = true;
            }

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

            curves.Sort((x, y) => x.PointAtStart.Z.CompareTo(y.PointAtStart.Z)); // Sort curve based on Height

            //recursion

            while (true)
            {
                //reset i if distance list end reached but curve is still long.
                if (i >= distanceList.Count - 1)
                {
                    switch (rep)
                    {
                    case 0:
                        i = -1;
                        break;

                    case 1:
                        i = distanceList.Count - 2;
                        break;

                    case 2:
                        goto Finish;
                    }
                }
                // increment
                i++;
                j++;

                //intersection properties for
                double       currentParam    = paramList[j];
                double       currentDistance = distanceList[i];
                NurbsSurface nurbsSrf        = new Sphere(crv.PointAt(currentParam), currentDistance).ToNurbsSurface();

                if (currentDistance < tol)  // if current distance is smaller than document tolerance, remove distance from computation
                {
                    tolBool = true;
                    distanceList.RemoveAt(i);
                }

                currentDistance = crv.Split(currentParam)[0].GetLength() + (distanceList[i] * 1.1);

                // sphere-curve intersection
                // using  overload with curve domain to limit intersection area- allows to break while-loop when curve reaches the end.
                CurveIntersections events = Intersection.CurveSurface(crv, new Interval(currentParam, currentDistance), nurbsSrf, tol, tol);

                if (events != null && events.Count > 0)
                {
                    if (events.Last().ParameterA > paramList.Last())
                    {
                        ptList.Add(events.Last().PointA);
                        vecList.Add(crv.TangentAt(events.Last().ParameterA));
                        paramList.Add(events.Last().ParameterA);
                    }
                    else
                    {
                        break;
                    }
                }
                else
                {
                    break;
                }
            }

Finish:
            crvList.Add(crv);
            ptList.Add(crv.PointAtEnd);
            vecList.Add(crv.TangentAtEnd);
            paramList.Add(crv.Domain.Max);

            vd.Curves               = crvList;
            vd.Points               = ptList;
            vd.Tangents             = vecList;
            vd.Parameters           = paramList;
            vd.WarningMessageTol    = tolBool;
            vd.WarningMessageEndPts = endPtsBool;

            return(vd);
        }
Exemplo n.º 18
0
        public List <Curve> Compute(Mesh msh, Vector3d vec, List <Mesh> pMesh)
        {
            Plane        pln     = new Plane(new Point3d(0, 0, 0), vec);
            List <Curve> crvList = new List <Curve>();

            double tol = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;

            List <PolyCurve> ppc = new List <PolyCurve>();
            List <Curve>     pc  = new List <Curve>();

            Polyline[] plArr = msh.GetOutlines(pln);

            List <PolylineCurve> _ppcs = new List <PolylineCurve>();

            Parallel.For(0, plArr.Length,
                         i =>
            {
                _ppcs.Add(plArr[i].ToPolylineCurve());
            });
            Curve[] _ppc = Curve.JoinCurves(_ppcs);
            foreach (var c in _ppc)
            {
                ppc.Add(c as PolyCurve);
            }

            // for each mesh in projection Mesh , Get The outline as polyline. convert to curve and join

            Parallel.ForEach(pMesh,
                             pM =>
            {
                Polyline[] _pPl           = pM.GetOutlines(pln);
                List <PolylineCurve> _pcs = new List <PolylineCurve>();
                Parallel.For(0, _pPl.Length,
                             i =>
                {
                    _pcs.Add(_pPl[i].ToPolylineCurve());
                });
                Curve[] _pc = Curve.JoinCurves(_pcs);
                foreach (Curve c in _pc)
                {
                    pc.Add(c);
                }
            });

            Parallel.For(0, plArr.Length,
                         i =>
            {
                Curve[] _crv = Curve.ProjectToMesh(ppc[i], pMesh, vec, tol);

                Parallel.ForEach(_crv,
                                 c =>
                {
                    if (c.IsClosed)
                    {
                        crvList.Add(c);
                    }
                    else
                    {
                        foreach (Curve curve in _ppcs)
                        {
                            CurveIntersections inter = Intersection.CurveCurve(c, curve, tol, tol);
                        }
                    }
                });
            });

            return(crvList);
        }
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            iPoints = new List <Point3d>();
            DA.GetDataList <Point3d>("Points", iPoints);
            iApicals = new List <Circle>();
            DA.GetDataList <Circle>("Apicals", iApicals);
            iMasses = new List <double>();
            DA.GetDataList <double>("Masses", iMasses);
            DA.GetData <Curve>("Boundary Curve", ref iBoundaryCurve);
            DA.GetData <double>("Rest Length Scale", ref iRestLengthScale);
            DA.GetData <double>("Rest Length Offset", ref iRestLengthOffset);
            DA.GetData <double>("Stiffness", ref iStiffness);
            DA.GetData <double>("Bending Stiffness", ref iBendingStiffness);
            DA.GetData <bool>("In/Out Switch", ref iInOutSwitch);
            DA.GetData <double>("In/Out Threshold", ref iInOutThreshold);
            DA.GetData <double>("Boundary Vertex Threshold", ref iBoundaryVertexThreshold);
            iFixedPointExclusion = new List <Curve>();
            DA.GetDataList <Curve>("Fixed Point Exclusion", iFixedPointExclusion);
            iFixedPointInclusion = new List <Curve>();
            DA.GetDataList <Curve>("Fixed Point Inclusion", iFixedPointInclusion);


            // ===========================================================================================
            // Compute Delaunay Triangulation
            // ===========================================================================================

            List <DelaunayVertex> delaunayVertices = new List <DelaunayVertex>();

            foreach (Point3d point in iPoints)
            {
                delaunayVertices.Add(new DelaunayVertex(point.X, point.Y));
            }

            List <Triad> triads = new DelaunayTriangulator().Triangulation(delaunayVertices);

            HashSet <Tuple <int, int> > delaunayEdgeTuples = new HashSet <Tuple <int, int> >();


            for (int i = 0; i < triads.Count; i++)
            {
                Triad triad = triads[i];
                delaunayEdgeTuples.Add(triad.a < triad.b ? new Tuple <int, int>(triad.a, triad.b) : new Tuple <int, int>(triad.b, triad.a));
                delaunayEdgeTuples.Add(triad.b < triad.c ? new Tuple <int, int>(triad.b, triad.c) : new Tuple <int, int>(triad.c, triad.b));
                delaunayEdgeTuples.Add(triad.c < triad.a ? new Tuple <int, int>(triad.c, triad.a) : new Tuple <int, int>(triad.a, triad.c));
            }


            // ===========================================================================================
            // Convert Delaunay mesh to particle-spring mesh
            // ===========================================================================================

            oSpringMesh = new SpringMesh();
            Curve boundaryCurveXY = Curve.ProjectToPlane(iBoundaryCurve, Plane.WorldXY);

            // Create edge list -----------------------------------------------------------------------------------------------

            foreach (Tuple <int, int> delaunayEdgeTuple in delaunayEdgeTuples)
            {
                Point3d A = iPoints[delaunayEdgeTuple.Item1];
                Point3d B = iPoints[delaunayEdgeTuple.Item2];
                Point3d M = 0.5 * (A + B);

                // Skip if the edge lies outside of the boundary
                double t;
                boundaryCurveXY.ClosestPoint(M, out t);
                Point3d N = boundaryCurveXY.PointAt(t);
                if (Vector3d.CrossProduct(boundaryCurveXY.TangentAt(t), M - N).Z *(iInOutSwitch ? -1.0 : 1.0) < 0.0 &&
                    Utils.DistanceSquared(M, N) > iInOutThreshold * iInOutThreshold)
                {
                    continue;
                }

                double edgeLength = Utils.Distance(A, B);
                double restLength = iRestLengthScale * edgeLength + iRestLengthOffset;
                oSpringMesh.Edges.Add(new Edge(delaunayEdgeTuple.Item1, delaunayEdgeTuple.Item2, restLength, iStiffness, Math.PI, iBendingStiffness));
            }

            // Create vertex list -----------------------------------------------------------------------------------------------

            List <HashSet <int> > neighborVerticesSets = new List <HashSet <int> >();

            for (int i = 0; i < iPoints.Count; i++)
            {
                neighborVerticesSets.Add(new HashSet <int>());
            }

            foreach (Edge edge in oSpringMesh.Edges)
            {
                neighborVerticesSets[edge.FirstVertexIndex].Add(edge.SecondVertexIndex);
                neighborVerticesSets[edge.SecondVertexIndex].Add(edge.FirstVertexIndex);
            }

            for (int i = 0; i < iPoints.Count; i++)
            {
                Point3d p = iPoints[i];
                double  t;
                boundaryCurveXY.ClosestPoint(p, out t);

                bool vertexFixedness  = false;
                bool isBoundaryVertex = false;
                bool isColumnVertex   = false;

                if (Utils.Distance(p, boundaryCurveXY.PointAt(t)) < iBoundaryVertexThreshold)
                {
                    vertexFixedness  = true;
                    isBoundaryVertex = true;
                }
                else
                {
                    foreach (Curve curve in iFixedPointInclusion)
                    {
                        if (curve.Contains(p) == PointContainment.Inside)
                        {
                            vertexFixedness = true;
                            isColumnVertex  = true;
                            break;
                        }
                    }
                }


                Vertex vertex = new Vertex(p, Vector3d.Zero, neighborVerticesSets[i].ToList <int>(), iMasses.Count == 1 ? iMasses[0] : iMasses[i], vertexFixedness);
                vertex.IsBoundaryVertex = isBoundaryVertex;
                vertex.IsColumnVertex   = isColumnVertex;
                oSpringMesh.Vertices.Add(vertex);
            }


            // Set boundary edge -----------------------------------------------------------------------------------------------

            foreach (Edge edge in oSpringMesh.Edges)
            {
                if (oSpringMesh.Vertices[edge.FirstVertexIndex].IsBoundaryVertex && oSpringMesh.Vertices[edge.SecondVertexIndex].IsBoundaryVertex)
                {
                    edge.IsBoundaryEdge = true;
                }
                else if (oSpringMesh.Vertices[edge.FirstVertexIndex].IsColumnVertex && oSpringMesh.Vertices[edge.SecondVertexIndex].IsColumnVertex)
                {
                    edge.IsColumnEdge = true;
                }
            }

            // Create triangle list ------------------------------------------------------------------------------------------------

            Dictionary <Tuple <int, int, int>, int> tripletDict = new Dictionary <Tuple <int, int, int>, int>();

            for (int k = 0; k < oSpringMesh.Edges.Count; k++)
            {
                Edge   edge = oSpringMesh.Edges[k];
                Vertex A    = oSpringMesh.Vertices[edge.FirstVertexIndex];
                Vertex B    = oSpringMesh.Vertices[edge.SecondVertexIndex];

                for (int i = 0; i < A.NeighborVertexIndices.Count; i++)
                {
                    for (int j = 0; j < B.NeighborVertexIndices.Count; j++)
                    {
                        if (A.NeighborVertexIndices[i] == B.NeighborVertexIndices[j])
                        {
                            Tuple <int, int, int> triplet = sortTriplet(edge.FirstVertexIndex, edge.SecondVertexIndex, A.NeighborVertexIndices[i]);

                            if (tripletDict.ContainsKey(triplet))
                            {
                                if (edge.FirstTriangleIndex < 0)
                                {
                                    edge.FirstTriangleIndex       = tripletDict[triplet];
                                    edge.FirstAdjacentVertexIndex = A.NeighborVertexIndices[i];
                                }
                                else
                                {
                                    edge.SecondTriangleIndex       = tripletDict[triplet];
                                    edge.SecondAdjacentVertexIndex = A.NeighborVertexIndices[i];
                                }
                            }
                            else
                            {
                                oSpringMesh.Triangles.Add(new Triangle(triplet.Item1, triplet.Item2, triplet.Item3));

                                int triangleIndex = oSpringMesh.Triangles.Count - 1;

                                if (edge.FirstTriangleIndex < 0)
                                {
                                    edge.FirstTriangleIndex       = triangleIndex;
                                    edge.FirstAdjacentVertexIndex = A.NeighborVertexIndices[i];
                                }
                                else
                                {
                                    edge.SecondTriangleIndex       = triangleIndex;
                                    edge.SecondAdjacentVertexIndex = A.NeighborVertexIndices[i];
                                }

                                tripletDict.Add(triplet, triangleIndex);
                            }
                        }
                    }
                }
            }

            // ===========================================================================================
            // Compute edge indices for each triangle
            // ===========================================================================================

            for (int i = 0; i < oSpringMesh.Edges.Count; i++)
            {
                Edge edge = oSpringMesh.Edges[i];

                Triangle triangle = oSpringMesh.Triangles[edge.FirstTriangleIndex];
                if (triangle.FirstEdgeIndex == -1)
                {
                    triangle.FirstEdgeIndex = i;
                }
                else if (triangle.SecondEdgeIndex == -1)
                {
                    triangle.SecondEdgeIndex = i;
                }
                else
                {
                    triangle.ThirdEdgeIndex = i;
                }

                if (edge.SecondTriangleIndex == -1)
                {
                    continue;
                }

                triangle = oSpringMesh.Triangles[edge.SecondTriangleIndex];
                if (triangle.FirstEdgeIndex == -1)
                {
                    triangle.FirstEdgeIndex = i;
                }
                else if (triangle.SecondEdgeIndex == -1)
                {
                    triangle.SecondEdgeIndex = i;
                }
                else
                {
                    triangle.ThirdEdgeIndex = i;
                }
            }


            // ===========================================================================================
            // Rearange the vertex order in each triangle so the normal calculation is consistent
            // ===========================================================================================

            for (int i = 0; i < oSpringMesh.Triangles.Count; i++)
            {
                if (oSpringMesh.ComputeTriangleNormal(i).Z < 0.0)
                {
                    int temp = oSpringMesh.Triangles[i].SecondVertexIndex;
                    oSpringMesh.Triangles[i].SecondVertexIndex = oSpringMesh.Triangles[i].ThirdVertexIndex;
                    oSpringMesh.Triangles[i].ThirdVertexIndex  = temp;
                }
            }


            // ===========================================================================================
            // Rearranging edge adjacent vertex indices for consitency
            // ===========================================================================================

            foreach (Edge edge in oSpringMesh.Edges)
            {
                if (edge.SecondAdjacentVertexIndex == -1)
                {
                    Point3d A = oSpringMesh.Vertices[edge.FirstVertexIndex].Position;
                    Point3d B = oSpringMesh.Vertices[edge.SecondVertexIndex].Position;
                    Point3d M = oSpringMesh.Vertices[edge.FirstAdjacentVertexIndex].Position;

                    if (Vector3d.CrossProduct(B - A, M - A) * oSpringMesh.ComputeTriangleNormal(edge.FirstTriangleIndex) < 0.0)
                    {
                        Point3d temp = A;
                        A = B;
                        B = temp;
                    }
                }
                else
                {
                    Point3d A = oSpringMesh.Vertices[edge.FirstVertexIndex].Position;
                    Point3d B = oSpringMesh.Vertices[edge.SecondVertexIndex].Position;
                    Point3d M = oSpringMesh.Vertices[edge.FirstAdjacentVertexIndex].Position;
                    Point3d N = oSpringMesh.Vertices[edge.SecondAdjacentVertexIndex].Position;

                    if (Vector3d.CrossProduct(B - A, M - A) * oSpringMesh.ComputeTriangleNormal(edge.FirstAdjacentVertexIndex) < 0.0)
                    {
                        int temp = edge.FirstAdjacentVertexIndex;
                        edge.FirstAdjacentVertexIndex  = edge.SecondAdjacentVertexIndex;
                        edge.SecondAdjacentVertexIndex = temp;

                        temp = edge.FirstTriangleIndex;
                        edge.FirstTriangleIndex  = edge.SecondTriangleIndex;
                        edge.SecondTriangleIndex = temp;
                    }
                }
            }

            // ===========================================================================================
            // Compute adjacent vertex index for each triangle
            // ===========================================================================================

            //foreach (Triangle triangle in oSpringMesh.Triangles)
            //{
            //    Vertex firstVertex = oSpringMesh.Vertices[triangle.FirstVertexIndex];
            //    Vertex secondVertex = oSpringMesh.Vertices[triangle.SecondVertexIndex];
            //    Vertex thirdVertex = oSpringMesh.Vertices[triangle.ThirdVertexIndex];

            //    foreach (int firstNeighbourIndex in firstVertex.NeighborVertexIndices)
            //        foreach (int secondNeighbourIndex in secondVertex.NeighborVertexIndices)
            //            if (firstNeighbourIndex == secondNeighbourIndex && firstNeighbourIndex != triangle.ThirdVertexIndex)
            //                triangle.FirstSecondAdjacentVertexIndex = firstNeighbourIndex;

            //    foreach (int secondNeighbourIndex in secondVertex.NeighborVertexIndices)
            //        foreach (int thirdNeighbourIndex in thirdVertex.NeighborVertexIndices)
            //            if (secondNeighbourIndex == thirdNeighbourIndex && secondNeighbourIndex != triangle.FirstVertexIndex)
            //                triangle.SecondThirdAdjacentVertexIndex = secondNeighbourIndex;

            //    foreach (int thirdNeighbourIndex in thirdVertex.NeighborVertexIndices)
            //        foreach (int firstNeighbourIndex in firstVertex.NeighborVertexIndices)
            //            if (thirdNeighbourIndex == firstNeighbourIndex && thirdNeighbourIndex != triangle.SecondVertexIndex)
            //                triangle.ThirdFirstAdjacentVertexIndex = thirdNeighbourIndex;
            //}


            // ===========================================================================================
            // 3D Boundary Curve
            // ===========================================================================================

            //Brep brep = Brep.CreatePatch(new List<GeometryBase>() { iBoundaryCurve }, null, DocumentTolerance());

            //DA.SetDataList(2, new List<Brep>() { brep });

            foreach (Vertex vertex in oSpringMesh.Vertices)
            {
                if (vertex.IsBoundaryVertex)
                {
                    double t;
                    boundaryCurveXY.ClosestPoint(vertex.Position, out t);
                    Plane frame;
                    boundaryCurveXY.PerpendicularFrameAt(t, out frame);

                    CurveIntersections curveInteresections = Intersection.CurvePlane(iBoundaryCurve, frame, DocumentTolerance());

                    Point3d intersection = Point3d.Unset;
                    double  minDist      = 999999.0;

                    for (int i = 0; i < curveInteresections.Count; i++)
                    {
                        double d = vertex.Position.DistanceTo(curveInteresections[i].PointA);
                        if (d < minDist)
                        {
                            minDist      = d;
                            intersection = curveInteresections[i].PointA;
                        }
                    }

                    vertex.Position = intersection;
                }
                else
                {
                    //LineCurve lineCurve = new LineCurve(
                    //    new Point3d(vertex.Position.X, vertex.Position.Y, vertex.Position.Z - 10.0),
                    //    new Point3d(vertex.Position.X, vertex.Position.Y, vertex.Position.Z + 10.0)
                    //    );

                    //Curve[] overlapCurves;
                    //Point3d[] intersectionPoints;
                    //Intersection.CurveBrep(lineCurve, brep, DocumentTolerance(), out overlapCurves, out intersectionPoints);

                    //if (intersectionPoints.Length > 0)
                    //    vertex.Position = intersectionPoints[0];
                }
            }

            // ===========================================================================================
            // Initial curving bias
            // ===========================================================================================

            DA.GetData <double>("Initial Curving Bias", ref iInitialCurvingBias);
            DA.GetData <bool>("Bias Apical Regions", ref iBiasApicalRegion);

            foreach (Vertex vertex in oSpringMesh.Vertices)
            {
                if (vertex.IsBoundaryVertex || vertex.IsFixed)
                {
                    continue;
                }
                vertex.Position.Z = computeBiasHeight(vertex.Position, iBiasApicalRegion, boundaryCurveXY);
            }


            // ===========================================================================================
            // Conclusion
            // ===========================================================================================

            foreach (Edge edge in oSpringMesh.Edges)
            {
                oDebugCurves1.Add(new LineCurve(oSpringMesh.Vertices[edge.FirstVertexIndex].Position, oSpringMesh.Vertices[edge.SecondVertexIndex].Position));
            }

            DA.SetData(0, oInfo);
            DA.SetDataList(1, oDebugCurves1);
            DA.SetData(6, oSpringMesh);
        }
Exemplo n.º 20
0
            protected override void SolveInstance(IGH_DataAccess DA)
            {
                //Input
                Surface S = null;

                if (!DA.GetData(0, ref S))
                {
                    return;
                }

                Point3d P = Point3d.Unset;

                if (!DA.GetData(1, ref P))
                {
                    P = S.PointAt(S.Domain(0).Mid, S.Domain(1).Mid);
                }

                double R = Rhino.RhinoMath.UnsetValue;

                if (!DA.GetData(2, ref R))
                {
                    return;
                }

                double A = Rhino.RhinoMath.UnsetValue;

                if (!DA.GetData(3, ref A))
                {
                    return;
                }

                int max = 0;

                if (!DA.GetData(4, ref max))
                {
                    return;
                }

                Boolean extend = false;

                if (!DA.GetData(5, ref extend))
                {
                    return;
                }

                if (R <= 0)
                {
                    this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Mesh edge length must be a positive, non-zero number.");
                    return;
                }

                Surface Sold = S;

                if (extend)   //Extend more and trim edges?
                {
                    S = S.Extend(IsoStatus.North, R * 2, true);
                    S = S.Extend(IsoStatus.East, R * 2, true);
                    S = S.Extend(IsoStatus.South, R * 2, true);
                    S = S.Extend(IsoStatus.West, R * 2, true);
                }

                //----------------------------------------------------------------------------------------------------------//
                //Solution

                // starting point
                double u0, v0;

                S.ClosestPoint(P, out u0, out v0);

                //Create plane on surface by point and surface normal, plane x,y axis are directions for the net
                Plane plane = new Plane(S.PointAt(u0, v0), S.NormalAt(u0, v0));

                plane.Rotate(Rhino.RhinoMath.ToRadians(A), S.NormalAt(u0, v0));
                Vector3d[] dir = new Vector3d[] { plane.XAxis *R, plane.YAxis *R, plane.XAxis * -R, plane.YAxis * -R };

                //Surface
                Curve[] MyNakedEdges = Sold.ToBrep().DuplicateNakedEdgeCurves(true, false);
                Mesh[]  meshes       = new Mesh[] { new Mesh(), new Mesh(), new Mesh(), new Mesh() };

                //----------------------------------------------------------------------------------------------------------//
                //Create axis
                // for each direction, walk out (and store list of points)

                double u, v;

                List <Point3d>[] axis = new List <Point3d> [4];
                List <Arc>[]     arcs = new List <Arc> [4];
                polylines = new List <Polyline>();

                for (int i = 0; i < 4; i++)
                {
                    // set u and v to starting point
                    u = u0;
                    v = v0;
                    List <Point3d> pts        = new List <Point3d>();
                    List <Arc>     arcCurrent = new List <Arc>();


                    for (int j = 0; j < max + 1; j++)
                    {
                        Point3d pt = S.PointAt(u, v); // get point and normal for uv
                        pts.Add(pt);

                        Vector3d srfNormal = S.NormalAt(u, v) * R;

                        Arc arc = new Arc(pt + srfNormal, pt + dir[i], pt - srfNormal); // create forward facing arc and find intersection point with surface (as uv)
                        arcCurrent.Add(arc);
                        CurveIntersections isct = Intersection.CurveSurface(arc.ToNurbsCurve(), S, 0.01, 0.01);


                        if (isct.Count > 0)
                        {
                            isct[0].SurfacePointParameter(out u, out v);
                        }
                        else
                        {
                            break;
                        }

                        // adjust direction vector (new position - old position)
                        dir[i] = S.PointAt(u, v) - pt;
                    }

                    axis[i] = pts;
                    arcs[i] = arcCurrent;
                }



                //----------------------------------------------------------------------------------------------------------//
                //Build up the mesh quads in between

                GH_PreviewUtil preview = new GH_PreviewUtil(GetValue("Animate", false));

                Mesh mesh = new Mesh();     // target mesh

                for (int k = 0; k < 4; k++) //Loop through each axis

                {
                    Mesh qmesh = new Mesh();                                                // local mesh for quadrant

                    int k0 = (k + 1) % 4;                                                   //Take neighbour id
                    Point3d[,] quad = new Point3d[axis[k].Count + 10, axis[k0].Count + 10]; // 2d array of points
                    int[,] qindex   = new int[axis[k].Count + 10, axis[k0].Count + 10];     // 2d array of points' indices in local mesh

                    int count = 0;

                    for (int i = 0; i < axis[k0].Count; i++)
                    {
                        quad[0, i] = axis[k0][i];        //store 2nd axis points in point array
                        qmesh.Vertices.Add(axis[k0][i]); //also add 2nd axis points to mesh
                        qindex[0, i] = count++;          //store indicies
                    }


                    for (int i = 1; i < quad.GetLength(0); i++)
                    {
                        if (i < axis[k].Count)              // add axis vertex
                        {
                            quad[i, 0] = axis[k][i];        //store 1st axis points in point array
                            qmesh.Vertices.Add(axis[k][i]); //also add 1st axis points to mesh
                            qindex[i, 0] = count++;         //store indicies
                        }

                        // for each column attempt to locate a new vertex in the grid
                        for (int j = 1; j < quad.GetLength(1); j++)
                        {
                            // if quad[i - 1, j] doesn't exist, try to add it and continue (or else break the current row)
                            if (quad[i - 1, j] == new Point3d())
                            {
                                if (j < 2)
                                {
                                    break;
                                }

                                CurveIntersections isct = this.ArcIntersect(S, quad[i - 1, j - 1], quad[i - 1, j - 2], R);

                                if (isct.Count > 0)
                                {
                                    quad[i - 1, j] = isct[0].PointB;
                                    qmesh.Vertices.Add(quad[i - 1, j]);

                                    qindex[i - 1, j] = count++;
                                }
                                else
                                {
                                    break;
                                }
                            }

                            // if quad[i, j - 1] doesn't exist, try to create quad[i, j] by projection and skip mesh face creation
                            if (quad[i, j - 1] == new Point3d())
                            {
                                if (i < 2)
                                {
                                    break;
                                }

                                CurveIntersections isct = this.ArcIntersect(S, quad[i - 1, j], quad[i - 2, j], R);

                                if (isct.Count > 0)
                                {
                                    quad[i, j] = isct[0].PointB;
                                    qmesh.Vertices.Add(quad[i, j]);
                                    qindex[i, j] = count++;

                                    continue;
                                }
                            }

                            // construct a sphere at each neighbouring vertex ([i,j-1] and [i-1,j]) and intersect

                            Sphere sph1 = new Sphere(quad[i, j - 1], R);
                            Sphere sph2 = new Sphere(quad[i - 1, j], R);
                            Circle cir;

                            if (Intersection.SphereSphere(sph1, sph2, out cir) == SphereSphereIntersection.Circle)
                            {
                                CurveIntersections cin = Intersection.CurveSurface(NurbsCurve.CreateFromCircle(cir), S, 0.01, 0.01);// intersect circle with surface

                                // attempt to find the new vertex (i.e not [i-1,j-1])

                                foreach (IntersectionEvent ie in cin)
                                {
                                    if ((ie.PointA - quad[i - 1, j - 1]).Length > 0.2 * R)  // compare with a tolerance, rather than exact comparison

                                    {
                                        quad[i, j] = ie.PointA;
                                        qmesh.Vertices.Add(quad[i, j]);
                                        qindex[i, j] = count++;

                                        Point3d[] facePt = new Point3d[] { quad[i, j], quad[i - 1, j], quad[i - 1, j - 1], quad[i, j - 1] };

                                        Sold.ClosestPoint(quad[i, j], out double u1, out double v1);
                                        Sold.ClosestPoint(quad[i - 1, j], out double u2, out double v2);
                                        Sold.ClosestPoint(quad[i - 1, j - 1], out double u3, out double v3);
                                        Sold.ClosestPoint(quad[i, j - 1], out double u4, out double v4);

                                        double tolerance = 0.01;
                                        bool[] flag      = new bool[] {
                                            Sold.PointAt(u1, v1).DistanceTo(quad[i, j]) < tolerance,
                                            Sold.PointAt(u2, v2).DistanceTo(quad[i - 1, j]) < tolerance,
                                            Sold.PointAt(u3, v3).DistanceTo(quad[i - 1, j - 1]) < tolerance,
                                            Sold.PointAt(u4, v4).DistanceTo(quad[i, j - 1]) < tolerance
                                        };



                                        if (flag[0] && flag[1] && flag[2] && flag[3])
                                        {
                                            qmesh.Faces.AddFace(qindex[i, j], qindex[i - 1, j], qindex[i - 1, j - 1], qindex[i, j - 1]);// create quad-face
                                        }
                                        else if (flag[0] || flag[1] || flag[2] || flag[3])
                                        {
                                            Polyline temp = new Polyline();

                                            for (int p = 0; p < 4; p++)
                                            {
                                                switch (Convert.ToInt32(flag[p]) * 10 + Convert.ToInt32(flag[(p + 1) % 4]))
                                                {
                                                case (11):
                                                    temp.Add(facePt[p]);
                                                    break;

                                                case (10):
                                                    temp.Add(facePt[p]);
                                                    temp.Add(ClosestPointOnNakedEdge(MyNakedEdges, facePt[p], new Line(facePt[p], facePt[(p + 1) % 4])));
                                                    break;

                                                case (1):
                                                    temp.Add(ClosestPointOnNakedEdge(MyNakedEdges, facePt[p], new Line(facePt[p], facePt[(p + 1) % 4])));
                                                    break;

                                                case (0):
                                                    Sold.ClosestPoint(facePt[p], out double u6, out double v6);
                                                    temp.Add(Sold.PointAt(u6, v6));
                                                    break;
                                                }
                                            }
                                            temp.Close();
                                            polylines.Add(temp);



                                            //qmesh.Faces.AddFace(qindex[i, j], qindex[i - 1, j], qindex[i - 1, j - 1], qindex[i, j - 1]);// create quad-face
                                        }



                                        //qmesh.Faces.AddFace(qindex[i, j], qindex[i - 1, j], qindex[i - 1, j - 1], qindex[i, j - 1]);// create quad-face
                                        break;
                                    }
                                }

                                if (preview.Enabled)
                                {
                                    preview.Clear();
                                    preview.AddMesh(mesh);
                                    preview.AddMesh(qmesh);
                                    preview.Redraw();
                                }
                            }
                        }
                    }

                    ;

                    mesh.Append(qmesh);// add local mesh to target
                }

                //----------------------------------------------------------------------------------------------------------//
                //Output
                mesh.Weld(Math.PI);
                mesh.Compact();
                mesh.Normals.ComputeNormals();

                DA.SetData(0, mesh);
                DA.SetDataTree(1, NGonsCore.GrasshopperUtil.IEOfIEToTree(axis, 0));
                DA.SetDataList(2, polylines);

                preview.Clear();
            }
Exemplo n.º 21
0
        public Curve CutCurveBetweenPerpIndexes(Curve g, List <Curve> perpGs, int index1, int index2)
        {
            Curve tempG = g.DuplicateCurve();

            tempG.Domain = new Interval(0, 1);

            CurveIntersections curveInt  = Intersection.CurveCurve(tempG, perpGs[index1], 0.0001, 0.0001);
            CurveIntersections curveInt2 = Intersection.CurveCurve(tempG, perpGs[index2], 0.0001, 0.0001);

            double t1 = tempG.Domain.T0;
            double t2 = tempG.Domain.T1;

            if (curveInt.Count != 0)
            {
                t1 = curveInt[0].ParameterA;
            }
            if (curveInt2.Count != 0)
            {
                t2 = curveInt2[0].ParameterA;
            }

            double tMid;

            if (t1 > t2)
            {
                double temp = t1;
                t1 = t2;
                t2 = temp;
            }
            tMid = (t2 + t1) / 2;

            Point3d midPoint = tempG.PointAt(tMid);

            if (curveInt.Count != 0 && t1 > tempG.Domain.T0)
            {
                Curve[] splitCurves = tempG.Split(t1);
                foreach (Curve crv in splitCurves)
                {
                    double closestT;
                    crv.ClosestPoint(midPoint, out closestT);

                    double distance = midPoint.DistanceTo(crv.PointAt(closestT));
                    if (distance < 0.001)
                    {
                        tempG = crv;
                    }
                }
            }

            tempG.Domain = new Interval(0, 1);
            t2           = tempG.Domain.T1;
            curveInt2    = Intersection.CurveCurve(tempG, perpGs[index2], 0.0001, 0.0001);
            if (curveInt2.Count != 0)
            {
                t2 = curveInt2[0].ParameterA;
            }

            if (curveInt2.Count != 0 && t2 < tempG.Domain.T1 && t2 > 0)
            {
                Curve[] splitCurves = tempG.Split(t2);
                foreach (Curve crv in splitCurves)
                {
                    double closestT;
                    crv.ClosestPoint(midPoint, out closestT);

                    double distance = midPoint.DistanceTo(crv.PointAt(closestT));
                    if (distance < 0.001)
                    {
                        tempG = crv;
                    }
                }
            }


            return(tempG);
        }
Exemplo n.º 22
0
        internal void indentifyAllFlippedEdges()
        {
            flippedEdgeInfo = new List <FlippedEdge>();
            for (int i = 0; i < proxyToMesh.faces.Count; i++)
            {
                Face face = proxyToMesh.faces[i];

                Curve curve = face.convertFaceToPolyLine().ToNurbsCurve();
                CurveIntersections intersections = Intersection.CurveSelf(curve, 0.1);
                if (intersections.Count > 0)
                {
                    controller.errorContainer.Add("Flipped edge check: " +
                                                  intersections.Count.ToString() + " intersection(s) found");
                    for (int j = 0; j < intersections.Count; j++)
                    {
                        IntersectionEvent intersection = intersections[j];
                        if (intersection.IsPoint)
                        {
                            int refA = (int)Math.Floor(intersection.ParameterA);
                            int refB = (int)Math.Floor(intersection.ParameterB);
                            if (refB == face.faceEdges.Count)
                            {
                                //has rounded up to the end of the curve
                                //is this possible maybe happening in lots of places
                                //not ideal!!!
                                //refB--;
                            }

                            if (face.faceEdges.Count == 4)
                            {//if 4 add both...
                                List <int> refsToAdd = new List <int>();
                                for (int k = 0; k < 4; k++)
                                {
                                    if (k != refA && k != refB)
                                    {
                                        refsToAdd.Add(k);
                                    }
                                }
                                if (refsToAdd.Count != 2)
                                {
                                }
                                addToFlippedEdgeInfo(refsToAdd[0], face, intersection);
                                addToFlippedEdgeInfo(refsToAdd[1], face, intersection);
                            }
                            else
                            {
                                int flippedEdgeIndex;
                                if (refB - refA == 2)
                                {
                                    flippedEdgeIndex = refB - 1;
                                }
                                else if ((refA + face.faceEdges.Count) - refB == 2)
                                {
                                    flippedEdgeIndex = (refB + 1) % face.faceEdges.Count;
                                }
                                else
                                {
                                    flippedEdgeIndex = -1;
                                    //do not have a simple flipped edge, need to do something else
                                }

                                if (flippedEdgeIndex != -1)
                                {
                                    addToFlippedEdgeInfo(flippedEdgeIndex, face, intersection);
                                }
                            }
                        }
                    }
                }
            }
        }
Exemplo n.º 23
0
            protected override void SolveInstance(IGH_DataAccess DA)
            {
                try {
                    //Input
                    Surface S = s;
                    //if (!DA.GetData(0, ref S)) { return; }
                    DA.GetData(0, ref S);
                    Point3d P = Point3d.Unset;

                    if (!DA.GetData(1, ref P))
                    {
                        P = S.PointAt(S.Domain(0).Mid, S.Domain(1).Mid);
                    }

                    double R = Rhino.RhinoMath.UnsetValue;
                    if (!DA.GetData(2, ref R))
                    {
                        return;
                    }

                    double A = Rhino.RhinoMath.UnsetValue;
                    if (!DA.GetData(3, ref A))
                    {
                        return;
                    }

                    int max = 0;
                    if (!DA.GetData(4, ref max))
                    {
                        return;
                    }

                    Boolean extend = false;
                    if (!DA.GetData(5, ref extend))
                    {
                        return;
                    }

                    if (R <= 0)
                    {
                        this.AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Mesh edge length must be a positive, non-zero number.");
                        return;
                    }

                    Mesh cutter = new Mesh();
                    //DA.GetData(8, ref cutter);

                    Surface Sold = S;
                    Sold.SetDomain(0, new Interval(0, 1));
                    Sold.SetDomain(1, new Interval(0, 1));
                    PointCloud cornerPoints = new PointCloud(new Point3d[] { Sold.PointAt(0, 0), Sold.PointAt(0, 1), Sold.PointAt(1, 0), Sold.PointAt(1, 1) });


                    if (extend)   //Extend more and trim edges?
                    {
                        S = S.Extend(IsoStatus.North, R * 2, true);
                        S = S.Extend(IsoStatus.East, R * 2, true);
                        S = S.Extend(IsoStatus.South, R * 2, true);
                        S = S.Extend(IsoStatus.West, R * 2, true);
                    }

                    //int L = 0;
                    //int W = 0;
                    //DA.GetData(6, ref L);
                    //DA.GetData(7, ref W);

                    //----------------------------------------------------------------------------------------------------------//
                    //Solution

                    // starting point
                    double u0, v0;
                    S.ClosestPoint(P, out u0, out v0);

                    //Create plane on surface by point and surface normal, plane x,y axis are directions for the net
                    Plane plane = new Plane(S.PointAt(u0, v0), S.NormalAt(u0, v0));
                    plane.Rotate(Rhino.RhinoMath.ToRadians(A), S.NormalAt(u0, v0));
                    Vector3d[] dir = new Vector3d[] { plane.XAxis *R, plane.YAxis *R, plane.XAxis * -R, plane.YAxis * -R };

                    //Surface
                    Curve[] MyNakedEdges     = Sold.ToBrep().DuplicateNakedEdgeCurves(true, false);
                    Curve   SurfaceNakedEdge = Curve.JoinCurves(MyNakedEdges)[0];
                    Mesh[]  meshes           = new Mesh[] { new Mesh(), new Mesh(), new Mesh(), new Mesh() };

                    //----------------------------------------------------------------------------------------------------------//
                    //Create axis
                    // for each direction, walk out (and store list of points)

                    double           u, v;
                    List <Point3d>[] axis = new List <Point3d> [4];
                    List <Arc>[]     arcs = new List <Arc> [4];
                    polylines = new List <Polyline>();

                    for (int i = 0; i < 4; i++)
                    {
                        // set u and v to starting point
                        u = u0;
                        v = v0;
                        List <Point3d> pts        = new List <Point3d>();
                        List <Arc>     arcCurrent = new List <Arc>();


                        for (int j = 0; j < max + 1; j++)
                        {
                            Point3d pt = S.PointAt(u, v); // get point and normal for uv
                            pts.Add(pt);

                            Vector3d srfNormal = S.NormalAt(u, v) * R;

                            Arc arc = new Arc(pt + srfNormal, pt + dir[i], pt - srfNormal); // create forward facing arc and find intersection point with surface (as uv)
                            arcCurrent.Add(arc);
                            CurveIntersections isct = Intersection.CurveSurface(arc.ToNurbsCurve(), S, 0.01, 0.01);


                            if (isct.Count > 0)
                            {
                                isct[0].SurfacePointParameter(out u, out v);
                            }
                            else
                            {
                                break;
                            }

                            // adjust direction vector (new position - old position)
                            dir[i] = S.PointAt(u, v) - pt;
                        }

                        axis[i] = pts;
                        arcs[i] = arcCurrent;
                    }



                    //----------------------------------------------------------------------------------------------------------//
                    //Build up the mesh quads in between
                    Rhino.RhinoApp.ClearCommandHistoryWindow();

                    GH_PreviewUtil preview = new GH_PreviewUtil(GetValue("Animate", false));

                    Mesh         mesh                = new Mesh();                                                                                                                                                   // target mesh
                    Mesh[]       fourMeshes          = new Mesh[4];
                    List <int>[] faceID              = new List <int>[] { new List <int>(), new List <int>(), new List <int>(), new List <int>() };                                                                  //columns lengths
                    List <List <Polyline> >[] strips = new List <List <Polyline> >[] { new List <List <Polyline> >(), new List <List <Polyline> >(), new List <List <Polyline> >(), new List <List <Polyline> >() }; //columns lengths
                    //List<Polyline> cuts = new List<Polyline>();

                    for (int k = 0; k < 4; k++)   //Loop through each axis

                    {
                        Mesh qmesh = new Mesh();                                                         // local mesh for quadrant

                        Point3d[,] quad = new Point3d[axis[k].Count + 10, axis[(k + 1) % 4].Count + 10]; // 2d array of points
                        int[,] qindex   = new int[axis[k].Count + 10, axis[(k + 1) % 4].Count + 10];     // 2d array of points' indices in local mesh

                        int count = 0;

                        //Add 2nd axis particles
                        for (int i = 0; i < axis[(k + 1) % 4].Count; i++)
                        {
                            quad[0, i] = axis[(k + 1) % 4][i];        //store 2nd axis points in point array
                            qmesh.Vertices.Add(axis[(k + 1) % 4][i]); //also add 2nd axis points to mesh
                            qindex[0, i] = count++;                   //store indicies
                        }


                        for (int i = 1; i < quad.GetLength(0); i++)
                        {
                            if (i < axis[k].Count)              // add axis vertex
                            {
                                quad[i, 0] = axis[k][i];        //store 1st axis points in point array
                                qmesh.Vertices.Add(axis[k][i]); //also add 1st axis points to mesh
                                qindex[i, 0] = count++;         //store indicies
                            }


                            int counter = 0;

                            List <Polyline> currentStrip = new List <Polyline>();
                            // for each column attempt to locate a new vertex in the grid
                            for (int j = 1; j < quad.GetLength(1); j++)
                            {
                                // if quad[i - 1, j] doesn't exist, try to add it and continue (or else break the current row)
                                if (quad[i - 1, j] == new Point3d())
                                {
                                    if (j < 2)
                                    {
                                        break;
                                    }

                                    CurveIntersections isct = this.ArcIntersect(S, quad[i - 1, j - 1], quad[i - 1, j - 2], R);

                                    if (isct.Count > 0)
                                    {
                                        quad[i - 1, j] = isct[0].PointB;
                                        qmesh.Vertices.Add(quad[i - 1, j]);
                                        qindex[i - 1, j] = count++;
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                // if quad[i, j - 1] doesn't exist, try to create quad[i, j] by projection and skip mesh face creation
                                if (quad[i, j - 1] == new Point3d())
                                {
                                    if (i < 2)
                                    {
                                        break;
                                    }

                                    CurveIntersections isct = this.ArcIntersect(S, quad[i - 1, j], quad[i - 2, j], R);

                                    if (isct.Count > 0)
                                    {
                                        quad[i, j] = isct[0].PointB;
                                        qmesh.Vertices.Add(quad[i, j]);
                                        qindex[i, j] = count++;

                                        continue;
                                    }
                                }

                                // construct a sphere at each neighbouring vertex ([i,j-1] and [i-1,j]) and intersect

                                Sphere sph1 = new Sphere(quad[i, j - 1], R);
                                Sphere sph2 = new Sphere(quad[i - 1, j], R);
                                Circle cir;

                                if (Intersection.SphereSphere(sph1, sph2, out cir) == SphereSphereIntersection.Circle)
                                {
                                    CurveIntersections cin = Intersection.CurveSurface(NurbsCurve.CreateFromCircle(cir), S, 0.01, 0.01);// intersect circle with surface

                                    // attempt to find the new vertex (i.e not [i-1,j-1])

                                    foreach (IntersectionEvent ie in cin)
                                    {
                                        if ((ie.PointA - quad[i - 1, j - 1]).Length > 0.2 * R)  // compare with a tolerance, rather than exact comparison

                                        {
                                            quad[i, j] = ie.PointA;
                                            qmesh.Vertices.Add(quad[i, j]);
                                            qindex[i, j] = count++;

                                            Point3d[] facePt = new Point3d[] { quad[i, j], quad[i - 1, j], quad[i - 1, j - 1], quad[i, j - 1] };

                                            Sold.ClosestPoint(quad[i, j], out double u1, out double v1);
                                            Sold.ClosestPoint(quad[i - 1, j], out double u2, out double v2);
                                            Sold.ClosestPoint(quad[i - 1, j - 1], out double u3, out double v3);
                                            Sold.ClosestPoint(quad[i, j - 1], out double u4, out double v4);

                                            double tolerance = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance * 10;
                                            bool[] flag      = new bool[] {
                                                Sold.PointAt(u1, v1).DistanceTo(quad[i, j]) < tolerance,
                                                Sold.PointAt(u2, v2).DistanceTo(quad[i - 1, j]) < tolerance,
                                                Sold.PointAt(u3, v3).DistanceTo(quad[i - 1, j - 1]) < tolerance,
                                                Sold.PointAt(u4, v4).DistanceTo(quad[i, j - 1]) < tolerance
                                            };



                                            if (flag[0] && flag[1] && flag[2] && flag[3])
                                            {
                                                qmesh.Faces.AddFace(qindex[i, j], qindex[i - 1, j], qindex[i - 1, j - 1], qindex[i, j - 1]);// create quad-face
                                                currentStrip.Add(new Polyline()
                                                {
                                                    quad[i, j], quad[i - 1, j], quad[i - 1, j - 1], quad[i, j - 1], quad[i, j]
                                                });
                                                counter++;
                                            }
                                            else if (flag[0] || flag[1] || flag[2] || flag[3])
                                            {
                                                Polyline temp = new Polyline()
                                                {
                                                    quad[i, j], quad[i - 1, j], quad[i - 1, j - 1], quad[i, j - 1]
                                                };
                                                Polyline trimmedTemp = new Polyline();
                                                //temp = new Polyline() { quad[i, j], quad[i - 1, j], quad[i - 1, j - 1], quad[i, j - 1], quad[i, j] };

                                                double        t = R * 0.1;
                                                HashSet <int> intersectedSurfaceEdgeId = new HashSet <int>();


                                                for (int l = 0; l < 4; l++)
                                                {
                                                    //If point is ons surface
                                                    Sold.ClosestPoint(temp[l], out double cpu, out double cpv);
                                                    if (Sold.PointAt(cpu, cpv).DistanceTo(temp[l]) < Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance)
                                                    {
                                                        trimmedTemp.Add(temp[l]);
                                                    }


                                                    //Intersect line segment with closed brep
                                                    Line faceSegment = new Line(temp[l], temp[MathUtil.Wrap(l + 1, 4)]);

                                                    Point3d[] meshLinePts = Intersection.MeshLine(cutter, faceSegment, out int[] faceIds);
                                                    if (meshLinePts.Length > 0)
                                                    {
                                                        trimmedTemp.Add(meshLinePts[0]);
                                                    }
                                                }


                                                trimmedTemp.Close();
                                                //cuts.Add(trimmedTemp);
                                            }

                                            break;
                                        }
                                    }

                                    if (preview.Enabled)
                                    {
                                        preview.Clear();
                                        preview.AddMesh(mesh);
                                        preview.AddMesh(qmesh);
                                        preview.Redraw();
                                    }
                                } //if sphere intersection
                            }     //for j

                            if (currentStrip.Count > 0)
                            {
                                strips[k].Add(currentStrip);
                            }
                        }//for i



                        mesh.Append(qmesh);// add local mesh to target
                        fourMeshes[k] = qmesh;
                    }//for k



                    //----------------------------------------------------------------------------------------------------------//
                    //Output



                    mesh.Weld(Math.PI);
                    mesh.Compact();
                    mesh.Normals.ComputeNormals();

                    DA.SetData(0, mesh);
                    DA.SetDataTree(1, NGonsCore.GrasshopperUtil.IE2(axis, 0));

                    this.PreparePreview(mesh, DA.Iteration, null, true, null, mesh.GetEdges());
                    //DA.SetDataList(2, cuts);
                    //DA.SetDataTree(3, NGonsCore.GrasshopperUtil.IE4(patches.ToList(), 0));
                    //DA.SetDataList(4, fourMeshes);
                    //DA.SetDataTree(5, GrasshopperUtil.IE3(strips, 0));

                    preview.Clear();
                }catch (Exception e) {
                    GrasshopperUtil.Debug(e);
                }
            }
        private SolveResults ComputeDivs(Curve crv, ConcurrentDictionary <int, List <double> > distanceList)
        {
            distanceList.Values[1]

            if (distanceList.Count == 0)
            {
                return(null);
            }

            if (crv.PointAtStart.DistanceTo(crv.PointAtEnd) < distanceList.Max())
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, " Distance between start and end points of curve(s) may be too small." +
                                  " If it yields undesirable results, consider increasing distance between them to max value in the supplied distances.");
            }

            // if parameter is within region A, use items from dictionary list A )
            //
            SolveResults result = new SolveResults();

            crv.Domain = new Interval(0, crv.GetLength());

            double t1 = crv.Domain.T1;
            double tol = Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance;
            int    i, j;

            i = j = -1;

            List <Curve>   crvList = new List <Curve>();
            List <Point3d> ptList  = new List <Point3d>()
            {
                crv.PointAtStart
            };
            List <double> paramList = new List <double>()
            {
                0.0
            };

            //List<double> div2 = distanceList2;


            // TODO: Fix intersection issues with curves that have their start and End points too close to each other; eg:closed curves.

            while (true)
            {
                //reset i if distance list end reached and curve still exists.
                if (i >= distanceList.Count - 1)
                {
                    i = -1;
                }

                // increment
                i++;
                j++;

                if (distanceList[i] < tol)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, " Distances less than or equal to rhino model tolerance will be ignored");
                    distanceList.RemoveAt(i);
                }

                // sphere-curve intersection
                // using  overload with curve domain to limit intersection area- allows to break while-loop when curve reaches the end.
                CurveIntersections events = Intersection.CurveSurface(crv, new Interval(paramList[j], t1), new Sphere(crv.PointAt(paramList[j]), distanceList[i]).ToNurbsSurface(), tol, tol);

                if (events != null && events.Count > 0)
                {
                    paramList.Add(events.Last().ParameterA);
                    ptList.Add(events.Last().PointA);
                }
                else
                {
                    break;
                }
            }

            crvList.Add(crv);
            ptList.Add(crv.PointAtEnd);
            paramList.Add(crv.Domain.Max);

            result.Curves     = crvList;
            result.Points     = ptList;
            result.Parameters = paramList;
            //result.div2 = div2;

            return(result);
        }
Exemplo n.º 25
0
        //Create inner Parkinglots
        private void CreateInnerParkinglots(Curve boundaryCurve, LocalRules localRules, Plane plane)
        {
            //Create offset curve with outer booth and driveway distance
            BoundingBox bx = boundaryCurve.GetBoundingBox(Plane.WorldXY);

            Point3d[] bxPT          = bx.GetCorners();
            Vector3d  outsideVector = bxPT[0] - bxPT[2];

            outsideVector.Unitize();
            Point3d outsidePT = bxPT[0] + outsideVector;

            Curve[] innerBounderyCrv = boundaryCurve.Offset(outsidePT, Vector3d.ZAxis, -(localRules.BoothDepth + localRules.ManeuveringArea), 0.5, CurveOffsetCornerStyle.Sharp);

            //Sometimes offset fails. This checks for that and uses alternative method, less precise method
            if (innerBounderyCrv[0].GetLength() < ((localRules.BoothDepth + localRules.ManeuveringArea) * 2) + Math.Sqrt((Math.Pow(localRules.BoothDepth + localRules.ManeuveringArea, 2) * 2)) + 1)
            {
                innerBounderyCrv = boundaryCurve.Offset(Plane.WorldXY, localRules.BoothDepth + localRules.ManeuveringArea, 0.01, CurveOffsetCornerStyle.Sharp);
                //Check direction
                if (innerBounderyCrv[0].Contains(boundaryCurve.PointAtStart, Plane.WorldXY, 0.01) == PointContainment.Inside)
                {
                    innerBounderyCrv = boundaryCurve.Offset(Plane.WorldXY, -(localRules.BoothDepth + localRules.ManeuveringArea), 0.01, CurveOffsetCornerStyle.Sharp);
                }
            }
            debug.AddRange(innerBounderyCrv);
            //Create BB and centerlines
            innerBounderyCrv[0].GetBoundingBox(plane, out Box boundarybox);
            Point3d[] boxCorners = boundarybox.GetCorners();
            Line      startLine  = new Line(boxCorners[0], boxCorners[1]);
            Line      endLine    = new Line(boxCorners[3], boxCorners[2]);

            // Direction of inner booths
            Vector3d boothDir = startLine.UnitTangent;

            boothDir.Unitize();
            boothDir = Vector3d.Multiply(localRules.BoothDepth, boothDir);

            //Copy center lines according to distancerules
            List <Curve> copyLines = new List <Curve>();

            for (double i = localRules.BoothDepth; i < startLine.Length;)
            {
                Point3d startPT = startLine.PointAtLength(i);
                Point3d endPT   = endLine.PointAtLength(i);
                copyLines.Add(new Line(startPT, endPT).ToNurbsCurve());
                i = i + (localRules.BoothDepth * 2) + localRules.ManeuveringArea;
            }


            //Find inner curves
            foreach (Curve crvline in copyLines)
            {
                var curveEvent = Intersection.CurveCurve(innerBounderyCrv[0], crvline, 0, 0);
                if (curveEvent != null)
                {
                    List <double> curveT = new List <double>();
                    for (int i = 0; i < curveEvent.Count; i++)
                    {
                        var crvLine = curveEvent[i];
                        curveT.Add(crvLine.ParameterB);
                    }

                    Curve[] curveSplit = crvline.Split(curveT);

                    foreach (Curve curve in curveSplit)
                    {
                        double midT = (curve.Domain.T0 + curve.Domain.T1) / 2;

                        if (innerBounderyCrv[0].Contains(curve.PointAt(midT), Plane.WorldXY, 0).Equals(PointContainment.Inside))
                        {
                            CenterLines.Add(curve);
                        }
                    }
                }
            }

            //Parking Booths
            foreach (Curve curve in CenterLines)
            {
                curve.DivideByLength(localRules.BoothWidth, true, false, out Point3d[] points);
                if (points == null)
                {
                    continue;
                }
                foreach (Point3d point in points)
                {
                    //One way
                    Plane        boothPlane   = new Plane(point, curve.TangentAt(0.1), boothDir);
                    Parkingspace parkingspace = new Parkingspace(boothPlane, localRules, true);
                    parkingLinesLeft.Add(parkingspace);
                    //Opposite way
                    boothDir.Reverse();
                    boothPlane   = new Plane(point, curve.TangentAt(0.1), boothDir);
                    parkingspace = new Parkingspace(boothPlane, localRules, true);
                    parkingLinesLeft.Add(parkingspace);
                    //Return Vector
                    boothDir.Reverse();
                }

                PointCloud startPTsLeft  = new PointCloud();
                PointCloud startPTsRight = new PointCloud();
                PointCloud allStartPT    = new PointCloud();

                //Check for collision with driving path

                List <Parkingspace> finalParkingLinesLeft  = new List <Parkingspace>();
                List <Parkingspace> finalParkingLinesRight = new List <Parkingspace>();
                for (int i = 0; i < parkingLinesLeft.Count; i++)
                {
                    CurveIntersections crvEvent = Intersection.CurveCurve(innerBounderyCrv[0], parkingLinesLeft[i].Curves, 0.0001, 0.0000);
                    if (crvEvent.Count > 0)
                    {
                        parkingEnds.Add(parkingLinesLeft[i].Curves);
                    }
                    else
                    {
                        finalParkingLinesLeft.Add(parkingLinesLeft[i]);
                        startPTsLeft.Add(parkingLinesLeft[i].Curves.PointAtStart);
                        allStartPT.Add(parkingLinesLeft[i].Curves.PointAtStart);
                    }
                }

                for (int i = 0; i < parkingLinesRight.Count; i++)
                {
                    CurveIntersections crvEvent = Intersection.CurveCurve(innerBounderyCrv[0], parkingLinesRight[i].Curves, 0.0001, 0.0000);
                    if (crvEvent.Count > 0)
                    {
                        parkingEnds.Add(parkingLinesRight[i].Curves);
                    }
                    else
                    {
                        finalParkingLinesRight.Add(parkingLinesRight[i]);
                        startPTsRight.Add(parkingLinesRight[i].Curves.PointAtStart);
                        allStartPT.Add(parkingLinesRight[i].Curves.PointAtStart);
                    }
                }



                //try
                //{
                //    //Fix one end
                //    Point3d crvEnd = curve.PointAtEnd;
                //    Curve endCurve = createEnds(innerBounderyCrv, startPTsLeft, startPTsRight, finalParkingLinesLeft, finalParkingLinesRight, crvEnd);
                //    notParkingSpaces.Add(endCurve);
                //    Curve splitCurveOne = splitend(curve, allStartPT, crvEnd);

                //    //Fix the other end
                //    Point3d crvStart = curve.PointAtStart;
                //    endCurve = createEnds(innerBounderyCrv, startPTsLeft, startPTsRight, finalParkingLinesLeft, finalParkingLinesRight, crvStart);
                //    notParkingSpaces.Add(endCurve);
                //    notParkingSpaces.Add(splitend(splitCurveOne, allStartPT, crvStart));

                //}
                //catch
                //{

                //}


                Spaces.AddRange(finalParkingLinesLeft);
                Spaces.AddRange(finalParkingLinesRight);

                parkingLinesLeft.Clear();
                parkingLinesRight.Clear();
            }
            parkingspaceNO = Spaces.Count;
        }
Exemplo n.º 26
0
        public Curve SplitGeodesicWithCurves(Curve geod, Curve perp1, Curve perp2)
        {
            Curve tempG = geod.DuplicateCurve(); // Copy curve to temp

            tempG.Domain = new Interval(0, 1);   // Normalize curve domain

            // Get intersections
            CurveIntersections curveInt  = Intersection.CurveCurve(tempG, perp1, 0.0001, 0.0001);
            CurveIntersections curveInt2 = Intersection.CurveCurve(tempG, perp2, 0.0001, 0.0001);

            double t1 = tempG.Domain.T0;
            double t2 = tempG.Domain.T1;

            if (curveInt.Count != 0)
            {
                t1 = curveInt[0].ParameterA;
            }
            if (curveInt2.Count != 0)
            {
                t2 = curveInt2[0].ParameterA;
            }

            double tMid;

            if (t1 > t2)
            {
                double temp = t1;
                t1 = t2;
                t2 = temp;
            }
            tMid = (t2 + t1) / 2;

            Point3d midPoint = tempG.PointAt(tMid);

            if (curveInt.Count != 0 && t1 > tempG.Domain.T0)
            {
                Curve[] splitCurves = tempG.Split(t1);
                if (splitCurves != null)
                {
                    foreach (Curve crv in splitCurves)
                    {
                        double closestT;
                        crv.ClosestPoint(midPoint, out closestT);

                        double distance = midPoint.DistanceTo(crv.PointAt(closestT));
                        if (distance < 0.001)
                        {
                            tempG = crv;
                        }
                    }
                }
            }

            tempG.Domain = new Interval(0, 1);
            t2           = tempG.Domain.T1;
            curveInt2    = Intersection.CurveCurve(tempG, perp2, 0.0001, 0.0001);
            if (curveInt2.Count != 0)
            {
                t2 = curveInt2[0].ParameterA;
            }

            if (curveInt2.Count != 0 && t2 < tempG.Domain.T1 && t2 > 0)
            {
                Curve[] splitCurves = tempG.Split(t2);
                if (splitCurves != null)
                {
                    foreach (Curve crv in splitCurves)
                    {
                        double closestT;
                        crv.ClosestPoint(midPoint, out closestT);

                        double distance = midPoint.DistanceTo(crv.PointAt(closestT));
                        if (distance < 0.001)
                        {
                            tempG = crv;
                        }
                    }
                }
            }


            return(tempG);
        }
Exemplo n.º 27
0
        private static void closeIntersect(Curve innerBounderyCrv, PointCloud startPTsLeft, List <Parkingspace> finalParkingLinesLeft, Point3d crvEnd, out Curve lineOne, out CurveIntersections intersectionsOne)
        {
            int indexOne = startPTsLeft.ClosestPoint(crvEnd);

            lineOne = finalParkingLinesLeft[indexOne].Curves;

            Vector3d vectorone = lineOne.TangentAtEnd;

            vectorone.Rotate(RhinoMath.ToRadians(90), new Vector3d(0, 0, 1));
            Point3d movedPTone = lineOne.PointAtStart + vectorone;

            vectorone.Rotate(RhinoMath.ToRadians(180), new Vector3d(0, 0, 1));
            Point3d    movedPTTwo  = lineOne.PointAtStart + vectorone;
            PointCloud directionPT = new PointCloud();

            directionPT.Add(movedPTone);
            directionPT.Add(movedPTTwo);

            int indexdir = directionPT.ClosestPoint(crvEnd);

            if (indexdir == 0)
            {
                vectorone.Rotate(RhinoMath.ToRadians(180), new Vector3d(0, 0, 1));
            }
            vectorone        = Vector3d.Multiply(vectorone, 10);
            intersectionsOne = Intersection.CurveCurve(innerBounderyCrv, new Line(lineOne.PointAtEnd, vectorone).ToNurbsCurve(), 0.01, 0.01);
        }