예제 #1
0
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
        //// Sample
        ////
        //// Use: Copy & Replace assembly references (1st Level refs only)
        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////

        public void ReplaceReference()
        {
            AssemblyDocument            oAsmDoc = (AssemblyDocument)_InvApplication.ActiveDocument;
            AssemblyComponentDefinition oAsmDef = oAsmDoc.ComponentDefinition;

            Document oNewRefDoc = default(Document);
            string   filename   = null;


            foreach (FileDescriptor oFileDesc in oAsmDoc.File.ReferencedFileDescriptors)
            {
                oNewRefDoc = oFileDesc.ReferencedFile.AvailableDocuments(1);

                filename = "C:\\Temp\\Copy-" + oNewRefDoc.DisplayName;

                oNewRefDoc.SaveAs(filename, true);

                oFileDesc.ReplaceReference(filename);
            }

            filename = "C:\\Temp\\Copy-" + oAsmDoc.DisplayName;
            oAsmDoc.SaveAs(filename, true);

            oAsmDoc.Close(true);
        }
예제 #2
0
 //when form close do next:
 private void addInForm_FormClosing(object sender, FormClosingEventArgs e)
 {
     try
     {
         var_es.part_doc.Close(true);
         assemb_doc.Close(true);
         System.IO.Directory.Delete(path, true);
     }
     catch { }
 }  //Main form closing
예제 #3
0
        public void ReplaceReferences(AssemblyDocument targetAssembly, TupleList <string, string> namePair, string folderPath)
        {
            OccurrenceList newOccs               = new OccurrenceList(targetAssembly);
            string         pathString            = folderPath;
            List <string>  patternComponentsList = new List <string>();

            for (int i = 0; i < newOccs.Items.Count; i++)
            {
                if (newOccs.Items[i].DefinitionDocumentType == DocumentTypeEnum.kPartDocumentObject)
                {
                    for (int f = 0; f < namePair.Count; f++)
                    {
                        if (namePair[f].Item1 == newOccs.Items[i].ReferencedFileDescriptor.FullFileName)
                        {
                            if (patternComponentsList.Contains(namePair[f].Item1))
                            {
                                newOccs.Items[i].ReferencedDocumentDescriptor.ReferencedFileDescriptor.ReplaceReference(namePair[f].Item2);
                            }

                            else
                            {
                                if (!System.IO.File.Exists(namePair[f].Item2))
                                {
                                    PartDocument partDoc = (PartDocument)PersistenceManager.InventorApplication.Documents.Open(namePair[f].Item1, false);
                                    partDoc.SaveAs(namePair[f].Item2, true);
                                    partDoc.Close(true);
                                    newOccs.Items[i].ReferencedDocumentDescriptor.ReferencedFileDescriptor.ReplaceReference(namePair[f].Item2);
                                }
                                patternComponentsList.Add(namePair[f].Item1);
                            }
                        }
                    }
                }

                else if (newOccs.Items[i].DefinitionDocumentType == DocumentTypeEnum.kAssemblyDocumentObject)
                {
                    for (int n = 0; n < namePair.Count; n++)
                    {
                        if (namePair[n].Item1 == newOccs.Items[i].ReferencedFileDescriptor.FullFileName)
                        {
                            AssemblyDocument subAssembly = (AssemblyDocument)PersistenceManager.InventorApplication.Documents.Open(newOccs.Items[i].ReferencedFileDescriptor.FullFileName, false);
                            ReplaceReferences(subAssembly, namePair, pathString);
                            string newFilePath = namePair[n].Item2;
                            subAssembly.SaveAs(namePair[n].Item2, true);
                            subAssembly.Close(true);
                            newOccs.Items[i].ReferencedDocumentDescriptor.ReferencedFileDescriptor.ReplaceReference(namePair[n].Item2);
                        }
                    }
                }
            }
        }
