private List <double> checkCoplanarity(SpringMesh sMesh, double thickness, List <Line> linesUp, List <Line> linesDown)
        {
            List <double> coplanarity = new List <double>();

            foreach (Edge edge in sMesh.Edges)
            {
                if (edge.SecondTriangleIndex >= 0)
                {
                    int triLeft  = edge.FirstTriangleIndex;
                    int triRight = edge.SecondTriangleIndex;

                    Point3d centreLeftO  = sMesh.ComputeTriangleCentroid(triLeft);
                    Point3d centreRightO = sMesh.ComputeTriangleCentroid(triRight);

                    Point3d centreLeft  = sMesh.ComputeTPI(triLeft);
                    Point3d centreRight = sMesh.ComputeTPI(triRight);

                    if (ICD.Utils.Distance(centreLeftO, centreLeft) < iMaxThickness && ICD.Utils.Distance(centreRightO, centreRight) < iMaxThickness)
                    {
                        Vector3d normalLeft  = sMesh.ComputeTriangleNormal(triLeft);
                        Vector3d normalRight = sMesh.ComputeTriangleNormal(triRight);

                        Point3d centreLeftUp  = centreLeft + normalLeft * thickness;
                        Point3d centreRightUp = centreRight + normalRight * thickness;

                        Point3d centreLeftDown  = centreLeft - normalLeft * thickness;
                        Point3d centreRightDown = centreRight - normalRight * thickness;

                        linesUp.Add(new Line(centreLeftUp, centreRightUp));
                        linesDown.Add(new Line(centreLeftDown, centreRightDown));

                        Line planarCheckLine01 = new Line(centreLeftUp, centreRightDown);
                        Line planarCheckLine02 = new Line(centreRightUp, centreLeftDown);

                        double dist = planarCheckLine01.MinimumDistanceTo(planarCheckLine02);
                        coplanarity.Add(dist);
                    }
                }
            }
            return(coplanarity);
        }
