示例#1
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            try {
                ////////////////////////////////////////////////////////////////////
                //Inputs Grasshopper
                Mesh M = DA.Fetch <Mesh>("Mesh");
                DataTree <Polyline> PanelOutlines = DA.FetchTree <GH_Curve>("Panels").ToPolylineDT();
                DataTree <Vector3d> EVec          = DA.FetchTree <GH_Vector>("EdgeVectors").ToDT();
                int    D      = DA.Fetch <int>("JointDiv");
                double L      = DA.Fetch <double>("JointLen");
                double H      = DA.Fetch <double>("JointHei");
                double W      = DA.Fetch <double>("JointThi");
                bool   Center = DA.Fetch <bool>("Center");
                bool   Finger = DA.Fetch <bool>("Finger");
                double Custom = DA.Fetch <double>("Custom");
                DataTree <Polyline> CChamfer = new DataTree <Polyline>();
                int           iterations     = DA.Fetch <int>("Iterations");
                List <int>    sequence       = DA.FetchList <int>("Sequence");
                List <double> textSize       = DA.FetchList <double>("TextScale");

                if (textSize.Count < 6)
                {
                    textSize = new List <double> {
                        20, 10, 10, 0.5, 0.75, 10
                    }
                }
                ;

                DataTree <Panel> PanelGroups = DA.FetchTree <GH_Curve>("Panels").ToPanelsDT();
                DataTree <Panel> JointGroups = new DataTree <Panel>();
                ////////////////////////////////////////////////////////////////////


                ////////////////////////////////////////////////////////////////////
                //Inputs Local
                int    divisions   = Math.Max(1, D);
                double jointLength = L;//Math.Max(0.1, L);
                double height      = Math.Max(0.1, H);
                double width       = Math.Max(0.1, W);

                int[][]                 tv      = M.GetNGonsTopoBoundaries();
                int[][]                 fe      = M.GetNGonFacesEdges(tv);
                HashSet <int>           e       = M.GetAllNGonEdges(tv);
                Dictionary <int, int[]> efDict  = M.GetFE(e, false);
                Point3d[]               centers = M.GetNGonCenters();
                ////////////////////////////////////////////////////////////////////

                ////////////////////////////////////////////////////////////////////
                //      Insertion vectors
                DataTree <Vector3d> EV = M.insertionVectors(Center, EVec);
                ////////////////////////////////////////////////////////////////////

                DataTree <Polyline> diagonalConnections = new DataTree <Polyline>();
                //DataTree<Polyline> recJoints = new DataTree<Polyline>();

                //Iterate insertion edges
                Dictionary <int, int> meshEdgeDict = new Dictionary <int, int>();
                for (int i = 0; i < EV.BranchCount; i++)  // EV.BranchCount


                {
                    int meshEdge = EV.Path(i).Indices[0];//mesh edge is used as dataTree branch

                    meshEdgeDict.Add(meshEdge, i);

                    if (efDict[meshEdge].Length != 2)
                    {
                        continue;
                    }
                    int f0 = efDict[meshEdge][0];
                    int f1 = efDict[meshEdge][1];

                    //Divide line into points and create a planes on these point, following insertion direction and average face normal
                    Point3d[] pts = M.TopologyEdges.EdgeLine(meshEdge).InterpolateLine(divisions, false);

                    for (int j = 0; j < pts.Length; j++)
                    {
                        JointGroups.Add(new Panel(new Plane(pts[j], EV.Branch(EV.Path(i))[0].UnitVector(), M.GetMeshEdgePerpDir(meshEdge))), EV.Path(i));
                    }


                    //Construct joint outlines from planes
                    //Iterate number of joints per edge
                    for (int j = 0; j < pts.Length; j++)
                    {
                        JointGroups.Branch(EV.Path(i))[j].planeOffset0    = JointGroups.Branch(EV.Path(i))[j].plane.MovePlanebyAxis(W * 0.5);         //offset planes
                        JointGroups.Branch(EV.Path(i))[j].planeOffset1    = JointGroups.Branch(EV.Path(i))[j].plane.MovePlanebyAxis(-W * 0.5);        //offset planes
                        JointGroups.Branch(EV.Path(i))[j].planeRot        = new Plane(pts[j], Vector3d.CrossProduct(EV.Branch(EV.Path(i))[0].UnitVector(), M.GetMeshEdgePerpDir(meshEdge)), M.GetMeshEdgePerpDir(meshEdge));
                        JointGroups.Branch(EV.Path(i))[j].planeRotOffset0 = JointGroups.Branch(EV.Path(i))[j].planeRot.MovePlanebyAxis(jointLength);  //offset planes
                        JointGroups.Branch(EV.Path(i))[j].planeRotOffset1 = JointGroups.Branch(EV.Path(i))[j].planeRot.MovePlanebyAxis(-jointLength); //offset plane
                        JointGroups.Branch(EV.Path(i))[j].planeEdge       = new Plane(pts[j], M.TopologyEdges.EdgeLine(meshEdge).Direction, M.GetMeshEdgePerpDir(meshEdge));

                        List <Plane> planesF0 = new List <Plane>();
                        List <Plane> planesF1 = new List <Plane>();
                        for (int k = 0; k < PanelGroups.Branch(f0).Count; k++)
                        {
                            planesF0.Add(PanelGroups.Branch(f0)[k].plane);
                            planesF1.Add(PanelGroups.Branch(f1)[k].plane);
                        }



                        JointGroups.Branch(EV.Path(i))[j].planeF0 = PlaneUtil.AveragePlaneOrigin(planesF0);
                        JointGroups.Branch(EV.Path(i))[j].planeF1 = PlaneUtil.AveragePlaneOrigin(planesF1);

                        List <Plane> jointPlaneLoop = new List <Plane> {
                            JointGroups.Branch(EV.Path(i))[j].planeRotOffset0,
                            JointGroups.Branch(EV.Path(i))[j].planeF0.MovePlanebyAxis(height),
                            JointGroups.Branch(EV.Path(i))[j].planeEdge,
                            JointGroups.Branch(EV.Path(i))[j].planeF1.MovePlanebyAxis(height),  //3
                            JointGroups.Branch(EV.Path(i))[j].planeRotOffset1,
                            JointGroups.Branch(EV.Path(i))[j].planeF1.MovePlanebyAxis(-height), //5
                            JointGroups.Branch(EV.Path(i))[j].planeEdge,
                            JointGroups.Branch(EV.Path(i))[j].planeF0.MovePlanebyAxis(-height),
                        };

                        //Rhino.RhinoDoc.ActiveDoc.Objects.AddRectangle(new Rectangle3d(JointGroups.Branch(EV.Path(i))[j].planeF1, new Interval(-20, 20), new Interval(-20, 20)));
                        //Rhino.RhinoDoc.ActiveDoc.Objects.AddRectangle(new Rectangle3d(JointGroups.Branch(EV.Path(i))[j].planeF1, new Interval(-20, 20), new Interval(-20, 20)));

                        JointGroups.Branch(EV.Path(i))[j].contourNoJoints[0] = PolylineUtil.PolylineFromPlanes(JointGroups.Branch(EV.Path(i))[j].planeOffset0, jointPlaneLoop);
                        JointGroups.Branch(EV.Path(i))[j].contourNoJoints[1] = PolylineUtil.PolylineFromPlanes(JointGroups.Branch(EV.Path(i))[j].planeOffset1, jointPlaneLoop);
                        JointGroups.Branch(EV.Path(i))[j].contour[0]         = new Polyline(JointGroups.Branch(EV.Path(i))[j].contourNoJoints[0]);
                        JointGroups.Branch(EV.Path(i))[j].contour[1]         = new Polyline(JointGroups.Branch(EV.Path(i))[j].contourNoJoints[1]);
                    }


                    //Construct Cuts
                    //Iterate number of joints per edge
                    for (int j = 0; j < pts.Length; j++)
                    {
                        int localMeshEdgeF0 = Array.IndexOf(fe[f0], meshEdge);
                        int localMeshEdgeF1 = Array.IndexOf(fe[f1], meshEdge);



                        //Iterate number of panels and create cuts
                        for (int k = 0; k < PanelGroups.Branch(f0).Count; k++)
                        {
                            Panel jointPanel = JointGroups.Branch(EV.Path(i))[j];

                            jointPanel.id = f0.ToString() + "-" + f1.ToString();

                            //if(f0==f1)
                            //  Rhino.RhinoApp.WriteLine(jointPanel.id);

                            if (pts.Length > 1)
                            {
                                jointPanel.id += "-" + j.ToString();
                            }

                            bool flag = f0 == 165 && f1 == 166;
                            PanelGroups.Branch(f0)[k].CreateCut(localMeshEdgeF0, JointGroups.Branch(EV.Path(i))[j].planeOffset0, JointGroups.Branch(EV.Path(i))[j].planeOffset1, jointLength, ref jointPanel, flag); //, ref neiPanel, ref jointPanel);
                            PanelGroups.Branch(f1)[k].CreateCut(localMeshEdgeF1, JointGroups.Branch(EV.Path(i))[j].planeOffset0, JointGroups.Branch(EV.Path(i))[j].planeOffset1, jointLength, ref jointPanel, flag); //, ref neiPanel, ref jointPanel);

                            JointGroups.Branch(EV.Path(i))[j] = jointPanel;
                        }
                    }
                }


                for (int i = 0; i < JointGroups.BranchCount; i++)
                {
                    for (int j = 0; j < JointGroups.Branch(i).Count; j++)
                    {
                        if (Custom > 0)
                        {
                            JointGroups.Branch(i)[j].ChangeJoint(Custom, 0);
                        }
                        else if (Custom < 0)
                        {
                            JointGroups.Branch(i)[j].ChangeJoint(Custom, 1, textSize[7]);
                        }
                    }
                }



                ////////////////////////Output
                var dtPlates       = new DataTree <Polyline>();
                var dtJoints       = new DataTree <Polyline>();
                var dtPlatesMid    = new DataTree <Polyline>();
                var dtJointsMid    = new DataTree <Polyline>();
                var dtPlatesPlanes = new DataTree <Plane>();
                var dtJointsPlanes = new DataTree <Plane>();
                var dtPlatesTxt    = new DataTree <Curve>();
                var dtJointsTxt    = new DataTree <Curve>();

                var dtPlatesLast       = new DataTree <Polyline>();
                var dtJointsLast       = new DataTree <Polyline>();
                var dtPlatesMidLast    = new DataTree <Polyline>();
                var dtJointsMidLast    = new DataTree <Polyline>();
                var dtPlatesPlanesLast = new DataTree <Plane>();
                var dtJointsPlanesLast = new DataTree <Plane>();
                var dtPlatesTxtLast    = new DataTree <Curve>();
                var dtJointsTxtLast    = new DataTree <Curve>();

                HashSet <int> jointSequence = new HashSet <int>();

                HashSet <int> jointSequenceLast = new HashSet <int>();
                int           last = Math.Min(iterations, PanelGroups.BranchCount);
                int           prev = Math.Max(0, last - (int)textSize[6]);


                for (int i = 0; i < last; i++)  //Math.Min(iterations, sequence.Count) PanelGroups.BranchCount

                {
                    for (int j = 0; j < fe[i].Length; j++)
                    {
                        bool seq = jointSequence.Add(fe[i][j]);

                        if (i >= prev)
                        {
                            if (seq)
                            {
                                jointSequenceLast.Add(fe[i][j]);
                            }
                        }
                    }

                    for (int j = 0; j < PanelGroups.Branch(i).Count; j++)
                    {
                        dtPlates.Add(PanelGroups.Branch(i)[j].contour[0], new GH_Path(i, j));
                        dtPlates.Add(PanelGroups.Branch(i)[j].contour[1], new GH_Path(i, j));
                        dtPlatesMid.Add(PanelGroups.Branch(i)[j].MidContour(), new GH_Path(i, j));

                        if (i >= prev)
                        {
                            dtPlatesLast.Add(PanelGroups.Branch(i)[j].contour[0], new GH_Path(i, j));
                            dtPlatesLast.Add(PanelGroups.Branch(i)[j].contour[1], new GH_Path(i, j));
                            dtPlatesMidLast.Add(PanelGroups.Branch(i)[j].MidContour(), new GH_Path(i, j));
                        }



                        Plane textPlane = PanelGroups.Branch(i)[j].planeOffset0;
                        textPlane.Flip();

                        if (j == 1)
                        {
                            textPlane = PanelGroups.Branch(i)[j].planeOffset1;
                        }



                        dtPlatesPlanes.Add(textPlane, new GH_Path(i, j));

                        if (i >= prev)
                        {
                            dtPlatesPlanesLast.Add(textPlane, new GH_Path(i, j));
                        }


                        string text   = i.ToString() + "-" + j.ToString();
                        var    txtCrv = Typewriter.Regular.Write(text, textPlane, textSize[0]);
                        dtPlatesTxt.AddRange(txtCrv, new GH_Path(i, j));

                        if (i >= prev)
                        {
                            dtPlatesTxtLast.AddRange(txtCrv, new GH_Path(i, j));
                        }


                        //for(int k = 0; k < PanelGroups.Branch(i)[j].contourNoJoints.Length; k++) {


                        Line[] segments = PanelGroups.Branch(i)[j].contourNoJoints[j].GetSegments();

                        int counter = 0;
                        foreach (Line l in segments)
                        {
                            int meshEdge = fe[i][counter];

                            int neiF = M.GetOppositeNgon(meshEdge, i);


                            //Adjacent face plane
                            Point3d  origin = l.PointAt(textSize[3]);
                            Vector3d xaxis  = l.Direction;
                            Vector3d yaxis  = l.Direction;
                            origin.Transform(Transform.Scale(textPlane.Origin, textSize[4]));
                            yaxis.Rotate(Math.PI * 0.5, textPlane.ZAxis);
                            Plane ePlane = new Plane(origin, xaxis, yaxis);

                            var txtCrvF = Typewriter.Regular.Write(neiF.ToString(), ePlane, textSize[2]);
                            dtPlatesTxt.AddRange(txtCrvF, new GH_Path(i, j));

                            if (i >= prev)
                            {
                                dtPlatesTxtLast.AddRange(txtCrvF, new GH_Path(i, j));
                            }



                            //Mesh edge direction
                            Line meshEdgeLine = M.TopologyEdges.EdgeLine(meshEdge);
                            meshEdgeLine.Transform(Transform.Scale(meshEdgeLine.PointAt(0.5), textSize[4]));
                            meshEdgeLine.Transform(Transform.Scale(textPlane.Origin, textSize[4]));
                            //meshEdgeLine.Extend(-textSize[4], -textSize[4]);


                            Plane e0Plane = new Plane(ePlane.ClosestPoint(meshEdgeLine.From), xaxis, yaxis);
                            Plane e1Plane = new Plane(ePlane.ClosestPoint(meshEdgeLine.To), xaxis, yaxis);

                            var txtCrvF0 = Typewriter.Regular.Write("I", e0Plane, textSize[2]);
                            dtPlatesTxt.AddRange(txtCrvF0, new GH_Path(i, j));

                            if (i >= prev)
                            {
                                dtPlatesTxtLast.AddRange(txtCrvF0, new GH_Path(i, j));
                            }

                            var txtCrvF1 = Typewriter.Regular.Write("II", e1Plane, textSize[2]);
                            dtPlatesTxt.AddRange(txtCrvF1, new GH_Path(i, j));

                            if (i >= prev)
                            {
                                dtPlatesTxtLast.AddRange(txtCrvF1, new GH_Path(i, j));
                            }


                            counter++;
                            //
                        }
                    }
                }

                foreach (int meshEdge in jointSequence)
                {
                    //for (int i = 0; i < Math.Min(iterations, sequence.Count); i++) {//JointGroups.BranchCount
                    if (!meshEdgeDict.ContainsKey(meshEdge))
                    {
                        continue;
                    }
                    int i = meshEdgeDict[meshEdge];

                    for (int j = 0; j < JointGroups.Branch(i).Count; j++)
                    {
                        dtJoints.Add(JointGroups.Branch(i)[j].contour[0], new GH_Path(meshEdge, j));
                        dtJoints.Add(JointGroups.Branch(i)[j].contour[1], new GH_Path(meshEdge, j));
                        dtJointsMid.Add(JointGroups.Branch(i)[j].MidContour(), new GH_Path(i, j));

                        dtJointsPlanes.Add(JointGroups.Branch(i)[j].planeOffset0, new GH_Path(meshEdge, j));

                        Plane planet = new Plane(JointGroups.Branch(i)[j].planeOffset0.Origin + JointGroups.Branch(i)[j].planeOffset0.YAxis * textSize[5], JointGroups.Branch(i)[j].planeOffset0.XAxis, JointGroups.Branch(i)[j].planeOffset0.YAxis);


                        string text   = JointGroups.Branch(i)[j].id;
                        var    txtCrv = Typewriter.Regular.Write(text, planet, textSize[1]);
                        dtJointsTxt.AddRange(txtCrv, new GH_Path(meshEdge, j));
                    }
                }

                foreach (int meshEdge in jointSequenceLast)
                {
                    //for (int i = 0; i < Math.Min(iterations, sequence.Count); i++) {//JointGroups.BranchCount
                    if (!meshEdgeDict.ContainsKey(meshEdge))
                    {
                        continue;
                    }
                    int i = meshEdgeDict[meshEdge];

                    for (int j = 0; j < JointGroups.Branch(i).Count; j++)
                    {
                        dtJointsLast.Add(JointGroups.Branch(i)[j].contour[0], new GH_Path(meshEdge, j));
                        dtJointsLast.Add(JointGroups.Branch(i)[j].contour[1], new GH_Path(meshEdge, j));
                        dtJointsMidLast.Add(JointGroups.Branch(i)[j].MidContour(), new GH_Path(i, j));

                        dtJointsPlanesLast.Add(JointGroups.Branch(i)[j].planeOffset0, new GH_Path(meshEdge, j));

                        Plane planet = new Plane(JointGroups.Branch(i)[j].planeOffset0.Origin + JointGroups.Branch(i)[j].planeOffset0.YAxis * textSize[5], JointGroups.Branch(i)[j].planeOffset0.XAxis, JointGroups.Branch(i)[j].planeOffset0.YAxis);


                        string text   = JointGroups.Branch(i)[j].id;
                        var    txtCrv = Typewriter.Regular.Write(text, planet, textSize[1]);
                        dtJointsTxtLast.AddRange(txtCrv, new GH_Path(meshEdge, j));
                    }
                }


                DA.SetDataTree(0, dtPlates);
                DA.SetDataTree(1, dtJoints);

                DA.SetDataTree(2, dtPlatesMid);
                DA.SetDataTree(3, dtJointsMid);

                DA.SetDataTree(4, dtPlatesPlanes);
                DA.SetDataTree(5, dtJointsPlanes);

                DA.SetDataTree(6, dtPlatesTxt);
                DA.SetDataTree(7, dtJointsTxt);



                DA.SetDataTree(8, dtPlatesLast);
                DA.SetDataTree(9, dtJointsLast);

                DA.SetDataTree(10, dtPlatesMidLast);
                DA.SetDataTree(11, dtJointsMidLast);

                DA.SetDataTree(12, dtPlatesPlanesLast);
                DA.SetDataTree(13, dtJointsPlanesLast);

                DA.SetDataTree(14, dtPlatesTxtLast);
                DA.SetDataTree(15, dtJointsTxtLast);
            } catch (Exception e) {
                Rhino.RhinoApp.WriteLine(e.ToString());
            }
        }
        /// <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)
        {
            #region updateInputs
            //if (!cap && this.Params.Input.Count ==7)
            //{
            //    this.Params.Input[5].RemoveAllSources();
            //    this.Params.UnregisterInputParameter(this.Params.Input[5]);
            //    this.Params.Input[6].RemoveAllSources();
            //    this.Params.UnregisterInputParameter(this.Params.Input[6]);

            //    Params.OnParametersChanged();
            //}
            //if (cap && this.Params.Input.Count == 5)
            //{
            //    this.Params.RegisterInputParam(new Param_Colour
            //    {
            //        Name = "MinColor",
            //        NickName = "MinColor",
            //        Description = "MinColor",
            //        Access = GH_ParamAccess.item,
            //        Optional = true
            //    });
            //    this.Params.RegisterInputParam(new Param_Colour
            //    {
            //        Name = "MaxColor",
            //        NickName = "MaxColor",
            //        Description = "MinColor",
            //        Access = GH_ParamAccess.item,
            //        Optional = true
            //    });

            //    Params.OnParametersChanged();
            //}

            #endregion updateInputs

            //bool caps = DA.Fetch<bool>("Cap");
            var maxColor   = DA.Fetch <Color>(inputSelecterMax);
            var minColor   = DA.Fetch <Color>(inputSelectorMin);
            var allResults = DA.FetchTree <GH_Number>("Results");
            var grids      = DA.FetchList <Grid>("Grids");
            var range      = DA.Fetch <string>("Range");
            var inStepSize = DA.Fetch <int>("StepSize");
            var inSteps    = DA.Fetch <int>("Steps");

            if (allResults.Branches.Count != grids.Count)
            {
                throw new Exception("Grid count doesnt match results");
            }

            if (!caps)
            {
                this.Params.Input[inputSelectorMin].NickName = "-";
                this.Params.Input[inputSelectorMin].Name     = "-";
                this.Params.Input[inputSelecterMax].NickName = "-";
                this.Params.Input[inputSelecterMax].Name     = "-";
            }
            else
            {
                this.Params.Input[inputSelectorMin].NickName = "MinColor";
                this.Params.Input[inputSelectorMin].Name     = "MinColor";
                this.Params.Input[inputSelecterMax].NickName = "MaxColor";
                this.Params.Input[inputSelecterMax].Name     = "MaxColor";
            }

            var domain = Misc.AutoDomain(range, allResults);
            //Rhino.RhinoApp.WriteLine($"{range}  ->  {domain[0]} to {domain[1]}");

            GH_GradientControl gc;
            try
            {
                gc = (GH_GradientControl)Params.Input[inputGradient].Sources[0].Attributes.GetTopLevel.DocObject;
            }
            catch (System.ArgumentOutOfRangeException)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Remember to add a gradient component in grasshopper!");
                gc = null;
            }

            GradientParser gp = new GradientParser(gc)
            {
                Cap      = caps,
                AboveMax = maxColor,
                BelowMin = minColor,
                Min      = domain[0],
                Max      = domain[1],
                Reverse  = Params.Input[inputGradient].Reverse
            };


            //Rhino.RhinoApp.WriteLine($"Probing {domain[0]} to the value of {gp.GetColors(new List<double> { domain[0] })[0]}");
            //Rhino.RhinoApp.WriteLine($"Probing {domain[1]} to the value of {gp.GetColors(new List<double> { domain[1] })[0]}");

            #region coloredMesh
            var outMeshes = new List <Mesh>();



            for (int i = 0; i < grids.Count; i++)
            {
                //AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, $"Mesh vertices: {grids[i].SimMesh.Vertices.Count}, colors = {gp.GetColors(allResults.Branches[i].Select(p => p.Value).ToArray()).Length} f");


                outMeshes.Add(grids[i].GetColoredMesh(gp.GetColors(allResults.Branches[i].Select(p => p.Value).ToArray())));

                Mesh      m      = grids[i].SimMesh;
                Point3d[] points = grids[i].SimPoints.ToArray();
                outMeshes[outMeshes.Count - 1].Translate(0, 0, Units.ConvertFromMeter(0.001));
            }


            DA.SetDataList(0, outMeshes);

            #endregion coloredMesh



            #region layeredMesh

            if (grids[0].UseCenters == true)
            {
                return;
            }

            //Outputs
            GH_Structure <GH_Mesh>  layeredMeshes = new GH_Structure <GH_Mesh>();
            List <GH_Mesh>          tempMeshes    = new List <GH_Mesh>();
            List <GH_Plane>         outPlanes     = new List <GH_Plane>();
            GH_Structure <GH_Curve> outCurves     = new GH_Structure <GH_Curve>();

            const double SCALAR = 1; // don't change.
            const float  OFFSET = 0.0001f;

            double allMin = double.MaxValue;
            double allMax = -double.MaxValue;

            for (int i = 0; i < allResults.Branches.Count; i++)
            {
                //System.Collections.IList results = allResults.get_Branch(i);

                for (int j = 0; j < allResults[i].Count; j++)
                {
                    double result = allResults[i][j].Value;
                    if (result < allMin)
                    {
                        allMin = result;
                    }
                    if (result > allMax)
                    {
                        allMax = result;
                    }
                }
            }

            stepSize = inStepSize;
            double roundToNearest = 1;
            if (inStepSize == 0) // auto
            {
                //double digits = Math.Round(Math.Log10((domain[1] - domain[0]))) + 1;
                //double multiplier = Math.Pow(10, digits);
                //stepSize = Math.Log10((domain[1] - domain[0]));
                //if (allMax > 1000)
                //    stepSize = 100;
                //else if (allMax > 100)
                //    stepSize = 10;
                //else if (allMax > 10)
                //    stepSize = 1;
                //else
                //    stepSize = 0.1;
                stepSize = Misc.AutoStep(domain, out roundToNearest); // <-- TODO: We can set each slice in exactly the "round to nearest" number.
            }
            else if (inStepSize < 0)                                  // fragment
            {
                stepSize = 1 / Math.Abs(inStepSize);
            }

            steps = Convert.ToInt32((domain[1] - domain[0]) / stepSize);


            for (int g = 0; g < grids.Count; g++)
            {
                //GH_Structure<GH_Curve> curves = new GH_Structure<GH_Curve>();
                Grid grid      = grids[g];
                Mesh meshToCut = grids[g].SimMesh.DuplicateMesh();
                //Mesh meshToCut = grids[g].SimMesh;

                List <double> results = ((List <GH_Number>)allResults.get_Branch(g)).Select(r => r.Value).ToList();

                if (grids[g].UseCenters == true)
                {
                    results = RTreeSolver.FindClosestWeightedValues(grids[g], results, true).ToList();
                    // ADD CONVERSION TODO:
                }



                //Rhino.RhinoApp.WriteLine($"min = {allMin}, max = {allMax}, steps = {steps}, stepsize = {stepSize}");

                if (steps <= 1 || steps > 100)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"too {(steps < 4 ? "few" : "many")} steps (should be between 1 to 100)");
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"min = {allMin}, max = {allMax}, steps = {steps}, stepsize = {stepSize}");
                    continue;
                }

                if (allMax == allMin)
                {
                    AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"max==min");
                    continue;
                }
                meshToCut.Normals.ComputeNormals();

                Plane cuttingPlane = new Plane(meshToCut.Vertices[0], meshToCut.FaceNormals[0]);

                //var planeOut = new Plane(plane);

                var planeBottom = new Plane(cuttingPlane);

                //List<int> belongsToWhichLayer = new List<int>();

                Vector3f normal = (Vector3f)(cuttingPlane.ZAxis);
                //AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"normal  x = {normal.X}, Y = {normal.Y}, Z = {normal.Z}");

                planeBottom.Transform(Transform.Translation(-cuttingPlane.ZAxis));

                //Moving the bottom down
                meshToCut.Translate(-normal * OFFSET);

                //Moving the vertices up
                for (int i = 0; i < results.Count; i++)
                {
                    meshToCut.Vertices[i] += (normal) * (float)SCALAR * (OFFSET + (float)results[i]);
                }

                Mesh topMesh = meshToCut.DuplicateMesh();

                tempMeshes.Add(new GH_Mesh(topMesh));

                Mesh edgeMesh = new Mesh();

                List <Point3d> ptOut = new List <Point3d>();
                Polyline[]     edges = meshToCut.GetNakedEdges();

                double totalLength = 0;

                for (int i = 0; i < edges.Length; i++)
                {
                    totalLength += edges[i].Length;
                }

                Polyline[] edgesProjected = new Polyline[edges.Length];

                Transform p = Transform.PlanarProjection(planeBottom);

                for (int i = 0; i < edges.Length; i++)
                {
                    for (int j = 0; j < edges[i].SegmentCount; j++)
                    {
                        Mesh      msh = new Mesh();
                        Point3d[] pts = new Point3d[4];

                        int id = (j == edges[i].SegmentCount - 1) ? 0 : j + 1;

                        pts[0] = new Point3d(edges[i].X[j], edges[i].Y[j], edges[i].Z[j]);
                        pts[1] = new Point3d(edges[i].X[id], edges[i].Y[id], edges[i].Z[id]);
                        pts[2] = new Point3d(pts[1]);
                        pts[3] = new Point3d(pts[0]);
                        pts[2].Transform(p);
                        pts[3].Transform(p);

                        msh.Vertices.AddVertices(pts);
                        var fc = new MeshFace(3, 2, 1, 0);
                        ptOut.AddRange(pts);
                        msh.Faces.AddFace(fc);

                        edgeMesh.Append(msh);
                    }
                }

                meshToCut.Append(edgeMesh);
                meshToCut.Weld(Math.PI);

                tempMeshes.Add(new GH_Mesh(meshToCut));

                //Transform t = Transform.Translation(new Vector3d(0, 0, inStepSize * SCALAR));

                Vector3f v = normal * (float)(stepSize.RoundTo(roundToNearest) * SCALAR);

                Transform t = Transform.Translation(v);

                //AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Vector v = {v.X}, {v.Y}, {v.Z},   instep = ");

                Mesh meshPerArea     = new Mesh();
                MeshingParameters mp = new MeshingParameters(0);


                //double resultValue = inputMin;
                //stepSize = (inputMax - inputMin) / (float)steps;



                double currentValue = domain[0];
                int    cuttingCount = -1;

                while (currentValue <= domain[1])
                {
                    cuttingCount++;

                    if (cuttingCount == 0)
                    {
                        currentValue = domain[0];
                    }


                    if (cuttingCount == 1)
                    {
                        cuttingPlane.Translate(new Vector3d(0, 0, domain[0].RoundTo(roundToNearest)));
                        //currentValue = domain[0];
                    }

                    if (cuttingCount > 0)
                    {
                        currentValue += stepSize;
                    }



                    if (cuttingCount > 80)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "ERROR CUT THE CUTTINGCOUNT");
                        break;
                    }

                    //Rhino.RhinoApp.WriteLine($"CurrentValue = {currentValue}, cuttingCount = {cuttingCount}");


                    //var resultValue = (double)cuttingCount / steps * (allMax - allMin) + allMin;


                    //resultValue = (double)cuttingCount / steps * (domain[1] - domain[0]) + domain[0];
                    //resultValue = (double)cuttingCount / steps * (domain[1] - domain[0]) + domain[0];

                    //var resultValue = currentValue; // new

                    //Rhino.RhinoApp.WriteLine($"Cutting {cuttingCount}, {resultValue}, {currentValue}, {allMin} - {allMax}");
                    //if (resultValue < domain[0])
                    //    continue;
                    //if (resultValue > domain[1])
                    //    break;



                    Polyline[] pl = Rhino.Geometry.Intersect.Intersection.MeshPlane(meshToCut, cuttingPlane);
                    outPlanes.Add(new GH_Plane(cuttingPlane));

                    if (pl == null)
                    {
                        break;
                    }



                    Color col = gp.GetColors(new List <double>()
                    {
                        cuttingCount == 0 ? double.MinValue : currentValue.RoundTo(roundToNearest)
                    })[0];
                    //Rhino.RhinoApp.WriteLine($"Probing value {currentValue} to {col}");

                    //Mesh meshPerCut = new Mesh();

                    GH_Path path = new GH_Path(g, cuttingCount);

                    if (pl.Length > 0)
                    {
                        List <Curve> curves = new List <Curve>();
                        for (int j = 0; j < pl.Length; j++)
                        {
                            Curve curve = new PolylineCurve(pl[j]);

                            if (cuttingCount <= 0)
                            {
                                curve.Translate(normal * (float)(domain[0] - stepSize));
                            }


                            curve.Translate(-normal * (float)(currentValue * 0.95 - stepSize)); // was 0.95 nice

                            //curve.Translate(-normal * (float)allMin + normal * (float)(cuttingCount * Units.ConvertFromMeter(0.01)));



                            curves.Add(curve);                           // to create brep later

                            outCurves.Append(new GH_Curve(curve), path); // for output
                        }

                        Brep[] breps2 = Brep.CreatePlanarBreps(curves, Units.ConvertFromMeter(0.001));
                        for (int j = 0; j < breps2.Length; j++)
                        {
                            Mesh[] mesh2 = Mesh.CreateFromBrep(breps2[j], mp);

                            for (int k = 0; k < mesh2.Length; k++)
                            {
                                mesh2[k].VertexColors.CreateMonotoneMesh(col);

                                //meshPerCut.Append(mesh2[k]);

                                layeredMeshes.Append(new GH_Mesh(mesh2[k]), path);
                            }
                        }
                    }

                    //meshPerCut.VertexColors.CreateMonotoneMesh(col);



                    if (cuttingCount > 0)
                    {
                        cuttingPlane.Transform(t);
                    }
                }

                //layeredMeshes.Append(new GH_Mesh(meshPerArea), new GH_Path(g, );
            }



            //for (int j = 0; j < pl.Length; j++)
            //{
            //    Curve curve = pl[j].ToNurbsCurve();
            //    GH_Path path = new GH_Path(g, cuttingCount);

            //    outCurves.Append(new GH_Curve(curve), path);


            //    Brep[] breps = Brep.CreatePlanarBreps(curve, Units.ConvertFromMeter(0.001));

            //    if (breps == null)
            //        continue;

            //    Brep brep = breps[0];

            //    var area = AreaMassProperties.Compute(brep);
            //    if (area.Area > maxSize)
            //    {
            //        maxSize = area.Area;
            //        outerIndex = j;
            //    }
            //}

            //boundaryEdge = pl[outerIndex];


            //for (int j = 0; j < pl.Length; j++)
            //{
            //    if (j != outerIndex)
            //        holes.Add(pl[j].ToNurbsCurve());
            //}

            //Mesh mesh = null;
            //if (boundaryEdge.IsClosed)
            //{
            //    mesh = Mesh.CreatePatch(boundaryEdge, Math.PI / 2.0, null, holes, null, null, false, 0);

            //}
            //else
            //{

            //    AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, $"Curve is not closed");
            //}



            //outPlanes.Add(new GH_Plane(new Plane(cuttingPlane)));



            //int curvesCount = pl.Length;
            //int[] pointsRanges = new int[curvesCount];
            //Point3d[][] pts = new Point3d[curvesCount][];

            //for (int j = 0; j < pl.Length; j++)
            //{
            //    //Mesh mesh = GreenScenario.MeshUtil.CreateMeshWithHoles(pl);
            //    //Mesh mesh = Mesh.CreateFromTessellation(points, pl, Plane.WorldXY, false);
            //    //var mesh = Mesh.CreateFromClosedPolyline(pl[j]);


            //    if (mesh == null)
            //        continue;

            //    //outCurves.Append(new GH_Curve(pl[j].ToNurbsCurve()));

            //    //List<Color> colorList = new List<Color>();

            //    ////for (int i = 0; i < mesh.Faces.Count; i++)
            //    ////{
            //    ////    colorList.Add(col);
            //    ////    colorList.Add(col);
            //    ////    colorList.Add(col);
            //    ////    if (mesh.Faces[i].IsQuad)
            //    ////        colorList.Add(col);
            //    ////}

            //    //for (int i = 0; i < mesh.Vertices.Count; i++)
            //    //{
            //    //    colorList.Add(col);
            //    //}



            //    ////mesh.VertexColors.SetColors(colorList.ToArray());
            //    //AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, $"Vertices = {mesh.Vertices.Count}, colors = {mesh.VertexColors.Count}");

            //    //    mesh.VertexColors.CreateMonotoneMesh(col);
            //    //mesh.Translate(-normal * inStepSize * (float)SCALAR * cuttingCount * 0.90f);

            //    //   meshPerArea.Append(mesh);


            //    // we don't have more heights to cut off.
            //    //if (brep == null)
            //    //    continue;


            //    //for (int i = 0; i < brep.Length; i++)
            //    //{

            //    //    belongsToWhichLayer.Add(count);

            //    //}
            //    //pts.Add(polylinecrv.PointAtStart);


            //}



            // By now curves are moved to different elevations.
            //crvs = crvs;



            //Rhino.RhinoApp.WriteLine("adding a mesh");



            //oNumbers = outNumbers;



            //B = breps;
            //meshOut = mesh;


            Message = $"Cap = {(this.caps ? "on" : "off")} | Steps = {steps} | Step = {stepSize:0.0}";

            DA.SetDataTree(1, layeredMeshes);
            DA.SetDataTree(2, outCurves);
            DA.SetDataList("Planes", outPlanes);
            DA.SetDataList("TempMeshes", tempMeshes);

            #endregion layeredMesh
        }
