示例#1
0
    internal void MoveAllPointsDepthDependant(CuttingInfo info, DMesh3 newMesh, Dictionary <int, BacksideAlgorithm.PeprStatusVert> stati)
    {
        var tree = new DMeshAABBTree3(info.oldMesh, true);

        tree.TriangleFilterF = i => tree.Mesh.GetTriangleGroup(i) != info.data.ColorNum;
        foreach (var status in stati)
        {
            var   shellPoint = newMesh.GetVertex(status.Value.idNewMeshOuter.Value);
            var   normal     = info.oldMesh.CalcVertexNormal(status.Value.idOldMeshOuter);
            var   position   = shellPoint + info.data.minDepth * normal;
            Ray3d ray        = new Ray3d(shellPoint - normal * info.data.minDepth, -normal); //tiny shift to make sure it's not hitting itself
            int   hit_tid    = tree.FindNearestHitTriangle(ray);
            Debug.Log("Hit " + hit_tid);
            if (hit_tid != DMesh3.InvalidID)
            {
                IntrRay3Triangle3 intr     = MeshQueries.TriangleIntersection(info.oldMesh, hit_tid, ray);
                double            hit_dist = shellPoint.Distance(ray.PointAt(intr.RayParameter));
                position = shellPoint - normal * hit_dist * (info.data.depth / 100);
                Debug.Log($"Hit Dist: {hit_dist}");
            }
            else
            {
                StaticFunctions.ErrorMessage("Depth Dependant Calculation has encountered an error");
            }
            info.mesh.SetVertex(status.Value.idOldMeshInner.Value, position);
            newMesh.SetVertex(status.Value.idNewMeshInner.Value, position);
        }
    }
示例#2
0
        public static Matrix2d GetMatrixFromRayShoot(Grid grid, Mesh union, bool top = false)
        {
            Matrix2d grid2d = new Matrix2d(grid.NumX, grid.NumY);

            double   zDim = -MAX_LIMIT;
            Vector3d axis = Vector3d.ZAxis;

            if (top)
            {
                zDim = MAX_LIMIT;
                axis = -Vector3d.ZAxis;
            }

            for (int i = 0; i < grid.NumX; i++)
            {
                for (int j = 0; j < grid.NumY; j++)
                {
                    Point3d point = new Point3d((i * grid.DimX) + grid.MinX, (j * grid.DimY) + grid.MinY, zDim);
                    Ray3d   ray   = new Ray3d(point, axis);

                    var intersection = Rhino.Geometry.Intersect.Intersection.MeshRay(union, ray);

                    if (intersection != -1.0)
                    {
                        int value = (int)Math.Round((float)ray.PointAt(intersection).Z, MidpointRounding.AwayFromZero);
                        if (value < 0)
                        {
                            value = 0;
                        }
                        grid2d[i, j] = value;
                    }
                }
            }
            return(grid2d);
        }
示例#3
0
        /// <summary>
        /// エージェントの視野を障害物か視野半径でカットするメソッド
        /// </summary>
        /// <returns></returns>
        ///
        /// 20190622 Matsu 作成
        /// 20190629 Matsu 交点がないときの処理を追加
        public void CutViewRay()
        {
            var            intersectVecLs = new List <Vector3d>();
            var            centerPt       = agent.AgentBasePlane.Origin;
            List <Point3d> intersectPt    = new List <Point3d>();

            //エージェントのビューから取得
            var vecLs = ShootRayView();

            for (var i = 0; i < vecLs.Count; i++)
            {
                var ray = new Ray3d(centerPt, vecLs[i]);

                try
                {
                    intersectPt = Rhino.Geometry.Intersect.Intersection.RayShoot(ray, agent.Obstacles, 1).ToList();
                }
                catch (ArgumentNullException)
                {
                    Point3d pt = ray.PointAt(agent.ViewRaidius);
                    intersectPt.Add(pt);
                }

                IsInnerRadius(centerPt, intersectPt[0], out Vector3d vec);
                intersectVecLs.Add(vec);
            }

            //エージェントクラス内に格納
            agent.AgentViewRay = intersectVecLs;
        }
示例#4
0
        ///Projection engines
        public static GH_Point ProjectPointToTopo(Mesh topoMesh, Point3d pt)
        {
            GH_Point ghPoint = new GH_Point();
            Ray3d    ray     = new Ray3d(pt, moveDir);
            double   t       = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, ray);

            if (t >= 0.0)
            {
                GH_Convert.ToGHPoint(ray.PointAt(t), GH_Conversion.Primary, ref ghPoint);
            }
            else
            {
                Ray3d  rayOpp = new Ray3d(pt, -moveDir);
                double tOpp   = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, rayOpp);
                if (tOpp >= 0.0)
                {
                    GH_Convert.ToGHPoint(rayOpp.PointAt(tOpp), GH_Conversion.Primary, ref ghPoint);
                }
                else
                {
                    return(null);
                }
            }
            return(ghPoint);
        }
示例#5
0
        public static List <Point3d> GetMatrixFromRayShoot(Grid grid, Mesh union, ref Matrix2d matrix)
        {
            List <Point3d> points = new List <Point3d>();

            int      zDim = Building.MAX_LIMIT;
            Vector3d axis = -Vector3d.ZAxis;

            for (int i = 0; i < grid.NumX; i++)
            {
                for (int j = 0; j < grid.NumY; j++)
                {
                    Point3d point = new Point3d((i * grid.DimX) + grid.MinX, (j * grid.DimY) + grid.MinY, zDim);
                    Ray3d   ray   = new Ray3d(point, axis);

                    var intersection = Rhino.Geometry.Intersect.Intersection.MeshRay(union, ray);

                    if (intersection != -1.0)
                    {
                        double value = ray.PointAt(intersection).Z;

                        if (value < 0)
                        {
                            value = 0;
                        }
                        Grid.FilterListBasedOnNumber(grid.Height.ToList(), value).ForEach(v =>
                        {
                            points.Add(new Point3d(point.X, point.Y, v));
                        });
                        matrix[i, j] = (int)Math.Round((float)value, MidpointRounding.AwayFromZero);
                    }
                }
            }

            return(points);
        }
示例#6
0
        public static GH_Mesh ProjectMeshToTopoFast(Mesh topoMesh, Mesh featureMesh)
        {
            GH_Mesh ghMesh = new GH_Mesh();
            Mesh    mesh   = featureMesh.DuplicateMesh();

            ///Move patch verts to topo
            for (int i = 0; i < mesh.Vertices.Count; i++)
            {
                Ray3d  ray = new Ray3d((Point3d)mesh.Vertices[i], moveDir);
                double t   = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, ray);

                if (t >= 0.0)
                {
                    mesh.Vertices.SetVertex(i, (Point3f)ray.PointAt(t));
                }
                else
                {
                    Ray3d  rayOpp = new Ray3d((Point3d)mesh.Vertices[i], -moveDir);
                    double tOpp   = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, rayOpp);
                    if (tOpp >= 0.0)
                    {
                        mesh.Vertices.SetVertex(i, (Point3f)rayOpp.PointAt(tOpp));
                    }
                    else
                    {
                        //mesh.Vertices.SetVertex(i, new Point3f(0, 0, 0));
                        //return null;
                    }
                }
            }
            GH_Convert.ToGHMesh(mesh, GH_Conversion.Primary, ref ghMesh);
            return(ghMesh);
        }
        public TerrainMap(WorldMap _world, Mesh m)
        {
            World = _world;

            int    sz_X = (int)(World.boundary.Width / World.resolution);
            int    sz_Y = (int)(World.boundary.Height / World.resolution);
            double resX = World.boundary.Width / sz_X;
            double resY = World.boundary.Height / sz_Y;


            Points = new Point3d[sz_X, sz_Y];
            Map    = new Terrain[sz_X, sz_Y];
            xLen   = sz_X;
            yLen   = sz_Y;
            //divide the rectangle into little rectangles, and assign location to be the midpoint of those rectangles.
            //set the locX, locY, value appropriately for MapArray
            for (int y = 0; y < sz_Y; y++)
            {
                for (int x = 0; x < sz_X; x++)
                {
                    Points[x, y] = World.boundary.Plane.Origin +
                                   (0.5 + x) * resX * World.boundary.Plane.XAxis +
                                   (0.5 + y) * resY * World.boundary.Plane.YAxis;
                    Map[x, y]            = new Terrain(this);
                    Map[x, y].locX       = x;
                    Map[x, y].locY       = y;
                    Map[x, y].val        = 0;
                    Map[x, y].neighbours = new List <Terrain>();
                }
            }

            //store neighbours
            for (int x = 0; x < sz_X; x++)
            {
                for (int y = 0; y < sz_Y; y++)
                {
                    Map[x, y].GenerateNeighbours();
                }
            }

            //from here do stuff that is specific to the implementation. In this case
            //terrain will change the values in the mapArray accordingly to reflect the landscape
            //of the mesh passed to it in the constructor.
            double safeHeight = m.GetBoundingBox(true).Max.Z + 10.0;

            for (int x = 0; x < xLen; x++)
            {
                for (int y = 0; y < yLen; y++)
                {
                    Point3d point = Points[x, y];
                    point.Z = safeHeight;
                    Ray3d   ray       = new Ray3d(point, -Vector3d.ZAxis);
                    double  t         = Rhino.Geometry.Intersect.Intersection.MeshRay(m, ray);
                    Point3d projected = ray.PointAt(t);
                    Map[x, y].val = projected.Z;
                }
            }
        }
示例#8
0
        private void FindMeshNodes()
        {
            NurbsCurve boundary = CaveTools.GetPlanarPanelBoundary(this);

            for (int c = 0; c < nodeGrid.Count; c++)
            {
                List <Curve> row = new List <Curve>();
                for (int d = 0; d < nodeGrid[c].Count; d++)
                {
                    Ray3d  ray = new Ray3d(nodeGrid[c][d], localPlane.ZAxis);
                    double t   = Rhino.Geometry.Intersect.Intersection.MeshRay(CavePanels, ray);
                    if (t >= 0)
                    {
                        meshnodes[c][d].point    = ray.PointAt(t);
                        meshnodes[c][d].pointset = true;
                        //is it too close to edge
                        double p = 0;
                        boundary.ClosestPoint(nodeGrid[c][d], out p);
                        Point3d boundaryPt = boundary.PointAt(p);
                        double  dist       = nodeGrid[c][d].DistanceTo(boundaryPt);
                        if (dist < parameters.cellGap / 2 - 5)
                        {
                            ghostNodesFound         = true;
                            meshnodes[c][d].isGhost = true;
                        }
                    }
                    else
                    {
                        Polyline[] edges   = CavePanels.GetNakedEdges();
                        double     minDist = double.MaxValue;
                        Point3d    closest = new Point3d();
                        Line       drop    = new Line(nodeGrid[c][d], localPlane.Normal, 1000);
                        Point3d    meshPt  = new Point3d();
                        foreach (Polyline pl in edges)
                        {
                            foreach (Point3d pt in pl)
                            {
                                Point3d temp = drop.ClosestPoint(pt, false);
                                if (temp.DistanceTo(pt) < minDist)
                                {
                                    minDist = temp.DistanceTo(pt);
                                    closest = temp;
                                    meshPt  = pt;
                                }
                            }
                        }
                        meshnodes[c][d].point    = closest;
                        meshnodes[c][d].pointset = true;
                        meshnodes[c][d].isGhost  = true;
                        ghostNodesFound          = true;
                        //RhinoDoc.ActiveDoc.Objects.AddPoint(meshnodes[c][d].point);
                    }
                }
            }
        }
示例#9
0
        public static Mesh MoveBuildingsUp(Mesh mesh, Mesh terrain)
        {
            Transform xmoveTerrain;
            Transform xmoveCentroid;

            const int    UnitBox        = 1;
            const double noIntersection = 0.0;

            Mesh newMesh = mesh.DuplicateMesh();

            try
            {
                // first traslation
                Point3d center = AreaMassProperties.Compute(newMesh).Centroid;

                Ray3d r = new Ray3d(center, Vector3d.ZAxis);

                var intersec = Rhino.Geometry.Intersect.Intersection.MeshRay(terrain, r);

                Point3d pt = r.PointAt(intersec);

                if (intersec != noIntersection)
                {
                    Vector3d vecCentroid = new Vector3d(0, 0, pt.Z - center.Z);
                    xmoveCentroid = Transform.Translation(vecCentroid);
                    newMesh.Transform(xmoveCentroid);
                }


                // move to terrain
                BoundingBox BBox    = newMesh.GetBoundingBox(true);
                Mesh        meshBox = Mesh.CreateFromBox(BBox, UnitBox, UnitBox, UnitBox);

                Line[] lines = Rhino.Geometry.Intersect.Intersection.MeshMeshFast(terrain, newMesh);

                Point3d minBBox = BBox.Min;

                // dimension
                double start = minBBox.Z;
                double end   = lines.Min(l => l.From.Z);


                Vector3d vecTerrain = new Vector3d(0, 0, end - start);
                xmoveTerrain = Transform.Translation(vecTerrain);
            }
            catch
            {
                xmoveTerrain = Transform.Translation(Vector3d.Zero);
            }

            newMesh.Transform(xmoveTerrain);

            return(newMesh);
        }
示例#10
0
        public static double?DistanceToTree(this DMeshAABBTree3 tree, Ray3d ray)
        {
            var hit_tid = tree.FindNearestHitTriangle(ray);

            if (hit_tid == DMesh3.InvalidID)
            {
                return(null);
            }
            var intr = MeshQueries.TriangleIntersection(tree.Mesh, hit_tid, ray);

            return(ray.Origin.Distance(ray.PointAt(intr.RayParameter)));
        }
示例#11
0
 private void FindMeshCurve()
 {
     for (int i = 0; i <= 50; i++)
     {
         Point3d p   = gridLine.PointAt(1.0 / 50 * i);
         Ray3d   ray = new Ray3d(p, toPanel);
         double  t   = Rhino.Geometry.Intersect.Intersection.MeshRay(panel, ray);
         if (t >= 0)
         {
             panelCurvepts.Add(ray.PointAt(t));
         }
     }
     panelCurve = NurbsCurve.Create(false, 1, panelCurvepts);
 }
示例#12
0
        private void FindIntersectsToKeep()
        {
            //compare to point grid to remove if too close

            for (int i = 0; i < interpts.Count; i++)
            {
                Point3d closest = CaveTools.ClosestPoint(interpts[i], planarPointGrid.SelectMany(x => x).ToList());
                if (closest.DistanceTo(interpts[i]) > parameters.cellGap / 4)
                {
                    Ray3d  ray = new Ray3d(interpts[i], panelFrame.localPlane.ZAxis);
                    double t   = Rhino.Geometry.Intersect.Intersection.MeshRay(panelFrame.CavePanels, ray);
                    if (t >= 0)
                    {
                        meshpts.Add(ray.PointAt(t));
                    }
                }
            }
        }