Пример #2
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            // =============================================================================================================
            // Reset
            // =============================================================================================================

            DA.GetData <bool>("Reset", ref iReset);

            if (iReset)
            {
                DA.GetData <SpringMesh>("Spring Mesh", ref iSpringMesh);
                DA.GetData <int>("Population Size", ref iPopulationSize);

                triangleCentres = new List <Point3d>();
                trianglePlanes  = new List <Plane>();
                triangleNormals = new List <Vector3d>();
                for (int i = 0; i < iSpringMesh.Triangles.Count; i++)
                {
                    triangleCentres.Add(iSpringMesh.ComputeCircumscribedCircleCenter(i));
                    trianglePlanes.Add(new Plane(
                                           iSpringMesh.Vertices[iSpringMesh.Triangles[i].FirstVertexIndex].Position,
                                           iSpringMesh.Vertices[iSpringMesh.Triangles[i].SecondVertexIndex].Position,
                                           iSpringMesh.Vertices[iSpringMesh.Triangles[i].ThirdVertexIndex].Position
                                           ));
                    triangleNormals.Add(iSpringMesh.ComputeTriangleNormal(i));
                }

                edgeXAxes   = new List <Vector3d>();
                edgeYAxes   = new List <Vector3d>();
                edgeZAxes   = new List <Vector3d>();
                edgePlanes  = new List <Plane>();
                edgeOrigins = new List <Point3d>();

                List <double> geneMinValues = new List <double>();
                List <double> geneMaxValues = new List <double>();

                foreach (Edge edge in iSpringMesh.Edges)
                {
                    if (edge.SecondTriangleIndex >= 0)
                    {
                        Vector3d edgeXAxis = iSpringMesh.Vertices[edge.SecondVertexIndex].Position - iSpringMesh.Vertices[edge.FirstVertexIndex].Position;
                        edgeXAxes.Add(edgeXAxis);

                        Vector3d edgeZAxis = triangleNormals[edge.FirstTriangleIndex] + triangleNormals[edge.SecondTriangleIndex];
                        edgeZAxis.Unitize();
                        edgeZAxes.Add(edgeZAxis);

                        Vector3d edgeYAxis = Vector3d.CrossProduct(edgeZAxis, edgeXAxis);
                        edgeYAxes.Add(edgeYAxis);

                        Point3d edgePlaneOrigin = 0.5 * (iSpringMesh.Vertices[edge.FirstVertexIndex].Position + iSpringMesh.Vertices[edge.SecondVertexIndex].Position);

                        edgeOrigins.Add(edgePlaneOrigin);


                        edgePlanes.Add(new Plane(edgePlaneOrigin, edgeXAxis, edgeYAxis));

                        double angle = Utils.AngleBetweenTwoUnitVectors(edgeZAxis, triangleNormals[edge.FirstTriangleIndex]);

                        geneMinValues.Add(-angle);
                        geneMaxValues.Add(angle);
                    }
                    else
                    {
                        Vector3d edgeXAxis = iSpringMesh.Vertices[edge.SecondVertexIndex].Position - iSpringMesh.Vertices[edge.FirstVertexIndex].Position;
                        edgeXAxes.Add(edgeXAxis);

                        Vector3d edgeZAxis = triangleNormals[edge.FirstTriangleIndex];
                        if (edgeZAxis.Z < 0.0)
                        {
                            edgeZAxis += -Vector3d.ZAxis;
                        }
                        else
                        {
                            Vector3d temp = new Vector3d(-edgeZAxis.X, -edgeZAxis.Y, 0.0);
                            temp.Unitize();
                            edgeZAxis += temp;
                        }

                        edgeZAxis.Unitize();
                        edgeZAxes.Add(edgeZAxis);

                        Vector3d edgeYAxis = Vector3d.CrossProduct(triangleNormals[edge.FirstTriangleIndex], edgeXAxis);
                        edgeYAxes.Add(edgeYAxis);

                        Point3d edgePlaneOrigin = 0.5 * (iSpringMesh.Vertices[edge.FirstVertexIndex].Position + iSpringMesh.Vertices[edge.SecondVertexIndex].Position);

                        edgeOrigins.Add(edgePlaneOrigin);

                        edgePlanes.Add(new Plane(edgePlaneOrigin, edgeXAxis, edgeYAxis));

                        double angle = Utils.AngleBetweenTwoUnitVectors(edgeZAxis, triangleNormals[edge.FirstTriangleIndex]);

                        geneMinValues.Add(-angle);
                        geneMaxValues.Add(angle);
                    }
                }

                beagle = new Beagle(iPopulationSize, geneMinValues, geneMaxValues);

                foreach (Genome genome in beagle.Genomes)
                {
                    computeFitness(genome);
                }

                goto Conclusion;
            }


            DA.GetData <bool>("Play", ref iPlay);

            if (iPlay)
            {
                ExpireSolution(true);
            }
            else
            {
                List <double> values = new List <double>();
                foreach (Gene gene in beagle.Genomes[0].Genes)
                {
                    values.Add(gene.Value);
                }
                DA.SetDataList(4, values);
                goto Conclusion;
            }
            //if (!iPlay) goto Conclusion;


            // ====================================================================================================
            // Evolution
            // ====================================================================================================

            DA.GetData <int>("Subiteration Count", ref iSubiterationCount);
            DA.GetData <double>("Max. Coupling Distance", ref iMaxCouplingDistance);
            DA.GetData <double>("Mutation Rate", ref iMutationRate);
            DA.GetData <double>("Mutation Amount", ref iMutationAmount);

            beagle.MaxCouplingDistance = iMaxCouplingDistance;
            beagle.MutationRate        = iMutationRate;
            beagle.MutationAmount      = iMutationAmount;

            for (int i = 0; i < iSubiterationCount; i++)
            {
                beagle.SelectParents();
                beagle.Reproduce();

                for (int j = beagle.PopulationSize; j < beagle.Genomes.Count; j++)
                {
                    computeFitness(beagle.Genomes[j]);
                }

                beagle.SelectFittests();
            }

            DA.SetDataList(3, new List <double> {
                beagle.Genomes[0].Fitness
            });

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