示例#3
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)
        {
            #region updateInputs
            //if (!cap && this.Params.Input.Count ==7)
            //{
            //    this.Params.Input[5].RemoveAllSources();
            //    this.Params.UnregisterInputParameter(this.Params.Input[5]);
            //    this.Params.Input[6].RemoveAllSources();
            //    this.Params.UnregisterInputParameter(this.Params.Input[6]);

            //    Params.OnParametersChanged();
            //}
            //if (cap && this.Params.Input.Count == 5)
            //{
            //    this.Params.RegisterInputParam(new Param_Colour
            //    {
            //        Name = "MinColor",
            //        NickName = "MinColor",
            //        Description = "MinColor",
            //        Access = GH_ParamAccess.item,
            //        Optional = true
            //    });
            //    this.Params.RegisterInputParam(new Param_Colour
            //    {
            //        Name = "MaxColor",
            //        NickName = "MaxColor",
            //        Description = "MinColor",
            //        Access = GH_ParamAccess.item,
            //        Optional = true
            //    });

            //    Params.OnParametersChanged();
            //}

            #endregion updateInputs

            //bool caps = DA.Fetch<bool>("Cap");
            Color?maxColor   = DA.Fetch <Color?>(i_inputSelecterMax);
            Color?minColor   = DA.Fetch <Color?>(i_inputSelectorMin);
            var   allResults = DA.FetchTree <GH_Number>("Results");
            var   grids      = DA.FetchList <Grid>("Grids");
            //var gradientRange = DA.Fetch<string>("GradientRange");
            //int maxCount = DA.Fetch<int>("MaxCount");
            int maxCount = 200;
            //var inStepSize = DA.Fetch<int>("StepSize");
            //var inSteps = DA.Fetch<int>("Steps");
            InputSelector inputSelector = DA.Fetch <InputSelector>("_Section Type");

            double globalMin = double.MaxValue;
            double globalMax = double.MinValue;

            for (int g = 0; g < grids.Count; g++)
            {
                globalMin = Math.Min(globalMin, ((List <GH_Number>)allResults.get_Branch(g)).Select(r => r.Value).Min());
                globalMax = Math.Max(globalMax, ((List <GH_Number>)allResults.get_Branch(g)).Select(r => r.Value).Max());
            }


            if (inputSelector == null)
            {
                inputSelector = new InputSelector(10, globalMin, globalMax);
            }



            if (allResults.Branches.Count != grids.Count)
            {
                throw new Exception("Grid count doesnt match results");
            }


            //var colorDomain = Misc.AutoDomain(gradientRange, allResults);
            //Rhino.RhinoApp.WriteLine($"{range}  ->  {domain[0]} to {domain[1]}");

            GH_GradientControl gc;
            try
            {
                gc = (GH_GradientControl)Params.Input[i_inputGradient].Sources[0].Attributes.GetTopLevel.DocObject;
            }
            catch (System.ArgumentOutOfRangeException)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Remember to add a gradient component in grasshopper!");
                gc = null;
            }

            GradientParser gp = new GradientParser(gc)
            {
                //Cap = caps,
                AboveMax = maxColor == default(Color) ? null : maxColor,
                BelowMin = minColor == default(Color) ? null : minColor,
                //Min = domain[0],
                //Max = domain[1],
                Reverse = Params.Input[i_inputGradient].Reverse
            };



            IDictionary <string, Color> colorDescriptions = new Dictionary <string, Color>();
            IDictionary <string, int>   colorPaths        = new Dictionary <string, int>();



            #region coloredMesh
            var outMeshes = new List <Mesh>();



            for (int i = 0; i < grids.Count; i++)
            {
                //AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, $"Mesh vertices: {grids[i].SimMesh.Vertices.Count}, colors = {gp.GetColors(allResults.Branches[i].Select(p => p.Value).ToArray()).Length} f");


                outMeshes.Add(grids[i].GetColoredMesh(gp.GetColors(allResults.Branches[i].Select(p => p.Value).ToArray())));

                Mesh      m      = grids[i].SimMesh;
                Point3d[] points = grids[i].SimPoints.ToArray();
                outMeshes[outMeshes.Count - 1].Translate(0, 0, Units.ConvertFromMeter(0.001));
            }


            DA.SetDataList(0, outMeshes);

            #endregion coloredMesh



            #region layeredMesh

            if (grids[0].UseCenters == true)
            {
                return;
            }

            //Outputs
            GH_Structure <GH_Mesh>  oLayeredMeshes = new GH_Structure <GH_Mesh>();
            List <GH_Mesh>          previewMeshes  = new List <GH_Mesh>();
            List <GH_Plane>         outPlanes      = new List <GH_Plane>();
            GH_Structure <GH_Curve> outCurves      = new GH_Structure <GH_Curve>();

            GH_Structure <GH_String> outValues = new GH_Structure <GH_String>();
            GH_Structure <GH_Colour> outColors = new GH_Structure <GH_Colour>();

            const double SCALAR = 1; // don't change.



            if (((GH_Structure <GH_Number>)gc.Params.Input[1].VolatileData)[0][0].Value == 1)
            {
                this.AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "The gradient connected has 1 as max. Is that on purpose? Check the inputs of your gradient component." +
                                       $"\nI suggest you set your max somewhere around {globalMax:0.0}");
            }


            for (int g = 0; g < grids.Count; g++)
            {
                //GH_Structure<GH_Curve> curves = new GH_Structure<GH_Curve>();
                Grid grid      = grids[g];
                Mesh inputMesh = grids[g].SimMesh.DuplicateMesh();
                //Mesh meshToCut = grids[g].SimMesh;

                List <double> results = ((List <GH_Number>)allResults.get_Branch(g)).Select(r => r.Value).ToList();

                if (grids[g].UseCenters == true)
                {
                    results = RTreeSolver.FindClosestWeightedValues(grids[g], results, true).ToList();
                    // ADD CONVERSION TODO:
                }

                inputMesh.Normals.ComputeNormals();

                Vector3f normal = inputMesh.FaceNormals[0];

                Plane basePlane = new Plane(inputMesh.Vertices[0], normal);

                Transform ProjectToBase = Transform.PlanarProjection(basePlane);

                Plane cuttingPlane = new Plane(basePlane);

                Mesh meshToCut = CreateMeshToBeCut(SCALAR, inputMesh, results, cuttingPlane);

                previewMeshes.Add(new GH_Mesh(inputMesh));

                MeshingParameters mp = new MeshingParameters(0);

                List <Mesh> layeredMeshesThisGrid = new List <Mesh>();


                double valueForSmallAreas = double.MinValue;

                double resultsMin = results.Min();

                foreach (var item in inputSelector)
                {
                    if (resultsMin >= item)
                    {
                        valueForSmallAreas = item;
                        break;
                    }
                }

                //Color col = gp.GetColors(new List<double>() { inputSelector.Min.Value })[0];
                Color col = gp.GetColors(new List <double>()
                {
                    gp.BelowMin.HasValue&& inputSelector.Min.Value <= gp.Min ? resultsMin > gp.Min ? valueForSmallAreas : double.MinValue :  inputSelector.Min.Value
                })[0];

                Polyline[] outlinePolylines = inputMesh.GetNakedEdges();

                PolylineCurve[] curvesFromOutline = new PolylineCurve[outlinePolylines.Length];

                for (int i = 0; i < outlinePolylines.Length; i++)
                {
                    curvesFromOutline[i] = new PolylineCurve(outlinePolylines[i]);
                    curvesFromOutline[i].Transform(ProjectToBase);
                }


                Mesh meshFromCurves = GetMeshFromCurves(curvesFromOutline, mp, in col);

                GH_Path startPath = new GH_Path(g, -1);
                oLayeredMeshes.Append(new GH_Mesh(meshFromCurves), startPath);


                string lessThanKey = gp.BelowMin.HasValue && inputSelector.Min.Value < gp.Min ? $"<{gp.Min:0.0}" : $"<{inputSelector.Min.Value:0.0}";
                if (!colorDescriptions.ContainsKey(lessThanKey) && inputSelector.First() < gp.Min)
                {
                    colorDescriptions.Add(lessThanKey, col);
                    colorPaths.Add(lessThanKey, -1);
                }

                ////outColors.Append(new GH_Colour(col), startPath);
                ////outValues.Append(new GH_Number(double.MinValue), startPath);

                //Mesh[] meshesFromCurves = GetMeshesFromCurves(curvesFromOutline, mp, in col);

                //oLayeredMeshes.AppendRange(meshesFromCurves.Select(m => new GH_Mesh(m)), new GH_Path(g, -1));



                int    cuttingCount  = 0;
                double previousValue = 0;

                foreach (double currentValue in inputSelector)
                {
                    if (cuttingCount > maxCount)
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Error, $"Too many steps... I reached  {maxCount} and then stopped");
                        break;
                    }

                    if (gp.BelowMin.HasValue && currentValue < gp.Min)
                    {
                        continue;
                    }


                    if (currentValue > results.Max())
                    {
                        break;
                    }


                    // Create planes

                    Vector3f moveUpVector = normal * (float)((currentValue - previousValue) * SCALAR);

                    Transform t = Transform.Translation(moveUpVector);

                    GH_Path path = new GH_Path(g, cuttingCount);

                    cuttingPlane.Transform(t);

                    outPlanes.Add(new GH_Plane(cuttingPlane));



                    // Create boundary intersected curves

                    Curve[] intersectedCurves = GetIntersectedCurves(inputMesh, cuttingPlane);



                    if (intersectedCurves != null)
                    {
                        outCurves.AppendRange(intersectedCurves.Select(c => new GH_Curve(c.DuplicateCurve())), path);

                        foreach (var curve in intersectedCurves)
                        {
                            curve.Transform(ProjectToBase);
                        }


                        // Create meshes

                        col = gp.GetColors(new List <double>()
                        {
                            currentValue
                        })[0];



                        meshFromCurves = GetMeshFromCurves(intersectedCurves, mp, in col);

                        meshFromCurves.Transform(Transform.Translation(0, 0, (cuttingCount + 1) * Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance * 12.0));



                        if (meshFromCurves != null)
                        {
                            //oLayeredMeshes.AppendRange(meshesFromCurves.Select(m => new GH_Mesh(m)), path);
                            oLayeredMeshes.Append(new GH_Mesh(meshFromCurves), path);
                            string key = currentValue >= gp.Max.Value ? $">{currentValue:0.0}" : $"{currentValue:0.0}";
                            if (!colorDescriptions.ContainsKey(key))
                            {
                                colorDescriptions.Add(key, col);
                                colorPaths.Add(key, cuttingCount);
                            }
                        }

                        if (currentValue >= gp.Max.Value)
                        {
                            break;
                        }
                    }



                    previousValue = currentValue;

                    cuttingCount++;
                }
            }

            foreach (KeyValuePair <string, Color> valuePair in colorDescriptions)
            {
                GH_Path path = new GH_Path(colorPaths[valuePair.Key]);


                outColors.Append(new GH_Colour(valuePair.Value), path);
                outValues.Append(new GH_String(valuePair.Key), path);
            }



            DA.SetDataTree(1, oLayeredMeshes);
            DA.SetDataTree(2, outCurves);
            DA.SetDataList("Planes", outPlanes);
            DA.SetDataList("TempMeshes", previewMeshes);
            DA.SetDataTree(6, outValues);
            DA.SetDataTree(5, outColors);

            #endregion layeredMesh
        }
