Esempio n. 1
0
        public override IEnumerator BeginGeneration()
        {
            var surface         = surfaceInputSlot.GetAsset <Surface>();
            var topology        = topologyInputSlot.GetAsset <Topology>();
            var vertexPositions = vertexPositionsInputSlot.GetAsset <IVertexAttribute <Vector3> >();
            var faceCentroids   = PositionalFaceAttribute.Create(surface, new Vector3[topology.internalFaces.Count]).SetName("Face Centroids");

            yield return(executive.GenerateConcurrently(() =>
            {
                if (flatten || surface is QuadrilateralSurface)
                {
                    FaceAttributeUtility.CalculateFaceCentroidsFromVertexPositions(topology.internalFaces, vertexPositions, faceCentroids);
                }
                else if (surface is SphericalSurface)
                {
                    var sphericalSurface = (SphericalSurface)surface;
                    FaceAttributeUtility.CalculateSphericalFaceCentroidsFromVertexPositions(topology.internalFaces, sphericalSurface, vertexPositions, faceCentroids);
                }
                else
                {
                    throw new System.NotImplementedException();
                }
            }));

            faceCentroidsOutputSlot.SetAsset(faceCentroids);

            yield break;
        }
        public override IEnumerator BeginGeneration()
        {
            var surface         = surfaceInputSlot.GetAsset <Surface>();
            var topology        = topologyInputSlot.GetAsset <Topology>();
            var vertexPositions = vertexPositionsInputSlot.source != null?vertexPositionsInputSlot.GetAsset <IVertexAttribute <Vector3> >() : null;

            var random = randomness.GetRandom();

            System.Func <float> relaxIterationFunction = null;
            System.Func <bool>  repairFunction         = null;
            System.Action       relaxationLoopFunction = null;

            if (vertexPositions != null)
            {
                if (surface is QuadrilateralSurface)
                {
                    if (relaxForRegularityWeight >= 1.0f)
                    {
                        var relaxedVertexPositions = new Vector3[topology.vertices.Count].AsVertexAttribute();
                        relaxIterationFunction = () =>
                        {
                            PlanarManifoldUtility.RelaxVertexPositionsForRegularity(topology, vertexPositions, lockBoundaryPositions, relaxedVertexPositions);
                            var relaxationAmount = PlanarManifoldUtility.CalculateRelaxationAmount(vertexPositions, relaxedVertexPositions);
                            for (int i = 0; i < vertexPositions.Count; ++i)
                            {
                                vertexPositions[i] = relaxedVertexPositions[i];
                            }
                            return(relaxationAmount);
                        };
                    }
                    else if (relaxForRegularityWeight <= 0.0f)
                    {
                        var relaxedVertexPositions = new Vector3[topology.vertices.Count].AsVertexAttribute();
                        var faceCentroids          = PositionalFaceAttribute.Create(surface, topology.internalFaces.Count);
                        var vertexAreas            = new float[topology.vertices.Count].AsVertexAttribute();

                        FaceAttributeUtility.CalculateFaceCentroidsFromVertexPositions(topology.internalFaces, vertexPositions, faceCentroids);
                        VertexAttributeUtility.CalculateVertexAreasFromVertexPositionsAndFaceCentroids(topology.vertices, vertexPositions, faceCentroids, vertexAreas);

                        var totalArea = 0f;
                        foreach (var vertexArea in vertexAreas)
                        {
                            totalArea += vertexArea;
                        }

                        relaxIterationFunction = () =>
                        {
                            PlanarManifoldUtility.RelaxVertexPositionsForEqualArea(topology, vertexPositions, totalArea, lockBoundaryPositions, relaxedVertexPositions, faceCentroids, vertexAreas);
                            var relaxationAmount = PlanarManifoldUtility.CalculateRelaxationAmount(vertexPositions, relaxedVertexPositions);
                            for (int i = 0; i < vertexPositions.Count; ++i)
                            {
                                vertexPositions[i] = relaxedVertexPositions[i];
                            }
                            return(relaxationAmount);
                        };
                    }
                    else
                    {
                        var regularityWeight = Mathf.Clamp01(relaxForRegularityWeight);
                        var equalAreaWeight  = 1f - regularityWeight;

                        var regularityRelaxedVertexPositions = new Vector3[topology.vertices.Count].AsVertexAttribute();
                        var equalAreaRelaxedVertexPositions  = new Vector3[topology.vertices.Count].AsVertexAttribute();
                        var relaxedVertexPositions           = regularityRelaxedVertexPositions;
                        var faceCentroids = PositionalFaceAttribute.Create(surface, topology.internalFaces.Count);
                        var vertexAreas   = new float[topology.vertices.Count].AsVertexAttribute();

                        FaceAttributeUtility.CalculateFaceCentroidsFromVertexPositions(topology.internalFaces, vertexPositions, faceCentroids);
                        VertexAttributeUtility.CalculateVertexAreasFromVertexPositionsAndFaceCentroids(topology.vertices, vertexPositions, faceCentroids, vertexAreas);

                        var totalArea = 0f;
                        foreach (var vertexArea in vertexAreas)
                        {
                            totalArea += vertexArea;
                        }

                        relaxIterationFunction = () =>
                        {
                            PlanarManifoldUtility.RelaxVertexPositionsForRegularity(topology, vertexPositions, lockBoundaryPositions, regularityRelaxedVertexPositions);
                            PlanarManifoldUtility.RelaxVertexPositionsForEqualArea(topology, vertexPositions, totalArea, lockBoundaryPositions, equalAreaRelaxedVertexPositions, faceCentroids, vertexAreas);
                            for (int i = 0; i < relaxedVertexPositions.Count; ++i)
                            {
                                relaxedVertexPositions[i] = regularityRelaxedVertexPositions[i] * regularityWeight + equalAreaRelaxedVertexPositions[i] * equalAreaWeight;
                            }
                            var relaxationAmount = PlanarManifoldUtility.CalculateRelaxationAmount(vertexPositions, relaxedVertexPositions);
                            for (int i = 0; i < vertexPositions.Count; ++i)
                            {
                                vertexPositions[i] = relaxedVertexPositions[i];
                            }
                            return(relaxationAmount);
                        };
                    }

                    repairFunction = () =>
                    {
                        return(PlanarManifoldUtility.ValidateAndRepair(topology, ((QuadrilateralSurface)surface).normal, vertexPositions, repairRate, lockBoundaryPositions));
                    };

                    relaxationLoopFunction = TopologyRandomizer.CreateRelaxationLoopFunction(maxRelaxIterations, maxRepairIterations, relaxRelativePrecision, relaxIterationFunction, repairFunction);
                }
                else if (surface is SphericalSurface)
                {
                    var sphericalSurface = (SphericalSurface)surface;
                    if (relaxForRegularityWeight >= 1.0f)
                    {
                        var relaxedVertexPositions = new Vector3[topology.vertices.Count].AsVertexAttribute();
                        relaxIterationFunction = () =>
                        {
                            SphericalManifoldUtility.RelaxVertexPositionsForRegularity(sphericalSurface, topology, vertexPositions, lockBoundaryPositions, relaxedVertexPositions);
                            var relaxationAmount = SphericalManifoldUtility.CalculateRelaxationAmount(vertexPositions, relaxedVertexPositions);
                            for (int i = 0; i < vertexPositions.Count; ++i)
                            {
                                vertexPositions[i] = relaxedVertexPositions[i];
                            }
                            return(relaxationAmount);
                        };
                    }
                    else if (relaxForRegularityWeight <= 0.0f)
                    {
                        var relaxedVertexPositions = new Vector3[topology.vertices.Count].AsVertexAttribute();
                        var faceCentroids          = PositionalFaceAttribute.Create(surface, topology.internalFaces.Count);
                        var faceCentroidAngles     = new float[topology.faceEdges.Count].AsEdgeAttribute();
                        var vertexAreas            = new float[topology.vertices.Count].AsVertexAttribute();
                        relaxIterationFunction = () =>
                        {
                            SphericalManifoldUtility.RelaxVertexPositionsForEqualArea(sphericalSurface, topology, vertexPositions, lockBoundaryPositions, relaxedVertexPositions, faceCentroids, faceCentroidAngles, vertexAreas);
                            var relaxationAmount = SphericalManifoldUtility.CalculateRelaxationAmount(vertexPositions, relaxedVertexPositions);
                            for (int i = 0; i < vertexPositions.Count; ++i)
                            {
                                vertexPositions[i] = relaxedVertexPositions[i];
                            }
                            return(relaxationAmount);
                        };
                    }
                    else
                    {
                        var regularityWeight = Mathf.Clamp01(relaxForRegularityWeight);
                        var equalAreaWeight  = 1f - regularityWeight;

                        var regularityRelaxedVertexPositions = new Vector3[topology.vertices.Count].AsVertexAttribute();
                        var equalAreaRelaxedVertexPositions  = new Vector3[topology.vertices.Count].AsVertexAttribute();
                        var relaxedVertexPositions           = regularityRelaxedVertexPositions;
                        var faceCentroids      = PositionalFaceAttribute.Create(surface, topology.internalFaces.Count);
                        var faceCentroidAngles = new float[topology.faceEdges.Count].AsEdgeAttribute();
                        var vertexAreas        = new float[topology.vertices.Count].AsVertexAttribute();
                        relaxIterationFunction = () =>
                        {
                            SphericalManifoldUtility.RelaxVertexPositionsForRegularity(sphericalSurface, topology, vertexPositions, lockBoundaryPositions, regularityRelaxedVertexPositions);
                            SphericalManifoldUtility.RelaxVertexPositionsForEqualArea(sphericalSurface, topology, vertexPositions, lockBoundaryPositions, equalAreaRelaxedVertexPositions, faceCentroids, faceCentroidAngles, vertexAreas);
                            for (int i = 0; i < relaxedVertexPositions.Count; ++i)
                            {
                                relaxedVertexPositions[i] = regularityRelaxedVertexPositions[i] * regularityWeight + equalAreaRelaxedVertexPositions[i] * equalAreaWeight;
                            }
                            var relaxationAmount = SphericalManifoldUtility.CalculateRelaxationAmount(vertexPositions, relaxedVertexPositions);
                            for (int i = 0; i < vertexPositions.Count; ++i)
                            {
                                vertexPositions[i] = relaxedVertexPositions[i];
                            }
                            return(relaxationAmount);
                        };
                    }

                    repairFunction = () =>
                    {
                        return(SphericalManifoldUtility.ValidateAndRepair(sphericalSurface, topology, vertexPositions, repairRate, lockBoundaryPositions));
                    };

                    relaxationLoopFunction = TopologyRandomizer.CreateRelaxationLoopFunction(maxRelaxIterations, maxRepairIterations, relaxRelativePrecision, relaxIterationFunction, repairFunction);
                }
            }

            yield return(executive.GenerateConcurrently(() =>
            {
                TopologyRandomizer.Randomize(topology, passCount, frequency,
                                             minVertexNeighbors, maxVertexNeighbors, minFaceNeighbors, maxFaceNeighbors,
                                             lockBoundaryPositions, random, relaxationLoopFunction);
            }));

            EditorUtility.SetDirty(topology);

            if (vertexPositions != null)
            {
                EditorUtility.SetDirty((Object)vertexPositions);
            }

            yield break;
        }