예제 #4
0
        private void SearchCasingComponents()
        {
            try
            {
                casingAssembly = (AssemblyDocument)inventorApp.Documents.Open(casingComponent.FullFileName, false);
                foreach (ComponentOccurrence occurrence in casingAssembly.ComponentDefinition.Occurrences)
                {
                    AddCasingComponentRecursive(occurrence, casingComponent);
                }

                casingAssembly.Close();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, System.Reflection.MethodBase.GetCurrentMethod().Name, MessageBoxButton.OK);
            }
        }
        private void SearchSheetMetalKits(Component component)
        {
            try
            {
                AssemblyDocument assembly = (AssemblyDocument)inventorApp.Documents.Open(component.FullFileName, false);
                // Get BOM
                BOM bom = assembly.ComponentDefinition.BOM;
                bom.StructuredViewFirstLevelOnly = false;
                bom.StructuredViewEnabled        = true;
                // Set a reference to the "Structured" BOMView
                BOMView bomView = bom.BOMViews["Структурированный"];

                foreach (BOMRow row in bomView.BOMRows)
                {
                    ComponentDefinition componentDefinition = row.ComponentDefinitions[1];
                    if (!(componentDefinition is VirtualComponentDefinition))
                    {
                        if (componentDefinition is AssemblyComponentDefinition)
                        {
                            AssemblyDocument locAssembly = (AssemblyDocument)componentDefinition.Document;
                            string           filePath    = locAssembly.FullFileName;
                            // Check whether assembly in casing subdirectory
                            if (filePath.IndexOf(casingDirectory) >= 0)
                            {
                                ReNumberSheetMetalKit(locAssembly, row.ChildRows);
                            }
                        }
                    }
                }
                assembly.Close();
            }
            catch (Exception ex)
            {
                System.Windows.MessageBox.Show(ex.Message, System.Reflection.MethodBase.GetCurrentMethod().Name, MessageBoxButton.OK);
            }
        }
예제 #6
0
        internal void MakeInvCopy(string templateAssemblyPath,
                                  string targetDirectory,
                                  OccurrenceList occurrenceList,
                                  UniqueModuleEvaluator uniqueModuleEvaluator)
        {
            // TODO Test for the existance of folders and assemblies.
            TemplateAssemblyPath = templateAssemblyPath;
            UniqueModules        = uniqueModuleEvaluator;


            //Get the folder name that will be used to store the files associated with this Module.
            string folderName = GetModuleFolderPath();

            //Need to get number of the parent occ, top level name as foldername
            ModulePath = System.IO.Path.Combine(targetDirectory, folderName);

            string topFileFullName = occurrenceList.TargetAssembly.FullDocumentName;
            string topFileNameOnly = System.IO.Path.GetFileName(topFileFullName);

            ModuleAssemblyPath = System.IO.Path.Combine(ModulePath, topFileNameOnly);

            //If this file already exists in the current location, for now we are
            //going to just skip the file creation, and assume it was previously done
            //correctly.  Probably need to give the user the option to redo and
            //overwrite files if they want to.
            if (!System.IO.File.Exists(ModuleAssemblyPath))
            {
                FilePathPair = new TupleList <string, string>();

                for (int i = 0; i < occurrenceList.Items.Count; i++)
                {
                    string targetOccPath   = occurrenceList.Items[i].ReferencedFileDescriptor.FullFileName;
                    string newCopyName     = System.IO.Path.GetFileName(targetOccPath);
                    string newFullCopyName = System.IO.Path.Combine(ModulePath, newCopyName);
                    FilePathPair.Add(targetOccPath, newFullCopyName);
                }

                //Check if an earlier module already made the folder, if not, create it.
                if (!System.IO.Directory.Exists(ModulePath))
                {
                    //This property is needed later when placing occurrences of the assembly this Module instance
                    //refers to.  If FirstTime is false, we will want to have a slightly different strategry for constraint
                    //placement.  If FirstTime is true, all constraints are important and we need not relax them.  If
                    //FirstTime is false, then we need tolerance in the constraints because of double precision.  When
                    //FirstTime is false, we really just want to position the occurrence correctly, not drive its
                    //geometry.

                    if (FirstTime == null)
                    {
                        FirstTime = true;
                    }

                    System.IO.Directory.CreateDirectory(ModulePath);
                    ReplaceReferences(occurrenceList.TargetAssembly, FilePathPair, ModulePath);
                    AssemblyDocument oAssDoc = (AssemblyDocument)PersistenceManager.InventorApplication.Documents.Open(TemplateAssemblyPath, false);
                    oAssDoc.SaveAs(ModuleAssemblyPath, true);
                    oAssDoc.Close(true);


                    //Need to copy presentation files if there are any.  For now this is only going to work with the top assembly.
                    string   templateDirectory = System.IO.Path.GetDirectoryName(TemplateAssemblyPath);
                    string[] presentationFiles = System.IO.Directory.GetFiles(templateDirectory, "*.ipn");
                    //If we want the ability to have subassemblies with .ipn files or multiple ones, this will have to be changed
                    //to iterate over all the .ipn files.
                    if (presentationFiles.Length != 0)
                    {
                        string newCopyPresName     = System.IO.Path.GetFileName(presentationFiles[0]);
                        string newFullCopyPresName = System.IO.Path.Combine(ModulePath, newCopyPresName);
                        PresentationDocument          presentationDocument = (PresentationDocument)PersistenceManager.InventorApplication.Documents.Open(presentationFiles[0], false);
                        DocumentDescriptorsEnumerator presFileDescriptors  = presentationDocument.ReferencedDocumentDescriptors;
                        foreach (DocumentDescriptor refPresDocDescriptor in presFileDescriptors)
                        {
                            if (refPresDocDescriptor.FullDocumentName == TemplateAssemblyPath)
                            {
                                refPresDocDescriptor.ReferencedFileDescriptor.ReplaceReference(ModuleAssemblyPath);
                                presentationDocument.SaveAs(newFullCopyPresName, true);
                                presentationDocument.Close(true);
                            }
                        }
                    }
                }

                else
                {
                    FirstTime = false;
                }
            }
        }
