示例#1
0
        /// <returns>
        /// Value of specified attribute that is set on the branch or its
        /// closest ancestor; null if neither branch nor any of its ancestors
        /// has this attribute set.
        /// </returns>
        static IAttributeInstance GetAttributeWithInheritance(
            IBranch branch,
            IAttributeKey attrKey)
        {
            if (branch == null)
            {
                return(null);
            }

            var attr = branch.Attributes.Get(attrKey);

            if (attr != null)
            {
                return(attr);
            }

            return(GetAttributeWithInheritance(branch.Parent, attrKey));
        }
示例#2
0
        static void Main(string[] args)
        {
            string projectAddress;

            if (args.Length < 1)
            {
                Console.Write("Enter path of \"Stabilizer\" example project: ");
                projectAddress = Console.ReadLine().Trim();
            }
            else
            {
                projectAddress = args[0];
            }

            Console.WriteLine("Opening project \"{0}\"...", projectAddress);
            using (var project = ProjectManager.Open(projectAddress, AccessMode.ReadWrite))
            {
                Console.WriteLine();

                var stopwatch = new Stopwatch();
                stopwatch.Start();

                // Branches in "Stabilizer" project have attributes coming
                // from PDMS, including such attributes as "Level" and "Purpose".
                //
                // The idea of this FRT generator is to:
                // - select all CAD branches that have "Level" attribute and
                //   that either have or inherit "Purpose" attribute;
                // - group them first by "Level", then by "Purpose"; and
                // - inject them into project's FRT hierarchy.
                //
                // The resulting FRT will look something like:
                // <root>
                //  +- Level A
                //     +- Purpose X
                //        +- branch 1
                //        +- branch 2
                //        +- ...
                //        +- branch N
                //     +- Purpose Y
                //        +- ...
                //  +- Level B
                //     +- Purpose X
                //        +- ...

                // Prepare attribute keys for "Level" and "Purpose".

                IProjectAttributeSource pdmsAttributeSource = project.AttributeSources.GetAll()
                                                              .Single(attrSrc => attrSrc.Kind.Equals(ProjectAttributeSourceKinds.Pdms));
                IAttributeKey levelKey   = pdmsAttributeSource.CreateKey("Level");
                IAttributeKey purposeKey = pdmsAttributeSource.CreateKey("Purpose");

                // Select all CAD branches of the project.

                IEnumerable <IBranch> cadRootBranches = project.Branches.GetRoots(BranchKind.Cad);
                IEnumerable <IBranch> allCadBranches  = cadRootBranches.Concat(
                    cadRootBranches.SelectMany(cadRoot => cadRoot.Descendants));

                // Scan all CAD branches and retrieve their "Level" and "Purpose".

                var cadBranchesWithLevelAndPurpose = allCadBranches
                                                     .Select(cadBranch => new
                {
                    Level           = cadBranch.Attributes.Get(levelKey),
                    Purpose         = GetAttributeWithInheritance(cadBranch, purposeKey),
                    SourceCadBranch = cadBranch,
                })
                                                     .Where(branchInfo => branchInfo.Level != null && branchInfo.Purpose != null);

                // Translate data into sequence of FrtBranchInfo and simplify
                // IAttributeInstances into simple strings.

                var frtBranchInfos = cadBranchesWithLevelAndPurpose
                                     .Select(branchInfo => new FrtBranchInfo
                {
                    Level           = (string)branchInfo.Level.Value,
                    Purpose         = (string)branchInfo.Purpose.Value,
                    SourceCadBranch = branchInfo.SourceCadBranch,
                });

                // Sort branch info so that branches can be created sequentially.
                // The sequence will look something like:
                //
                // Level A | Purpose X | branch 1
                // Level A | Purpose X | ...
                // Level A | Purpose X | branch N1
                // Level A | Purpose Y | branch 1
                // Level A | Purpose Y | ...
                // Level A | Purpose Y | branch N2
                // Level B | Purpose X | branch 1
                // Level B | Purpose X | ...
                // Level B | Purpose X | branch N3
                // ...     | ...       | ...

                var orderedFrtBranchInfos = frtBranchInfos
                                            .OrderBy(branchInfo => branchInfo.Level)
                                            .ThenBy(branchInfo => branchInfo.Purpose)
                                            .ThenBy(branchInfo => branchInfo.SourceCadBranch.Name);

                // Translate branch infos to creation params, to be fed into
                // Branch.Create().

                var branchCreationParams = GenerateBranchCreationParams(orderedFrtBranchInfos);

                // Fastest way to create many branches is with Branches.Create().
                // It has significant optimizations, especially for standalone
                // projects. Current maximum rate, if creating branches one-by-one,
                // is 6-10 branches per second. Using Branches.Create() it
                // is possible to create thousands of branches per second.

                Console.WriteLine("Injecting FRT branches...");
                project.Branches.Create(branchCreationParams);
                Console.WriteLine();

                stopwatch.Stop();
                Console.WriteLine("Done in {0}.", stopwatch.Elapsed);
            }

            Console.WriteLine("Press Enter to exit...");
            Console.ReadLine();
        }