示例#13
0
        public static GH_Surface ProjectSurfaceToTopoFast(Mesh topoMesh, Surface featureSurface)
        {
            GH_Surface   ghSurface = new GH_Surface();
            NurbsSurface surface   = featureSurface.ToNurbsSurface();

            ///Move patch verts to topo
            for (int u = 0; u < surface.Points.CountU; u++)
            {
                for (int v = 0; v < surface.Points.CountV; v++)
                {
                    Point3d controlPt;
                    surface.Points.GetPoint(u, v, out controlPt);
                    Ray3d  ray = new Ray3d(controlPt, moveDir);
                    double t   = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, ray);

                    if (t >= 0.0)
                    {
                        surface.Points.SetPoint(u, v, ray.PointAt(t));
                    }
                    else
                    {
                        Ray3d  rayOpp = new Ray3d(controlPt, -moveDir);
                        double tOpp   = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, rayOpp);
                        if (tOpp >= 0.0)
                        {
                            surface.Points.SetPoint(u, v, rayOpp.PointAt(t));
                        }
                        else
                        {
                            //return null;
                        }
                    }
                }
            }
            if (surface.IsValid)
            {
                GH_Convert.ToGHSurface(surface, GH_Conversion.Primary, ref ghSurface);
                return(ghSurface);
            }
            else
            {
                return(null);
            }
        }
示例#14
0
        public static GH_Curve ProjectPolylineToTopo(Mesh topoMesh, Polyline pLine)
        {
            GH_Curve ghCurve = new GH_Curve();


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

            for (int j = 0; j < pLine.Count; j++)
            {
                Ray3d  ray = new Ray3d(pLine[j], moveDir);
                double t   = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, ray);
                if (t >= 0.0)
                {
                    projectedPts.Add(ray.PointAt(t));
                }
                else
                {
                    Ray3d  rayOpp = new Ray3d(pLine[j], -moveDir);
                    double tOpp   = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, rayOpp);
                    if (tOpp >= 0.0)
                    {
                        projectedPts.Add(rayOpp.PointAt(tOpp));
                    }
                    else
                    {
                        //return null;
                    }
                }
            }
            Polyline pLineOut = new Polyline(projectedPts);

            if (pLineOut.IsValid)
            {
                GH_Convert.ToGHCurve(pLineOut.ToNurbsCurve(), GH_Conversion.Primary, ref ghCurve);
                return(ghCurve);
            }
            else
            {
                return(null);
            }
        }
示例#15
0
        /// <summary>
        /// Find intersection of *WORLD* ray with Mesh
        /// </summary>
        override public bool FindRayIntersection(Ray3f rayW, out SORayHit hit)
        {
            hit = null;
            if (enable_spatial == false)
            {
                return(false);
            }

            validate_spatial();

            // convert ray to local
            FScene scene     = this.GetScene();
            Ray3f  rayS      = scene.ToSceneRay(rayW);
            Ray3d  local_ray = SceneTransforms.SceneToObject(this, rayS);

            int hit_tid = spatial.FindNearestHitTriangle(local_ray);

            if (hit_tid != DMesh3.InvalidID)
            {
                IntrRay3Triangle3 intr = MeshQueries.TriangleIntersection(mesh, hit_tid, local_ray);

                Vector3f hitPos = (Vector3f)local_ray.PointAt(intr.RayParameter);
                hitPos = SceneTransforms.ObjectToSceneP(this, hitPos);
                hitPos = scene.ToWorldP(hitPos);

                Vector3f hitNormal = (Vector3f)mesh.GetTriNormal(hit_tid);
                hitNormal = SceneTransforms.ObjectToSceneN(this, hitNormal);
                hitNormal = scene.ToWorldN(hitNormal);

                hit           = new SORayHit();
                hit.hitPos    = hitPos;
                hit.hitNormal = hitNormal;
                hit.hitIndex  = hit_tid;
                hit.fHitDist  = hit.hitPos.Distance(rayW.Origin);   // simpler than transforming!
                hit.hitGO     = RootGameObject;
                hit.hitSO     = this;
                return(true);
            }
            return(false);
        }
示例#16
0
        /// <summary>
        /// Find intersection of *WORLD* ray with Mesh
        /// </summary>
        override public bool FindRayIntersection(Ray3f rayW, out SORayHit hit)
        {
            hit = null;
            if (enable_spatial == false)
            {
                return(false);
            }

            if (spatial == null)
            {
                spatial = new DMeshAABBTree3(mesh);
                spatial.Build();
            }

            // convert ray to local
            Frame3f f = new Frame3f(rayW.Origin, rayW.Direction);

            f = SceneTransforms.TransformTo(f, this, CoordSpace.WorldCoords, CoordSpace.ObjectCoords);
            Ray3d local_ray = new Ray3d(f.Origin, f.Z);

            int hit_tid = spatial.FindNearestHitTriangle(local_ray);

            if (hit_tid != DMesh3.InvalidID)
            {
                IntrRay3Triangle3 intr = MeshQueries.TriangleIntersection(mesh, hit_tid, local_ray);

                Frame3f hitF = new Frame3f(local_ray.PointAt(intr.RayParameter), mesh.GetTriNormal(hit_tid));
                hitF = SceneTransforms.TransformTo(hitF, this, CoordSpace.ObjectCoords, CoordSpace.WorldCoords);

                hit           = new SORayHit();
                hit.hitPos    = hitF.Origin;
                hit.hitNormal = hitF.Z;
                hit.hitIndex  = hit_tid;
                hit.fHitDist  = hit.hitPos.Distance(rayW.Origin);   // simpler than transforming!
                hit.hitGO     = RootGameObject;
                hit.hitSO     = this;
                return(true);
            }
            return(false);
        }
示例#17
0
        public static Vector3d GetMinProjectedPointToMesh(List <Point3d> points, Mesh topoMesh)
        {
            List <Point3d> projectedPts = new List <Point3d>();

            foreach (Point3d pt in points)
            {
                Ray3d  ray = new Ray3d(pt, moveDir);
                double t   = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, ray);
                if (t >= 0.0)
                {
                    projectedPts.Add(ray.PointAt(t));
                }
                else
                {
                    Ray3d  rayOpp = new Ray3d(pt, -moveDir);
                    double tOpp   = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, rayOpp);
                    if (tOpp >= 0.0)
                    {
                        projectedPts.Add(rayOpp.PointAt(tOpp));
                    }
                    else
                    {
                        return(new Vector3d(0, 0, Double.MaxValue));
                    }
                }
            }

            Vector3d min_v = new Vector3d(0, 0, Double.MaxValue);

            for (int i = 0; i < points.Count; i++)
            {
                Vector3d v = projectedPts[i] - points[i];
                if (v.Length < min_v.Length)
                {
                    min_v = v;
                }
            }

            return(min_v);
        }
示例#18
0
        // [RMS] this is not working right now...
        override public bool FindRayIntersection(Ray3f ray, out SORayHit hit)
        {
            hit = null;
            if (enable_spatial == false)
            {
                return(false);
            }

            if (spatial == null)
            {
                spatial = new DMeshAABBTree3(mesh);
                spatial.Build();
            }

            Transform xform = ((GameObject)RootGameObject).transform;

            // convert ray to local
            Ray3d local_ray = new Ray3d();

            local_ray.Origin    = xform.InverseTransformPoint(ray.Origin);
            local_ray.Direction = xform.InverseTransformDirection(ray.Direction);
            local_ray.Direction.Normalize();

            int hit_tid = spatial.FindNearestHitTriangle(local_ray);

            if (hit_tid != DMesh3.InvalidID)
            {
                IntrRay3Triangle3 intr = MeshQueries.TriangleIntersection(mesh, hit_tid, local_ray);

                hit           = new SORayHit();
                hit.fHitDist  = (float)intr.RayParameter;
                hit.hitPos    = xform.TransformPoint((Vector3f)local_ray.PointAt(intr.RayParameter));
                hit.hitNormal = xform.TransformDirection((Vector3f)mesh.GetTriNormal(hit_tid));
                hit.hitGO     = RootGameObject;
                hit.hitSO     = this;
                return(true);
            }
            return(false);
        }
示例#19
0
        /// <summary>
        /// Rayを飛ばして一歩進めるかどうか判定する
        /// </summary>
        /// <param name="ray"></param>
        /// <returns></returns>
        ///
        /// 20190622 Matsu 作成
        public virtual bool IsGoing(Ray3d ray)
        {
            List <Point3d> intersectPt = new List <Point3d>();

            try
            {
                intersectPt = Rhino.Geometry.Intersect.Intersection.RayShoot(ray, agent.Obstacles, 1).ToList();
            }
            catch (ArgumentNullException)
            {
                Point3d pt = ray.PointAt(agent.ViewRaidius);
                intersectPt.Add(pt);
            }
            // 交点との距離が1歩以上ならTrue、以下ならFalseを返す
            if (agent.AgentBasePlane.Origin.DistanceTo(intersectPt[0]) > agent.StepCount)
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
示例#20
0
        public bool RayIntersect(Ray3d ray, out Vector3D vHit, out Vector3D vHitNormal)
        {
            vHit       = Vector3D.Zero;
            vHitNormal = Vector3D.AxisX;
            int tHitID = Spatial.FindNearestHitTriangle(ray);

            if (tHitID == NGonsCore.geometry3Sharp.mesh.DMesh3.InvalidID)
            {
                return(false);
            }
            IntrRay3Triangle3 t = MeshQueries.TriangleIntersection(Mesh, tHitID, ray);

            vHit = ray.PointAt(t.RayParameter);
            if (UseFaceNormal == false && Mesh.HasVertexNormals)
            {
                vHitNormal = Mesh.GetTriBaryNormal(tHitID, t.TriangleBaryCoords.x, t.TriangleBaryCoords.y, t.TriangleBaryCoords.z);
            }
            else
            {
                vHitNormal = Mesh.GetTriNormal(tHitID);
            }
            return(true);
        }
示例#21
0
        void update_current_hole_type()
        {
            if (HoleType == HoleTypes.CutHole)
            {
                if (CutOp != null)
                {
                    CutOp.StartPoint = LastUpdateRay.Origin;
                    CutOp.EndPoint   = LastUpdateRay.PointAt(LastThroughDepth);
                }
            }

            if (HoleType == HoleTypes.CavityObject || AlwaysShowPreview)
            {
                Frame3f holeFrame = new Frame3f(LastUpdateRay.Origin, LastUpdateRay.Direction);
                holeFrame.Translate((float)(-CurEndOffset) * holeFrame.Z);

                Frame3f holeFrameS = SceneTransforms.ObjectToScene(InputMeshSO, holeFrame);
                CavityPreviewSO.SetLocalFrame(holeFrameS, CoordSpace.SceneCoords);
                CavityPreviewSO.SetLocalScale(new Vector3f(hole_size, hole_size, (float)CurHoleDepth));
            }

            active_hole_type = HoleType;
        }
示例#22
0
    internal Vector3d MovePointDepthDependant(CuttingInfo info, Vector3d shellPoint, Vector3d normal)
    {
        normal = normal.Normalized;
        var   position = shellPoint + info.data.minDepth * normal;;
        var   tree     = new DMeshAABBTree3(info.oldMesh, true);
        Ray3d ray      = new Ray3d(shellPoint, -normal);
        int   hit_tid  = tree.FindNearestHitTriangle(ray);

        Debug.Log("Hit " + hit_tid);
        if (hit_tid != DMesh3.InvalidID)
        {
            IntrRay3Triangle3 intr     = MeshQueries.TriangleIntersection(info.oldMesh, hit_tid, ray);
            double            hit_dist = shellPoint.Distance(ray.PointAt(intr.RayParameter));
            position = shellPoint - normal * hit_dist * (info.data.depth / 100);
            Debug.Log($"Hit Dist: {hit_dist}");
        }
        else
        {
            StaticFunctions.ErrorMessage("Depth Dependant Calculation failed");
        }

        return(position);
    }
示例#23
0
文件: LtComponent.cs 项目: linluz/Lt
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            if (DA.Iteration > 1)
            {
                AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "超出数据已被忽视");
                return;
            }

            Mesh tm = new Mesh();

            if (!DA.GetData(0, ref tm) && !tm.IsValid)
            {
                return;
            }
            List <Mesh> o = new List <Mesh>(3);

            DA.GetDataList(1, o);
            List <Point3d> pl = new List <Point3d>();

            if (!DA.GetDataList(2, pl))
            {
                return;
            }

            int a = 0;

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

            #region 制作网格上用于测量的点阵

            BoundingBox mb = new BoundingBox();
            foreach (Point3f p3f in tm.Vertices)
            {
                mb.Union(new Point3d(p3f));
            }
            double         px   = mb.Min.X;
            double         py   = mb.Min.Y;
            int            rx   = (int)Math.Ceiling((mb.Max.X - px) / a);
            int            ry   = (int)Math.Ceiling((mb.Max.Y - py) / a);
            List <Point3d> grid = new List <Point3d>(rx * ry);
            for (int ix = 0; ix < rx; ix++)
            {
                for (int iy = 0; iy < ry; iy++)
                {
                    Ray3d  ray = new Ray3d(new Point3d(px, py, mb.Min.Z), Vector3d.ZAxis);
                    double pmd = Intersection.MeshRay(tm, ray);
                    if (RhinoMath.IsValidDouble(pmd) && pmd > 0.0)
                    {
                        grid.Add(ray.PointAt(pmd));
                    }
                    py += a;
                }

                px += a;
                py  = mb.Min.Y;
            } //获取网格上点阵制作栅格点阵z射线,与网格相交,交点加入grid

            #endregion

            List <Point3d> pt = new List <Point3d>(pl.Count);

            #region 将观测点投影到地形网格上,并增加眼高

            foreach (Point3d p0 in pl)
            {
                Point3d p = p0;

                Ray3d  rayp = new Ray3d(new Point3d(p.X, p.Y, mb.Min.Z), Vector3d.ZAxis);
                double pmdp = Intersection.MeshRay(tm, rayp);
                if (RhinoMath.IsValidDouble(pmdp) && pmdp > 0.0)
                {
                    p = rayp.PointAt(pmdp);
                }
                else
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"观测点{p}无法被Z向投影至地形网格上");
                    return;
                }

                p.Z += 1.5; //增加眼高
                pt.Add(p);
            } //采样点

            #endregion

            foreach (Mesh m in o) //将障碍物附加入网格
            {
                tm.Append(m);
            }

            bool[] grib = new bool[grid.Count]; //采样点布尔数组

            foreach (Point3d p in pt)
            {
                if (Environment.ProcessorCount > 2)
                {
                    Parallel.For(0, grid.Count, j => //多线程处理每个采样点
                    {
                        if (!grib[j])                //grib为否(尚未可见)时 判定当前是否为可见点,与网格上的点阵交点仅为1的即可见点
                        {
                            grib[j] = Intersection.MeshLine(tm, new Line(p, grid[j]), out _).Length == 1;
                        }
                    });
                }
                else
                {
                    for (int j = 0; j < grid.Count; j++)
                    {
                        if (!grib[j]) //grib为否(尚未可见)时 判定当前是否为可见点,与网格上的点阵交点仅为1的即可见点
                        {
                            grib[j] = Intersection.MeshLine(tm, new Line(p, grid[j]), out _).Length == 1;
                        }
                    }
                }
            }


            for (int i = grid.Count - 1; i >= 0; i--) //剔除不可见点
            {
                if (!grib[i])
                {
                    grid.RemoveAt(i);
                }
            }


            DA.SetDataList(0, pt);
            DA.SetDataList(1, grid);
        }
