public override IEnumerator BeginGeneration() { var topology = topologyInputSlot.GetAsset <Topology>(); var faceGroupIndices = new int[topology.internalFaces.Count].AsFaceAttribute(); List <int>[] faceGroupFaceIndices; var random = randomness.GetRandom(); var clampedRootCount = Mathf.Clamp(groupCount, 1, topology.internalFaces.Count); faceGroupFaceIndices = new List <int> [clampedRootCount]; var waitHandle = executive.GenerateConcurrently(() => { var rootFaces = new List <Topology.Face>(); var rootFaceEdges = new List <Topology.FaceEdge>(); for (int faceGroupIndex = 0; faceGroupIndex < clampedRootCount; ++faceGroupIndex) { faceGroupFaceIndices[faceGroupIndex] = new List <int>(); Topology.Face face; do { face = topology.internalFaces[random.Index(topology.internalFaces.Count)]; } while (rootFaces.Contains(face)); rootFaces.Add(face); foreach (var edge in face.edges) { if (edge.face.isInternal) { rootFaceEdges.Add(edge); } } faceGroupIndices[face] = faceGroupIndex; faceGroupFaceIndices[faceGroupIndex].Add(face.index); } TopologyVisitor.VisitFacesInRandomOrder( rootFaceEdges, (FaceEdgeVisitor visitor) => { var faceGroupIndex = faceGroupIndices[visitor.edge.nearFace]; faceGroupIndices[visitor.edge] = faceGroupIndex; faceGroupFaceIndices[faceGroupIndex].Add(visitor.edge.face.index); visitor.VisitInternalNeighborsExceptSource(); }, random); }); while (waitHandle.WaitOne(10) == false) { yield return(null); } faceGroupOutputSlots = GeneratorUtility.ResizeArray(faceGroupOutputSlots, faceGroupFaceIndices.Length, (int index) => { return(OutputSlot.CreateGrouped <FaceGroup>(this, string.Format("Face Group {0}", index), faceGroupCollectionOutputSlot.name, true, OutputSlot.Availability.DuringGeneration)); }, (OutputSlot output, int index) => { output.DisconnectAll(); output.path = faceGroupCollectionOutputSlot.name; return(output); }); var faceGroupCollection = FaceGroupCollection.Create(faceGroupFaceIndices.Length); for (int faceGroupIndex = 0; faceGroupIndex < faceGroupFaceIndices.Length; ++faceGroupIndex) { var faceGroup = ArrayFaceGroup.Create(topology, faceGroupFaceIndices[faceGroupIndex].ToArray()).SetName(faceGroupOutputSlots[faceGroupIndex].name); faceGroupCollection.faceGroups[faceGroupIndex] = faceGroupOutputSlots[faceGroupIndex].SetAsset(faceGroup); } faceGroupCollectionOutputSlot.SetAsset(faceGroupCollection); faceGroupIndicesOutputSlot.SetAsset(IntFaceAttribute.Create(faceGroupIndices.array)); yield break; }
public override IEnumerator BeginGeneration() { var surface = surfaceInputSlot.GetAsset <QuadrilateralSurface>(); var topology = topologyInputSlot.GetAsset <Topology>(); var facePositions = facePositionsInputSlot.GetAsset <IFaceAttribute <Vector3> >(); int groupCount = 0; var faceGroupFaceIndices = new List <int> [axisDivisions.x * axisDivisions.y]; var waitHandle = executive.GenerateConcurrently(() => { var axis0Vector = surface.axis0.vector; var axis1Vector = surface.axis1.vector; var surfaceNormal = Vector3.Cross(axis0Vector, axis1Vector).normalized; var axis0Normal = Vector3.Cross(axis0Vector, surfaceNormal).normalized; var axis1Normal = Vector3.Cross(axis1Vector, surfaceNormal).normalized; var axis0DividedVector = axis0Vector / axisDivisions.x; var axis1DividedVector = axis1Vector / axisDivisions.y; var axis0Dot = Vector3.Dot(axis1Normal, axis0DividedVector); var axis1Dot = Vector3.Dot(axis0Normal, axis1DividedVector); var origin = surface.origin; for (int i = 0; i < faceGroupFaceIndices.Length; ++i) { faceGroupFaceIndices[i] = new List <int>(); } foreach (var face in topology.internalFaces) { var facePosition = facePositions[face]; var axis0Offset = Vector3.Dot(axis1Normal, facePosition - origin) / axis0Dot; var axis1Offset = Vector3.Dot(axis0Normal, facePosition - origin) / axis1Dot; var axis0Index = Mathf.Clamp(Mathf.FloorToInt(axis0Offset), 0, axisDivisions.x - 1); var axis1Index = Mathf.Clamp(Mathf.FloorToInt(axis1Offset), 0, axisDivisions.y - 1); faceGroupFaceIndices[axis0Index + axis1Index * axisDivisions.x].Add(face.index); } foreach (var group in faceGroupFaceIndices) { if (group.Count > 0) { ++groupCount; } } }); while (waitHandle.WaitOne(10) == false) { yield return(null); } faceGroupOutputSlots = GeneratorUtility.ResizeArray(faceGroupOutputSlots, groupCount, (int index) => { return(null); }, (OutputSlot output, int index) => { output.DisconnectAll(); return(output); }); var faceGroupCollection = FaceGroupCollection.Create(groupCount); var faceGroupIndices = new int[topology.internalFaces.Count]; var groupIndex = 0; for (int axis1Index = 0; axis1Index < axisDivisions.y; ++axis1Index) { for (int axis0Index = 0; axis0Index < axisDivisions.x; ++axis0Index) { var group = faceGroupFaceIndices[axis0Index + axis1Index * axisDivisions.x]; if (group.Count > 0) { var faceGroupName = string.Format("Face Group [{0}, {1}]", axis0Index, axis1Index); var faceGroup = ArrayFaceGroup.Create(topology, group.ToArray()).SetName(faceGroupName); if (faceGroupOutputSlots[groupIndex] == null) { faceGroupOutputSlots[groupIndex] = OutputSlot.CreateGrouped <FaceGroup>(this, faceGroupName, faceGroupCollectionOutputSlot.name, true, OutputSlot.Availability.DuringGeneration); } else { faceGroupOutputSlots[groupIndex].name = faceGroupName; faceGroupOutputSlots[groupIndex].path = faceGroupCollectionOutputSlot.name; } faceGroupCollection.faceGroups[groupIndex] = faceGroupOutputSlots[groupIndex].SetAsset(faceGroup); foreach (var faceIndex in group) { faceGroupIndices[faceIndex] = groupIndex; } ++groupIndex; } } } faceGroupCollectionOutputSlot.SetAsset(faceGroupCollection); faceGroupIndicesOutputSlot.SetAsset(IntFaceAttribute.Create(faceGroupIndices)); yield break; }