Conclusion:

            Genome bestGenome = beagle.Genomes[0];

            for (int i = 0; i < bestGenome.Genes.Count; i++)
            {
                double angle = bestGenome.Genes[i].Value;

                Vector3d planeNormal = Math.Sin(angle) * edgeYAxes[i] + Math.Cos(angle) * edgeZAxes[i];

                edgePlanes[i] = new Plane(
                    edgePlanes[i].Origin,
                    edgePlanes[i].XAxis,
                    Vector3d.CrossProduct(planeNormal, edgePlanes[i].XAxis)
                    );
            }

            //List<Plane> nastyPlanes = new List<Plane>();
            List <Point3d> planeTripletIntersections = new List <Point3d>();

            foreach (Triangle triangle in iSpringMesh.Triangles)
            {
                Point3d intersectionPoint;
                if (Intersection.PlanePlanePlane(edgePlanes[triangle.FirstEdgeIndex], edgePlanes[triangle.SecondEdgeIndex], edgePlanes[triangle.ThirdEdgeIndex], out intersectionPoint))
                {
                    planeTripletIntersections.Add(intersectionPoint);
                }
                //else
                //{
                //    nastyPlanes.Add(edgePlanes[triangle.FirstEdgeIndex]);
                //    nastyPlanes.Add(edgePlanes[triangle.FirstEdgeIndex]);
                //    nastyPlanes.Add(edgePlanes[triangle.FirstEdgeIndex]);
                //}
            }

            DA.SetDataList(1, edgePlanes);
            DA.SetDataList(2, planeTripletIntersections);



            //DA.SetDataList(1, edgePlanes);
            //DA.SetDataList(2, edgeOrigins);
            //DA.SetDataList(3, edgeXAxes);
            //DA.SetDataList(4, edgeYAxes);
            //DA.SetDataList(5, edgeZAxes);
        }
