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; }
public override IEnumerator BeginGeneration() { var surface = surfaceOutputSlot.GetAsset <SphericalSurface>(); if (surface == null) { surface = surfaceOutputSlot.SetAsset(CreateInstance <SphericalSurface>(), false); } surface.Reset(primaryPole, equatorialPole, radius, isInverted); Topology topology; Vector3[] vertexPositions; switch (sphericalPolyhedron) { case SphericalPolyhedrons.Tetrahedron: SphericalManifoldUtility.CreateTetrahedron(surface, out topology, out vertexPositions); break; case SphericalPolyhedrons.Cube: SphericalManifoldUtility.CreateCube(surface, out topology, out vertexPositions); break; case SphericalPolyhedrons.Octahedron: SphericalManifoldUtility.CreateOctahedron(surface, out topology, out vertexPositions); break; case SphericalPolyhedrons.Dodecahedron: if (subdivisionDegree == 0) { SphericalManifoldUtility.CreateDodecahedron(surface, out topology, out vertexPositions); } else { SphericalManifoldUtility.CreateIcosahedron(surface, out topology, out vertexPositions); } break; case SphericalPolyhedrons.Icosahedron: SphericalManifoldUtility.CreateIcosahedron(surface, out topology, out vertexPositions); break; default: throw new System.NotImplementedException(); } SphericalManifoldUtility.Subdivide(surface, topology, vertexPositions.AsVertexAttribute(), subdivisionDegree, out topology, out vertexPositions); var alreadyDual = sphericalPolyhedron == SphericalPolyhedrons.Dodecahedron && subdivisionDegree != 0; if (useDualPolyhedron != alreadyDual) { SphericalManifoldUtility.MakeDual(surface, topology, ref vertexPositions); } surfaceOutputSlot.Persist(); topologyOutputSlot.SetAsset(topology); vertexPositionsOutputSlot.SetAsset(Vector3VertexAttribute.Create(vertexPositions).SetName("Vertex Positions")); yield break; }