예제 #7
0
 public void CloseTargetAssembly()
 {
     templateAssemblyDoc.Close();
 }
예제 #8
0
        private DataTable GetDataTable(Component specComponent)
        {
            DataTable resultTable = new DataTable();

            // Format table
            resultTable.Columns.Add("VPNumber", typeof(string));             // Code from purchase roll
            resultTable.Columns.Add("PartNumber", typeof(string));
            resultTable.Columns.Add("Description", typeof(string));
            resultTable.Columns.Add("Quantity", typeof(string));
            resultTable.Columns.Add("IsConsumable", typeof(bool));
            resultTable.Columns.Add("UnitOfMeasure", typeof(string));
            try
            {
                AssemblyDocument assembly = (AssemblyDocument)inventorApp.Documents.Open(specComponent.FullFileName, false);
                // Get BOM
                BOM bom = assembly.ComponentDefinition.BOM;
                bom.StructuredViewFirstLevelOnly = false;
                bom.StructuredViewEnabled        = true;
                // Get merge settings
                bool     mergeEnabled     = false;
                string[] mergeExcludeList = new string[] { "жопа" };
                bom.GetPartNumberMergeSettings(out mergeEnabled, out mergeExcludeList);
                // Set merge settings to false temporarily
                bom.SetPartNumberMergeSettings(false, mergeExcludeList);
                // Set a reference to the "Structured" BOMView
                BOMView bomView = bom.BOMViews["Структурированный"];


                foreach (BOMRow BOMrow in bomView.BOMRows)
                {
                    DataRow             row = resultTable.NewRow();
                    ComponentDefinition componentDefinition = BOMrow.ComponentDefinitions[1];
                    Document            locDoc   = (Document)componentDefinition.Document;
                    PropertySet         oPropSet = locDoc.PropertySets["Design Tracking Properties"];
                    row["PartNumber"]  = oPropSet["Part Number"].Value.ToString();
                    row["Description"] = oPropSet["Description"].Value.ToString();
                    oPropSet           = locDoc.PropertySets["Inventor User Defined Properties"];
                    if (Library.HasInventorProperty(oPropSet, "Расходник"))
                    {
                        row["IsConsumable"] = oPropSet["Расходник"].Value;
                    }
                    else
                    {
                        row["IsConsumable"] = false;
                    }
                    row["Quantity"] = BOMrow.TotalQuantity;
                    // Add row
                    resultTable.Rows.Add(row);
                }

                // Restore BOM merge settings
                bom.SetPartNumberMergeSettings(mergeEnabled, mergeExcludeList);
                if (specComponent.FullFileName != mainComponent.FullFileName)
                {
                    assembly.Close();
                }
                return(resultTable);
            }

            catch (Exception ex)
            {
                System.Windows.MessageBox.Show(ex.Message, System.Reflection.MethodBase.GetCurrentMethod().Name, MessageBoxButton.OK);
                return(null);
            }
        }