示例#4
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            try {
                ////////////////////////////////////////////////////////////////////
                //Inputs Grasshopper
                Mesh M = DA.Fetch <Mesh>("Mesh");
                DataTree <Polyline> PanelOutlines = DA.FetchTree <GH_Curve>("Panels").ToPolylineDT();

                //Create joints
                DataTree <Vector3d> order = DA.FetchTree <GH_Vector>("InsertionVec").ToVectorDT();


                ////////////////////////////////////////////////////////////////////
                //      Insertion vectors

                //DataTree<Vector3d> EV = M.insertionVectors(Center, EVec);

                bool Center = DA.Fetch <bool>("Center");
                if (order.DataCount == 0)
                {
                    order = M.insertionVectorsJoints(Center, null);//joints
                }
                DataTree <Vector3d> EV = order;
                ////////////////////////////////////////////////////////////////////

                List <Point3d> twoJoints        = DA.FetchList <Point3d>("TwoJoints");
                List <Line>    extendedJoints   = DA.FetchList <Line>("ExtendedJoints");
                List <Line>    deeperCutsJoints = DA.FetchList <Line>("DeeperCutsJoints");

                List <JointsVDAInputs> joints = GetJoints(order, M, twoJoints, extendedJoints, deeperCutsJoints);

                if (order.DataCount != 0)
                {
                    order = M.insertionVectorsJoints(Center, joints);//joints
                }
                bool Finger = DA.Fetch <bool>("Finger");
                DataTree <Polyline> CChamfer = new DataTree <Polyline>();
                int           iterations     = DA.Fetch <int>("Iterations");
                List <int>    sequence       = DA.FetchList <int>("Sequence");
                List <double> textSize       = DA.FetchList <double>("TextScale");


                if (textSize.Count != 8)
                {
                    textSize = new List <double> {
                        30, 12, 15, 0.5, 0.6, 0, 1, 5
                    }
                }
                ;

                DataTree <Panel> PanelGroups = DA.FetchTree <GH_Curve>("Panels").ToPanelsDT();
                DataTree <Panel> JointGroups = new DataTree <Panel>();

                ////////////////////////////////////////////////////////////////////


                ////////////////////////////////////////////////////////////////////

                int[][]                 tv      = M.GetNGonsTopoBoundaries();
                int[][]                 fe      = M.GetNGonFacesEdges(tv);
                HashSet <int>           e       = M.GetAllNGonEdges(tv);
                Dictionary <int, int[]> efDict  = M.GetFE(e, false);
                Point3d[]               centers = M.GetNGonCenters();

                Vector3d[] fn = M.GetNgonNormals();
                //int[][] ef = M.GetNgonsConnectedToNGonsEdges(e, true);
                ////////////////////////////////////////////////////////////////////


                DataTree <Polyline> diagonalConnections = new DataTree <Polyline>();
                //DataTree<Polyline> recJoints = new DataTree<Polyline>();

                //Iterate insertion edges
                Dictionary <int, int> meshEdgeDict = new Dictionary <int, int>();
                for (int i = 0; i < EV.BranchCount; i++)  // EV.BranchCount


                {
                    int meshEdge = EV.Path(i).Indices[0];//mesh edge is used as dataTree branch

                    meshEdgeDict.Add(meshEdge, i);

                    if (efDict[meshEdge].Length != 2)
                    {
                        continue;
                    }
                    int f0 = efDict[meshEdge][0];
                    int f1 = efDict[meshEdge][1];

                    //Divide line into points and create a planes on these point, following insertion direction and average face normal
                    // Point3d[] pts = M.TopologyEdges.EdgeLine(meshEdge).InterpolateLine(divisions, false);
                    Point3d[] pts = M.TopologyEdges.EdgeLine(meshEdge).InterpolateLine(joints[i].divisions, false);

                    Vector3d avNormal = fn[f0] + fn[f1];
                    //Vector3d jointVector = Vector3d.CrossProduct(M.TopologyEdges.EdgeLine(meshEdge).Direction, avNormal);
                    //EV.Branch(EV.Path(i))[0] = jointVector;

                    for (int j = 0; j < pts.Length; j++)
                    {
                        //(new Line(pts[j], pts[j]+ avNormal*40)).Bake();
                        //JointGroups.Add(new Panel(new Plane(pts[j], EV.Branch(EV.Path(i))[0].UnitVector(), M.GetMeshEdgePerpDir(meshEdge))), EV.Path(i));
                        Plane plane = new Plane(pts[j], avNormal, EV.Branch(EV.Path(i))[0].UnitVector());
                        // Plane plane = new Plane(pts[j],EV.Branch(EV.Path(i))[0].UnitVector(), M.GetMeshEdgePerpDir(meshEdge));

                        plane = plane.Switch("YX");
                        JointGroups.Add(new Panel(plane), EV.Path(i));
                        //plane.Bake(40);
                    }


                    //Construct joint outlines from planes
                    //Iterate number of joints per edge
                    for (int j = 0; j < pts.Length; j++)
                    {
                        JointGroups.Branch(EV.Path(i))[j].planeOffset0 = JointGroups.Branch(EV.Path(i))[j].plane.MovePlanebyAxis(joints[i].thickness * 0.5);  //offset planes

                        JointGroups.Branch(EV.Path(i))[j].planeOffset1 = JointGroups.Branch(EV.Path(i))[j].plane.MovePlanebyAxis(-joints[i].thickness * 0.5); //offset planes
                        JointGroups.Branch(EV.Path(i))[j].planeRot     = new Plane(pts[j], Vector3d.CrossProduct(EV.Branch(EV.Path(i))[0].UnitVector(), M.GetMeshEdgePerpDir(meshEdge)), M.GetMeshEdgePerpDir(meshEdge));
                        int[] ngons     = M.GetEdgeNgons(meshEdge);
                        Plane tempPlane = JointGroups.Branch(EV.Path(i))[j].planeRot.MovePlanebyAxis(joints[i].length);
                        int   sign      = tempPlane.Origin.DistanceToSquared(centers[ngons[0]]) < tempPlane.Origin.DistanceToSquared(centers[ngons[1]]) ? 1 : -1;

                        JointGroups.Branch(EV.Path(i))[j].planeRotOffset0 = JointGroups.Branch(EV.Path(i))[j].planeRot.MovePlanebyAxis(joints[i].length * sign);  //offset planes
                        JointGroups.Branch(EV.Path(i))[j].planeRotOffset1 = JointGroups.Branch(EV.Path(i))[j].planeRot.MovePlanebyAxis(-joints[i].length * sign); //offset plane
                        JointGroups.Branch(EV.Path(i))[j].planeEdge       = new Plane(pts[j], M.TopologyEdges.EdgeLine(meshEdge).Direction, M.GetMeshEdgePerpDir(meshEdge));

                        List <Plane> planesF0 = new List <Plane>();
                        List <Plane> planesF1 = new List <Plane>();
                        for (int k = 0; k < PanelGroups.Branch(f0).Count; k++)
                        {
                            planesF0.Add(PanelGroups.Branch(f0)[k].plane);
                        }
                        for (int k = 0; k < PanelGroups.Branch(f1).Count; k++)
                        {
                            planesF1.Add(PanelGroups.Branch(f1)[k].plane);
                        }



                        JointGroups.Branch(EV.Path(i))[j].planeF0 = PlaneUtil.AveragePlaneOrigin(planesF0);
                        JointGroups.Branch(EV.Path(i))[j].planeF1 = PlaneUtil.AveragePlaneOrigin(planesF1);

                        //JointGroups.Branch(EV.Path(i))[j].planeF0.MovePlanebyAxis(joints[i].height).Bake(40);
                        //JointGroups.Branch(EV.Path(i))[j].planeF1.MovePlanebyAxis(joints[i].height).Bake(40);

                        List <Plane> jointPlaneLoop = new List <Plane> {
                            JointGroups.Branch(EV.Path(i))[j].planeRotOffset0,
                            JointGroups.Branch(EV.Path(i))[j].planeF0.MovePlanebyAxis(joints[i].height),
                            JointGroups.Branch(EV.Path(i))[j].planeEdge,
                            JointGroups.Branch(EV.Path(i))[j].planeF1.MovePlanebyAxis(joints[i].height),                                   //3
                            JointGroups.Branch(EV.Path(i))[j].planeRotOffset1,
                            JointGroups.Branch(EV.Path(i))[j].planeF1.MovePlanebyAxis(-joints[i].height),                                  //5
                            JointGroups.Branch(EV.Path(i))[j].planeEdge,
                            JointGroups.Branch(EV.Path(i))[j].planeF0.MovePlanebyAxis(-joints[i].height),
                        };

                        //Rhino.RhinoDoc.ActiveDoc.Objects.AddRectangle(new Rectangle3d(JointGroups.Branch(EV.Path(i))[j].planeF1, new Interval(-20, 20), new Interval(-20, 20)));
                        //Rhino.RhinoDoc.ActiveDoc.Objects.AddRectangle(new Rectangle3d(JointGroups.Branch(EV.Path(i))[j].planeF1, new Interval(-20, 20), new Interval(-20, 20)));

                        JointGroups.Branch(EV.Path(i))[j].contourNoJoints[0] = PolylineUtil.PolylineFromPlanes(JointGroups.Branch(EV.Path(i))[j].planeOffset0, jointPlaneLoop);
                        JointGroups.Branch(EV.Path(i))[j].contourNoJoints[1] = PolylineUtil.PolylineFromPlanes(JointGroups.Branch(EV.Path(i))[j].planeOffset1, jointPlaneLoop);
                        JointGroups.Branch(EV.Path(i))[j].contour[0]         = new Polyline(JointGroups.Branch(EV.Path(i))[j].contourNoJoints[0]);
                        JointGroups.Branch(EV.Path(i))[j].contour[1]         = new Polyline(JointGroups.Branch(EV.Path(i))[j].contourNoJoints[1]);
                        //JointGroups.Branch(EV.Path(i))[j].contour[0].Bake();
                    }


                    //Construct Cuts
                    //Iterate number of joints per edge
                    for (int j = 0; j < pts.Length; j++)
                    {
                        int localMeshEdgeF0 = Array.IndexOf(fe[f0], meshEdge);
                        int localMeshEdgeF1 = Array.IndexOf(fe[f1], meshEdge);



                        //Iterate number of panels and create cuts
                        for (int k = 0; k < PanelGroups.Branch(f0).Count; k++)
                        {
                            Panel jointPanel = JointGroups.Branch(EV.Path(i))[j];
                            //Rhino.RhinoApp.WriteLine(jointPanel.contourNoJoints[0].Count.ToString());

                            jointPanel.id = f0.ToString() + "-" + f1.ToString();

                            if (pts.Length > 1)
                            {
                                jointPanel.id += "-" + j.ToString();
                            }

                            PanelGroups.Branch(f0)[k].CreateCut(localMeshEdgeF0, JointGroups.Branch(EV.Path(i))[j].planeOffset0, JointGroups.Branch(EV.Path(i))[j].planeOffset1, joints[i].length, ref jointPanel, false);//, ref neiPanel, ref jointPanel);
                            //PanelGroups.Branch(f1)[k].CreateCut(localMeshEdgeF1, JointGroups.Branch(EV.Path(i))[j].planeOffset0, JointGroups.Branch(EV.Path(i))[j].planeOffset1, joints[i].length, ref jointPanel, false);//, ref neiPanel, ref jointPanel);

                            JointGroups.Branch(EV.Path(i))[j] = jointPanel;
                        }


                        //Iterate number of panels and create cuts
                        for (int k = 0; k < PanelGroups.Branch(f1).Count; k++)
                        {
                            Panel jointPanel = JointGroups.Branch(EV.Path(i))[j];

                            jointPanel.id = f0.ToString() + "-" + f1.ToString();

                            if (pts.Length > 1)
                            {
                                jointPanel.id += "-" + j.ToString();
                            }

                            //PanelGroups.Branch(f0)[k].CreateCut(localMeshEdgeF0, JointGroups.Branch(EV.Path(i))[j].planeOffset0, JointGroups.Branch(EV.Path(i))[j].planeOffset1, joints[i].length, ref jointPanel, false);//, ref neiPanel, ref jointPanel);
                            PanelGroups.Branch(f1)[k].CreateCut(localMeshEdgeF1, JointGroups.Branch(EV.Path(i))[j].planeOffset0, JointGroups.Branch(EV.Path(i))[j].planeOffset1, joints[i].length, ref jointPanel, false);//, ref neiPanel, ref jointPanel);

                            JointGroups.Branch(EV.Path(i))[j] = jointPanel;
                        }
                    }
                }


                for (int i = 0; i < JointGroups.BranchCount; i++)
                {
                    for (int j = 0; j < JointGroups.Branch(i).Count; j++)
                    {
                        if (joints[i].custom == 0)
                        {
                            if (joints[i].custom > 0)
                            {
                                JointGroups.Branch(i)[j].ChangeJoint(joints[i].custom, 0, joints[i].cutExtend, joints[i].addExtend);
                            }
                            else if (joints[i].custom < 0)
                            {
                                JointGroups.Branch(i)[j].ChangeJoint(joints[i].custom, 1, joints[i].cutExtend, joints[i].addExtend);
                            }
                        }
                    }
                }



                ////////////////////////Output
                var dtPlates       = new DataTree <Polyline>();
                var dtJoints       = new DataTree <Polyline>();
                var dtPlatesMid    = new DataTree <Polyline>();
                var dtJointsMid    = new DataTree <Polyline>();
                var dtPlatesPlanes = new DataTree <Plane>();
                var dtJointsPlanes = new DataTree <Plane>();
                var dtPlatesTxt    = new DataTree <Curve>();
                var dtJointsTxt    = new DataTree <Curve>();

                var dtPlatesLast       = new DataTree <Polyline>();
                var dtJointsLast       = new DataTree <Polyline>();
                var dtPlatesMidLast    = new DataTree <Polyline>();
                var dtJointsMidLast    = new DataTree <Polyline>();
                var dtPlatesPlanesLast = new DataTree <Plane>();
                var dtJointsPlanesLast = new DataTree <Plane>();
                var dtPlatesTxtLast    = new DataTree <Curve>();
                var dtJointsTxtLast    = new DataTree <Curve>();

                HashSet <int> jointSequenceTemp = new HashSet <int>();
                HashSet <int> jointSequence     = new HashSet <int>();

                HashSet <int> jointSequenceLast = new HashSet <int>();
                int           last = Math.Min(iterations, PanelGroups.BranchCount);
                int           prev = Math.Max(0, last - (int)textSize[6]);



                for (int i = 0; i < last; i++)  //Math.Min(iterations, sequence.Count) PanelGroups.BranchCount

                {
                    for (int j = 0; j < fe[i].Length; j++)
                    {
                        bool seq = jointSequenceTemp.Add(fe[i][j]);

                        if (i >= prev)
                        {
                            if (seq)
                            {
                                jointSequenceLast.Add(fe[i][j]);
                            }
                            else
                            {
                                jointSequence.Add(fe[i][j]);
                            }
                        }
                        else
                        {
                            jointSequence.Add(fe[i][j]);
                        }
                    }

                    for (int j = 0; j < PanelGroups.Branch(i).Count; j++)
                    {
                        if (i >= prev)
                        {
                            dtPlatesLast.Add(PanelGroups.Branch(i)[j].contour[0], new GH_Path(i, j));
                            dtPlatesLast.Add(PanelGroups.Branch(i)[j].contour[1], new GH_Path(i, j));
                            dtPlatesMidLast.Add(PanelGroups.Branch(i)[j].MidContour(), new GH_Path(i, j));
                        }
                        else
                        {
                            dtPlates.Add(PanelGroups.Branch(i)[j].contour[0], new GH_Path(i, j));
                            dtPlates.Add(PanelGroups.Branch(i)[j].contour[1], new GH_Path(i, j));
                            dtPlatesMid.Add(PanelGroups.Branch(i)[j].MidContour(), new GH_Path(i, j));
                        }



                        Plane textPlane = PanelGroups.Branch(i)[j].planeOffset0;
                        textPlane.Flip();

                        if (j > 0)
                        {
                            textPlane = PanelGroups.Branch(i)[j].planeOffset1;
                        }



                        if (i >= prev)
                        {
                            dtPlatesPlanesLast.Add(textPlane, new GH_Path(i, j));
                        }
                        else
                        {
                            dtPlatesPlanes.Add(textPlane, new GH_Path(i, j));
                        }


                        string text   = i.ToString() + "-" + j.ToString();
                        var    txtCrv = Typewriter.Regular.Write(text, textPlane, textSize[0]);


                        if (i >= prev)
                        {
                            dtPlatesTxtLast.AddRange(txtCrv, new GH_Path(i, j));
                        }
                        else
                        {
                            dtPlatesTxt.AddRange(txtCrv, new GH_Path(i, j));
                        }


                        var a = PanelGroups.Branch(i)[j];

                        Line[] segments = PanelGroups.Branch(i)[j].contourNoJoints[Math.Min(1, j)].GetSegments();


                        int counter = 0;
                        foreach (Line l in segments)
                        {
                            int meshEdge = fe[i][counter];

                            int neiF = M.GetOppositeNgon(meshEdge, i);


                            //Adjacent face plane
                            Point3d  origin = l.PointAt(textSize[3]);
                            Vector3d xaxis  = l.Direction;
                            Vector3d yaxis  = l.Direction;
                            origin.Transform(Rhino.Geometry.Transform.Scale(textPlane.Origin, textSize[4]));
                            yaxis.Rotate(Math.PI * 0.5, textPlane.ZAxis);
                            Plane ePlane = new Plane(origin, xaxis, yaxis);

                            var txtCrvF = Typewriter.Regular.Write(neiF.ToString(), ePlane, textSize[2]);


                            if (i >= prev)
                            {
                                dtPlatesTxtLast.AddRange(txtCrvF, new GH_Path(i, j));
                            }
                            else
                            {
                                dtPlatesTxt.AddRange(txtCrvF, new GH_Path(i, j));
                            }



                            //Mesh edge direction
                            Line meshEdgeLine = M.TopologyEdges.EdgeLine(meshEdge);
                            meshEdgeLine.Transform(Rhino.Geometry.Transform.Scale(meshEdgeLine.PointAt(0.5), textSize[4]));
                            meshEdgeLine.Transform(Rhino.Geometry.Transform.Scale(textPlane.Origin, textSize[4]));
                            //meshEdgeLine.Extend(-textSize[4], -textSize[4]);


                            Plane e0Plane = new Plane(ePlane.ClosestPoint(meshEdgeLine.From), xaxis, yaxis);
                            Plane e1Plane = new Plane(ePlane.ClosestPoint(meshEdgeLine.To), xaxis, yaxis);

                            var txtCrvF0 = Typewriter.Regular.Write("I", e0Plane, textSize[2]);


                            if (i >= prev)
                            {
                                dtPlatesTxtLast.AddRange(txtCrvF0, new GH_Path(i, j));
                            }
                            else
                            {
                                dtPlatesTxt.AddRange(txtCrvF0, new GH_Path(i, j));
                            }

                            var txtCrvF1 = Typewriter.Regular.Write("II", e1Plane, textSize[2]);


                            if (i >= prev)
                            {
                                dtPlatesTxtLast.AddRange(txtCrvF1, new GH_Path(i, j));
                            }
                            else
                            {
                                dtPlatesTxt.AddRange(txtCrvF1, new GH_Path(i, j));
                            }


                            counter++;
                            //
                        }
                    }
                }

                DataTree <Vector3d> insertionVectors = new DataTree <Vector3d>();


                foreach (int meshEdge in jointSequence)
                {
                    if (!meshEdgeDict.ContainsKey(meshEdge))
                    {
                        continue;
                    }
                    int i = meshEdgeDict[meshEdge];



                    for (int j = 0; j < JointGroups.Branch(i).Count; j++)
                    {
                        GH_Path path = new GH_Path(meshEdge, j);

                        insertionVectors.Add(JointGroups.Branch(i)[j].planeOffset0.XAxis, path);


                        dtJoints.Add(JointGroups.Branch(i)[j].contour[0], path);
                        dtJoints.Add(JointGroups.Branch(i)[j].contour[1], path);
                        dtJointsMid.Add(JointGroups.Branch(i)[j].MidContour(), path);
                        dtJointsPlanes.Add(JointGroups.Branch(i)[j].planeOffset0, path);

                        Plane planet = new Plane(JointGroups.Branch(i)[j].planeOffset0.Origin + JointGroups.Branch(i)[j].planeOffset0.YAxis * textSize[5], JointGroups.Branch(i)[j].planeOffset0.XAxis, JointGroups.Branch(i)[j].planeOffset0.YAxis);



                        string text   = JointGroups.Branch(i)[j].id;
                        var    txtCrv = Typewriter.Regular.Write(text, planet, textSize[1]);
                        dtJointsTxt.AddRange(txtCrv, path);
                    }
                }



                foreach (int meshEdge in jointSequenceLast)
                {
                    if (!meshEdgeDict.ContainsKey(meshEdge))
                    {
                        continue;
                    }
                    int i = meshEdgeDict[meshEdge];



                    for (int j = 0; j < JointGroups.Branch(i).Count; j++)
                    {
                        dtJointsLast.Add(JointGroups.Branch(i)[j].contour[0], new GH_Path(meshEdge, j));
                        dtJointsLast.Add(JointGroups.Branch(i)[j].contour[1], new GH_Path(meshEdge, j));
                        dtJointsMidLast.Add(JointGroups.Branch(i)[j].MidContour(), new GH_Path(meshEdge, j));

                        dtJointsPlanesLast.Add(JointGroups.Branch(i)[j].planeOffset0, new GH_Path(meshEdge, j));

                        Plane planet = new Plane(JointGroups.Branch(i)[j].planeOffset0.Origin + JointGroups.Branch(i)[j].planeOffset0.YAxis * textSize[5], JointGroups.Branch(i)[j].planeOffset0.XAxis, JointGroups.Branch(i)[j].planeOffset0.YAxis);


                        string text   = JointGroups.Branch(i)[j].id;
                        var    txtCrv = Typewriter.Regular.Write(text, planet, textSize[1]);
                        dtJointsTxtLast.AddRange(txtCrv, new GH_Path(meshEdge, j));
                    }
                }


                DA.SetDataTree(0, dtPlates);
                DA.SetDataTree(1, dtJoints);

                DA.SetDataTree(2, dtPlatesMid);
                DA.SetDataTree(3, dtJointsMid);

                DA.SetDataTree(4, dtPlatesPlanes);
                DA.SetDataTree(5, dtJointsPlanes);

                DA.SetDataTree(6, dtPlatesTxt);
                DA.SetDataTree(7, dtJointsTxt);



                DA.SetDataTree(8, dtPlatesLast);
                DA.SetDataTree(9, dtJointsLast);

                DA.SetDataTree(10, dtPlatesMidLast);
                DA.SetDataTree(11, dtJointsMidLast);

                DA.SetDataTree(12, dtPlatesPlanesLast);
                DA.SetDataTree(13, dtJointsPlanesLast);

                DA.SetDataTree(14, dtPlatesTxtLast);
                DA.SetDataTree(15, dtJointsTxtLast);
            } catch (Exception e) {
                Rhino.RhinoApp.WriteLine(e.ToString());
            }
        }