Пример #3
0
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            iPoints = new List <Point3d>();
            DA.GetDataList <Point3d>("Points", iPoints);
            iApicals = new List <Circle>();
            DA.GetDataList <Circle>("Apicals", iApicals);
            iMasses = new List <double>();
            DA.GetDataList <double>("Masses", iMasses);
            DA.GetData <Curve>("Boundary Curve", ref iBoundaryCurve);
            DA.GetData <double>("Rest Length Scale", ref iRestLengthScale);
            DA.GetData <double>("Rest Length Offset", ref iRestLengthOffset);
            DA.GetData <double>("Stiffness", ref iStiffness);
            DA.GetData <double>("Bending Stiffness", ref iBendingStiffness);
            DA.GetData <bool>("In/Out Switch", ref iInOutSwitch);
            DA.GetData <double>("In/Out Threshold", ref iInOutThreshold);
            DA.GetData <double>("Fixed Point Threshold", ref iFixedPointThreshold);
            iFixedPointExclusion = new List <Curve>();
            DA.GetDataList <Curve>("Fixed Point Exclusion", iFixedPointExclusion);
            iFixedPointInclusion = new List <Curve>();
            DA.GetDataList <Curve>("Fixed Point Inclusion", iFixedPointInclusion);


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

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

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

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

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


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


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

            oSpringMesh = new SpringMesh();

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

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

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

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

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

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

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

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

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

                bool vertexFixedness = true;

                if (Utils.Distance(p, iBoundaryCurve.PointAt(t)) > iFixedPointThreshold)
                {
                    vertexFixedness = false;
                }
                else
                {
                    foreach (Curve curve in iFixedPointExclusion)
                    {
                        if (curve.Contains(p) == PointContainment.Inside)
                        {
                            vertexFixedness = false;
                            break;
                        }
                    }
                }

                foreach (Curve curve in iFixedPointInclusion)
                {
                    if (curve.Contains(p) == PointContainment.Inside)
                    {
                        vertexFixedness = true;
                        break;
                    }
                }

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


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

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


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

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

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

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

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

                                int triangleIndex = oSpringMesh.Triangles.Count - 1;

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

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

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

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

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

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

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


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

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


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

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

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

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

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

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

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

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

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

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


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

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

            foreach (Vertex vertex in oSpringMesh.Vertices)
            {
                vertex.Position.Z = computeBiasHeight(vertex.Position, iBiasApicalRegion);
            }


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

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

            DA.SetData(0, oInfo);
            DA.SetDataList(1, oDebugCurves1);
            DA.SetData(6, oSpringMesh);
        }
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            DA.GetData <SpringMesh>("Spring Mesh", ref iSpringMesh);
            DA.GetData <bool>("Reset", ref iReset);
            DA.GetData <bool>("Play", ref iPlay);
            DA.GetData <int>("Subiteration Count", ref iSubiterationCount);
            DA.GetData <int>("Population Size", ref iPopulationSize);
            DA.GetData <double>("Mutation Rate", ref iMutationRate);
            DA.GetData <double>("Mutation Amount", ref iMutationAmount);


            // -------------------------------------------------------------------------------------------------------

            List <Vector3d> triangleNormals = new List <Vector3d>();

            for (int i = 0; i < iSpringMesh.Triangles.Count; i++)
            {
                triangleNormals.Add(iSpringMesh.ComputeTriangleNormal(i));
            }

            List <List <Plane> > planeTriplets = new List <List <Plane> >();

            for (int i = 0; i < iSpringMesh.Triangles.Count; i++)
            {
                planeTriplets.Add(new List <Plane>());
            }

            List <Plane> edgePlanes = new List <Plane>();;

            foreach (Edge edge in iSpringMesh.Edges)
            {
                if (edge.SecondTriangleIndex >= 0)
                {
                    Vector3d planeNormal = triangleNormals[edge.FirstTriangleIndex] + triangleNormals[edge.SecondTriangleIndex];
                    Point3d  planeOrigin = 0.5 * (iSpringMesh.Vertices[edge.FirstVertexIndex].Position + iSpringMesh.Vertices[edge.SecondVertexIndex].Position);


                    Vector3d localX = iSpringMesh.Vertices[edge.SecondVertexIndex].Position - iSpringMesh.Vertices[edge.FirstVertexIndex].Position;

                    localX.Unitize();
                    planeNormal.Unitize();

                    Vector3d localY = Vector3d.CrossProduct(localX, planeNormal);

                    Plane plane = new Plane(planeOrigin, localX, localY);

                    planeTriplets[edge.FirstTriangleIndex].Add(plane);
                    planeTriplets[edge.SecondTriangleIndex].Add(plane);
                    edgePlanes.Add(plane);
                }
                else
                {
                    /////////////////////
                }
            }

            List <Plane>   nastyPlanes = new List <Plane>();
            List <Point3d> planeTripletIntersections = new List <Point3d>();

            foreach (List <Plane> planeTriplet in planeTriplets)
            {
                if (planeTriplet.Count != 3)
                {
                    continue;
                }

                Point3d intersectionPoint;
                if (Intersection.PlanePlanePlane(planeTriplet[0], planeTriplet[1], planeTriplet[2], out intersectionPoint))
                {
                    planeTripletIntersections.Add(intersectionPoint);
                }
                else
                {
                    nastyPlanes.Add(planeTriplet[0]);
                    nastyPlanes.Add(planeTriplet[1]);
                    nastyPlanes.Add(planeTriplet[2]);
                }
            }



            DA.SetDataList(1, edgePlanes);
            DA.SetDataList(2, planeTripletIntersections);
            DA.SetDataList(3, nastyPlanes);


            //for (int i = 0; i < planeTriplets.Count; i++)
            //{
            //    if (planeTriplets[i].Count == 3) //////// remove later
            //    {
            //        Point3d intersectionPoint;

            //        if (Intersection.PlanePlanePlane(planeTriplets[i][0], planeTriplets[i][1], planeTriplets[i][2], out intersectionPoint))
            //            trianglePoints.Add(intersectionPoint);
            //        else
            //            trianglePoints.Add(iSpringMesh.ComputeTriangleCentroid(i));
            //    }
            //    else
            //    {
            //        Line intersectionLine;
            //        if (Intersection.PlanePlane(planeTriplets[i][0], planeTriplets[i][1], out intersectionLine))
            //        {
            //            trianglePoints.Add(
            //                Utils.ClosestPointOnLine(
            //                iSpringMesh.ComputeTriangleCentroid(i),
            //                intersectionLine.PointAt(0.0),
            //                intersectionLine.PointAt(1.0)));
            //        }

            //        else
            //            trianglePoints.Add(iSpringMesh.ComputeTriangleCentroid(i));
            //    }

            //}

            //Mesh oRhinoMesh = new Mesh();

            //List<PolylineCurve> quadPolylines = new List<PolylineCurve>();

            //foreach (Edge edge in iSpringMesh.Edges)
            //{
            //    if (edge.SecondTriangleIndex >= 0)
            //    {
            //        Point3d A = iSpringMesh.Vertices[edge.FirstVertexIndex].Position;
            //        Point3d C = iSpringMesh.Vertices[edge.SecondVertexIndex].Position;

            //        Point3d B = trianglePoints[edge.FirstTriangleIndex];
            //        Point3d D = trianglePoints[edge.SecondTriangleIndex];

            //        oRhinoMesh.Vertices.Add(A);
            //        oRhinoMesh.Vertices.Add(B);
            //        oRhinoMesh.Vertices.Add(C);
            //        oRhinoMesh.Vertices.Add(D);

            //        oRhinoMesh.Faces.AddFace(oRhinoMesh.Vertices.Count - 4, oRhinoMesh.Vertices.Count - 3, oRhinoMesh.Vertices.Count - 2, oRhinoMesh.Vertices.Count - 1);

            //        quadPolylines.Add(new PolylineCurve(new List<Point3d>() { A, B, C, D , A}));
            //    }
            //}
        }
        public bool CalculateSurface(SpringMesh sMesh, double thickness, List <Curve> curvesRight, List <Curve> curvesLeft)
        {
            foreach (Edge edge in sMesh.Edges)
            {
                if (edge.SecondTriangleIndex >= 0)
                {
                    // first vertex
                    // first triangle
                    #region curve01

                    int firstPtId            = edge.FirstVertexIndex;
                    int firstTriangleIdRight = edge.FirstTriangleIndex;

                    Vertex firstPtVertex = sMesh.Vertices[firstPtId];
                    //Point3d firstTriCentreRight = sMesh.ComputeTriangleCenter(firstTriangleIdRight);
                    Point3d firstTriCentreRight = sMesh.ComputeCircumscribedCircleCenter(firstTriangleIdRight);

                    Vector3d firstNormalRight = thickness * sMesh.ComputeTriangleNormal(firstTriangleIdRight);

                    Point3d firstTriCentreUpRight   = firstTriCentreRight + firstNormalRight;    // the first control point
                    Point3d firstTriCentreDownRight = firstTriCentreRight - firstNormalRight;    // the seventh control point

                    Point3d firstCPt02Right = (firstPtVertex.Factor - 0.2) * firstPtVertex.Position + (1 - firstPtVertex.Factor + 0.2) * firstTriCentreRight;

                    Point3d firstCPt02UpRight   = firstCPt02Right + firstNormalRight;              // the second control point
                    Point3d firstCPt02DownRight = firstCPt02Right - firstNormalRight;              // the sixth control point

                    Point3d firstCPt03Right = firstPtVertex.Factor * firstPtVertex.Position + (1 - firstPtVertex.Factor) * firstTriCentreRight;

                    Point3d firstCPt03UpRight   = firstCPt03Right + firstNormalRight;      // the third control point
                    Point3d firstCPt03DownRight = firstCPt03Right - firstNormalRight;      // the fifth control point

                    Point3d firstUpPtRight = firstPtVertex.Position;                       // the fourth control point

                    List <Point3d> firstControlPointRight = new List <Point3d>()
                    {
                        firstTriCentreUpRight, firstCPt02UpRight, firstCPt03UpRight, firstUpPtRight,
                        firstCPt03DownRight, firstCPt02DownRight, firstTriCentreDownRight
                    };
                    #endregion
                    NurbsCurve firstNurbCurveRight = NurbsCurve.Create(false, 5, firstControlPointRight);

                    // second triangle
                    #region curve02

                    int firstTriangleIdLeft = edge.SecondTriangleIndex;

                    //Point3d firstTriCentreLeft = sMesh.ComputeTriangleCenter(firstTriangleIdLeft);
                    Point3d firstTriCentreLeft = sMesh.ComputeCircumscribedCircleCenter(firstTriangleIdLeft);

                    Vector3d firstNormalLeft = thickness * sMesh.ComputeTriangleNormal(firstTriangleIdLeft);

                    Point3d firstTriCentreUpLeft   = firstTriCentreLeft + firstNormalLeft;    // the first control point
                    Point3d firstTriCentreDownLeft = firstTriCentreLeft - firstNormalLeft;    // the seventh control point

                    Point3d firstCPt02Left = (firstPtVertex.Factor - 0.2) * firstPtVertex.Position + (1 - firstPtVertex.Factor + 0.2) * firstTriCentreLeft;

                    Point3d firstCPt02UpLeft   = firstCPt02Left + firstNormalLeft;              // the second control point
                    Point3d firstCPt02DownLeft = firstCPt02Left - firstNormalLeft;              // the sixth control point

                    Point3d firstCPt03Left = firstPtVertex.Factor * firstPtVertex.Position + (1 - firstPtVertex.Factor) * firstTriCentreLeft;

                    Point3d firstCPt03UpLeft   = firstCPt03Left + firstNormalLeft;        // the third control point
                    Point3d firstCPt03DownLeft = firstCPt03Left - firstNormalLeft;        // the fifth control point

                    Point3d firstUpPtLeft = firstPtVertex.Position;                       // the fourth control point

                    List <Point3d> firstControlPointLeft = new List <Point3d>()
                    {
                        firstTriCentreUpLeft, firstCPt02UpLeft, firstCPt03UpLeft, firstUpPtLeft,
                        firstCPt03DownLeft, firstCPt02DownLeft, firstTriCentreDownLeft
                    };
                    #endregion
                    NurbsCurve firstNurbCurveLeft = NurbsCurve.Create(false, 5, firstControlPointLeft);

                    curvesRight.Add(firstNurbCurveRight);
                    curvesLeft.Add(firstNurbCurveLeft);

                    /*
                     * Brep[] brep1 = Brep.CreateFromLoft(
                     *  new List<Curve>() { firstNurbCurveRight, firstNurbCurveLeft },
                     *  Point3d.Unset, Point3d.Unset, LoftType.Developable, false);
                     *
                     * if (brep1.Length > 0) breps.Add(brep1[0]); */

                    // second vertex
                    // first triangle
                    #region curve03

                    int secondPtId            = edge.SecondVertexIndex;
                    int secondTriangleIdRight = edge.FirstTriangleIndex;

                    Vertex secondPtVertex = sMesh.Vertices[secondPtId];
                    //Point3d secondTriCentreRight = sMesh.ComputeTriangleCenter(secondTriangleIdRight);
                    Point3d secondTriCentreRight = sMesh.ComputeCircumscribedCircleCenter(secondTriangleIdRight);

                    Vector3d secondNormalRight = thickness * sMesh.ComputeTriangleNormal(secondTriangleIdRight);

                    Point3d secondTriCentreUpRight   = secondTriCentreRight + secondNormalRight;    // the second control point
                    Point3d secondTriCentreDownRight = secondTriCentreRight - secondNormalRight;    // the seventh control point

                    Point3d secondCPt02Right = (secondPtVertex.Factor - 0.2) * secondPtVertex.Position + (1 - secondPtVertex.Factor + 0.2) * secondTriCentreRight;

                    Point3d secondCPt02UpRight   = secondCPt02Right + secondNormalRight;              // the second control point
                    Point3d secondCPt02DownRight = secondCPt02Right - secondNormalRight;              // the sixth control point

                    Point3d secondCPt03Right = secondPtVertex.Factor * secondPtVertex.Position + (1 - secondPtVertex.Factor) * secondTriCentreRight;

                    Point3d secondCPt03UpRight   = secondCPt03Right + secondNormalRight;     // the third control point
                    Point3d secondCPt03DownRight = secondCPt03Right - secondNormalRight;     // the fifth control point

                    Point3d secondUpPtRight = secondPtVertex.Position;                       // the fourth control point

                    List <Point3d> secondControlPointRight = new List <Point3d>()
                    {
                        secondTriCentreUpRight, secondCPt02UpRight, secondCPt03UpRight, secondUpPtRight,
                        secondCPt03DownRight, secondCPt02DownRight, secondTriCentreDownRight
                    };

                    #endregion
                    NurbsCurve secondNurbCurveRight = NurbsCurve.Create(false, 5, secondControlPointRight);

                    // second triangle
                    #region curve04

                    int secondTriangleIdLeft = edge.SecondTriangleIndex;

                    //Point3d secondTriCentreLeft = sMesh.ComputeTriangleCenter(secondTriangleIdLeft);
                    Point3d secondTriCentreLeft = sMesh.ComputeCircumscribedCircleCenter(secondTriangleIdLeft);

                    Vector3d secondNormalLeft = thickness * sMesh.ComputeTriangleNormal(secondTriangleIdLeft);

                    Point3d secondTriCentreUpLeft   = secondTriCentreLeft + secondNormalLeft;    // the second control point
                    Point3d secondTriCentreDownLeft = secondTriCentreLeft - secondNormalLeft;    // the seventh control point

                    Point3d secondCPt02Left = (secondPtVertex.Factor - 0.2) * secondPtVertex.Position + (1 - secondPtVertex.Factor + 0.2) * secondTriCentreLeft;

                    Point3d secondCPt02UpLeft   = secondCPt02Left + secondNormalLeft;              // the second control point
                    Point3d secondCPt02DownLeft = secondCPt02Left - secondNormalLeft;              // the sixth control point

                    Point3d secondCPt03Left = secondPtVertex.Factor * secondPtVertex.Position + (1 - secondPtVertex.Factor) * secondTriCentreLeft;

                    Point3d secondCPt03UpLeft   = secondCPt03Left + secondNormalLeft;       // the third control point
                    Point3d secondCPt03DownLeft = secondCPt03Left - secondNormalLeft;       // the fifth control point

                    Point3d secondUpPtLeft = secondPtVertex.Position;                       // the fourth control point

                    List <Point3d> secondControlPointLeft = new List <Point3d>()
                    {
                        secondTriCentreUpLeft, secondCPt02UpLeft, secondCPt03UpLeft, secondUpPtLeft,
                        secondCPt03DownLeft, secondCPt02DownLeft, secondTriCentreDownLeft
                    };
                    #endregion
                    NurbsCurve secondNurbCurveLeft = NurbsCurve.Create(false, 5, secondControlPointLeft);

                    curvesRight.Add(secondNurbCurveRight);
                    curvesLeft.Add(secondNurbCurveLeft);

                    /*
                     * Brep[] brep2 = Brep.CreateFromLoft(
                     *  new List<Curve>() { firstNurbCurveRight, firstNurbCurveLeft },
                     *  Point3d.Unset, Point3d.Unset, LoftType.Developable, false);
                     *
                     * if (brep2.Length > 0) breps.Add(brep2[0]);  */
                }
            }
            return(true);
        }