예제 #9
0
        public void RunWithArguments(Document doc, NameValueMap map)
        {
            LogTrace("Initialiting");
            PartDocument oPartDoc = (PartDocument)inventorApplication.Documents.Add(DocumentTypeEnum.kPartDocumentObject, inventorApplication.FileManager.GetTemplateFile(DocumentTypeEnum.kPartDocumentObject), true);

            LogTrace("Part template opened");
            TransientGeometry       oTG         = inventorApplication.TransientGeometry;
            PartComponentDefinition oPartComDef = oPartDoc.ComponentDefinition;
            UserParameters          oParams     = oPartComDef.Parameters.UserParameters;

            XmlDocument xmlDoc     = new XmlDocument();
            string      currentDir = System.IO.Directory.GetCurrentDirectory();
            string      projectDir = Directory.GetParent(currentDir).Parent.FullName;

            LogTrace("Reading XML input file from " + projectDir);
            xmlDoc.Load(System.IO.Path.Combine(projectDir, "react-test-output.xml"));
            //xmlDoc.Load("react-test-output.xml");
            //xmlDoc.Load("C:\\webapps\\IpartCreator\\React-BIM-output.xml");
            XmlNodeList FloorList      = xmlDoc.DocumentElement.SelectNodes("/Building/Floors/Floor");
            XmlNodeList FloorPointList = xmlDoc.DocumentElement.SelectNodes("/Building/Floors/Floor/BoundaryPoints/Point");
            XmlNodeList ComponentName  = xmlDoc.DocumentElement.SelectNodes("/Building/Floors/Floor/ComponentName");
            XmlNodeList PointX         = xmlDoc.DocumentElement.SelectNodes("/Building/Floors/Floor/BoundaryPoints/Point/X");
            XmlNodeList PointY         = xmlDoc.DocumentElement.SelectNodes("/Building/Floors/Floor/BoundaryPoints/Point/Y");
            XmlNodeList PointZ         = xmlDoc.DocumentElement.SelectNodes("/Building/Floors/Floor/BoundaryPoints/Point/Z");



            for (int i = 0; i < FloorList.Count; i++)
            {
                //oParams.AddByExpression("ComponentName" + i, ComponentName[i].InnerText, UnitsTypeEnum.kUnitlessUnits);


                int numPoint = FloorPointList.Count / FloorList.Count;

                Point2d[]     oPoints  = new Point2d[numPoint];
                SketchPoint[] osPoints = new SketchPoint[numPoint];

                for (int j = 0; j < numPoint; j++)
                {
                    oParams.AddByExpression("PointX" + j, PointX[j].InnerText, UnitsTypeEnum.kMillimeterLengthUnits);
                    oParams.AddByExpression("PointY" + j, PointY[j].InnerText, UnitsTypeEnum.kMillimeterLengthUnits);
                    oParams.AddByExpression("PointZ" + j, PointZ[j].InnerText, UnitsTypeEnum.kMillimeterLengthUnits);

                    oPoints[j] = oTG.CreatePoint2d(oPartComDef.Parameters.GetValueFromExpression("PointX" + j, UnitsTypeEnum.kMillimeterLengthUnits), oPartComDef.Parameters.GetValueFromExpression("PointY" + j, UnitsTypeEnum.kMillimeterLengthUnits));
                }

                SketchLine[] oLines  = new SketchLine[numPoint];
                PlanarSketch oSketch = oPartComDef.Sketches.Add(oPartComDef.WorkPlanes[2]);
                osPoints[0] = oSketch.SketchPoints.Add(oPoints[0]);
                osPoints[1] = oSketch.SketchPoints.Add(oPoints[1]);
                osPoints[2] = oSketch.SketchPoints.Add(oPoints[2]);
                osPoints[3] = oSketch.SketchPoints.Add(oPoints[3]);

                oLines[0] = oSketch.SketchLines.AddByTwoPoints(osPoints[0], osPoints[1]);
                oLines[1] = oSketch.SketchLines.AddByTwoPoints(oLines[0].EndSketchPoint, osPoints[2]);
                oLines[2] = oSketch.SketchLines.AddByTwoPoints(oLines[1].EndSketchPoint, osPoints[3]);
                oLines[3] = oSketch.SketchLines.AddByTwoPoints(oLines[2].EndSketchPoint, oLines[0].StartSketchPoint);

                oSketch.DimensionConstraints.AddTwoPointDistance(osPoints[0], osPoints[1], DimensionOrientationEnum.kAlignedDim, oPoints[1]); //d0//
                oSketch.DimensionConstraints.AddTwoPointDistance(osPoints[1], osPoints[2], DimensionOrientationEnum.kAlignedDim, oPoints[3]); //d1//

                Profile           oProfile    = oSketch.Profiles.AddForSolid();
                ExtrudeDefinition oExtrudeDef = oPartComDef.Features.ExtrudeFeatures.CreateExtrudeDefinition(oProfile, PartFeatureOperationEnum.kJoinOperation);
                oExtrudeDef.SetDistanceExtent(oPartComDef.Parameters.UserParameters.AddByExpression("length", "8", UnitsTypeEnum.kMillimeterLengthUnits), PartFeatureExtentDirectionEnum.kPositiveExtentDirection);
                ExtrudeFeature oExtrude = oPartComDef.Features.ExtrudeFeatures.Add(oExtrudeDef);

                string PartPath = projectDir + "/results/" + ComponentName[i].InnerText + i + ".ipt";
                //string PartPath = ComponentName[i].InnerText + i + ".ipt";
                oPartDoc.SaveAs(PartPath, false);

                oExtrude.Delete();
            }

            oPartDoc.Close(false);

            AssemblyDocument            oAssyDoc      = (AssemblyDocument)inventorApplication.Documents.Add(DocumentTypeEnum.kAssemblyDocumentObject, inventorApplication.FileManager.GetTemplateFile(DocumentTypeEnum.kAssemblyDocumentObject), true);
            AssemblyComponentDefinition oAssyComDef   = oAssyDoc.ComponentDefinition;
            ComponentOccurrences        oAssyCompOccs = oAssyComDef.Occurrences;
            Matrix oPos  = oTG.CreateMatrix();
            int    oStep = 0;
            int    icomp;
            int    numite = FloorPointList.Count / FloorList.Count;

            for (icomp = 0; icomp <= numite; icomp++)
            {
                oStep = oStep + 150;
                oPos.SetTranslation(oTG.CreateVector(oStep, oStep, 0), false);
                string PartPath = projectDir + "/results/" + ComponentName[icomp].InnerText + icomp + ".ipt";
                //string PartPath = ComponentName[icomp].InnerText + icomp + ".ipt";
                ComponentOccurrence oOcc = oAssyCompOccs.Add(PartPath, oPos);
            }

            oAssyDoc.SaveAs(projectDir + "/results/result.iam", false);
            //oAssyDoc.SaveAs("result.iam", false);
            oAssyDoc.Close();
            ZipFile.CreateFromDirectory(projectDir + "/results", projectDir + "/forgeResult.zip");
        }