示例#24
0
        protected override Rhino.Commands.Result RunCommand(RhinoDoc doc, Rhino.Commands.RunMode mode)
        {
            Mesh meshObj;
            Point3d pointObj = new Point3d(0.0,0.0,0.0);

            RhinoApp.WriteLine("dikka dikka dikka...");

            Rhino.Input.Custom.GetPoint gp = new Rhino.Input.Custom.GetPoint();
            gp.SetCommandPrompt("Start of ray");
            gp.Get();
            if (gp.CommandResult() != Rhino.Commands.Result.Success)
                return gp.CommandResult();

            pointObj = gp.Point();
            doc.Objects.AddPoint(pointObj);

            Rhino.Input.Custom.GetObject go = new Rhino.Input.Custom.GetObject();
            go.SetCommandPrompt("Select the mesh to print");
            go.Get();
            Result rc = go.CommandResult();

            if (rc != Rhino.Commands.Result.Success)
            {
                RhinoApp.WriteLine("sdfafadsfda");
                return rc;
            }

            RhinoApp.WriteLine("2 2 dikka dikka dikka...");

            meshObj = new Mesh();
            if (go.ObjectCount == 1)
            {
                ObjRef tmpRef = new ObjRef(go.Object(0).ObjectId);
                meshObj = tmpRef.Mesh();
                if (meshObj == null)
                {
                    return rc;
                }
            }

            Ray3d rayObj = new Ray3d(pointObj, new Vector3d(1.0, 1.0, 1.0));
            doc.Objects.AddPoint(rayObj.PointAt(1.0));
            doc.Objects.AddPoint(rayObj.PointAt(2.0));
            doc.Objects.AddPoint(rayObj.PointAt(3.0));

            double p  = Intersection.MeshRay(meshObj, rayObj);
            string a = string.Format("mesh ray gives {0:0.00}",p);
            doc.Objects.AddPoint(rayObj.PointAt(p));
            RhinoApp.WriteLine(a);
            return Rhino.Commands.Result.Success;
        }