Пример #6
0
        public void DualTPI(bool flip)
        {
            List <List <LineCurve> > dualVertices = new List <List <LineCurve> >();

            for (int i = 0; i < oSpringMesh.Vertices.Count; i++)
            {
                dualVertices.Add(new List <LineCurve>());
            }

            ////// this is to create planar plate
            foreach (Edge edge in oSpringMesh.Edges)
            {
                if (edge.SecondTriangleIndex >= 0)
                {
                    int firstVertexIndex    = edge.FirstVertexIndex;
                    int secondVertexIndex   = edge.SecondVertexIndex;
                    int firstTriangleIndex  = edge.FirstTriangleIndex;
                    int secondTriangleIndex = edge.SecondTriangleIndex;

                    Point3d firstTPI  = oSpringMesh.ComputeDoubleLayerTPI(firstTriangleIndex, othickness, flip, iPlatesOffset);
                    Point3d secondTPI = oSpringMesh.ComputeDoubleLayerTPI(secondTriangleIndex, othickness, flip, iPlatesOffset);

                    Point3d firstTPIO       = oSpringMesh.ComputeTPI(firstTriangleIndex);
                    Point3d secondTPIO      = oSpringMesh.ComputeTPI(secondTriangleIndex);
                    Point3d firstCenterPtO  = oSpringMesh.ComputeTriangleCentroid(firstTriangleIndex);
                    Point3d secondCenterPtO = oSpringMesh.ComputeTriangleCentroid(secondTriangleIndex);

                    Point3d firstCenterPt;
                    Point3d secondCenterPt;

                    if (!flip)
                    {
                        firstCenterPt = oSpringMesh.ComputeTriangleCentroid(firstTriangleIndex) +
                                        oSpringMesh.ComputeTriangleNormal(firstTriangleIndex);
                        secondCenterPt = oSpringMesh.ComputeTriangleCentroid(secondTriangleIndex) +
                                         oSpringMesh.ComputeTriangleNormal(secondTriangleIndex);
                    }
                    else
                    {
                        firstCenterPt = oSpringMesh.ComputeTriangleCentroid(firstTriangleIndex) -
                                        oSpringMesh.ComputeTriangleNormal(firstTriangleIndex);
                        secondCenterPt = oSpringMesh.ComputeTriangleCentroid(secondTriangleIndex) -
                                         oSpringMesh.ComputeTriangleNormal(secondTriangleIndex);
                    }

                    // ===========================================================================
                    // Added 14/06/2015 to make some tolerance for plates

                    Circle firstCircle  = oSpringMesh.ComputeDoubleLayerIncircle(firstTriangleIndex, iPlatesThreadsP, othickness, flip, iPlatesOffset);
                    Circle secondCircle = oSpringMesh.ComputeDoubleLayerIncircle(secondTriangleIndex, iPlatesThreadsP, othickness, flip, iPlatesOffset);

                    //Circle firstCircle = oSpringMesh.ComputeDoubleLayerCircumscribedCircle(firstTriangleIndex, iPlatesThreadsP, othickness, flip, iPlatesOffset);
                    //Circle secondCircle = oSpringMesh.ComputeDoubleLayerCircumscribedCircle(secondTriangleIndex, iPlatesThreadsP, othickness, flip, iPlatesOffset);

                    Circle firstCircleO  = oSpringMesh.ComputeIncircle(firstTriangleIndex, iPlatesThreadsP); // iPlatesThreads = 0.0-1.0
                    Circle secondCircleO = oSpringMesh.ComputeIncircle(secondTriangleIndex, iPlatesThreadsP);

                    Plane firstPO  = oSpringMesh.ComputePlane(firstTriangleIndex);
                    Plane secondPO = oSpringMesh.ComputePlane(secondTriangleIndex);

                    Point3d projectFirstTPIO  = firstPO.ClosestPoint(firstTPIO);
                    Point3d projectSecondTPIO = secondPO.ClosestPoint(secondTPIO);


                    Point3d newFirstTPI  = firstCircle.ClosestPoint(firstTPI);
                    Point3d newSecondTPI = secondCircle.ClosestPoint(secondTPI);

                    // manuel selected plates
                    foreach (int id in iID)
                    {
                        if (id == firstVertexIndex)
                        {
                            dualVertices[firstVertexIndex].Add(new LineCurve(newFirstTPI, newSecondTPI));
                        }
                        if (id == secondVertexIndex)
                        {
                            dualVertices[secondVertexIndex].Add(new LineCurve(newFirstTPI, newSecondTPI));
                        }
                    }
                    // auto generated plates
                    if (ICD.Utils.Distance(projectFirstTPIO, firstCenterPtO) < iPlatesThreads &&
                        ICD.Utils.Distance(projectSecondTPIO, secondCenterPtO) < iPlatesThreads &&
                        iAutoGenPlates && !iID.Contains(firstVertexIndex) && !iID.Contains(secondVertexIndex))
                    {
                        dualVertices[firstVertexIndex].Add(new LineCurve(newFirstTPI, newSecondTPI));
                        dualVertices[secondVertexIndex].Add(new LineCurve(newFirstTPI, newSecondTPI));
                    }
                }
                else
                {
                }
            }

            int counter = -1;

            for (int i = 0; i < oSpringMesh.Vertices.Count; i++)
            {
                // if is close and all right
                if (dualVertices[i].Count == oSpringMesh.Vertices[i].NeighborVertexIndices.Count &&
                    !iID.Contains(i))
                {
                    Curve dualcurve = Curve.JoinCurves(dualVertices[i])[0];

                    oInfo += dualcurve.IsClosed.ToString() + "\n";

                    if (dualcurve.IsClosed)
                    {
                        oPolyLine.Add(dualcurve);
                        counter++;
                        // change the vertex staus to be occupied
                        oVertexStatus[i] = true;
                        oPolyLineID[i]   = counter;
                    }
                }
                // manuel selected plate
                foreach (int id in iID)
                {
                    if (id == i)
                    {
                        Curve dualcurve = Curve.JoinCurves(dualVertices[i])[0];
                        if (dualcurve.IsClosed)
                        {
                            oPolyLine.Add(dualcurve);
                            counter++;
                            // change the vertex staus to be occupied
                            oVertexStatus[i] = true;
                            oPolyLineID[i]   = counter;
                        }
                    }
                }
            }
        }