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;
        }
Esempio n. 2
0
        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;
        }