示例#25
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            ITargetLength TargetLength = null;
            bool reset = false;
            int Flip = 0;
            List<Curve> FC = new List<Curve>();
            List<Point3d> FV = new List<Point3d>();
            double FixT = 0.01;
            double PullStrength = 0.8;
            double SmoothStrength = 0.8;
            double LengthTol = 0.15;
            bool Minim = false;
            int Iters = 1;

            GH_ObjectWrapper Surf = new GH_ObjectWrapper();
            DA.GetData<GH_ObjectWrapper>(0, ref Surf);

            GH_ObjectWrapper Obj = null;
            DA.GetData<GH_ObjectWrapper>(1, ref Obj);
            TargetLength = Obj.Value as ITargetLength;

            DA.GetDataList<Curve>(2, FC);
            DA.GetDataList<Point3d>(3, FV);
            DA.GetData<int>(4, ref Flip);

            DA.GetData<double>(5, ref PullStrength);

            DA.GetData<int>(6, ref Iters);
            DA.GetData<bool>(7, ref reset);

            if (PullStrength == 0) { Minim = true; }

            if (Surf.Value is GH_Mesh)
            {
                DA.GetData<Mesh>(0, ref M);
                M.Faces.ConvertQuadsToTriangles();
            }
            else
            {
                double L = 1.0;
                MeshingParameters MeshParams = new MeshingParameters();
                MeshParams.MaximumEdgeLength = 3 * L;
                MeshParams.MinimumEdgeLength = L;
                MeshParams.JaggedSeams = false;
                MeshParams.SimplePlanes = false;
                Brep SB = null;
                DA.GetData<Brep>(0, ref SB);
                Mesh[] BrepMeshes = Mesh.CreateFromBrep(SB, MeshParams);
                M = new Mesh();
                foreach (var mesh in BrepMeshes)
                    M.Append(mesh);
            }

            if (reset || initialized == false)
            {
                #region reset
                M.Faces.ConvertQuadsToTriangles();
                P = M.ToPlanktonMesh();

                initialized = true;

                AnchorV.Clear();
                FeatureV.Clear();
                FeatureE.Clear();

                //Mark any vertices or edges lying on features
                for (int i = 0; i < P.Vertices.Count; i++)
                {
                    Point3d Pt = P.Vertices[i].ToPoint3d();
                    AnchorV.Add(-1);
                    for (int j = 0; j < FV.Count; j++)
                    {
                        if (Pt.DistanceTo(FV[j]) < FixT)
                        { AnchorV[AnchorV.Count - 1] = j; }
                    }

                    FeatureV.Add(-1);
                    for (int j = 0; j < FC.Count; j++)
                    {
                        double param = new double();
                        FC[j].ClosestPoint(Pt, out param);
                        if (Pt.DistanceTo(FC[j].PointAt(param)) < FixT)
                        { FeatureV[FeatureV.Count - 1] = j; }
                    }
                }

                int EdgeCount = P.Halfedges.Count / 2;
                for (int i = 0; i < EdgeCount; i++)
                {
                    FeatureE.Add(-1);
                    int vStart = P.Halfedges[2 * i].StartVertex;
                    int vEnd = P.Halfedges[2 * i + 1].StartVertex;

                    Point3d PStart = P.Vertices[vStart].ToPoint3d();
                    Point3d PEnd = P.Vertices[vEnd].ToPoint3d();

                    for (int j = 0; j < FC.Count; j++)
                    {
                        double paramS = new double();
                        double paramE = new double();
                        Curve thisFC = FC[j];
                        thisFC.ClosestPoint(PStart, out paramS);
                        thisFC.ClosestPoint(PEnd, out paramE);
                        if ((PStart.DistanceTo(thisFC.PointAt(paramS)) < FixT) &&
                          (PEnd.DistanceTo(thisFC.PointAt(paramE)) < FixT))
                        {
                            FeatureE[FeatureE.Count - 1] = j;
                        }
                    }
                }
                #endregion
            }

            else
            {
                for (int iter = 0; iter < Iters; iter++)
                {
                    int EdgeCount = P.Halfedges.Count / 2;
                    double[] EdgeLength = P.Halfedges.GetLengths();
                    List<bool> Visited = new List<bool>();
                    Vector3d[] Normals = new Vector3d[P.Vertices.Count];

                    for (int i = 0; i < P.Vertices.Count; i++)
                    {
                        Visited.Add(false);
                        Normals[i] = Normal(P, i);
                    }

                    double t = LengthTol;     //a tolerance for when to split/collapse edges
                    double smooth = SmoothStrength;  //smoothing strength
                    double pull = PullStrength;  //pull to target mesh strength

                    // Split the edges that are too long
                    for (int i = 0; i < EdgeCount; i++)
                    {
                        if (P.Halfedges[2 * i].IsUnused == false)
                        {
                            int vStart = P.Halfedges[2 * i].StartVertex;
                            int vEnd = P.Halfedges[2 * i + 1].StartVertex;

                            if ((Visited[vStart] == false)
                              && (Visited[vEnd] == false))
                            {

                                double L2 = TargetLength.Calculate(P, 2 * i);

                                if (EdgeLength[2 * i] > (1 + t) * (4f / 3f) * L2)
                                {

                                    int SplitHEdge = P.Halfedges.TriangleSplitEdge(2 * i);
                                    if (SplitHEdge != -1)
                                    {
                                        int SplitCenter = P.Halfedges[SplitHEdge].StartVertex;
                                        P.Vertices.SetVertex(SplitCenter, MidPt(P, i));

                                        //update the feature information
                                        FeatureE.Add(FeatureE[i]);
                                        FeatureV.Add(FeatureE[i]);
                                        AnchorV.Add(-1);

                                        //2 additional new edges have also been created (or 1 if split was on a boundary)
                                        //mark these as non-features
                                        int CEdgeCount = P.Halfedges.Count / 2;
                                        while (FeatureE.Count < CEdgeCount)
                                        { FeatureE.Add(-1); }

                                        Visited.Add(true);
                                        int[] Neighbours = P.Vertices.GetVertexNeighbours(SplitCenter);
                                        foreach (int n in Neighbours)
                                        { Visited[n] = true; }
                                    }
                                }

                            }
                        }
                    }

                    //Collapse the edges that are too short
                    for (int i = 0; i < EdgeCount; i++)
                    {
                        if (P.Halfedges[2 * i].IsUnused == false)
                        {
                            int vStart = P.Halfedges[2 * i].StartVertex;
                            int vEnd = P.Halfedges[2 * i + 1].StartVertex;
                            if ((Visited[vStart] == false)
                              && (Visited[vEnd] == false))
                            {
                                if (!(AnchorV[vStart] != -1 && AnchorV[vEnd] != -1)) // if both ends are anchored, don't collapse
                                {
                                    int Collapse_option = 0; //0 for none, 1 for collapse to midpt, 2 for towards start, 3 for towards end
                                    //if neither are anchorV
                                    if (AnchorV[vStart] == -1 && AnchorV[vEnd] == -1)
                                    {
                                        // if both on same feature (or neither on a feature)
                                        if (FeatureV[vStart] == FeatureV[vEnd])
                                        { Collapse_option = 1; }
                                        // if start is on a feature and end isn't
                                        if ((FeatureV[vStart] != -1) && (FeatureV[vEnd] == -1))
                                        { Collapse_option = 2; }
                                        // if end is on a feature and start isn't
                                        if ((FeatureV[vStart] == -1) && (FeatureV[vEnd] != -1))
                                        { Collapse_option = 3; }
                                    }
                                    else // so one end must be an anchor
                                    {
                                        // if start is an anchor
                                        if (AnchorV[vStart] != -1)
                                        {
                                            // if both are on same feature, or if the end is not a feature
                                            if ((FeatureE[i] != -1) || (FeatureV[vEnd] == -1))
                                            { Collapse_option = 2; }
                                        }
                                        // if end is an anchor
                                        if (AnchorV[vEnd] != -1)
                                        {
                                            // if both are on same feature, or if the start is not a feature
                                            if ((FeatureE[i] != -1) || (FeatureV[vStart] == -1))
                                            { Collapse_option = 3; }
                                        }
                                    }

                                    Point3d Mid = MidPt(P, i);

                                    double L2 = TargetLength.Calculate(P, 2 * i);

                                    if ((Collapse_option != 0) && (EdgeLength[2 * i] < (1 - t) * 4f / 5f * L2))
                                    {
                                        int Collapsed = -1;
                                        int CollapseRtn = -1;
                                        if (Collapse_option == 1)
                                        {
                                            Collapsed = P.Halfedges[2 * i].StartVertex;
                                            P.Vertices.SetVertex(Collapsed, MidPt(P, i));
                                            CollapseRtn = P.Halfedges.CollapseEdge(2 * i);
                                        }
                                        if (Collapse_option == 2)
                                        {
                                            Collapsed = P.Halfedges[2 * i].StartVertex;
                                            CollapseRtn = P.Halfedges.CollapseEdge(2 * i);
                                        }
                                        if (Collapse_option == 3)
                                        {
                                            Collapsed = P.Halfedges[2 * i + 1].StartVertex;
                                            CollapseRtn = P.Halfedges.CollapseEdge(2 * i + 1);
                                        }
                                        if (CollapseRtn != -1)
                                        {
                                            int[] Neighbours = P.Vertices.GetVertexNeighbours(Collapsed);
                                            foreach (int n in Neighbours)
                                            { Visited[n] = true; }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    EdgeCount = P.Halfedges.Count / 2;

                    if ((Flip == 0) && (PullStrength > 0))
                    {
                        //Flip edges to reduce valence error
                        for (int i = 0; i < EdgeCount; i++)
                        {
                            if (!P.Halfedges[2 * i].IsUnused
                              && (P.Halfedges[2 * i].AdjacentFace != -1)
                              && (P.Halfedges[2 * i + 1].AdjacentFace != -1)
                              && (FeatureE[i] == -1)  // don't flip feature edges
                              )
                            {
                                int Vert1 = P.Halfedges[2 * i].StartVertex;
                                int Vert2 = P.Halfedges[2 * i + 1].StartVertex;
                                int Vert3 = P.Halfedges[P.Halfedges[P.Halfedges[2 * i].NextHalfedge].NextHalfedge].StartVertex;
                                int Vert4 = P.Halfedges[P.Halfedges[P.Halfedges[2 * i + 1].NextHalfedge].NextHalfedge].StartVertex;

                                int Valence1 = P.Vertices.GetValence(Vert1);
                                int Valence2 = P.Vertices.GetValence(Vert2);
                                int Valence3 = P.Vertices.GetValence(Vert3);
                                int Valence4 = P.Vertices.GetValence(Vert4);

                                if (P.Vertices.NakedEdgeCount(Vert1) > 0) { Valence1 += 2; }
                                if (P.Vertices.NakedEdgeCount(Vert2) > 0) { Valence2 += 2; }
                                if (P.Vertices.NakedEdgeCount(Vert3) > 0) { Valence3 += 2; }
                                if (P.Vertices.NakedEdgeCount(Vert4) > 0) { Valence4 += 2; }

                                int CurrentError =
                                  Math.Abs(Valence1 - 6) +
                                  Math.Abs(Valence2 - 6) +
                                  Math.Abs(Valence3 - 6) +
                                  Math.Abs(Valence4 - 6);
                                int FlippedError =
                                  Math.Abs(Valence1 - 7) +
                                  Math.Abs(Valence2 - 7) +
                                  Math.Abs(Valence3 - 5) +
                                  Math.Abs(Valence4 - 5);
                                if (CurrentError > FlippedError)
                                {
                                    P.Halfedges.FlipEdge(2 * i);
                                }
                            }
                        }
                    }
                    else
                    {
                        //Flip edges based on angle
                        for (int i = 0; i < EdgeCount; i++)
                        {
                            if (!P.Halfedges[2 * i].IsUnused
                              && (P.Halfedges[2 * i].AdjacentFace != -1)
                              && (P.Halfedges[2 * i + 1].AdjacentFace != -1)
                              && (FeatureE[i] == -1) // don't flip feature edges
                              )
                            {
                                int Vert1 = P.Halfedges[2 * i].StartVertex;
                                int Vert2 = P.Halfedges[2 * i + 1].StartVertex;
                                int Vert3 = P.Halfedges[P.Halfedges[P.Halfedges[2 * i].NextHalfedge].NextHalfedge].StartVertex;
                                int Vert4 = P.Halfedges[P.Halfedges[P.Halfedges[2 * i + 1].NextHalfedge].NextHalfedge].StartVertex;

                                Point3d P1 = P.Vertices[Vert1].ToPoint3d();
                                Point3d P2 = P.Vertices[Vert2].ToPoint3d();
                                Point3d P3 = P.Vertices[Vert3].ToPoint3d();
                                Point3d P4 = P.Vertices[Vert4].ToPoint3d();

                                double A1 = Vector3d.VectorAngle(new Vector3d(P3 - P1), new Vector3d(P4 - P1))
                                  + Vector3d.VectorAngle(new Vector3d(P4 - P2), new Vector3d(P3 - P2));

                                double A2 = Vector3d.VectorAngle(new Vector3d(P1 - P4), new Vector3d(P2 - P4))
                                  + Vector3d.VectorAngle(new Vector3d(P2 - P3), new Vector3d(P1 - P3));

                                if (A2 > A1)
                                {
                                    P.Halfedges.FlipEdge(2 * i);
                                }
                            }
                        }
                    }

                    if (Minim)
                    {
                        Vector3d[] SmoothC = LaplacianSmooth(P, 1, smooth);

                        for (int i = 0; i < P.Vertices.Count; i++)
                        {
                            if (AnchorV[i] == -1) // don't smooth feature vertices
                            {
                                P.Vertices.MoveVertex(i, 0.5 * SmoothC[i]);
                            }
                        }
                    }

                    Vector3d[] Smooth = LaplacianSmooth(P, 0, smooth);

                    for (int i = 0; i < P.Vertices.Count; i++)
                    {
                        if (AnchorV[i] == -1) // don't smooth feature vertices
                        {
                            // make it tangential only
                            Vector3d VNormal = Normal(P, i);
                            double ProjLength = Smooth[i] * VNormal;
                            Smooth[i] = Smooth[i] - (VNormal * ProjLength);

                            P.Vertices.MoveVertex(i, Smooth[i]);

                            if (P.Vertices.NakedEdgeCount(i) != 0)//special smoothing for feature edges
                            {
                                int[] Neighbours = P.Vertices.GetVertexNeighbours(i);
                                int ncount = 0;
                                Point3d Avg = new Point3d();

                                for (int j = 0; j < Neighbours.Length; j++)
                                {
                                    if (P.Vertices.NakedEdgeCount(Neighbours[j]) != 0)
                                    {
                                        ncount++;
                                        Avg = Avg + P.Vertices[Neighbours[j]].ToPoint3d();
                                    }
                                }
                                Avg = Avg * (1.0 / ncount);
                                Vector3d move = Avg - P.Vertices[i].ToPoint3d();
                                move = move * smooth;
                                P.Vertices.MoveVertex(i, move);
                            }

                            if (FeatureV[i] != -1)//special smoothing for feature edges
                            {
                                int[] Neighbours = P.Vertices.GetVertexNeighbours(i);
                                int ncount = 0;
                                Point3d Avg = new Point3d();

                                for (int j = 0; j < Neighbours.Length; j++)
                                {
                                    if ((FeatureV[Neighbours[j]] == FeatureV[i]) || (AnchorV[Neighbours[j]] != -1))
                                    {
                                        ncount++;
                                        Avg = Avg + P.Vertices[Neighbours[j]].ToPoint3d();
                                    }
                                }
                                Avg = Avg * (1.0 / ncount);
                                Vector3d move = Avg - P.Vertices[i].ToPoint3d();
                                move = move * smooth;
                                P.Vertices.MoveVertex(i, move);
                            }

                            //projecting points onto the target along their normals

                            if (pull > 0)
                            {
                                Point3d Point = P.Vertices[i].ToPoint3d();
                                Vector3d normal = Normal(P, i);
                                Ray3d Ray1 = new Ray3d(Point, normal);
                                Ray3d Ray2 = new Ray3d(Point, -normal);
                                double RayPt1 = Rhino.Geometry.Intersect.Intersection.MeshRay(M, Ray1);
                                double RayPt2 = Rhino.Geometry.Intersect.Intersection.MeshRay(M, Ray2);
                                Point3d ProjectedPt;

                                if ((RayPt1 < RayPt2) && (RayPt1 > 0) && (RayPt1 < 1.0))
                                {
                                    ProjectedPt = Point * (1 - pull) + pull * Ray1.PointAt(RayPt1);
                                }
                                else if ((RayPt2 < RayPt1) && (RayPt2 > 0) && (RayPt2 < 1.0))
                                {
                                    ProjectedPt = Point * (1 - pull) + pull * Ray2.PointAt(RayPt2);
                                }
                                else
                                {
                                    ProjectedPt = Point * (1 - pull) + pull * M.ClosestPoint(Point);
                                }

                                P.Vertices.SetVertex(i, ProjectedPt);
                            }

                            if (FeatureV[i] != -1) //pull feature vertices onto feature curves
                            {
                                Point3d Point = P.Vertices[i].ToPoint3d();
                                Curve CF = FC[FeatureV[i]];
                                double param1 = 0.0;
                                Point3d onFeature = new Point3d();
                                CF.ClosestPoint(Point, out param1);
                                onFeature = CF.PointAt(param1);
                                P.Vertices.SetVertex(i, onFeature);
                            }
                        }
                        else
                        {
                            P.Vertices.SetVertex(i, FV[AnchorV[i]]); //pull anchor vertices onto their points
                        }
                    }

                    //end new

                    AnchorV = CompactByVertex(P, AnchorV); //compact the fixed points along with the vertices
                    FeatureV = CompactByVertex(P, FeatureV);
                    FeatureE = CompactByEdge(P, FeatureE);

                    P.Compact(); //this cleans the mesh data structure of unused elements
                }

            }

            DA.SetData(0, P);
        }
示例#26
0
        /// <summary>
        /// Cut a "partial" hole, ie we cut the mesh with the polygon once, and then
        /// extrude downwards to a planar version of the cut boundary.
        ///
        /// Currently only supports extruding downwards from topmost intersection.
        ///
        /// </summary>
        protected bool CutPartialHole(DMesh3 mesh, HoleInfo hi, Vector3d translate, bool bUpwards)
        {
            if (hi.IsVertical == false)
            {
                throw new Exception("unsupported!");
            }

            Vector3d basePoint = CombinedBounds.Center - CombinedBounds.Extents.y * Vector3d.AxisY + translate;

            // do we need to compute spatial DS for each hole? not super efficient...
            DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh, true);

            Vector3d direction = (bUpwards) ? Vector3d.AxisY : -Vector3d.AxisY;
            Vector3d center    = basePoint + new Vector3d(hi.XZOffset.x, 0, hi.XZOffset.y) - 10000 * direction;


            Ray3d ray     = new Ray3d(center, direction);
            int   hit_tid = spatial.FindNearestHitTriangle(ray);

            if (hit_tid == DMesh3.InvalidID)
            {
                return(false);
            }

            IntrRay3Triangle3 intersection = MeshQueries.TriangleIntersection(mesh, hit_tid, ray);
            Vector3d          inter_pos    = ray.PointAt(intersection.RayParameter);

            Frame3f projectFrame = new Frame3f(ray.Origin, ray.Direction);

            int nVerts = 32;

            if (hi.Vertices != 0)
            {
                nVerts = hi.Vertices;
            }
            double    angleShiftRad = hi.AxisAngleD * MathUtil.Deg2Rad;
            Polygon2d circle        = Polygon2d.MakeCircle(hi.Radius, nVerts, angleShiftRad);

            try {
                EdgeLoop loop = null;

                MeshInsertProjectedPolygon insert = new MeshInsertProjectedPolygon(mesh, circle, projectFrame, hit_tid)
                {
                    SimplifyInsertion = false
                };
                if (insert.Insert())
                {
                    loop = insert.InsertedLoop;

                    // [RMS] do we need to simplify for this one?
                    //if (loop.VertexCount > circle.VertexCount)
                    //    loop = simplify_loop(mesh, loop, circle.VertexCount);

                    MeshEditor editor = new MeshEditor(mesh);

                    Vector3d base_pos = inter_pos;
                    base_pos.y = basePoint.y + hi.PartialHoleBaseHeight;

                    int   N       = loop.VertexCount;
                    int[] newLoop = new int[N];
                    for (int k = 0; k < N; ++k)
                    {
                        newLoop[k] = mesh.AppendVertex(mesh, loop.Vertices[k]);
                        Vector3d cur_v = mesh.GetVertex(newLoop[k]);
                        cur_v.y = base_pos.y;
                        mesh.SetVertex(newLoop[k], cur_v);
                    }
                    int   base_vid = mesh.AppendVertex(base_pos);
                    int[] fan_tris = editor.AddTriangleFan_OrderedVertexLoop(base_vid, newLoop);
                    FaceGroupUtil.SetGroupID(mesh, fan_tris, hi.PartialHoleGroupID);
                    int[] stitch_tris = editor.StitchLoop(loop.Vertices, newLoop);

                    // need to remesh fan region because otherwise we get pathological cases
                    RegionRemesher remesh = new RegionRemesher(mesh, fan_tris);
                    remesh.SetTargetEdgeLength(2.0);
                    remesh.SmoothSpeedT       = 1.0;
                    remesh.PreventNormalFlips = true;
                    for (int k = 0; k < 25; ++k)
                    {
                        remesh.BasicRemeshPass();
                    }
                    //remesh.EnableCollapses = remesh.EnableFlips = remesh.EnableSplits = false;
                    //for (int k = 0; k < 20; ++k)
                    //    remesh.BasicRemeshPass();
                    remesh.BackPropropagate();

                    return(true);
                }
                else
                {
                    return(false);
                }
            } catch (Exception e) {
                f3.DebugUtil.Log("partial hole {0} failed!! {1}", hi.nHole, e.Message);
                return(false);
            }
        }
示例#27
0
文件: FOV.cs 项目: Esrup/Antflow
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Point3d     person       = new Point3d(0, 0, 0);
            int         angle        = 0;
            Vector3d    direction    = new Vector3d(0, 0, 0);
            double      viewDistance = 0;
            List <Mesh> obstacles    = new List <Mesh>();


            List <Ray3d>   viewRays = new List <Ray3d>();
            List <Point3d> Rayhits  = new List <Point3d>();
            int            fovfree  = 0;

            Mesh meshes = new Mesh();



            DA.GetData(0, ref person);
            DA.GetData(1, ref direction);
            DA.GetData(2, ref viewDistance);
            DA.GetData(3, ref angle);
            DA.GetDataList(4, obstacles);

            int viewRes = angle;

            foreach (Mesh mesh in obstacles)
            {
                meshes.Append(mesh);
            }



            direction.Z = 0;


            direction.Rotate(Rhino.RhinoMath.ToRadians(angle / 2), new Vector3d(0, 0, 1));
            Line viewAngleA = new Line(person, direction, viewDistance);

            direction.Rotate(-Rhino.RhinoMath.ToRadians(angle / 2) * 2, new Vector3d(0, 0, 1));
            Line viewAngleB = new Line(person, direction, viewDistance);

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

            Liness.Add(viewAngleA);
            Liness.Add(viewAngleB);

            for (int i = 0; i < viewRes + 2; i++)
            {
                if (i > 1)
                {
                    direction.Rotate(Rhino.RhinoMath.ToRadians((angle / viewRes)), new Vector3d(0, 0, 1));
                }

                Ray3d  ray  = new Ray3d(person, direction);
                double rayT = Rhino.Geometry.Intersect.Intersection.MeshRay(meshes, ray);

                Vector3d newvec = Rhino.Geometry.Vector3d.Multiply(direction, viewDistance);

                if (rayT > 0)
                {
                    if (person.DistanceTo(ray.PointAt(rayT)) < viewDistance)
                    {
                        Rayhits.Add(ray.PointAt(rayT));
                    }
                    else
                    {
                        Rayhits.Add(new Point3d(newvec.X + person.X, newvec.Y + person.Y, person.Z));
                        fovfree = fovfree + 1;
                    }
                }
                else
                {
                    Rayhits.Add(new Point3d(newvec.X + person.X, newvec.Y + person.Y, person.Z));
                    fovfree = fovfree + 1;
                }
            }

            Mesh viewMesh = new Mesh();

            viewMesh.Vertices.UseDoublePrecisionVertices = true;

            //Make mesh from hitspoints
            viewMesh.Vertices.Add(new Point3f((float)person.X, (float)person.Y, (float)person.Z));
            viewMesh.VertexColors.Add(System.Drawing.Color.Ivory);

            for (int i = 0; i < Rayhits.Count; i++)
            {
                viewMesh.Vertices.Add(new Point3f((float)Rayhits[i].X, (float)Rayhits[i].Y, (float)Rayhits[i].Z));
                viewMesh.VertexColors.Add(System.Drawing.Color.Ivory);
            }
            for (int i = 0; i < (viewRes + 2); i++)
            {
                viewMesh.Faces.AddFace(0, i, i + 1);
            }


            viewMesh.Faces.RemoveAt(0);



            DA.SetData(0, viewMesh);
            DA.SetData(1, fovfree);
        }
示例#28
0
        public static GH_Mesh ProjectMeshToTopoSlow(Mesh topoMesh, Mesh topoFlatMesh, Point3d[] topoFlatPoints, RTree rTree, Mesh featureMesh)
        {
            ///TODO: Look into using Mesh.SplitWithProjectedPolylines available in RhinoCommon 7.0

            GH_Mesh ghMesh = new GH_Mesh();

            Mesh[] disjointMeshes          = featureMesh.SplitDisjointPieces();
            Mesh   projectedDisjointMeshes = new Mesh();

            foreach (Mesh disjointMesh in disjointMeshes)
            {
                ///Flatten disjointMesh first
                for (int i = 0; i < disjointMesh.Vertices.Count; i++)
                {
                    Point3f v = disjointMesh.Vertices[i];
                    v.Z = 0;
                    disjointMesh.Vertices.SetVertex(i, v);
                }

                ///Get naked edges and sort list so that outer boundary is first
                Polyline[] nakedEdges       = disjointMesh.GetNakedEdges();
                var        nakedEdgesCurves = new Dictionary <Curve, double>();
                foreach (Polyline p in nakedEdges)
                {
                    Curve pNurbs = p.ToNurbsCurve();
                    nakedEdgesCurves.Add(pNurbs, AreaMassProperties.Compute(pNurbs).Area);
                }
                var nakedEdgesSorted = from pair in nakedEdgesCurves
                                       orderby pair.Value descending
                                       select pair.Key;

                BoundingBox bbox = disjointMesh.GetBoundingBox(false);

                ///Project naked edges to flat topo to add control points at mesh edge intersections
                List <Curve> trimCurves = new List <Curve>();
                foreach (Curve nakedEdge in nakedEdgesSorted)
                {
                    Curve[] projectedCurves = Curve.ProjectToMesh(nakedEdge, topoFlatMesh, moveDir, tol);
                    ///If projection of naked edge results in more than one curve, join curves back into one closed curve.
                    ///Approximation at edge of topo is unavoidable
                    if (projectedCurves.Length > 0)
                    {
                        if (projectedCurves.Length > 1)
                        {
                            ///Collector polyline to combine projectedCurves
                            Polyline projBoundary = new Polyline();
                            ///Add individual curves from Curve.ProjectToMesh together by converting to Polyline and appending the vetexes together
                            foreach (Curve c in projectedCurves)
                            {
                                Polyline tempPolyline = new Polyline();
                                c.TryGetPolyline(out tempPolyline);
                                projBoundary.AddRange(tempPolyline);
                            }
                            ///Make sure polyine is closed
                            projBoundary.Add(projBoundary[0]);
                            trimCurves.Add(projBoundary.ToNurbsCurve());
                        }
                        else if (!projectedCurves[0].IsClosed)
                        {
                            Line  closer = new Line(projectedCurves[0].PointAtEnd, projectedCurves[0].PointAtStart);
                            Curve closedProjectedCurve = Curve.JoinCurves(new Curve[] { projectedCurves[0], closer.ToNurbsCurve() })[0];
                            trimCurves.Add(closedProjectedCurve);
                        }
                        else
                        {
                            trimCurves.Add(projectedCurves[0]);
                        }
                    }
                    else
                    {
                        ///Projection missed the topoFlatMesh
                        return(null);
                    }
                } ///End projected naked edges

                Polyline pL = new Polyline();
                trimCurves[0].TryGetPolyline(out pL);
                trimCurves.RemoveAt(0);

                ///Add points from topoMeshFlat to array used for Mesh.CreatePatch
                List <Point3f> bboxPoints = new List <Point3f>();

                ///Try RTree method. RTree of topoFlatPoints
                ///https://discourse.mcneel.com/t/rtree-bounding-box-search/96282/6

                var boxSearchData = new BoxSearchData();
                rTree.Search(bbox, BoundingBoxCallback, boxSearchData);

                foreach (int id in boxSearchData.Ids)
                {
                    Ray3d  ray = new Ray3d((Point3d)topoFlatPoints[id], -moveDir);
                    double t   = Rhino.Geometry.Intersect.Intersection.MeshRay(disjointMesh, ray);
                    if (t >= 0.0)
                    {
                        bboxPoints.Add((Point3f)ray.PointAt(t));
                    }
                    else
                    {
                        Ray3d  rayOpp = new Ray3d((Point3d)topoFlatPoints[id], moveDir);
                        double tOpp   = Rhino.Geometry.Intersect.Intersection.MeshRay(disjointMesh, rayOpp);
                        if (tOpp >= 0.0)
                        {
                            bboxPoints.Add((Point3f)rayOpp.PointAt(tOpp));
                        }
                        else
                        {
                            //return null;
                        }
                    }
                }

                ///A hack way of adding points to newVerts which is needed in the form of an array for Mesh.CreatePatch
                disjointMesh.Vertices.AddVertices(bboxPoints);
                Point3d[] newVerts = disjointMesh.Vertices.ToPoint3dArray();

                ///Create patch
                Mesh mPatch = Mesh.CreatePatch(pL, tol, null, trimCurves, null, newVerts, true, 1);

                ///Move patch verts to topo
                for (int i = 0; i < mPatch.Vertices.Count; i++)
                {
                    Ray3d  ray = new Ray3d((Point3d)mPatch.Vertices[i], moveDir);
                    double t   = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, ray);
                    if (t >= 0.0)
                    {
                        mPatch.Vertices.SetVertex(i, (Point3f)ray.PointAt(t));
                    }
                    else
                    {
                        Ray3d  rayOpp = new Ray3d((Point3d)mPatch.Vertices[i], -moveDir);
                        double tOpp   = Rhino.Geometry.Intersect.Intersection.MeshRay(topoMesh, rayOpp);
                        if (tOpp >= 0.0)
                        {
                            mPatch.Vertices.SetVertex(i, (Point3f)rayOpp.PointAt(tOpp));
                        }
                        else
                        {
                            return(null);
                        }
                    }
                }
                ///Combine disjoint meshes
                if (mPatch.IsValid)
                {
                    projectedDisjointMeshes.Append(mPatch);
                    mPatch.Dispose();
                }
                else
                {
                    return(null);
                }
            }
            projectedDisjointMeshes.Ngons.AddPlanarNgons(tol);
            projectedDisjointMeshes.Compact();
            GH_Convert.ToGHMesh(projectedDisjointMeshes, GH_Conversion.Primary, ref ghMesh);
            return(ghMesh);
        }
示例#29
0
        protected override Result RunCommand(RhinoDoc doc, RunMode mode)
        {
            // TODO: start here modifying the behaviour of your command.
            // ---
            RhinoApp.WriteLine("MeshMachine WIP test", EnglishName);

            Brep SB;

            using (GetObject getBrep = new GetObject())
            {
                getBrep.SetCommandPrompt("Please select the brep to remesh");
                getBrep.Get();
                SB = getBrep.Object(0).Brep();
            }

            //GetNumber TargetLength = new GetNumber();
            //double L = TargetLength.Number();

            Rhino.Input.Custom.GetNumber gn = new Rhino.Input.Custom.GetNumber();
            gn.SetCommandPrompt("Specify a Target Edge Length");
            gn.SetLowerLimit(0.5, false);
            gn.Get();
            if (gn.CommandResult() != Rhino.Commands.Result.Success)
            {
                return(gn.CommandResult());
            }
            double L = gn.Number();

            //Point3d pt0;
            //using (GetPoint getPointAction = new GetPoint())
            //{
            //    getPointAction.SetCommandPrompt("Please select the start point");
            //    if (getPointAction.Get() != GetResult.Point)
            //    {
            //        RhinoApp.WriteLine("No start point was selected.");
            //        return getPointAction.CommandResult();
            //    }
            //    pt0 = getPointAction.Point();
            //}

            //Point3d pt1;
            //using (GetPoint getPointAction = new GetPoint())
            //{
            //    getPointAction.SetCommandPrompt("Please select the end point");
            //    getPointAction.SetBasePoint(pt0, true);
            //    getPointAction.DynamicDraw +=
            //      (sender, e) => e.Display.DrawLine(pt0, e.CurrentPoint, System.Drawing.Color.DarkRed);
            //    if (getPointAction.Get() != GetResult.Point)
            //    {
            //        RhinoApp.WriteLine("No end point was selected.");
            //        return getPointAction.CommandResult();
            //    }
            //    pt1 = getPointAction.Point();
            //}

            //doc.Objects.AddLine(pt0, pt1);

            PlanktonMesh P = new PlanktonMesh();

            List <int> AnchorV        = new List <int>();
            List <int> FeatureV       = new List <int>();
            List <int> FeatureE       = new List <int>();
            double     FixT           = 0.00001;
            double     LengthTol      = 0.15; //a tolerance for when to split/collapse edges
            double     SmoothStrength = 0.8;  //smoothing strength
            double     PullStrength   = 0.8;  //pull to target mesh strength
            double     CurvDep        = 0;
            int        Flip           = 1;

            MeshingParameters MeshParams = new MeshingParameters();

            MeshParams.MaximumEdgeLength = 3 * L;
            MeshParams.MinimumEdgeLength = L;
            MeshParams.JaggedSeams       = false;
            MeshParams.SimplePlanes      = false;

            Mesh[] BrepMeshes = Mesh.CreateFromBrep(SB, MeshParams);
            Mesh   M          = new Mesh();

            foreach (var mesh in BrepMeshes)
            {
                M.Append(mesh);
            }

            M.Faces.ConvertQuadsToTriangles();
            P = M.ToPlanktonMesh();

            var FC = new List <Curve>();

            foreach (BrepEdge E in SB.Edges)
            {
                if (!E.IsSmoothManifoldEdge(0.01))
                {
                    FC.Add(E.ToNurbsCurve());
                }
            }
            var            Corners = SB.Vertices;
            List <Point3d> FV      = new List <Point3d>();

            foreach (Point Pt in Corners)
            {
                FV.Add(Pt.Location);
            }

            //Mark any vertices or edges lying on features
            for (int i = 0; i < P.Vertices.Count; i++)
            {
                Point3d Pt = P.Vertices[i].ToPoint3d();
                AnchorV.Add(-1);
                for (int j = 0; j < FV.Count; j++)
                {
                    if (Pt.DistanceTo(FV[j]) < FixT)
                    {
                        AnchorV[AnchorV.Count - 1] = j;
                    }
                }

                FeatureV.Add(-1);
                for (int j = 0; j < FC.Count; j++)
                {
                    double param = new double();
                    FC[j].ClosestPoint(Pt, out param);
                    if (Pt.DistanceTo(FC[j].PointAt(param)) < FixT)
                    {
                        FeatureV[FeatureV.Count - 1] = j;
                    }
                }
            }

            int EdgeCount = P.Halfedges.Count / 2;

            for (int i = 0; i < EdgeCount; i++)
            {
                FeatureE.Add(-1);
                int vStart = P.Halfedges[2 * i].StartVertex;
                int vEnd   = P.Halfedges[2 * i + 1].StartVertex;

                Point3d PStart = P.Vertices[vStart].ToPoint3d();
                Point3d PEnd   = P.Vertices[vEnd].ToPoint3d();

                for (int j = 0; j < FC.Count; j++)
                {
                    double paramS = new double();
                    double paramE = new double();
                    Curve  thisFC = FC[j];
                    thisFC.ClosestPoint(PStart, out paramS);
                    thisFC.ClosestPoint(PEnd, out paramE);
                    if ((PStart.DistanceTo(thisFC.PointAt(paramS)) < FixT) &&
                        (PEnd.DistanceTo(thisFC.PointAt(paramE)) < FixT))
                    {
                        FeatureE[FeatureE.Count - 1] = j;
                    }
                }
            }



            for (int iter = 0; iter < 30; iter++)
            {
                EdgeCount = P.Halfedges.Count / 2;
                double[]    EdgeLength = P.Halfedges.GetLengths();
                List <bool> Visited    = new List <bool>();
                Vector3d[]  Normals    = new Vector3d[P.Vertices.Count];

                for (int i = 0; i < P.Vertices.Count; i++)
                {
                    Visited.Add(false);
                    Normals[i] = Util.Normal(P, i);
                }

                double t      = LengthTol;      //a tolerance for when to split/collapse edges
                double smooth = SmoothStrength; //smoothing strength
                double pull   = PullStrength;   //pull to target mesh strength

                //    Split the edges that are too long
                for (int i = 0; i < EdgeCount; i++)
                {
                    if (P.Halfedges[2 * i].IsUnused == false)
                    {
                        int vStart = P.Halfedges[2 * i].StartVertex;
                        int vEnd   = P.Halfedges[2 * i + 1].StartVertex;

                        if ((Visited[vStart] == false) &&
                            (Visited[vEnd] == false))
                        {
                            double  L2  = L;
                            Point3d Mid = Util.MidPt(P, i);

                            //if (CurvDep > 0)
                            //{
                            //    double NormDiff = Vector3d.VectorAngle(Normals[vStart], Normals[vEnd]);
                            //    L2 = Math.Min((1.0 / (3.0 * NormDiff) * L), 5 * L);

                            //    if (CurvDep != 1)
                            //    {
                            //        L2 = L2 * (CurvDep) + L * (1.0 - CurvDep);
                            //    }

                            //}
                            //if (BoundScale != 1.0)
                            //{
                            //    double MinDist = 99954;

                            //    for (int j = 0; j < FC.Count; j++)
                            //    {
                            //        double param = new double();

                            //        FC[j].ClosestPoint(Mid, out param);
                            //        double ThisDist = Mid.DistanceTo(FC[j].PointAt(param));
                            //        if (ThisDist < MinDist)
                            //        { MinDist = ThisDist; }
                            //    }

                            //    if (MinDist < BoundDist)
                            //    {
                            //        L2 = L2 * BoundScale + (MinDist / BoundDist) * (L2 * (1 - BoundScale));
                            //    }
                            //}

                            //if (SizP.Count > 0)
                            //{
                            //    L2 = WeightedCombo(Mid, SizP, SizV, WExp, L2, BGW);
                            //    //  L2 = (WL * (1.0 - BGW)) + (BGW * L2);
                            //}

                            if (EdgeLength[2 * i] > (1 + t) * (4f / 3f) * L2)
                            {
                                int SplitHEdge = P.Halfedges.TriangleSplitEdge(2 * i);
                                if (SplitHEdge != -1)
                                {
                                    int SplitCenter = P.Halfedges[SplitHEdge].StartVertex;
                                    P.Vertices.SetVertex(SplitCenter, Util.MidPt(P, i));

                                    //update the feature information
                                    FeatureE.Add(FeatureE[i]);
                                    FeatureV.Add(FeatureE[i]);
                                    AnchorV.Add(-1);

                                    //2 additional new edges have also been created (or 1 if split was on a boundary)
                                    //mark these as non-features
                                    int CEdgeCount = P.Halfedges.Count / 2;
                                    while (FeatureE.Count < CEdgeCount)
                                    {
                                        FeatureE.Add(-1);
                                    }

                                    Visited.Add(true);
                                    int[] Neighbours = P.Vertices.GetVertexNeighbours(SplitCenter);
                                    foreach (int n in Neighbours)
                                    {
                                        Visited[n] = true;
                                    }
                                }
                            }
                        }
                    }
                }

                //Collapse the edges that are too short
                for (int i = 0; i < EdgeCount; i++)
                {
                    if (P.Halfedges[2 * i].IsUnused == false)
                    {
                        int vStart = P.Halfedges[2 * i].StartVertex;
                        int vEnd   = P.Halfedges[2 * i + 1].StartVertex;
                        if ((Visited[vStart] == false) &&
                            (Visited[vEnd] == false))
                        {
                            if (!(AnchorV[vStart] != -1 && AnchorV[vEnd] != -1)) // if both ends are anchored, don't collapse
                            {
                                int Collapse_option = 0;                         //0 for none, 1 for collapse to midpt, 2 for towards start, 3 for towards end
                                //if neither are anchorV
                                if (AnchorV[vStart] == -1 && AnchorV[vEnd] == -1)
                                {
                                    // if both on same feature (or neither on a feature)
                                    if (FeatureV[vStart] == FeatureV[vEnd])
                                    {
                                        Collapse_option = 1;
                                    }
                                    // if start is on a feature and end isn't
                                    if ((FeatureV[vStart] != -1) && (FeatureV[vEnd] == -1))
                                    {
                                        Collapse_option = 2;
                                    }
                                    // if end is on a feature and start isn't
                                    if ((FeatureV[vStart] == -1) && (FeatureV[vEnd] != -1))
                                    {
                                        Collapse_option = 3;
                                    }
                                }
                                else // so one end must be an anchor
                                {
                                    // if start is an anchor
                                    if (AnchorV[vStart] != -1)
                                    {
                                        // if both are on same feature, or if the end is not a feature
                                        if ((FeatureE[i] != -1) || (FeatureV[vEnd] == -1))
                                        {
                                            Collapse_option = 2;
                                        }
                                    }
                                    // if end is an anchor
                                    if (AnchorV[vEnd] != -1)
                                    {
                                        // if both are on same feature, or if the start is not a feature
                                        if ((FeatureE[i] != -1) || (FeatureV[vStart] == -1))
                                        {
                                            Collapse_option = 3;
                                        }
                                    }
                                }

                                double  L2  = L;
                                Point3d Mid = Util.MidPt(P, i);

                                if (CurvDep > 0)
                                {
                                    double NormDiff = Vector3d.VectorAngle(Normals[vStart], Normals[vEnd]);
                                    L2 = Math.Min((1.0 / (3.0 * NormDiff) * L), 5 * L);

                                    if (CurvDep != 1)
                                    {
                                        L2 = L2 * (CurvDep) + L * (1.0 - CurvDep);
                                    }
                                }

                                //if (BoundScale != 1.0)
                                //{
                                //    double MinDist = 99954;

                                //    for (int j = 0; j < FC.Count; j++)
                                //    {
                                //        double param = new double();

                                //        FC[j].ClosestPoint(Mid, out param);
                                //        double ThisDist = Mid.DistanceTo(FC[j].PointAt(param));
                                //        if (ThisDist < MinDist)
                                //        { MinDist = ThisDist; }
                                //    }

                                //    if (MinDist < BoundDist)
                                //    {
                                //        L2 = L2 * BoundScale + (MinDist / BoundDist) * (L2 * (1 - BoundScale));
                                //    }
                                //}

                                //if (SizP.Count > 0)
                                //{
                                //    L2 = WeightedCombo(Mid, SizP, SizV, WExp, L2, BGW);
                                //    //double WL = WeightedCombo(Mid, SizP, SizV, WExp);
                                //    //L2 = (WL * (1.0 - BGW)) + (BGW * L2);
                                //}

                                if ((Collapse_option != 0) && (EdgeLength[2 * i] < (1 - t) * 4f / 5f * L2))
                                {
                                    int Collapsed   = -1;
                                    int CollapseRtn = -1;
                                    if (Collapse_option == 1)
                                    {
                                        Collapsed = P.Halfedges[2 * i].StartVertex;
                                        P.Vertices.SetVertex(Collapsed, Util.MidPt(P, i));
                                        CollapseRtn = P.Halfedges.CollapseEdge(2 * i);
                                    }
                                    if (Collapse_option == 2)
                                    {
                                        Collapsed   = P.Halfedges[2 * i].StartVertex;
                                        CollapseRtn = P.Halfedges.CollapseEdge(2 * i);
                                    }
                                    if (Collapse_option == 3)
                                    {
                                        Collapsed   = P.Halfedges[2 * i + 1].StartVertex;
                                        CollapseRtn = P.Halfedges.CollapseEdge(2 * i + 1);
                                    }
                                    if (CollapseRtn != -1)
                                    {
                                        int[] Neighbours = P.Vertices.GetVertexNeighbours(Collapsed);
                                        foreach (int n in Neighbours)
                                        {
                                            Visited[n] = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                }

                EdgeCount = P.Halfedges.Count / 2;

                if ((Flip == 0) && (PullStrength > 0))
                {
                    //Flip edges to reduce valence error
                    for (int i = 0; i < EdgeCount; i++)
                    {
                        if (!P.Halfedges[2 * i].IsUnused &&
                            (P.Halfedges[2 * i].AdjacentFace != -1) &&
                            (P.Halfedges[2 * i + 1].AdjacentFace != -1) &&
                            (FeatureE[i] == -1)   // don't flip feature edges
                            )
                        {
                            int Vert1 = P.Halfedges[2 * i].StartVertex;
                            int Vert2 = P.Halfedges[2 * i + 1].StartVertex;
                            int Vert3 = P.Halfedges[P.Halfedges[P.Halfedges[2 * i].NextHalfedge].NextHalfedge].StartVertex;
                            int Vert4 = P.Halfedges[P.Halfedges[P.Halfedges[2 * i + 1].NextHalfedge].NextHalfedge].StartVertex;

                            int Valence1 = P.Vertices.GetValence(Vert1);
                            int Valence2 = P.Vertices.GetValence(Vert2);
                            int Valence3 = P.Vertices.GetValence(Vert3);
                            int Valence4 = P.Vertices.GetValence(Vert4);

                            if (P.Vertices.NakedEdgeCount(Vert1) > 0)
                            {
                                Valence1 += 2;
                            }
                            if (P.Vertices.NakedEdgeCount(Vert2) > 0)
                            {
                                Valence2 += 2;
                            }
                            if (P.Vertices.NakedEdgeCount(Vert3) > 0)
                            {
                                Valence3 += 2;
                            }
                            if (P.Vertices.NakedEdgeCount(Vert4) > 0)
                            {
                                Valence4 += 2;
                            }

                            int CurrentError =
                                Math.Abs(Valence1 - 6) +
                                Math.Abs(Valence2 - 6) +
                                Math.Abs(Valence3 - 6) +
                                Math.Abs(Valence4 - 6);
                            int FlippedError =
                                Math.Abs(Valence1 - 7) +
                                Math.Abs(Valence2 - 7) +
                                Math.Abs(Valence3 - 5) +
                                Math.Abs(Valence4 - 5);
                            if (CurrentError > FlippedError)
                            {
                                P.Halfedges.FlipEdge(2 * i);
                            }
                        }
                    }
                }
                else
                {
                    //Flip edges based on angle
                    for (int i = 0; i < EdgeCount; i++)
                    {
                        if (!P.Halfedges[2 * i].IsUnused &&
                            (P.Halfedges[2 * i].AdjacentFace != -1) &&
                            (P.Halfedges[2 * i + 1].AdjacentFace != -1) &&
                            (FeatureE[i] == -1)  // don't flip feature edges
                            )
                        {
                            int Vert1 = P.Halfedges[2 * i].StartVertex;
                            int Vert2 = P.Halfedges[2 * i + 1].StartVertex;
                            int Vert3 = P.Halfedges[P.Halfedges[P.Halfedges[2 * i].NextHalfedge].NextHalfedge].StartVertex;
                            int Vert4 = P.Halfedges[P.Halfedges[P.Halfedges[2 * i + 1].NextHalfedge].NextHalfedge].StartVertex;

                            Point3d P1 = P.Vertices[Vert1].ToPoint3d();
                            Point3d P2 = P.Vertices[Vert2].ToPoint3d();
                            Point3d P3 = P.Vertices[Vert3].ToPoint3d();
                            Point3d P4 = P.Vertices[Vert4].ToPoint3d();

                            double A1 = Vector3d.VectorAngle(new Vector3d(P3 - P1), new Vector3d(P4 - P1))
                                        + Vector3d.VectorAngle(new Vector3d(P4 - P2), new Vector3d(P3 - P2));

                            double A2 = Vector3d.VectorAngle(new Vector3d(P1 - P4), new Vector3d(P2 - P4))
                                        + Vector3d.VectorAngle(new Vector3d(P2 - P3), new Vector3d(P1 - P3));

                            if (A2 > A1)
                            {
                                P.Halfedges.FlipEdge(2 * i);
                            }
                        }
                    }
                }

                //if (Minim)
                //{
                //    Vector3d[] SmoothC = LaplacianSmooth(P, 1, smooth);

                //    for (int i = 0; i < P.Vertices.Count; i++)
                //    {
                //        if (AnchorV[i] == -1) // don't smooth feature vertices
                //        {
                //            P.Vertices.MoveVertex(i, 0.5 * SmoothC[i]);
                //        }
                //    }
                //}

                Vector3d[] Smooth = Util.LaplacianSmooth(P, 0, smooth);

                for (int i = 0; i < P.Vertices.Count; i++)
                {
                    if (AnchorV[i] == -1) // don't smooth feature vertices
                    {
                        // make it tangential only
                        Vector3d VNormal    = Util.Normal(P, i);
                        double   ProjLength = Smooth[i] * VNormal;
                        Smooth[i] = Smooth[i] - (VNormal * ProjLength);

                        P.Vertices.MoveVertex(i, Smooth[i]);

                        if (P.Vertices.NakedEdgeCount(i) != 0)//special smoothing for feature edges
                        {
                            int[]   Neighbours = P.Vertices.GetVertexNeighbours(i);
                            int     ncount     = 0;
                            Point3d Avg        = new Point3d();

                            for (int j = 0; j < Neighbours.Length; j++)
                            {
                                if (P.Vertices.NakedEdgeCount(Neighbours[j]) != 0)
                                {
                                    ncount++;
                                    Avg = Avg + P.Vertices[Neighbours[j]].ToPoint3d();
                                }
                            }
                            Avg = Avg * (1.0 / ncount);
                            Vector3d move = Avg - P.Vertices[i].ToPoint3d();
                            move = move * smooth;
                            P.Vertices.MoveVertex(i, move);
                        }

                        if (FeatureV[i] != -1)//special smoothing for feature edges
                        {
                            int[]   Neighbours = P.Vertices.GetVertexNeighbours(i);
                            int     ncount     = 0;
                            Point3d Avg        = new Point3d();

                            for (int j = 0; j < Neighbours.Length; j++)
                            {
                                if ((FeatureV[Neighbours[j]] == FeatureV[i]) || (AnchorV[Neighbours[j]] != -1))
                                {
                                    ncount++;
                                    Avg = Avg + P.Vertices[Neighbours[j]].ToPoint3d();
                                }
                            }
                            Avg = Avg * (1.0 / ncount);
                            Vector3d move = Avg - P.Vertices[i].ToPoint3d();
                            move = move * smooth;
                            P.Vertices.MoveVertex(i, move);
                        }

                        //projecting points onto the target along their normals

                        if (pull > 0)
                        {
                            Point3d  Point  = P.Vertices[i].ToPoint3d();
                            Vector3d normal = Util.Normal(P, i);
                            Ray3d    Ray1   = new Ray3d(Point, normal);
                            Ray3d    Ray2   = new Ray3d(Point, -normal);
                            double   RayPt1 = Rhino.Geometry.Intersect.Intersection.MeshRay(M, Ray1);
                            double   RayPt2 = Rhino.Geometry.Intersect.Intersection.MeshRay(M, Ray2);
                            Point3d  ProjectedPt;

                            if ((RayPt1 < RayPt2) && (RayPt1 > 0) && (RayPt1 < 1.0))
                            {
                                ProjectedPt = Point * (1 - pull) + pull * Ray1.PointAt(RayPt1);
                            }
                            else if ((RayPt2 < RayPt1) && (RayPt2 > 0) && (RayPt2 < 1.0))
                            {
                                ProjectedPt = Point * (1 - pull) + pull * Ray2.PointAt(RayPt2);
                            }
                            else
                            {
                                ProjectedPt = Point * (1 - pull) + pull * M.ClosestPoint(Point);
                            }

                            P.Vertices.SetVertex(i, ProjectedPt);
                        }


                        if (FeatureV[i] != -1) //pull feature vertices onto feature curves
                        {
                            Point3d Point     = P.Vertices[i].ToPoint3d();
                            Curve   CF        = FC[FeatureV[i]];
                            double  param1    = 0.0;
                            Point3d onFeature = new Point3d();
                            CF.ClosestPoint(Point, out param1);
                            onFeature = CF.PointAt(param1);
                            P.Vertices.SetVertex(i, onFeature);
                        }
                    }
                    else
                    {
                        P.Vertices.SetVertex(i, FV[AnchorV[i]]); //pull anchor vertices onto their points
                    }
                }



                AnchorV  = Util.CompactByVertex(P, AnchorV); //compact the fixed points along with the vertices
                FeatureV = Util.CompactByVertex(P, FeatureV);
                FeatureE = Util.CompactByEdge(P, FeatureE);

                P.Compact(); //this cleans the mesh data structure of unused elements
            }


            Mesh MR = P.ToRhinoMesh();

            MR.Unweld(0.4, true);

            doc.Objects.AddMesh(MR);

            doc.Views.Redraw();
            RhinoApp.WriteLine("The {0} command added one mesh to the document.", EnglishName);

            // ---

            return(Result.Success);
        }
示例#30
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)
        {
            List <Plane> camPlanes = new List <Plane>();

            DA.GetDataList <Plane>(0, camPlanes);

            string folder = string.Empty;

            DA.GetData <string>(1, ref folder);
            bool saveCubemaps = !string.IsNullOrEmpty(folder);

            if (saveCubemaps)
            {
                folder = Path.GetFullPath(folder);
                if (!folder.EndsWith(Path.DirectorySeparatorChar.ToString()))
                {
                    folder += Path.DirectorySeparatorChar;
                }
            }

            string prefix = string.Empty;

            DA.GetData <string>(2, ref prefix);

            int imageWidth = 0;

            DA.GetData <int>(3, ref imageWidth);
            imageWidth = imageWidth / 4;
            Size size = new Size(imageWidth, imageWidth);

            string displayMode = string.Empty;

            DA.GetData <string>(4, ref displayMode);

            List <Color> colors = new List <Color>();

            DA.GetDataList <Color>(5, colors);
            bool filterColors = colors.Any();

            GH_Structure <GH_Mesh> ghObstacles = new GH_Structure <GH_Mesh>();

            DA.GetDataTree <GH_Mesh>(6, out ghObstacles);

            ///Flatten obstacle meshes and join them into one mesh
            ghObstacles.FlattenData();
            Mesh obstacles = new Mesh();
            bool showRays  = false;

            if (ghObstacles.DataCount > 0)
            {
                showRays = true;
                foreach (var obstacle in ghObstacles)
                {
                    Mesh temp = new Mesh();
                    GH_Convert.ToMesh(obstacle, ref temp, GH_Conversion.Primary);
                    obstacles.Append(temp);
                }
            }


            bool run = false;

            DA.GetData <bool>(7, ref run);

            int pad = camPlanes.Count.ToString().Length;

            List <string> cubemaps = new List <string>();

            GH_Structure <GH_Line>   rayTree   = new GH_Structure <GH_Line>();
            GH_Structure <GH_Colour> colorTree = new GH_Structure <GH_Colour>();

            ///Save the intial camera
            saveCam = camFromVP(Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.ActiveViewport);

            ///Set the display mode to be used for bitmaps
            ///TODO: Add menu item to use "Heron View Analysis" display mode
            DisplayModeDescription viewMode = Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.ActiveViewport.DisplayMode;

            if (DisplayModeDescription.FindByName(displayMode) != null)
            {
                viewMode = DisplayModeDescription.FindByName(displayMode);
            }

            Message = viewMode.EnglishName;

            if (run)
            {
                for (int i = 0; i < camPlanes.Count; i++)
                {
                    ///TODO: setup ability to save cameras to the Rhino doc
                    ///Setup camera
                    Rhino.Display.RhinoView     view = Rhino.RhinoDoc.ActiveDoc.Views.ActiveView;
                    Rhino.Display.RhinoViewport vp   = view.ActiveViewport;

                    ///Get the bounding box of all visible object in the doc for use in setting up the camera
                    ///target so that the far frustrum plane doesn't clip anything
                    double zoomDistance = Rhino.RhinoDoc.ActiveDoc.Objects.BoundingBoxVisible.Diagonal.Length;

                    Plane    camPlane = camPlanes[i];
                    Point3d  camPoint = camPlane.Origin;
                    Vector3d camDir   = camPlane.YAxis;
                    Point3d  tarPoint = Transform.Translation(camDir * zoomDistance / 2) * camPoint;


                    vp.ChangeToPerspectiveProjection(false, 12.0);
                    vp.Size        = size;
                    vp.DisplayMode = viewMode;
                    //view.Redraw();

                    ///Set up final bitmap
                    Bitmap cubemap = new Bitmap(imageWidth * 4, imageWidth * 3);

                    ///Place the images on cubemap bitmap
                    using (Graphics gr = Graphics.FromImage(cubemap))
                    {
                        ///Grab bitmap

                        ///Set up camera directions
                        Point3d        tarLeft    = Transform.Translation(-camPlane.XAxis * zoomDistance / 2) * camPoint;
                        Point3d        tarFront   = Transform.Translation(camPlane.YAxis * zoomDistance / 2) * camPoint;
                        Point3d        tarRight   = Transform.Translation(camPlane.XAxis * zoomDistance / 2) * camPoint;
                        Point3d        tarBack    = Transform.Translation(-camPlane.YAxis * zoomDistance / 2) * camPoint;
                        Point3d        tarUp      = Transform.Translation(camPlane.ZAxis * zoomDistance / 2) * camPoint;
                        Point3d        tarDown    = Transform.Translation(-camPlane.ZAxis * zoomDistance / 2) * camPoint;
                        List <Point3d> camTargets = new List <Point3d>()
                        {
                            tarLeft, tarFront, tarRight, tarBack, tarUp, tarDown
                        };

                        ///Loop through pano directions
                        int insertLoc = 0;
                        for (int d = 0; d < 4; d++)
                        {
                            ///Set camera direction
                            vp.SetCameraLocations(camTargets[d], camPoint);
                            //view.Redraw();

                            Bitmap bitmap = new Bitmap(view.CaptureToBitmap(size, viewMode));

                            if (saveCubemaps)
                            {
                                gr.DrawImage(bitmap, insertLoc, imageWidth);
                            }

                            if (showRays)
                            {
                                GH_MemoryBitmap sampler = new GH_MemoryBitmap(bitmap);
                                Color           col     = Color.Transparent;
                                for (int x = 0; x < bitmap.Width; x++)
                                {
                                    for (int y = 0; y < bitmap.Height; y++)
                                    {
                                        if (sampler.Sample(x, y, ref col))
                                        {
                                            if (colors.Contains(col))
                                            {
                                                GH_Path path = new GH_Path(i, colors.IndexOf(col));

                                                Line line = vp.ClientToWorld(new System.Drawing.Point(x, y));

                                                Ray3d   ray             = new Ray3d(vp.CameraLocation, -line.Direction);
                                                double  rayEnd          = (double)Rhino.Geometry.Intersect.Intersection.MeshRay(obstacles, ray);
                                                Point3d rayIntersection = ray.PointAt(rayEnd);
                                                Line    ln = new Line(camPoint, rayIntersection);

                                                if (ln.IsValid & rayEnd > 0)
                                                {
                                                    rayTree.Append(new GH_Line(ln), path);
                                                    colorTree.Append(new GH_Colour(col), path);
                                                }
                                            }
                                            else if (!filterColors)
                                            {
                                                colors.Add(col);
                                                GH_Path path = new GH_Path(i, colors.IndexOf(col));

                                                Line line = vp.ClientToWorld(new System.Drawing.Point(x, y));

                                                Ray3d   ray             = new Ray3d(vp.CameraLocation, -line.Direction);
                                                double  rayEnd          = (double)Rhino.Geometry.Intersect.Intersection.MeshRay(obstacles, ray);
                                                Point3d rayIntersection = ray.PointAt(rayEnd);
                                                Line    ln = new Line(camPoint, rayIntersection);

                                                if (ln.IsValid & rayEnd > 0)
                                                {
                                                    rayTree.Append(new GH_Line(ln), path);
                                                    colorTree.Append(new GH_Colour(col), path);
                                                }
                                            }
                                        }
                                    }
                                }
                                sampler.Release(false);
                            }

                            insertLoc = insertLoc + imageWidth;

                            bitmap.Dispose();
                        }


                        ///Get up and down views

                        ///Get up view
                        vp.SetCameraLocations(tarUp, camPoint);
                        view.Redraw();

                        Bitmap bitmapUp = new Bitmap(view.CaptureToBitmap(size, viewMode));

                        if (showRays)
                        {
                            GH_MemoryBitmap sampler = new GH_MemoryBitmap(bitmapUp);
                            Color           col     = Color.Transparent;
                            for (int x = 0; x < bitmapUp.Width; x++)
                            {
                                for (int y = 0; y < bitmapUp.Height; y++)
                                {
                                    if (sampler.Sample(x, y, ref col))
                                    {
                                        if (colors.Contains(col))
                                        {
                                            GH_Path path = new GH_Path(i, colors.IndexOf(col));

                                            Line line = vp.ClientToWorld(new System.Drawing.Point(x, y));

                                            Ray3d   ray             = new Ray3d(vp.CameraLocation, -line.Direction);
                                            double  rayEnd          = (double)Rhino.Geometry.Intersect.Intersection.MeshRay(obstacles, ray);
                                            Point3d rayIntersection = ray.PointAt(rayEnd);
                                            Line    ln = new Line(camPoint, rayIntersection);

                                            if (ln.IsValid & rayEnd > 0)
                                            {
                                                rayTree.Append(new GH_Line(ln), path);
                                                colorTree.Append(new GH_Colour(col), path);
                                            }
                                        }
                                        else if (!filterColors)
                                        {
                                            colors.Add(col);
                                            GH_Path path = new GH_Path(i, colors.IndexOf(col));

                                            Line line = vp.ClientToWorld(new System.Drawing.Point(x, y));

                                            Ray3d   ray             = new Ray3d(vp.CameraLocation, -line.Direction);
                                            double  rayEnd          = (double)Rhino.Geometry.Intersect.Intersection.MeshRay(obstacles, ray);
                                            Point3d rayIntersection = ray.PointAt(rayEnd);
                                            Line    ln = new Line(camPoint, rayIntersection);

                                            if (ln.IsValid & rayEnd > 0)
                                            {
                                                rayTree.Append(new GH_Line(ln), path);
                                                colorTree.Append(new GH_Colour(col), path);
                                            }
                                        }
                                    }
                                }
                            }
                            sampler.Release(false);
                        }

                        bitmapUp.RotateFlip(RotateFlipType.Rotate180FlipNone);
                        if (saveCubemaps)
                        {
                            gr.DrawImage(bitmapUp, imageWidth, 0);
                        }

                        bitmapUp.Dispose();


                        ///Get down view
                        vp.SetCameraLocations(tarDown, camPoint);
                        view.Redraw();

                        Bitmap bitmapDown = new Bitmap(view.CaptureToBitmap(size, viewMode));

                        if (saveCubemaps)
                        {
                            gr.DrawImage(bitmapDown, imageWidth, imageWidth * 2);
                        }

                        if (showRays)
                        {
                            GH_MemoryBitmap sampler = new GH_MemoryBitmap(bitmapDown);
                            Color           col     = Color.Transparent;
                            for (int x = 0; x < bitmapDown.Width; x++)
                            {
                                for (int y = 0; y < bitmapDown.Height; y++)
                                {
                                    if (sampler.Sample(x, y, ref col))
                                    {
                                        if (colors.Contains(col))
                                        {
                                            GH_Path path = new GH_Path(i, colors.IndexOf(col));

                                            Line line = vp.ClientToWorld(new System.Drawing.Point(x, y));

                                            Ray3d   ray             = new Ray3d(vp.CameraLocation, -line.Direction);
                                            double  rayEnd          = (double)Rhino.Geometry.Intersect.Intersection.MeshRay(obstacles, ray);
                                            Point3d rayIntersection = ray.PointAt(rayEnd);
                                            Line    ln = new Line(camPoint, rayIntersection);

                                            if (ln.IsValid & rayEnd > 0)
                                            {
                                                rayTree.Append(new GH_Line(ln), path);
                                                colorTree.Append(new GH_Colour(col), path);
                                            }
                                        }

                                        else if (!filterColors)
                                        {
                                            colors.Add(col);
                                            GH_Path path = new GH_Path(i, colors.IndexOf(col));

                                            Line line = vp.ClientToWorld(new System.Drawing.Point(x, y));

                                            Ray3d   ray             = new Ray3d(vp.CameraLocation, -line.Direction);
                                            double  rayEnd          = (double)Rhino.Geometry.Intersect.Intersection.MeshRay(obstacles, ray);
                                            Point3d rayIntersection = ray.PointAt(rayEnd);
                                            Line    ln = new Line(camPoint, rayIntersection);

                                            if (ln.IsValid & rayEnd > 0)
                                            {
                                                rayTree.Append(new GH_Line(ln), path);
                                                colorTree.Append(new GH_Colour(col), path);
                                            }
                                        }
                                    }
                                }
                            }
                            sampler.Release(false);
                        }

                        bitmapDown.Dispose();
                    }
                    ///End pano directions loop

                    if (saveCubemaps)
                    {
                        ///Save cubemap bitmap
                        string s        = i.ToString().PadLeft(pad, '0');
                        string saveText = folder + prefix + "_" + s + ".png";
                        cubemap.Save(saveText, System.Drawing.Imaging.ImageFormat.Png);
                        cubemaps.Add(saveText);
                    }
                    cubemap.Dispose();
                }
            }

            ///Restore initial camera
            setCamera(saveCam, Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.ActiveViewport);
            Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.Redraw();

            DA.SetDataList(0, cubemaps);
            DA.SetDataTree(1, rayTree);
            DA.SetDataTree(2, colorTree);
        }
示例#31
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            //Script to discretize a topography-mesh into cubes for the FFD solver
            //  2016-09-07  Christoph Waibel
            //



            //input:
            //  x,y,z grid size
            //  x,y,z cell numbers
            //  origin point (all calculations use this as reference)
            //  mesh geometry
            List <double> xyzsize = new List <double>();

            if (!DA.GetDataList(0, xyzsize))
            {
                return;
            }
            ;
            List <int> xyzcells = new List <int>();

            if (!DA.GetDataList(1, xyzcells))
            {
                return;
            }
            ;
            List <Mesh> meshs = new List <Mesh>();

            if (!DA.GetDataList(2, meshs))
            {
                return;
            }
            Point3d origin = Point3d.Unset;

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

            double tolerance = 0.01;

            //output:
            //  list of cubes (as double [6]{xmin, xmax, ymin, ymax, zmin, zmax})

            //1. create list of points on grid cells 0-point
            List <Point3d> pts       = new List <Point3d>();
            double         xcelldist = xyzsize[0] / xyzcells[0];
            double         ycelldist = xyzsize[1] / xyzcells[1];
            double         zcelldist = xyzsize[2] / xyzcells[2];

            for (int x = 0; x < xyzcells[0]; x++)
            {
                for (int y = 0; y < xyzcells[1]; y++)
                {
                    pts.Add(new Point3d((x + 0.5) * xcelldist + origin[0], (y + 0.5) * ycelldist + origin[1], origin[2]));
                }
            }

            Vector3d vec = new Vector3d(0, 0, 1);
            //foreach grid cell
            List <Box>      box   = new List <Box>();
            List <double[]> cubes = new List <double[]>();

            foreach (Point3d pt in pts)
            {
                foreach (Mesh mesh in meshs)
                {
                    //2. shoot rays straight up (from z-origin to zmax)
                    //Ray3d ray = new Ray3d(new Point3d(pt[0] + 0.5 * (double)xcelldist, pt[1] + 0.5 * (double)ycelldist, pt[2]), vec);
                    Ray3d ray = new Ray3d(new Point3d(pt[0], pt[1], pt[2]), vec);
                    //3. check for intersections with mesh
                    Point3d ptX1      = new Point3d(pt[0], pt[1], pt[2]);
                    bool    blninters = false;
                    double  inters1   = Rhino.Geometry.Intersect.Intersection.MeshRay(mesh, ray);


                    if (inters1 > 0)
                    {
                        Point3d ptat1 = ray.PointAt(inters1);
                        ray = new Ray3d(new Point3d(ptat1[0], ptat1[1], ptat1[2] + tolerance), vec);

                        //flatten point to the next/previous grid step
                        ptat1 = new Point3d(ptat1.X, ptat1.Y, Math.Round((ptat1[2] - origin[2]) / zcelldist, 0) * zcelldist + origin[2]);

                        double inters2 = Rhino.Geometry.Intersect.Intersection.MeshRay(mesh, ray);
                        if (inters2 > 0)
                        {
                            Point3d ptat2 = ray.PointAt(inters2);
                            blninters = true;
                            //repeat until there are no other intersections anymore
                            while (blninters == true)
                            {
                                //5. create cube with xmin xmax ymin ymax zmin (all already known), and zmax (calculated with mesh intersection)
                                //      rounding the intersection-z-value to match the grid-z-values
                                Point3d ptmax = new Point3d(ptat1[0] + 0.5 * xcelldist, ptat1[1] + 0.5 * ycelldist, Math.Round((ptat2[2] - origin[2]) / zcelldist, 0) * zcelldist + origin[2]);
                                box.Add(new Box(new BoundingBox(new Point3d(ptat1[0] - 0.5 * xcelldist, ptat1 [1] - 0.5 * ycelldist, ptat1[2]), ptmax)));
                                cubes.Add(new double[] { ptat1[0] - origin[0] - 0.5 * xcelldist, ptmax[0] - origin[0], ptat1[1] - origin[1] - 0.5 * ycelldist, ptmax[1] - origin[1], ptat1[2] - origin[2], ptmax[2] - origin[2] });

                                //check another intersection couple  */------/*
                                ptat1   = new Point3d(ptat2[0], ptat2[1], ptat2[2] + tolerance);
                                ray     = new Ray3d(ptat1, vec);
                                inters1 = Rhino.Geometry.Intersect.Intersection.MeshRay(mesh, ray);
                                if (inters1 > 0)
                                {
                                    ptat1   = ray.PointAt(inters1);
                                    ray     = new Ray3d(new Point3d(ptat1[0], ptat1[1], ptat1[2] + tolerance), vec);
                                    inters2 = Rhino.Geometry.Intersect.Intersection.MeshRay(mesh, ray);
                                    if (inters2 > 0)
                                    {
                                        ptat2 = ray.PointAt(inters2);
                                    }
                                    else
                                    {
                                        blninters = false;
                                    }
                                }
                                else
                                {
                                    blninters = false;
                                }
                            }
                        }
                    }
                }
            }



            DA.SetDataList(0, box);
            DA.SetDataList(1, cubes);
        }
示例#32
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object can be used to retrieve data from input parameters and
        /// to store data in output parameters.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            ITargetLength  TargetLength   = null;
            bool           reset          = false;
            int            Flip           = 0;
            List <Curve>   FC             = new List <Curve>();
            List <Point3d> FV             = new List <Point3d>();
            double         FixT           = 0.01;
            double         PullStrength   = 0.8;
            double         SmoothStrength = 0.8;
            double         LengthTol      = 0.15;
            bool           Minim          = false;
            int            Iters          = 1;

            GH_ObjectWrapper Surf = new GH_ObjectWrapper();

            DA.GetData <GH_ObjectWrapper>(0, ref Surf);

            GH_ObjectWrapper Obj = null;

            DA.GetData <GH_ObjectWrapper>(1, ref Obj);
            TargetLength = Obj.Value as ITargetLength;

            DA.GetDataList <Curve>(2, FC);
            DA.GetDataList <Point3d>(3, FV);
            DA.GetData <int>(4, ref Flip);

            DA.GetData <double>(5, ref PullStrength);

            DA.GetData <int>(6, ref Iters);
            DA.GetData <bool>(7, ref reset);


            if (PullStrength == 0)
            {
                Minim = true;
            }

            if (Surf.Value is GH_Mesh)
            {
                DA.GetData <Mesh>(0, ref M);
                M.Faces.ConvertQuadsToTriangles();
            }
            else
            {
                double            L          = 1.0;
                MeshingParameters MeshParams = new MeshingParameters();
                MeshParams.MaximumEdgeLength = 3 * L;
                MeshParams.MinimumEdgeLength = L;
                MeshParams.JaggedSeams       = false;
                MeshParams.SimplePlanes      = false;
                Brep SB = null;
                DA.GetData <Brep>(0, ref SB);
                Mesh[] BrepMeshes = Mesh.CreateFromBrep(SB, MeshParams);
                M = new Mesh();
                foreach (var mesh in BrepMeshes)
                {
                    M.Append(mesh);
                }
            }

            if (reset || initialized == false)
            {
                #region reset
                M.Faces.ConvertQuadsToTriangles();
                P = M.ToPlanktonMesh();

                initialized = true;

                AnchorV.Clear();
                FeatureV.Clear();
                FeatureE.Clear();

                //Mark any vertices or edges lying on features
                for (int i = 0; i < P.Vertices.Count; i++)
                {
                    Point3d Pt = P.Vertices[i].ToPoint3d();
                    AnchorV.Add(-1);
                    for (int j = 0; j < FV.Count; j++)
                    {
                        if (Pt.DistanceTo(FV[j]) < FixT)
                        {
                            AnchorV[AnchorV.Count - 1] = j;
                        }
                    }

                    FeatureV.Add(-1);
                    for (int j = 0; j < FC.Count; j++)
                    {
                        double param = new double();
                        FC[j].ClosestPoint(Pt, out param);
                        if (Pt.DistanceTo(FC[j].PointAt(param)) < FixT)
                        {
                            FeatureV[FeatureV.Count - 1] = j;
                        }
                    }
                }
                //
                int EdgeCount = P.Halfedges.Count / 2;
                for (int i = 0; i < EdgeCount; i++)
                {
                    FeatureE.Add(-1);
                    //同一条线分为两条线编号分别为2i和2i+1,朝向相对,两个的起始点为
                    int vStart = P.Halfedges[2 * i].StartVertex;
                    int vEnd   = P.Halfedges[2 * i + 1].StartVertex;

                    Point3d PStart = P.Vertices[vStart].ToPoint3d();
                    Point3d PEnd   = P.Vertices[vEnd].ToPoint3d();

                    for (int j = 0; j < FC.Count; j++)
                    {
                        double paramS = new double();
                        double paramE = new double();
                        Curve  thisFC = FC[j];
                        thisFC.ClosestPoint(PStart, out paramS);
                        thisFC.ClosestPoint(PEnd, out paramE);
                        if ((PStart.DistanceTo(thisFC.PointAt(paramS)) < FixT) &&
                            (PEnd.DistanceTo(thisFC.PointAt(paramE)) < FixT))
                        {
                            FeatureE[FeatureE.Count - 1] = j;
                        }
                    }
                }
                #endregion
            }

            else
            {
                for (int iter = 0; iter < Iters; iter++)
                {
                    int         EdgeCount  = P.Halfedges.Count / 2;
                    double[]    EdgeLength = P.Halfedges.GetLengths();
                    List <bool> Visited    = new List <bool>();
                    Vector3d[]  Normals    = new Vector3d[P.Vertices.Count];

                    for (int i = 0; i < P.Vertices.Count; i++)
                    {
                        Visited.Add(false);
                        Normals[i] = Normal(P, i);
                    }

                    double t      = LengthTol;      //a tolerance for when to split/collapse edges
                    double smooth = SmoothStrength; //smoothing strength
                    double pull   = PullStrength;   //pull to target mesh strength

                    // Split the edges that are too long
                    for (int i = 0; i < EdgeCount; i++)
                    {
                        if (P.Halfedges[2 * i].IsUnused == false)
                        {
                            int vStart = P.Halfedges[2 * i].StartVertex;
                            int vEnd   = P.Halfedges[2 * i + 1].StartVertex;

                            if ((Visited[vStart] == false) &&
                                (Visited[vEnd] == false))
                            {
                                double L2 = TargetLength.Calculate(P, 2 * i);

                                if (EdgeLength[2 * i] > (1 + t) * (4f / 3f) * L2)
                                {
                                    int SplitHEdge = P.Halfedges.TriangleSplitEdge(2 * i);
                                    if (SplitHEdge != -1)
                                    {
                                        int SplitCenter = P.Halfedges[SplitHEdge].StartVertex;
                                        P.Vertices.SetVertex(SplitCenter, MidPt(P, i));

                                        //update the feature information
                                        FeatureE.Add(FeatureE[i]);
                                        FeatureV.Add(FeatureE[i]);
                                        AnchorV.Add(-1);

                                        //2 additional new edges have also been created (or 1 if split was on a boundary)
                                        //mark these as non-features
                                        int CEdgeCount = P.Halfedges.Count / 2;
                                        while (FeatureE.Count < CEdgeCount)
                                        {
                                            FeatureE.Add(-1);
                                        }

                                        Visited.Add(true);
                                        int[] Neighbours = P.Vertices.GetVertexNeighbours(SplitCenter);
                                        foreach (int n in Neighbours)
                                        {
                                            Visited[n] = true;
                                        }
                                    }
                                }
                            }
                        }
                    }

                    //Collapse the edges that are too short
                    for (int i = 0; i < EdgeCount; i++)
                    {
                        if (P.Halfedges[2 * i].IsUnused == false)
                        {
                            int vStart = P.Halfedges[2 * i].StartVertex;
                            int vEnd   = P.Halfedges[2 * i + 1].StartVertex;
                            if ((Visited[vStart] == false) &&
                                (Visited[vEnd] == false))
                            {
                                if (!(AnchorV[vStart] != -1 && AnchorV[vEnd] != -1)) // if both ends are anchored, don't collapse
                                {
                                    int Collapse_option = 0;                         //0 for none, 1 for collapse to midpt, 2 for towards start, 3 for towards end
                                    //if neither are anchorV
                                    if (AnchorV[vStart] == -1 && AnchorV[vEnd] == -1)
                                    {
                                        // if both on same feature (or neither on a feature)
                                        if (FeatureV[vStart] == FeatureV[vEnd])
                                        {
                                            Collapse_option = 1;
                                        }
                                        // if start is on a feature and end isn't
                                        if ((FeatureV[vStart] != -1) && (FeatureV[vEnd] == -1))
                                        {
                                            Collapse_option = 2;
                                        }
                                        // if end is on a feature and start isn't
                                        if ((FeatureV[vStart] == -1) && (FeatureV[vEnd] != -1))
                                        {
                                            Collapse_option = 3;
                                        }
                                    }
                                    else // so one end must be an anchor
                                    {
                                        // if start is an anchor
                                        if (AnchorV[vStart] != -1)
                                        {
                                            // if both are on same feature, or if the end is not a feature
                                            if ((FeatureE[i] != -1) || (FeatureV[vEnd] == -1))
                                            {
                                                Collapse_option = 2;
                                            }
                                        }
                                        // if end is an anchor
                                        if (AnchorV[vEnd] != -1)
                                        {
                                            // if both are on same feature, or if the start is not a feature
                                            if ((FeatureE[i] != -1) || (FeatureV[vStart] == -1))
                                            {
                                                Collapse_option = 3;
                                            }
                                        }
                                    }

                                    Point3d Mid = MidPt(P, i);


                                    double L2 = TargetLength.Calculate(P, 2 * i);



                                    if ((Collapse_option != 0) && (EdgeLength[2 * i] < (1 - t) * 4f / 5f * L2))
                                    {
                                        int Collapsed   = -1;
                                        int CollapseRtn = -1;
                                        if (Collapse_option == 1)
                                        {
                                            Collapsed = P.Halfedges[2 * i].StartVertex;
                                            P.Vertices.SetVertex(Collapsed, MidPt(P, i));
                                            CollapseRtn = P.Halfedges.CollapseEdge(2 * i);
                                        }
                                        if (Collapse_option == 2)
                                        {
                                            Collapsed   = P.Halfedges[2 * i].StartVertex;
                                            CollapseRtn = P.Halfedges.CollapseEdge(2 * i);
                                        }
                                        if (Collapse_option == 3)
                                        {
                                            Collapsed   = P.Halfedges[2 * i + 1].StartVertex;
                                            CollapseRtn = P.Halfedges.CollapseEdge(2 * i + 1);
                                        }
                                        if (CollapseRtn != -1)
                                        {
                                            int[] Neighbours = P.Vertices.GetVertexNeighbours(Collapsed);
                                            foreach (int n in Neighbours)
                                            {
                                                Visited[n] = true;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }

                    EdgeCount = P.Halfedges.Count / 2;

                    if ((Flip == 0) && (PullStrength > 0))
                    {
                        //Flip edges to reduce valence error
                        for (int i = 0; i < EdgeCount; i++)
                        {
                            if (!P.Halfedges[2 * i].IsUnused &&
                                (P.Halfedges[2 * i].AdjacentFace != -1) &&
                                (P.Halfedges[2 * i + 1].AdjacentFace != -1) &&
                                (FeatureE[i] == -1)   // don't flip feature edges
                                )
                            {
                                int Vert1 = P.Halfedges[2 * i].StartVertex;
                                int Vert2 = P.Halfedges[2 * i + 1].StartVertex;
                                int Vert3 = P.Halfedges[P.Halfedges[P.Halfedges[2 * i].NextHalfedge].NextHalfedge].StartVertex;
                                int Vert4 = P.Halfedges[P.Halfedges[P.Halfedges[2 * i + 1].NextHalfedge].NextHalfedge].StartVertex;

                                int Valence1 = P.Vertices.GetValence(Vert1);
                                int Valence2 = P.Vertices.GetValence(Vert2);
                                int Valence3 = P.Vertices.GetValence(Vert3);
                                int Valence4 = P.Vertices.GetValence(Vert4);

                                if (P.Vertices.NakedEdgeCount(Vert1) > 0)
                                {
                                    Valence1 += 2;
                                }
                                if (P.Vertices.NakedEdgeCount(Vert2) > 0)
                                {
                                    Valence2 += 2;
                                }
                                if (P.Vertices.NakedEdgeCount(Vert3) > 0)
                                {
                                    Valence3 += 2;
                                }
                                if (P.Vertices.NakedEdgeCount(Vert4) > 0)
                                {
                                    Valence4 += 2;
                                }

                                int CurrentError =
                                    Math.Abs(Valence1 - 6) +
                                    Math.Abs(Valence2 - 6) +
                                    Math.Abs(Valence3 - 6) +
                                    Math.Abs(Valence4 - 6);
                                int FlippedError =
                                    Math.Abs(Valence1 - 7) +
                                    Math.Abs(Valence2 - 7) +
                                    Math.Abs(Valence3 - 5) +
                                    Math.Abs(Valence4 - 5);
                                if (CurrentError > FlippedError)
                                {
                                    P.Halfedges.FlipEdge(2 * i);
                                }
                            }
                        }
                    }
                    else
                    {
                        //Flip edges based on angle
                        for (int i = 0; i < EdgeCount; i++)
                        {
                            if (!P.Halfedges[2 * i].IsUnused &&
                                (P.Halfedges[2 * i].AdjacentFace != -1) &&
                                (P.Halfedges[2 * i + 1].AdjacentFace != -1) &&
                                (FeatureE[i] == -1)  // don't flip feature edges
                                )
                            {
                                int Vert1 = P.Halfedges[2 * i].StartVertex;
                                int Vert2 = P.Halfedges[2 * i + 1].StartVertex;
                                int Vert3 = P.Halfedges[P.Halfedges[P.Halfedges[2 * i].NextHalfedge].NextHalfedge].StartVertex;
                                int Vert4 = P.Halfedges[P.Halfedges[P.Halfedges[2 * i + 1].NextHalfedge].NextHalfedge].StartVertex;

                                Point3d P1 = P.Vertices[Vert1].ToPoint3d();
                                Point3d P2 = P.Vertices[Vert2].ToPoint3d();
                                Point3d P3 = P.Vertices[Vert3].ToPoint3d();
                                Point3d P4 = P.Vertices[Vert4].ToPoint3d();

                                double A1 = Vector3d.VectorAngle(new Vector3d(P3 - P1), new Vector3d(P4 - P1))
                                            + Vector3d.VectorAngle(new Vector3d(P4 - P2), new Vector3d(P3 - P2));

                                double A2 = Vector3d.VectorAngle(new Vector3d(P1 - P4), new Vector3d(P2 - P4))
                                            + Vector3d.VectorAngle(new Vector3d(P2 - P3), new Vector3d(P1 - P3));

                                if (A2 > A1)
                                {
                                    P.Halfedges.FlipEdge(2 * i);
                                }
                            }
                        }
                    }

                    if (Minim)
                    {
                        Vector3d[] SmoothC = LaplacianSmooth(P, 1, smooth);

                        for (int i = 0; i < P.Vertices.Count; i++)
                        {
                            if (AnchorV[i] == -1) // don't smooth feature vertices
                            {
                                P.Vertices.MoveVertex(i, 0.5 * SmoothC[i]);
                            }
                        }
                    }

                    Vector3d[] Smooth = LaplacianSmooth(P, 0, smooth);

                    for (int i = 0; i < P.Vertices.Count; i++)
                    {
                        if (AnchorV[i] == -1) // don't smooth feature vertices
                        {
                            // make it tangential only
                            Vector3d VNormal    = Normal(P, i);
                            double   ProjLength = Smooth[i] * VNormal;
                            Smooth[i] = Smooth[i] - (VNormal * ProjLength);

                            P.Vertices.MoveVertex(i, Smooth[i]);

                            if (P.Vertices.NakedEdgeCount(i) != 0)//special smoothing for feature edges
                            {
                                int[]   Neighbours = P.Vertices.GetVertexNeighbours(i);
                                int     ncount     = 0;
                                Point3d Avg        = new Point3d();

                                for (int j = 0; j < Neighbours.Length; j++)
                                {
                                    if (P.Vertices.NakedEdgeCount(Neighbours[j]) != 0)
                                    {
                                        ncount++;
                                        Avg = Avg + P.Vertices[Neighbours[j]].ToPoint3d();
                                    }
                                }
                                Avg = Avg * (1.0 / ncount);
                                Vector3d move = Avg - P.Vertices[i].ToPoint3d();
                                move = move * smooth;
                                P.Vertices.MoveVertex(i, move);
                            }

                            if (FeatureV[i] != -1)//special smoothing for feature edges
                            {
                                int[]   Neighbours = P.Vertices.GetVertexNeighbours(i);
                                int     ncount     = 0;
                                Point3d Avg        = new Point3d();

                                for (int j = 0; j < Neighbours.Length; j++)
                                {
                                    if ((FeatureV[Neighbours[j]] == FeatureV[i]) || (AnchorV[Neighbours[j]] != -1))
                                    {
                                        ncount++;
                                        Avg = Avg + P.Vertices[Neighbours[j]].ToPoint3d();
                                    }
                                }
                                Avg = Avg * (1.0 / ncount);
                                Vector3d move = Avg - P.Vertices[i].ToPoint3d();
                                move = move * smooth;
                                P.Vertices.MoveVertex(i, move);
                            }

                            //projecting points onto the target along their normals

                            if (pull > 0)
                            {
                                Point3d  Point  = P.Vertices[i].ToPoint3d();
                                Vector3d normal = Normal(P, i);
                                Ray3d    Ray1   = new Ray3d(Point, normal);
                                Ray3d    Ray2   = new Ray3d(Point, -normal);
                                double   RayPt1 = Rhino.Geometry.Intersect.Intersection.MeshRay(M, Ray1);
                                double   RayPt2 = Rhino.Geometry.Intersect.Intersection.MeshRay(M, Ray2);
                                Point3d  ProjectedPt;

                                if ((RayPt1 < RayPt2) && (RayPt1 > 0) && (RayPt1 < 1.0))
                                {
                                    ProjectedPt = Point * (1 - pull) + pull * Ray1.PointAt(RayPt1);
                                }
                                else if ((RayPt2 < RayPt1) && (RayPt2 > 0) && (RayPt2 < 1.0))
                                {
                                    ProjectedPt = Point * (1 - pull) + pull * Ray2.PointAt(RayPt2);
                                }
                                else
                                {
                                    ProjectedPt = Point * (1 - pull) + pull * M.ClosestPoint(Point);
                                }

                                P.Vertices.SetVertex(i, ProjectedPt);
                            }


                            if (FeatureV[i] != -1) //pull feature vertices onto feature curves
                            {
                                Point3d Point     = P.Vertices[i].ToPoint3d();
                                Curve   CF        = FC[FeatureV[i]];
                                double  param1    = 0.0;
                                Point3d onFeature = new Point3d();
                                CF.ClosestPoint(Point, out param1);
                                onFeature = CF.PointAt(param1);
                                P.Vertices.SetVertex(i, onFeature);
                            }
                        }
                        else
                        {
                            P.Vertices.SetVertex(i, FV[AnchorV[i]]); //pull anchor vertices onto their points
                        }
                    }



                    //end new



                    AnchorV  = CompactByVertex(P, AnchorV); //compact the fixed points along with the vertices
                    FeatureV = CompactByVertex(P, FeatureV);
                    FeatureE = CompactByEdge(P, FeatureE);

                    P.Compact(); //this cleans the mesh data structure of unused elements
                }
            }

            DA.SetData(0, P);
        }