예제 #10
0
        private void DrawAssemDoc(string filename)
        {
            DrawingDocument oDoc;
            Sheet           oSheet;

            SetupNewDrawingDocument(out oDoc, out oSheet);

            ///////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //Open the Ass document, invisibly.
            AssemblyDocument oBlockAssem = mApp.Documents.Open(filename, false) as AssemblyDocument;
            //AssemblyDocument oBlockAssem = mApp.Documents.Open(@"E:\Projects\TST PRJ\Assembly1.iam", false) as AssemblyDocument;
            TransientGeometry oTG = mApp.TransientGeometry;

            //Create base drawing view//0.1 = 1:10 or 0.2 = 1:5 1:20=0.02   X-> Y ^
            DrawingView oBaseView = oSheet.DrawingViews.AddBaseView(oBlockAssem as _Document,
                                                                    oTG.CreatePoint2d(28.7, 21), 0.1,
                                                                    ViewOrientationTypeEnum.kFrontViewOrientation,
                                                                    DrawingViewStyleEnum.kHiddenLineDrawingViewStyle, "", null, null);
            //59.4 x 42.0   29.7 X 21.0
            DrawingView oTopView = oSheet.DrawingViews.AddProjectedView(oBaseView,
                                                                        oTG.CreatePoint2d(28.7, 29),
                                                                        DrawingViewStyleEnum.kFromBaseDrawingViewStyle, null);

            //Create Projected views
            DrawingView oRightView = oSheet.DrawingViews.AddProjectedView(oBaseView,
                                                                          oTG.CreatePoint2d(45, 21),
                                                                          DrawingViewStyleEnum.kFromBaseDrawingViewStyle, null);

            //Find an edge in the part to dimension.  Any method can be used, (attributes, B-Rep query, selection, etc.).  This
            //looks through the curves in the drawing view and finds the top horizontal curve.
            oSheet.RevisionTables.Add(oTG.CreatePoint2d(48.4, 23.5));  //1mm div 10//1 row = 4

            DrawingCurve oSelectedCurve = null;

            foreach (DrawingCurve oCurve in oBaseView.get_DrawingCurves(null))
            {
                //Skip Circles
                if (oCurve.StartPoint != null && oCurve.EndPoint != null)
                {
                    if (WithinTol(oCurve.StartPoint.Y, oCurve.EndPoint.Y, 0.001))
                    {
                        if (oSelectedCurve == null)
                        {
                            //This is the first horizontal curve found.
                            oSelectedCurve = oCurve;
                        }
                        else
                        {
                            //Check to see if this curve is higher (smaller x value) than the current selected
                            if (oCurve.MidPoint.Y < oSelectedCurve.MidPoint.X)
                            {
                                oSelectedCurve = oCurve;
                            }
                        }
                    }
                }
            }
            //Create geometry intents point for the curve.
            GeometryIntent oGeomIntent1 = oSheet.CreateGeometryIntent(oSelectedCurve, PointIntentEnum.kStartPointIntent);
            GeometryIntent oGeomIntent2 = oSheet.CreateGeometryIntent(oSelectedCurve, PointIntentEnum.kEndPointIntent);
            Point2d        oDimPos      = oTG.CreatePoint2d(oSelectedCurve.MidPoint.X - 2, oSelectedCurve.MidPoint.Y);
            /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
            //set up Dim
            GeneralDimensions oGeneralDimensions = oSheet.DrawingDimensions.GeneralDimensions;

            DimensionStyle dimstyle = oDoc.StylesManager.DimensionStyles[cmbDimStyles.Text];

            //Set Layer
            Layer layer = oDoc.StylesManager.Layers[cmbLayers.Text];

            //Create the dimension.
            LinearGeneralDimension oLinearDim;

            oLinearDim = oGeneralDimensions.AddLinear(oDimPos, oGeomIntent1, oGeomIntent2,
                                                      DimensionTypeEnum.kAlignedDimensionType, true,
                                                      dimstyle,
                                                      layer);

            string newfilename;
            string swapfilename;

            newfilename  = "";
            swapfilename = "";
            //Build New Filname
            Inventor.PropertySet InvPropertySet = oBlockAssem.PropertySets["{D5CDD505-2E9C-101B-9397-08002B2CF9AE}"];
            swapfilename = oBlockAssem.FullFileName.Substring(0, oBlockAssem.FullFileName.LastIndexOf("\\") + 1);
            //MessageBox.Show(swapfilename);
            newfilename = swapfilename + InvPropertySet["FULLFILENAME"].Value + ".idw";
            oBlockAssem.Close(true);
            oDoc.SaveAs(newfilename, true);
            oDoc.Close(true);
        }