示例#5
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            Mesh M = DA.Fetch <Mesh>("Mesh");
            GH_Structure <GH_Curve>  Curves      = DA.FetchTree <GH_Curve>("Panels");
            DataTree <Polyline>      C           = new DataTree <Polyline>();
            GH_Structure <GH_Vector> edgeVectors = DA.FetchTree <GH_Vector>("EdgeVectors");
            DataTree <Vector3d>      EVec        = new DataTree <Vector3d>();
            int    D      = DA.Fetch <int>("JointDiv");
            double L      = DA.Fetch <double>("JointLen");
            double H      = DA.Fetch <double>("JointHei");
            double W      = DA.Fetch <double>("JointThi");
            bool   Center = DA.Fetch <bool>("Center");
            bool   Finger = DA.Fetch <bool>("Finger");
            double Custom = DA.Fetch <double>("Custom");
            GH_Structure <GH_Curve> CurvesChamfer = DA.FetchTree <GH_Curve>("PanelsChamfer");
            DataTree <Polyline>     CChamfer      = new DataTree <Polyline>();


            for (int i = 0; i < Curves.Branches.Count; i++)
            {
                for (int j = 0; j < Curves.get_Branch(i).Count; j++)
                {
                    Polyline polyline;
                    Curves.get_DataItem(Curves.Paths[i], j).Value.TryGetPolyline(out polyline);
                    C.Add(polyline, Curves.Paths[i]);
                }
            }

            if (CurvesChamfer.DataCount == Curves.DataCount)
            {
                for (int i = 0; i < Curves.Branches.Count; i++)
                {
                    for (int j = 0; j < Curves.get_Branch(i).Count; j++)
                    {
                        Polyline polyline;
                        CurvesChamfer.get_DataItem(Curves.Paths[i], j).Value.TryGetPolyline(out polyline);
                        CChamfer.Add(polyline, Curves.Paths[i]);
                    }
                }
            }

            for (int i = 0; i < edgeVectors.Branches.Count; i++)
            {
                for (int j = 0; j < edgeVectors.get_Branch(i).Count; j++)
                {
                    EVec.Add(edgeVectors.get_DataItem(edgeVectors.Paths[i], j).Value, edgeVectors.Paths[i]);
                }
            }

            //Solution

            DataTree <Polyline> diagonalConnections = new DataTree <Polyline>();



            int    divisions = Math.Max(1, D);
            double length    = L;//Math.Max(0.1, L);
            double height    = Math.Max(0.1, H);
            double width     = Math.Max(0.1, W);


            int[][]                 tv     = M.GetNGonsTopoBoundaries();
            int[][]                 fe     = M.GetNGonFacesEdges(tv);
            HashSet <int>           e      = M.GetAllNGonEdges(tv);
            Dictionary <int, int[]> efDict = M.GetFE(e, false);

            Point3d[] centers = M.GetNGonCenters();


            DataTree <Polyline> Ccut = new DataTree <Polyline>();

            for (int i = 0; i < C.BranchCount; i++)
            {
                for (int j = 0; j < C.Branch(i).Count; j++)
                {
                    if (CurvesChamfer.DataCount == Curves.DataCount)
                    {
                        Ccut.Add(new Polyline(CChamfer.Branch(i)[j]), new GH_Path(CChamfer.Path(i)));
                    }
                    else
                    {
                        Ccut.Add(new Polyline(C.Branch(i)[j]), new GH_Path(C.Path(i)));
                        //Rhino.RhinoApp.WriteLine(CChamfer.DataCount.ToString() + " " + Curves.DataCount.ToString());
                    }
                }
            }



            DataTree <Vector3d> EV = new DataTree <Vector3d>();

            if (EVec.DataCount == 0)
            {
                foreach (int ee in e)
                {
                    if (M.TopologyEdges.GetConnectedFaces(ee).Length != 1)
                    {
                        if (Center)
                        {
                            int[]    facePair     = efDict[ee];
                            Vector3d insertionVec = centers[facePair[0]] - centers[facePair[1]];
                            insertionVec.Unitize();
                            EV.Add(insertionVec, new GH_Path(ee));
                            //Line li = new Line(centers[facePair[0]] , centers[facePair[1]]);
                            //Rhino.RhinoDoc.ActiveDoc.Objects.AddLine(li);
                        }
                        else
                        {
                            EV.Add(NGonsCore.VectorUtil.BisectorVector(M.TopologyEdges.EdgeLine(ee), M.GetNGonNormal(efDict[ee][0])), new GH_Path(ee));
                        }
                    }
                }
            }
            else
            {
                EV = EVec;
            }



            DataTree <Polyline> recJoints = new DataTree <Polyline>();

            for (int i = 0; i < EV.BranchCount; i++)
            {
                GH_Path p    = EV.Path(i);
                int     ecur = p.Indices[0];
                int     f0   = efDict[ecur][0];
                int     f1   = efDict[ecur][1];

                //Divide line into points
                Line      line = M.TopologyEdges.EdgeLine(ecur);
                Point3d[] pts  = NGonsCore.PointUtil.InterpolatePoints(line.From, line.To, divisions, false);
                Point3d[] pts0 = new Point3d[pts.Length];
                Point3d[] pts1 = new Point3d[pts.Length];

                //Get average normal between faces
                Vector3d edgeNormal = M.GetNGonNormal(f0) + M.GetNGonNormal(f1);
                edgeNormal.Unitize();
                Vector3d cross = Vector3d.CrossProduct(edgeNormal, EV.Branch(p)[0]);
                cross.Unitize();

                //Get line planes
                Plane[] edgePlanes  = new Plane[pts.Length];
                Plane   edgePlane90 = new Plane(line.PointAt(0.5), cross, edgeNormal);

                for (int j = 0; j < pts.Length; j++)
                {
                    Vector3d v = EV.Branch(p)[0];
                    v.Unitize();
                    edgePlanes[j] = new Plane(pts[j], v, edgeNormal);
                }



                Point3d[][] edgePoints = new Point3d[edgePlanes.Length][];



                for (int j = 0; j < edgePlanes.Length; j++)  //C.Branch(f0).Count


                {
                    Polyline[]        rectangleWithoutJoints = new Polyline[] { new Polyline(), new Polyline() };
                    List <Polyline>[] rectangleJoints        = new List <Polyline>[] { new List <Polyline>(), new List <Polyline>() };

                    foreach (int fn in efDict[ecur])
                    {
                        int e0 = Array.IndexOf(fe[fn], ecur);

                        edgePoints[j] = new Point3d[C.Branch(fn).Count];
                        Polyline[] perpJoint = new Polyline[C.Branch(fn).Count];

                        Polyline recJoint0 = new Polyline();
                        Polyline recJoint1 = new Polyline();

                        for (int k = 0; k < C.Branch(fn).Count; k++)
                        {
                            if (k % 2 == 0 && k != 0)
                            {
                                //rectangleJoints[0].Add(recJoint0);
                                //rectangleJoints[1].Add(recJoint1);
                                recJoint0.Clear();
                                recJoint1.Clear();
                            }


                            Line  segment   = C.Branch(fn)[k].SegmentAt(e0);
                            Plane planeOff0 = edgePlanes[j].MovePlanebyAxis(W * 0.5);
                            Plane planeOff1 = edgePlanes[j].MovePlanebyAxis(-W * 0.5);

                            Plane planeFace = C.Branch(fn)[k].plane();
                            Plane plane3    = new Plane(planeFace.Origin, edgePlanes[j].Normal, planeFace.Normal);


                            //Face0 edge points
                            Point3d edgePoint0 = PlaneUtil.LinePlane(segment, planeOff0);
                            Point3d edgePoint1 = PlaneUtil.LinePlane(segment, planeOff1);
                            //Inner Points
                            Vector3d v0 = PlaneUtil.PlanePlaneVec(planeFace, planeOff0);
                            Vector3d v1 = PlaneUtil.PlanePlaneVec(planeFace, planeOff1);

                            bool moveFlag = (segment.PointAt(0.5) + v0).DistanceTo(planeFace.Origin) < (segment.PointAt(0.5) - v0).DistanceTo(planeFace.Origin);
                            bool flagMod  = j % 2 == 0;
                            bool flagFace = efDict[ecur][0] == fn;
                            flagMod = false;

                            //double scalarLength = (centers[fn] - edgePlanes[j].Origin).Length*(double)Math.Abs(length);
                            if (L < 0)
                            {
                                length = (centers[fn] - edgePlanes[j].Origin).Length * (double)Math.Abs(L);
                            }
                            //length = (centers[fn] - edgePlanes[j].Origin).Length*1;

                            Point3d innerPoint0 = (moveFlag) ? edgePoint0 + (v0 * length) : edgePoint0 - (v0 * length);
                            Point3d innerPoint1 = (moveFlag) ? edgePoint1 + (v1 * length) : edgePoint1 - (v1 * length);

                            if (Finger)
                            {
                                innerPoint0 = (!moveFlag && !Finger) ? edgePoint0 + (v0 * length) : edgePoint0 - (v0 * length);
                                innerPoint1 = (!moveFlag && !Finger) ? edgePoint1 + (v1 * length) : edgePoint1 - (v1 * length);
                            }

                            //Point3d innerPoint0 = edgePoint0 +(v0 * L);
                            //Point3d innerPoint1 = edgePoint1 +(v1 * L) ;

                            Polyline polylinep0 = new Polyline(new Point3d[] { edgePoint0, innerPoint0, innerPoint1, edgePoint1 });

                            // Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(polylinep0);



                            Line    guideLine0 = new Line(edgePoint0, innerPoint0);
                            Line    guideLine1 = new Line(edgePoint1, innerPoint1);
                            Point3d mid        = (innerPoint1 + innerPoint0) * 0.5;
                            innerPoint0 = guideLine0.ClosestPoint(mid, false);
                            innerPoint1 = guideLine1.ClosestPoint(mid, false);

                            Point3d center = (edgePoint0 + innerPoint0 + innerPoint1 + edgePoint1) * 0.25;



                            Point3d center0 = guideLine0.ClosestPoint(center, false);
                            Point3d center1 = guideLine1.ClosestPoint(center, false);

                            perpJoint[k] = new Polyline(new Point3d[] { innerPoint0, center0, center1, innerPoint1 });
                            Polyline polyline0 = new Polyline(new Point3d[] { edgePoint0, center0, center1, edgePoint1 });

                            //finger joints or standard
                            if (Finger)
                            {
                                if (efDict[ecur][0] == fn)
                                {
                                    Ccut.Branch(efDict[ecur][0])[k].InsertPolyline(polyline0);//offset needed
                                }
                                else
                                {
                                    Ccut.Branch(efDict[ecur][1])[k].InsertPolyline(polyline0);//offset needed
                                }
                            }
                            else
                            {
                                Ccut.Branch(fn)[k].InsertPolyline(polyline0);//offset needed
                            }


                            if (fn == efDict[ecur][0])
                            {
                                if (k == 1 || k == NGonsCore.MathUtil.Wrap(C.Branch(fn).Count - 2, C.Branch(fn).Count))
                                {
                                    rectangleWithoutJoints[0].Add(innerPoint0);
                                    rectangleWithoutJoints[1].Add(innerPoint1);
                                }
                            }
                            else
                            {
                                if (k == 1)
                                {
                                    rectangleWithoutJoints[0].Add(innerPoint0);
                                    rectangleWithoutJoints[1].Add(innerPoint1);
                                }

                                if (k == NGonsCore.MathUtil.Wrap(C.Branch(fn).Count - 2, C.Branch(fn).Count))
                                {
                                    rectangleWithoutJoints[0].Insert(2, innerPoint0);
                                    rectangleWithoutJoints[1].Insert(2, innerPoint1);
                                }
                            }


                            // Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(innerPoint0);
                            //Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(center0);
                            //Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(innerPoint1);
                            // Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(recJoint0);
                            //Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(recJoint1);

                            if (k % 2 == 0)
                            {
                                recJoint0.Add(innerPoint0);
                                recJoint0.Add(center0);
                                recJoint1.Add(innerPoint1);
                                recJoint1.Add(center1);
                            }
                            else
                            {
                                recJoint0.Add(center0);
                                recJoint0.Add(innerPoint0);
                                recJoint1.Add(center1);
                                recJoint1.Add(innerPoint1);
                            }

                            if (k % 2 == 1)
                            {
                                rectangleJoints[0].Add(new Polyline(recJoint0));
                                rectangleJoints[1].Add(new Polyline(recJoint1));
                            }
                            if (k % 2 == 1)
                            {
                                //Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(recJoint0);
                                //Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(recJoint1);
                            }
                            //edgePoints[j][k] = edgePoint0;
                            //            Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(edgePoint0);
                            //            Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(edgePoint1);
                            //            Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(innerPoint0);
                            //            Rhino.RhinoDoc.ActiveDoc.Objects.AddPoint(innerPoint1);
                            //            Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(polyline0);
                        }
                    }
                    for (int m = 0; m < rectangleWithoutJoints.Length; m++)
                    {
                        Line l0 = CurveUtil.ExtendLine(rectangleWithoutJoints[m].SegmentAt(0), height);
                        Line l1 = CurveUtil.ExtendLine(rectangleWithoutJoints[m].SegmentAt(2), height);
                        if (l0.From.DistanceTo(l1.From) < l0.From.DistanceTo(l1.To))
                        {
                            l1.Flip();
                        }
                        rectangleWithoutJoints[m] = new Polyline(new Point3d[] { l0.From, l0.To, l1.From, l1.To, l0.From });
                        // Line line
                    }

                    for (int m = 0; m < rectangleJoints[0].Count; m++)
                    {
                        //Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(rectangleJoints[0][j]);
                        rectangleWithoutJoints[0].InsertPolyline(rectangleJoints[0][m]);
                        rectangleWithoutJoints[1].InsertPolyline(rectangleJoints[1][m]);
                    }

                    //try make special joint
                    if (Custom >= 0 && C.Branch(0).Count == 4)
                    {
                        Polyline rebuild0 = new Polyline();
                        Polyline rebuild1 = new Polyline();
                        for (int m = 2; m < 18; m++)
                        {
                            if (m == 2)
                            {
                                Vector3d v0 = rectangleWithoutJoints[0][m] - rectangleWithoutJoints[0][m + 1];
                                v0.Unitize();
                                rebuild0.Add(rectangleWithoutJoints[0][m] + v0 * Custom);
                                rebuild1.Add(rectangleWithoutJoints[1][m] + v0 * Custom);
                            }
                            else if (m == 17)
                            {
                                Vector3d v0 = rectangleWithoutJoints[0][17] - rectangleWithoutJoints[0][16];
                                v0.Unitize();
                                rebuild0.Add(rectangleWithoutJoints[0][17] + v0 * Custom);
                                rebuild1.Add(rectangleWithoutJoints[1][17] + v0 * Custom);
                            }
                            else
                            {
                                rebuild0.Add(rectangleWithoutJoints[0][m]);
                                rebuild1.Add(rectangleWithoutJoints[1][m]);
                            }
                        }
                        rebuild0.Close();
                        rebuild1.Close();
                        rectangleWithoutJoints[0] = rebuild0;
                        rectangleWithoutJoints[1] = rebuild1;
                    }

                    recJoints.AddRange(rectangleWithoutJoints, new GH_Path(ecur));
                }



                //Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(rectangleWithoutJoints[0]);
                //Rhino.RhinoDoc.ActiveDoc.Objects.AddPolyline(rectangleWithoutJoints[1]);
                //A = edgePlanes;
            }

            DA.SetDataTree(0, Ccut);
            DA.SetDataTree(1, recJoints);

            //DC = diagonalConnections;
            //Panels = Ccut;
            //Joints = recJoints;
        }