예제 #11
0
        /// <summary>
        /// Main program control for copying, placing, constraining template assemblies,
        /// as well as evaluating duplicate geometries.
        /// </summary>
        /// <param name="templateAssemblyPath">Path to template assembly file to be copied and placed in model</param>
        /// <param name="destinationFolder">Path where created files will be saved</param>
        /// <param name="reuseDuplicates">Let the library determine if files can be reused</param>
        /// <param name="testMode">If true will create only three modules</param>
        private void InternalPlaceModules(string templateAssemblyPath, string destinationFolder, bool reuseDuplicates, bool testMode)
        {
            //Do some initial validation that this is going to work.
            //TODO: MOVE THIS INTO THE CONSTRUCTOR
            if (!IsConstraintSetUniform)
            {
                throw new Exception("Each module must have the same number of points.");
            }

            //If the user has chosen to try to reuse files for duplicate geometries, we need
            //evaluate that first before creating any new files.

            //TODO: MOVE THIS TO THE CONSTRUCTOR/ModulePoints property changed event.
            //Create this thing in constructor and set it to null in
            //this method if the user sets reuseDuplicates to false.  We
            //are evaluating this shit every time
            UniqueModules = null;

            if (reuseDuplicates)
            {
                ModulesList.Select(p => { p.ReuseDuplicates = false; return(p); }).ToList();
                //UniqueModuleEvaluator needs to be passed into the constructor.
                UniqueModules = UniqueModuleEvaluator.ByModules(ModulesList);
            }

            //We need to get a flattened list of all the ComponentOccurrence objects in the
            //template assembly.

            //Inventor's API was developed in Russia.
            AssemblyDocument templateAssembly    = (AssemblyDocument)PersistenceManager.InventorApplication.Documents.Open(templateAssemblyPath, false);
            OccurrenceList   templateOccurrences = new OccurrenceList(templateAssembly);

            _testMode = testMode;
            if (testMode)
            {
                if (ModulesList.Count < 3)
                {
                    for (int i = 0; i < ModulesList.Count; i++)
                    {
                        ModulesList[i].MakeInvCopy(templateAssemblyPath, destinationFolder, templateOccurrences, UniqueModules);
                    }
                }
                else
                {
                    for (int i = 0; i < 3; i++)
                    {
                        ModulesList[i].MakeInvCopy(templateAssemblyPath, destinationFolder, templateOccurrences, UniqueModules);
                    }
                }
            }
            else
            {
                for (int i = 0; i < ModulesList.Count; i++)
                {
                    ModulesList[i].MakeInvCopy(templateAssemblyPath, destinationFolder, templateOccurrences, UniqueModules);
                }
            }

            templateAssembly.Close();

            //ApprenticeServerComponent apprenticeServer = InventorPersistenceManager.ActiveApprenticeServer;
            //ApprenticeServerDocument templateAssemblyApprenticeDoc = apprenticeServer.Open(templateAssemblyPath);
            //OccurrenceList templateOccurrences = new OccurrenceList(apprenticeServer, templateAssemblyApprenticeDoc);
            //apprenticeServer.Close();


            //Create Inventor files needed to accommodate this set of "Modules".

            //Create a layout file.  This file will contain all the individual geometries as
            //work geometry.  It will be placed first in the assembly we are making, and each
            //Module will get constrained to its corresponding set of work geometry.
            //This only needs to happen the first time.
            EnsureLayoutPartExists(destinationFolder);

            //Place the layout part and put work geometry in it.
            CreateLayout(destinationFolder);

            //Place the actual Inventor assemblies.

            //PersistenceManager.InventorApplication.Visible = false;
            try
            {
                if (testMode)
                {
                    if (ModulesList.Count < 3)
                    {
                        for (int i = 0; i < ModulesList.Count; i++)
                        {
                            ModulesList[i].PlaceModule();
                        }
                    }
                    else
                    {
                        for (int i = 0; i < 3; i++)
                        {
                            ModulesList[i].PlaceModule();
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < ModulesList.Count; i++)
                    {
                        ModulesList[i].PlaceModule();
                    }
                }
            }
            catch
            {
                PersistenceManager.InventorApplication.Visible = true;
            }
            //PersistenceManager.InventorApplication.Visible = true;

            //Update the view
            PersistenceManager.ActiveAssemblyDoc.Update2();
        }