Beispiel #1
0
        public void RunWithArguments(Document doc, NameValueMap map)
        {
            if (doc == null && map.HasKey("ilod"))
            {
                string docPath = map.AsString("ilod");
                LogTrace($"Opening /ilod document name: {docPath}");

                if (docPath.ToUpper().EndsWith(".IAM"))
                {
                    FileManager fm = _inventorApplication.FileManager;

                    string dvActRep = fm.GetLastActiveDesignViewRepresentation(docPath);
                    LogTrace($"LastActiveDesignViewRepresentation: {dvActRep}");

                    string lodActRep = fm.GetLastActiveLevelOfDetailRepresentation(docPath);
                    LogTrace($"LastActiveLevelOfDetailRepresentation: {lodActRep}");

                    NameValueMap openOptions = _inventorApplication.TransientObjects.CreateNameValueMap();
                    openOptions.Add("LevelOfDetailRepresentation", lodActRep);
                    openOptions.Add("DesignViewRepresentation", dvActRep);

                    doc = _inventorApplication.Documents.OpenWithOptions(docPath, openOptions, false);
                }
                else
                {
                    doc = _inventorApplication.Documents.Open(docPath, false);
                }
                LogTrace($"Full document name: {doc.FullDocumentName}");
            }

            ExecWithArguments(doc, map);
        }
        // Check if the Drawing file has more sheets
        private NameValueMap GetSheetOptions(Document doc)
        {
            DrawingDocument drawingDocument = doc as DrawingDocument;

            NameValueMap sheets = inventorApplication.TransientObjects.CreateNameValueMap();

            foreach (Sheet sheet in drawingDocument.Sheets)
            {
                NameValueMap option = inventorApplication.TransientObjects.CreateNameValueMap();
                option.Add("Name", sheet.Name);
                option.Add("3DModel", false);
                sheets.Add("Sheet" + sheets.Count + 1, option);
            }

            return(sheets);
        }
Beispiel #3
0
    /// <summary>
    /// The lightweight equivalent of the 'Add From Inventor' button in the <see cref="ExporterForm"/>. Used in <see cref="ExportMeshesLite(RigidNode_Base)"/>
    /// </summary>
    /// <param name="occurrences"></param>
    /// <returns></returns>
    public RigidNode_Base ExportSkeleteonLite(List <ComponentOccurrence> occurrences)
    {
        if (occurrences.Count == 0)
        {
            throw new ArgumentException("ERROR: 0 Occurrences passed to ExportSkeletonLite", "occurrences");
        }

        #region CenterJoints
        int NumCentered = 0;

        SetProgressText(string.Format("Centering Joints {0} / {1}", NumCentered, occurrences.Count));
        foreach (ComponentOccurrence component in occurrences)
        {
            Exporter.CenterAllJoints(component);
            NumCentered++;
            SetProgressText(string.Format("Centering Joints {0} / {1}", NumCentered, occurrences.Count));
        }
        #endregion

        #region Build Models
        //Getting Rigid Body Info...
        SetProgressText("Getting Rigid Body Info...", ProgressTextType.ShortTaskBegin);
        NameValueMap RigidGetOptions = InventorManager.Instance.TransientObjects.CreateNameValueMap();

        RigidGetOptions.Add("DoubleBearing", false);
        RigidBodyResults RawRigidResults = InventorManager.Instance.AssemblyDocument.ComponentDefinition.RigidBodyAnalysis(RigidGetOptions);

        //Getting Rigid Body Info...Done
        SetProgressText(null, ProgressTextType.ShortTaskEnd);
        CustomRigidResults RigidResults = new CustomRigidResults(RawRigidResults);


        //Building Model...
        SetProgressText("Building Model...", ProgressTextType.ShortTaskBegin);
        RigidBodyCleaner.CleanGroundedBodies(RigidResults);
        RigidNode baseNode = RigidBodyCleaner.BuildAndCleanDijkstra(RigidResults);

        //Building Model...Done
        SetProgressText(null, ProgressTextType.ShortTaskEnd);
        #endregion

        #region Cleaning Up
        //Cleaning Up...
        LiteExporterForm.Instance.SetProgressText("Cleaning Up...", ProgressTextType.ShortTaskBegin);
        List <RigidNode_Base> nodes = new List <RigidNode_Base>();
        baseNode.ListAllNodes(nodes);

        foreach (RigidNode_Base node in nodes)
        {
            node.ModelFileName = ((RigidNode)node).group.ToString();
            node.ModelFullID   = node.GetModelID();
        }
        //Cleaning Up...Done
        LiteExporterForm.Instance.SetProgressText(null, ProgressTextType.ShortTaskEnd);
        #endregion
        return(baseNode);
    }
Beispiel #4
0
 public byte[] readJoints()
 {
     try {
         List <byte>  jointBytes = new List <byte>();
         NameValueMap nameMap    = currentApplication.TransientObjects.CreateNameValueMap();
         nameMap.Add("DoubleBearing", false);
         RigidBodyResults jointsContainer = currentDocument.ComponentDefinition.RigidBodyAnalysis(nameMap);
         RigidBodyJoints  jointList       = jointsContainer.RigidBodyJoints;
         JointData        jointDataObject = null;
         foreach (RigidBodyJoint joint in jointList)
         {
             foreach (AssemblyJoint assemblyJoint in joint.Joints)
             {
                 foreach (byte byteID in BitConverter.GetBytes(0003))
                 {
                     jointBytes.Add(byteID);
                 }
                 foreach (JointData jointData in jointDataList)
                 {
                     if (jointData.jointOfType.OccurrenceOne.Name.Equals(assemblyJoint.OccurrenceOne.Name) && jointData.jointOfType.OccurrenceTwo.Name.Equals(assemblyJoint.OccurrenceTwo.Name))
                     {
                         jointDataObject = jointData;
                     }
                 }
                 if (joint.JointType.Equals("kSlideJointType"))
                 {
                     foreach (byte byteJID in BitConverter.GetBytes((ushort)0000))
                     {
                         jointBytes.Add(byteJID);
                     }
                     foreach (byte jointSection in ProcessLinearJoint(joint, jointDataObject))
                     {
                         jointBytes.Add(jointSection);
                     }
                 }
                 if (joint.JointType.Equals("kRotationalJointType"))
                 {
                     foreach (byte byteJID in BitConverter.GetBytes((ushort)0001))
                     {
                         jointBytes.Add(byteJID);
                     }
                     foreach (byte jointSection in ProcessRotationalJoint(joint, jointDataObject))
                     {
                         jointBytes.Add(jointSection);
                     }
                 }
             }
         }
         return(jointBytes.ToArray());
     }
     catch (Exception e) {
         //catches problems
         MessageBox.Show(e.Message + "\n\n\n" + e.StackTrace);
         return(null);
     }
 }
Beispiel #5
0
        public void Run(Document doc, string documentName)
        {
            LogTrace("Run ...");

            //Local Debug
            NameValueMap map = inventorApplication.TransientObjects.CreateNameValueMap();

            map.Add("_1", documentName);
            RunWithArguments(doc, map);
        }
Beispiel #6
0
 static I()
 {
     app    = Macros.StandardAddInServer.m_inventorApplication;
     tg     = app.TransientGeometry;
     objs   = app.TransientObjects;
     nvm    = objs.CreateNameValueMap();
     nvmDrw = objs.CreateNameValueMap();
     nvm.Add("SkipAllUnresolvedFiles", true);
     nvmDrw.Add("SkipAllUnresolvedFiles", true);
     nvmDrw.Add("DeferUpdates", true);
 }
Beispiel #7
0
    public static RigidNode_Base ExportSkeleton(List <ComponentOccurrence> occurrences)
    {
        if (occurrences.Count == 0)
        {
            throw new Exception("No components selected!");
        }

        SynthesisGUI.Instance.ExporterSetOverallText("Centering joints");

        SynthesisGUI.Instance.ExporterReset();
        SynthesisGUI.Instance.ExporterSetSubText("Centering 0 / 0");
        SynthesisGUI.Instance.ExporterSetProgress(0);
        SynthesisGUI.Instance.ExporterSetMeshes(2);

        int numOccurrences = occurrences.Count;

        SynthesisGUI.Instance.ExporterStepOverall();
        SynthesisGUI.Instance.ExporterSetOverallText("Getting rigid info");

        Console.WriteLine("Get rigid info...");
        //Group components into rigid bodies.
        NameValueMap options = InventorManager.Instance.TransientObjects.CreateNameValueMap();

        options.Add("DoubleBearing", false);
        RigidBodyResults rigidResults = InventorManager.Instance.AssemblyDocument.ComponentDefinition.RigidBodyAnalysis(options);

        Console.WriteLine("Got rigid info...");
        CustomRigidResults customRigid = new CustomRigidResults(rigidResults);

        Console.WriteLine("Build model...");
        RigidBodyCleaner.CleanGroundedBodies(customRigid);
        //After this point, all grounded groups have been merged into one CustomRigidGroup, and their joints have been updated.

        RigidNode baseNode = RigidBodyCleaner.BuildAndCleanDijkstra(customRigid);

        Console.WriteLine("Built");

        Console.WriteLine(baseNode.ToString());

        SynthesisGUI.Instance.ExporterStepOverall();

        List <RigidNode_Base> nodes = new List <RigidNode_Base>();

        baseNode.ListAllNodes(nodes);

        foreach (RigidNode_Base node in nodes)
        {
            node.ModelFileName = ((RigidNode)node).group.ToString();
            node.ModelFullID   = node.GetModelID();
        }

        return(baseNode);
    }
        private static void importaFromAutocad(string v)
        {
            TranslatorAddIn oDWGTranslator = (TranslatorAddIn)iApp.ApplicationAddIns.ItemById["{C24E3AC2-122E-11D5-8E91-0010B541CD80}"];

            DataMedium oDataMedium = iApp.TransientObjects.CreateDataMedium();

            oDataMedium.FileName = @"X:\Commesse\Focchi\200000 40L\99 Service\Matrici full\" + v + "_def.dwg";

            TranslationContext oTranslationContext = iApp.TransientObjects.CreateTranslationContext();

            oTranslationContext.Type = Inventor.IOMechanismEnum.kFileBrowseIOMechanism;


            PartDocument oDoc = (PartDocument)iApp.Documents.Add(DocumentTypeEnum.kPartDocumentObject);

            PartComponentDefinition oPartCompDef = oDoc.ComponentDefinition;

            PlanarSketch oSketchC = oPartCompDef.Sketches.Add(oPartCompDef.WorkPlanes[2], true);

            oSketchC.Name = "testtttttt";

            Sketch oSketch = (Sketch)oPartCompDef.Sketches["testtttttt"];

            oSketch.Edit();

            oTranslationContext.OpenIntoExisting = oSketch;

            NameValueMap oOptions = iApp.TransientObjects.CreateNameValueMap();

            oOptions.Add("SelectedLayers", "0");

            oOptions.Add("InvertLayersSelection", false);
            oOptions.Add("ConstrainEndPoints", true);

            object boh;

            oDWGTranslator.Open(oDataMedium, oTranslationContext, oOptions, out boh);
            oSketch.ExitEdit();
            // RegisterAutoCADDefault()
        }
Beispiel #9
0
        public byte[] ReadJoints()
        {
            try
            {
                List <byte>  jointBytes = new List <byte>();
                NameValueMap nameMap    = currentApplication.TransientObjects.CreateNameValueMap();
                nameMap.Add("DoubleBearing", false);
                RigidBodyResults jointsContainer = currentDocument.ComponentDefinition.RigidBodyAnalysis(nameMap);
                RigidBodyJoints  jointList       = jointsContainer.RigidBodyJoints;

                foreach (RigidBodyJoint rigidJoint in jointList)
                {
                    foreach (AssemblyJoint assemblyJoint in rigidJoint.Joints)
                    {
                        if (assemblyJoint.Definition.JointType.ToString().Equals("kSlideJoint"))
                        {
                            jointBytes.AddRange(ProcessLinearJoint(rigidJoint));
                        }
                        if (assemblyJoint.Definition.JointType.ToString().Equals("kRotationalJointType"))
                        {
                            jointBytes.AddRange(ProcessRotationalJoint(rigidJoint));
                        }
                        if (assemblyJoint.Definition.JointType.ToString().Equals("kCylindricalJointType"))
                        {
                            jointBytes.AddRange(ProcessCylindricalJoint(rigidJoint));
                        }
                        if (assemblyJoint.Definition.JointType.ToString().Equals("kPlanarJointType"))
                        {
                            jointBytes.AddRange(ProcessPlanarJoint(rigidJoint));
                        }
                        if (assemblyJoint.Definition.JointType.ToString().Equals("kBallJointType"))
                        {
                            jointBytes.AddRange(ProcessBallJoint(rigidJoint));
                        }
                    }
                }
                //Adds ID of joint section and the size of the section if there are joints in the model, to avoid excess data in the file.
                if (jointBytes.Count > 0)
                {
                    jointBytes.AddRange(BitConverter.GetBytes(0003));
                    jointBytes.InsertRange(4, BitConverter.GetBytes(jointBytes.Count - 4));
                }
                return(jointBytes.ToArray());
            }
            catch (Exception e)
            {
                //catches problems
                MessageBox.Show(e.Message + "\n\n\n" + e.StackTrace);
                return(null);
            }
        }
        /// <summary>
        /// The lightweight equivalent of the 'Add From Inventor' button in the <see cref="ExporterForm"/>. Used in <see cref="ExportMeshesLite(RigidNode_Base)"/>
        /// </summary>
        /// <param name="occurrences"></param>
        /// <returns></returns>
        public RigidNode_Base ExportSkeleton(List <ComponentOccurrence> occurrences)
        {
            if (occurrences.Count == 0)
            {
                throw new Exporter.EmptyAssemblyException();
            }

            #region Build Models
            //Getting Rigid Body Info...
            SetProgress("Getting physics info...", occurrences.Count, occurrences.Count + 3);
            NameValueMap RigidGetOptions = InventorManager.Instance.TransientObjects.CreateNameValueMap();

            RigidGetOptions.Add("DoubleBearing", false);
            RigidBodyResults RawRigidResults = InventorManager.Instance.AssemblyDocument.ComponentDefinition.RigidBodyAnalysis(RigidGetOptions);

            //Getting Rigid Body Info...Done
            CustomRigidResults RigidResults = new CustomRigidResults(RawRigidResults);


            //Building Model...
            SetProgress("Building model...", occurrences.Count + 1, occurrences.Count + 3);
            RigidBodyCleaner.CleanGroundedBodies(RigidResults);
            RigidNode baseNode = RigidBodyCleaner.BuildAndCleanDijkstra(RigidResults);

            //Building Model...Done
            #endregion

            #region Cleaning Up
            //Cleaning Up...
            SetProgress("Cleaning up...", occurrences.Count + 2, occurrences.Count + 3);
            List <RigidNode_Base> nodes = new List <RigidNode_Base>();
            baseNode.ListAllNodes(nodes);

            foreach (RigidNode_Base node in nodes)
            {
                node.ModelFileName = ((RigidNode)node).group.ToString();
                node.ModelFullID   = node.GetModelID();
            }
            //Cleaning Up...Done
            #endregion
            SetProgress("Done", occurrences.Count + 3, occurrences.Count + 3);
            return(baseNode);
        }
        public void ExportRFA(Document doc, string filePath)
        {
            LogTrace("Exporting RFA file.");

            BIMComponent bimComponent = getBIMComponent(doc);

            if (bimComponent == null)
            {
                LogTrace("Could not export RFA file.");
                return;
            }

            NameValueMap nvm            = inventorApplication.TransientObjects.CreateNameValueMap();
            string       currentDir     = System.IO.Directory.GetCurrentDirectory();
            var          reportFileName = System.IO.Path.Combine(currentDir, "Report.html");

            nvm.Add("ReportFileName", reportFileName);
            bimComponent.ExportBuildingComponentWithOptions(filePath, nvm);

            LogTrace("Exported RFA file.");
        }
        public void ExportRFA(Document doc)
        {
            LogTrace("Export RFA file.");

            BIMComponent bimComponent = getBIMComponent(doc);

            if (bimComponent == null)
            {
                return;
            }

            var startDir = System.IO.Directory.GetCurrentDirectory();

            // output file name
            var fileName = System.IO.Path.Combine(startDir, "Output.rfa");

            NameValueMap nvm = _inventorApplication.TransientObjects.CreateNameValueMap();

            LogTrace($"Exporting to {fileName}");

            var reportFileName = System.IO.Path.Combine(startDir, "Report.html");

            LogTrace($"Reporting to {reportFileName}");
            nvm.Add("ReportFileName", reportFileName);

            DateTime t = DateTime.Now;
            DateTime t2;

            using (new HeartBeat())
            {
                try
                {
                    bimComponent.ExportBuildingComponentWithOptions(fileName, nvm);
                    LogTrace("Export finished");
                    t2 = DateTime.Now;
                }
                catch (Exception e)
                {
                    t2 = DateTime.Now;
                    LogTrace($"ERROR: Exporting FAILED : {e.Message}");
                }
            }

            if (System.IO.File.Exists(fileName))
            {
                LogTrace($"EXPORTED to : {fileName}");
                LogTrace($"EXPORT took : {(t2 - t).TotalSeconds} seconds");
            }
            else
            {
                LogTrace($"ERROR: EXPORT does not exist !!!!!!!");
            }

            if (System.IO.File.Exists(reportFileName))
            {
                LogTrace($"REPORT generated.");
            }
            else
            {
                LogTrace($"ERROR: REPORT does not exist !!!!!!!");
            }
        }
Beispiel #13
0
        //  Load template file and extract related parameters
        public List <InventorParameterStructure> LoadInventorTemplateParameters(string fullPath)
        {
            NLogger.LogText("Entered LoadInventorTemplateParameters method");

            var        inventorParams = new List <InventorParameterStructure>();
            Parameters InventorParams = null;

            //  TODO: HANDLE THE HARDCODED PATH
            //var rootPath = Utilities.GetBIM360RootPath();
            //var fullPath = rootPath + @"ATDSK ​DEV​\Sample Project\Project Files\Libraries\" + templateName;

            try
            {
                NLogger.LogText($"Try opening assembly document {fullPath}");

                try
                {
                    NLogger.LogText($"Try opening assembly document {fullPath} with LOD specified");

                    NameValueMap oOptions = m_InventorApplication.TransientObjects.CreateNameValueMap();
                    oOptions.Add("LevelOfDetailRepresentation", "LOD1");

                    m_AssemblyDocument = (AssemblyDocument)m_InventorApplication.Documents.OpenWithOptions(fullPath, oOptions, false);

                    NLogger.LogText($"Opening assembly document {fullPath} with LOD specified suceeded");
                }
                catch
                {
                    NLogger.LogText($"Failed opening assembly document {fullPath} with LOD specified. Try to open it without LOD specified");

                    m_AssemblyDocument = (AssemblyDocument)m_InventorApplication.Documents.Open(fullPath, false);

                    NLogger.LogText($"Opening assembly document {fullPath} without LOD specified suceeded");
                }

                //  Load params
                NLogger.LogText("Load assembly document parameters");
                InventorParams = m_AssemblyDocument.ComponentDefinition.Parameters;
            }
            catch (Exception ex)
            {
                NLogger.LogText("An error has occurred casting to an Inventor Assembly document. Try casting to a Part document");

                try
                {
                    NLogger.LogText($"Try opening part document {fullPath}");

                    m_PartDocument = (PartDocument)m_InventorApplication.Documents.Open(fullPath, false);

                    NLogger.LogText($"Opening part document {fullPath} suceeded");

                    //  Load params
                    NLogger.LogText("Load Part document parameters");

                    InventorParams = m_PartDocument.ComponentDefinition.Parameters;
                }
                catch (Exception ex1)
                {
                    NLogger.LogText("An error has occurred casting to an Inventor Part document");

                    NLogger.LogError(ex1);
                    throw (ex1);
                }
            }

            NLogger.LogText("Create 'InventorParameterStructure'");

            for (int h = 1; h <= InventorParams.Count; h++)
            {
                if (ConfigUtilities.GetInventorElementShowOnlyKeys().ToLower() == "true")
                {
                    if (InventorParams[h].IsKey)
                    {
                        inventorParams.Add(new InventorParameterStructure {
                            Name = InventorParams[h].Name.ToString()
                        });
                    }
                }
                else
                {
                    inventorParams.Add(new InventorParameterStructure {
                        Name = InventorParams[h].Name.ToString()
                    });
                }
            }

            NLogger.LogText("Remove documents from  Inventor application instance");

            m_InventorApplication.Documents.CloseAll();

            NLogger.LogText("Exit LoadInventorTemplateParameters method");

            return(inventorParams);
        }
Beispiel #14
0
        /// <summary>
        /// creation of a balloon. Select a linear drawing curve and run the sample
        /// </summary>
        /// <remarks></remarks>
        public void CreateBalloon()
        {
            // Set a reference to the drawing document.
            // This assumes a drawing document is active.
            DrawingDocument oDrawDoc = (DrawingDocument)_InvApplication.ActiveDocument;

            // Set a reference to the active sheet.
            Sheet oActiveSheet = oDrawDoc.ActiveSheet;

            // Set a reference to the drawing curve segment.
            // This assumes that a drwaing curve is selected.
            DrawingCurveSegment oDrawingCurveSegment = oDrawDoc.SelectSet[1];

            // Set a reference to the drawing curve.
            DrawingCurve oDrawingCurve = oDrawingCurveSegment.Parent;

            // Get the mid point of the selected curve
            // assuming that the selection curve is linear
            Point2d oMidPoint = oDrawingCurve.MidPoint;

            // Set a reference to the TransientGeometry object.
            TransientGeometry oTG = _InvApplication.TransientGeometry;

            ObjectCollection oLeaderPoints = _InvApplication.TransientObjects.CreateObjectCollection();

            // Create a couple of leader points.
            oLeaderPoints.Add(oTG.CreatePoint2d(oMidPoint.X + 10, oMidPoint.Y + 10));
            oLeaderPoints.Add(oTG.CreatePoint2d(oMidPoint.X + 10, oMidPoint.Y + 5));

            // Add the GeometryIntent to the leader points collection.
            // This is the geometry that the balloon will attach to.
            GeometryIntent oGeometryIntent = oActiveSheet.CreateGeometryIntent(oDrawingCurve);

            oLeaderPoints.Add(oGeometryIntent);

            // Set a reference to the parent drawing view of the selected curve
            DrawingView oDrawingView = oDrawingCurve.Parent;

            // Set a reference to the referenced model document
            Document oModelDoc = oDrawingView.ReferencedDocumentDescriptor.ReferencedDocument;

            // Check if a partslist or a balloon has already been created for this model
            bool IsDrawingBOMDefined = false;

            IsDrawingBOMDefined = oDrawDoc.DrawingBOMs.IsDrawingBOMDefined(oModelDoc.FullFileName);

            Balloon oBalloon = null;


            if (IsDrawingBOMDefined)
            {
                // Just create the balloon with the leader points
                // All other arguments can be ignored
                oBalloon = oDrawDoc.ActiveSheet.Balloons.Add(oLeaderPoints);
            }
            else
            {
                // First check if the 'structured' BOM view has been enabled in the model

                // Set a reference to the model's BOM object
                AssemblyDocument            oAssDoc = (AssemblyDocument)oModelDoc;
                AssemblyComponentDefinition oComDef = oAssDoc.ComponentDefinition;
                BOM oBOM = oComDef.BOM;


                if (oBOM.StructuredViewEnabled)
                {
                    // Level needs to be specified
                    // Numbering options have already been defined
                    // Get the Level ('All levels' or 'First level only')
                    // from the model BOM view - must use the same here
                    PartsListLevelEnum Level = default(PartsListLevelEnum);
                    if (oBOM.StructuredViewFirstLevelOnly)
                    {
                        Level = PartsListLevelEnum.kStructured;
                    }
                    else
                    {
                        Level = PartsListLevelEnum.kStructuredAllLevels;
                    }

                    // Create the balloon by specifying just the level
                    oBalloon = oActiveSheet.Balloons.Add(oLeaderPoints, null, Level);
                }
                else
                {
                    // Level and numbering options must be specified
                    // The corresponding model BOM view will automatically be enabled
                    NameValueMap oNumberingScheme = _InvApplication.TransientObjects.CreateNameValueMap();

                    // Add the option for a comma delimiter
                    oNumberingScheme.Add("Delimiter", ",");

                    // Create the balloon by specifying the level and numbering scheme
                    oBalloon = oActiveSheet.Balloons.Add(oLeaderPoints, null, PartsListLevelEnum.kStructuredAllLevels, oNumberingScheme);
                }
            }
        }
        public JobOutcome Execute(IJobProcessorServices context, IJob job)
        {
            try
            {
                Inventor.InventorServer mInv = context.InventorObject as InventorServer;

                #region validate execution rules

                //pick up this job's context
                mConnection = context.Connection;
                Autodesk.Connectivity.WebServicesTools.WebServiceManager mWsMgr = mConnection.WebServiceManager;
                long   mEntId    = Convert.ToInt64(job.Params["EntityId"]);
                string mEntClsId = job.Params["EntityClassId"];

                // only run the job for files; handle the scenario, that an item lifecycle transition accidently submitted the job
                if (mEntClsId != "FILE")
                {
                    context.Log(null, "This job type is for files only.");
                    return(JobOutcome.Failure);
                }

                // only run the job for ipt and iam file types,
                List <string> mFileExtensions = new List <string> {
                    ".ipt", ".iam", "idw", "dwg"
                };
                ACW.File mFile = mWsMgr.DocumentService.GetFileById(mEntId);
                if (!mFileExtensions.Any(n => mFile.Name.EndsWith(n)))
                {
                    context.Log(null, "Skipped Job execution as file type did not match iLogic enabled files (ipt, iam, idw/dwg");
                    return(JobOutcome.Success);
                }
                //run iLogic for Inventor DWG file types/skip AutoCAD DWG files
                ACW.PropDef[] mPropDefs = mWsMgr.PropertyService.GetPropertyDefinitionsByEntityClassId("FILE");
                ACW.PropDef   mPropDef  = null;
                ACW.PropInst  mPropInst = null;
                if (mFile.Name.EndsWith(".dwg"))
                {
                    mPropDef  = mPropDefs.Where(n => n.SysName == "Provider").FirstOrDefault();
                    mPropInst = (mWsMgr.PropertyService.GetPropertiesByEntityIds("FILE", new long[] { mFile.Id })).Where(n => n.PropDefId == mPropDef.Id).FirstOrDefault();
                    if (mPropInst.Val.ToString() != "Inventor DWG")
                    {
                        context.Log(null, "Skipped Job execution as DWG type did not match Inventor DWG");
                        return(JobOutcome.Success);
                    }
                }

                ApplicationAddIns mInvSrvAddIns = mInv.ApplicationAddIns;
                ApplicationAddIn  iLogicAddIn   = mInvSrvAddIns.ItemById["{3BDD8D79-2179-4B11-8A5A-257B1C0263AC}"];

                if (iLogicAddIn != null && iLogicAddIn.Activated != true)
                {
                    iLogicAddIn.Activate();
                }

                dynamic mAutomation = iLogicAddIn.Automation;

                if (mAutomation == null)
                {
                    Trace.WriteLine("iLogic-AddIn automation is not available; exiting job processing");
                    context.Log(null, "iLogic-AddIn automation is not available");
                    return(JobOutcome.Failure);
                }

                #endregion validate execution rules

                #region VaultInventorServer IPJ activation

                //override InventorServer default project settings by your Vault specific ones
                Inventor.DesignProjectManager mInvIpjManager;
                Inventor.DesignProject        mInvDfltProject, mInvVltProject;
                String   mIpjPath      = "";
                String   mWfPath       = "";
                String   mIpjLocalPath = "";
                ACW.File mIpj;
                VDF.Vault.Currency.Entities.FileIteration mIpjFileIter = null;

                //validate ipj setting, a single, enforced ipj is expected
                if (mWsMgr.DocumentService.GetEnforceWorkingFolder() && mWsMgr.DocumentService.GetEnforceInventorProjectFile())
                {
                    mIpjPath = mWsMgr.DocumentService.GetInventorProjectFileLocation();
                    mWfPath  = mWsMgr.DocumentService.GetRequiredWorkingFolderLocation();
                    //Set mWfPath to alternate temporary working folder if needed, e.g. to delete all files after job execution
                }
                else
                {
                    context.Log(null, "Job requires both settings enabled: 'Enforce Workingfolder' and 'Enforce Inventor Project'.");
                    return(JobOutcome.Failure);
                }
                //download and activate the Inventor Project file in VaultInventorServer
                mIpj = (mWsMgr.DocumentService.FindLatestFilesByPaths(new string[] { mIpjPath })).FirstOrDefault();

                try
                {
                    String[] mIpjFullFileName = mIpjPath.Split(new string[] { "/" }, StringSplitOptions.None);
                    String   mIpjFileName     = mIpjFullFileName.LastOrDefault();

                    //define download settings for the project file
                    VDF.Vault.Settings.AcquireFilesSettings mAcqrIpjSettings = new VDF.Vault.Settings.AcquireFilesSettings(mConnection);
                    mAcqrIpjSettings.LocalPath = new VDF.Currency.FolderPathAbsolute(mWfPath);
                    mIpjFileIter = new VDF.Vault.Currency.Entities.FileIteration(mConnection, mIpj);
                    mAcqrIpjSettings.AddFileToAcquire(mIpjFileIter, VDF.Vault.Settings.AcquireFilesSettings.AcquisitionOption.Download);

                    //download project file and get local path
                    VDF.Vault.Results.AcquireFilesResults   mDownLoadResult;
                    VDF.Vault.Results.FileAcquisitionResult fileAcquisitionResult;
                    mDownLoadResult       = mConnection.FileManager.AcquireFiles(mAcqrIpjSettings);
                    fileAcquisitionResult = mDownLoadResult.FileResults.FirstOrDefault();
                    mIpjLocalPath         = fileAcquisitionResult.LocalPath.FullPath;

                    //activate this Vault's ipj
                    mInvIpjManager  = mInv.DesignProjectManager;
                    mInvDfltProject = mInvIpjManager.ActiveDesignProject;
                    mInvVltProject  = mInvIpjManager.DesignProjects.AddExisting(mIpjLocalPath);
                    mInvVltProject.Activate();

                    //[Optionally:] get Inventor Design Data settings and download all related files ---------
                }
                catch
                {
                    context.Log(null, "Job was not able to activate Inventor project file. - Note: The ipj must not be checked out by another user.");
                    return(JobOutcome.Failure);
                }
                #endregion VaultInventorServer IPJ activation


                #region download source file(s)

                //build download options including DefaultAcquisitionOptions
                VDF.Vault.Currency.Entities.FileIteration mFileIteration    = new VDF.Vault.Currency.Entities.FileIteration(mConnection, mFile);
                VDF.Vault.Currency.Entities.FileIteration mNewFileIteration = null;
                VDF.Vault.Settings.AcquireFilesSettings   mAcqrFlsSettings;
                VDF.Vault.Results.AcquireFilesResults     mAcqrFlsResults2;
                VDF.Vault.Results.FileAcquisitionResult   mFileAcqsResult2;
                string mLocalFileFullName = "", mExt = "";

                if (mFileIteration.IsCheckedOut == true && mFileIteration.IsCheckedOutToCurrentUser == false)
                {
                    //exit the job, as the job user is not able to edit the file reserved to another user
                    mInvDfltProject.Activate();
                    context.Log(null, "Job stopped execution as the source file to process is checked-out by another user.");
                    return(JobOutcome.Failure);
                }
                //download only
                if (mFileIteration.IsCheckedOut == true && mFileIteration.IsCheckedOutToCurrentUser == true)
                {
                    mAcqrFlsSettings = CreateAcquireSettings(false);
                    mAcqrFlsSettings.AddFileToAcquire(mFileIteration, mAcqrFlsSettings.DefaultAcquisitionOption);
                    mAcqrFlsResults2   = this.mConnection.FileManager.AcquireFiles(mAcqrFlsSettings);
                    mNewFileIteration  = mFileIteration;
                    mFileAcqsResult2   = mAcqrFlsResults2.FileResults.Where(n => n.File.EntityName == mFileIteration.EntityName).FirstOrDefault();
                    mLocalFileFullName = mFileAcqsResult2.LocalPath.FullPath;
                    mExt = System.IO.Path.GetExtension(mLocalFileFullName);
                }
                //checkout and download
                if (mFileIteration.IsCheckedOut == false)
                {
                    try
                    {
                        mAcqrFlsSettings = CreateAcquireSettings(true); //checkout (don't checkout related children)
                        mAcqrFlsSettings.AddFileToAcquire(mFileIteration, mAcqrFlsSettings.DefaultAcquisitionOption);
                        mAcqrFlsResults2  = this.mConnection.FileManager.AcquireFiles(mAcqrFlsSettings);
                        mFileAcqsResult2  = mAcqrFlsResults2.FileResults.Where(n => n.File.EntityName == mFileIteration.EntityName).FirstOrDefault();
                        mNewFileIteration = mFileAcqsResult2.NewFileIteration;
                        mAcqrFlsSettings  = null;
                        mAcqrFlsSettings  = CreateAcquireSettings(false);//download (include related children)
                        mAcqrFlsSettings.AddFileToAcquire(mNewFileIteration, mAcqrFlsSettings.DefaultAcquisitionOption);
                        mAcqrFlsResults2   = this.mConnection.FileManager.AcquireFiles(mAcqrFlsSettings);
                        mLocalFileFullName = mFileAcqsResult2.LocalPath.FullPath;
                        mExt = System.IO.Path.GetExtension(mLocalFileFullName);
                    }
                    catch (Exception)
                    {
                        mInvDfltProject.Activate();
                        context.Log(null, "Job stopped execution as the source file to process did not download or check-out.");
                        return(JobOutcome.Failure);
                    }
                }

                #endregion download source file(s)

                #region capture dependencies
                //we need to return all relationships during later check-in
                List <ACW.FileAssocParam> mFileAssocParams = new List <ACW.FileAssocParam>();
                ACW.FileAssocArray        mFileAssocArray  = mWsMgr.DocumentService.GetLatestFileAssociationsByMasterIds(new long[] { mFile.MasterId },
                                                                                                                         ACW.FileAssociationTypeEnum.None, false, ACW.FileAssociationTypeEnum.All, false, false, false, true).FirstOrDefault();
                if (mFileAssocArray.FileAssocs != null)
                {
                    foreach (ACW.FileAssoc item in mFileAssocArray.FileAssocs)
                    {
                        ACW.FileAssocParam mFileAssocParam = new ACW.FileAssocParam();
                        mFileAssocParam.CldFileId         = item.CldFile.Id;
                        mFileAssocParam.ExpectedVaultPath = item.ExpectedVaultPath;
                        mFileAssocParam.RefId             = item.RefId;
                        mFileAssocParam.Source            = item.Source;
                        mFileAssocParam.Typ = item.Typ;
                        mFileAssocParams.Add(mFileAssocParam);
                    }
                }

                #endregion capture dependencies

                #region iLogic Configuration

                //avoid unplanned rule execution triggered by the document itself
                mAutomation.RulesOnEventsEnabled = false;
                mAutomation.RulesEnabled         = false;

                //set the iLogic Advanced Configuration Settings
                dynamic mFileOptions = mAutomation.FileOptions;
                mFileOptions.AddinDirectory = mSettings.iLogicAddinDLLs;
                //add the job extension app path and configured external rule directories to the FileOptions.ExternalRuleDirectories for iLogic
                List <string> mExtRuleDirs = new List <string>();
                mExtRuleDirs.Add(mAppPath);
                mExtRuleDirs.AddRange(mSettings.ExternalRuleDirectories.Split(',').ToList <string>());
                mFileOptions.ExternalRuleDirectories = mExtRuleDirs.ToArray();

                //enable iLogic logging
                dynamic mLogCtrl = mAutomation.LogControl;
                switch (mSettings.iLogicLogLevel)
                {
                case "None":
                    mLogCtrl.Level = 0;
                    break;

                case "Trace":
                    mLogCtrl.Level = 1;
                    break;

                case "Debug":
                    mLogCtrl.Level = 2;
                    break;

                case "Info":
                    mLogCtrl.Level = 3;
                    break;

                case "Warn":
                    mLogCtrl.Level = 4;
                    break;

                case "Error":
                    mLogCtrl.Level = 5;
                    break;

                case "Fatal":
                    mLogCtrl.Level = 6;
                    break;

                default:
                    mLogCtrl.Level = 5;
                    break;
                }

                //enable iLogic to save a log file for each job Id.
                string mILogicLogFileFullName = "";
                if (mLogCtrl.Level != 0)
                {
                    string mLogName = job.Id + "_" + mFile.Name + "_iLogicSampleJob.log";
                    System.IO.DirectoryInfo mLogDirInfo = new System.IO.DirectoryInfo(mSettings.iLogicLogDir);
                    if (mLogDirInfo.Exists == false)
                    {
                        mLogDirInfo = System.IO.Directory.CreateDirectory(mSettings.iLogicLogDir);
                    }
                    mILogicLogFileFullName = System.IO.Path.Combine(mLogDirInfo.FullName, mLogName);
                }



                //read rule execution settings
                string mVaultRule       = mSettings.VaultRuleFullFileName;
                string mExtRule         = mSettings.ExternalRuleName;
                string mExtRuleFullName = null;
                string mIntRulesOption  = mSettings.InternalRulesOption;

                if (mVaultRule != "")
                {
                    ACW.File mRuleFile = mWsMgr.DocumentService.FindLatestFilesByPaths(new string[] { mVaultRule }).FirstOrDefault();
                    //build download options including DefaultAcquisitionOptions
                    VDF.Vault.Currency.Entities.FileIteration mRuleFileIter = new VDF.Vault.Currency.Entities.FileIteration(mConnection, mRuleFile);

                    VDF.Vault.Settings.AcquireFilesSettings mAcqrRuleSettings = CreateAcquireSettings(false);

                    mAcqrRuleSettings.AddFileToAcquire(mRuleFileIter, mAcqrRuleSettings.DefaultAcquisitionOption);

                    //download
                    VDF.Vault.Results.AcquireFilesResults mAcqrRuleResults = this.mConnection.FileManager.AcquireFiles(mAcqrRuleSettings);
                    //pick-up the new file iteration in case of check-out
                    VDF.Vault.Results.FileAcquisitionResult mRuleAcqResult = mAcqrRuleResults.FileResults.Where(n => n.File.EntityName == mRuleFileIter.EntityName).FirstOrDefault();
                    if (mRuleAcqResult.LocalPath != null)
                    {
                        mExtRuleFullName = mRuleAcqResult.LocalPath.FullPath;
                        System.IO.FileInfo fileInfo = new System.IO.FileInfo(mExtRuleFullName);
                        if (fileInfo.Exists == false)
                        {
                            context.Log(null, "Job downloaded rule file but exited due to missing rule file: " + mExtRuleFullName + ".");
                            mConnection.FileManager.UndoCheckoutFile(mNewFileIteration);
                            return(JobOutcome.Failure);
                        }
                        else
                        {
                            mExtRule = fileInfo.Name;
                            if (!mExtRuleDirs.Any(n => fileInfo.DirectoryName.Equals(n)))
                            {
                                context.Log(null, "Job downloaded rule file but exited due to missing iLogic External Rule Directory configuration: Add the path"
                                            + fileInfo.DirectoryName + " to the list of External Rule Directories.");
                                mConnection.FileManager.UndoCheckoutFile(mNewFileIteration);
                                return(JobOutcome.Failure);
                            }
                        }
                    }
                    else
                    {
                        context.Log(null, "Job could not download configured rule file and exited. Compare the 'VaultRuleFullFileName' setting and available rule in Vault.");
                        return(JobOutcome.Failure);
                    }
                }

                #endregion iLogic Configuration

                #region Run iLogic Rule(s)

                //Open Inventor Document
                Document mDoc = mInv.Documents.Open(mLocalFileFullName);

                //use case  - apply external rule with arguments; additional Vault UDP, status or any information might fill rule arguments
                if (mExtRule != "")
                {
                    //required rule arguments to continue Vault interaction within the rule (iLogic-Vault library)
                    NameValueMap ruleArguments = mInv.TransientObjects.CreateNameValueMap();
                    ruleArguments.Add("ServerName", mConnection.Server);
                    ruleArguments.Add("VaultName", mConnection.Vault);
                    ruleArguments.Add("UserId", mConnection.UserID);
                    ruleArguments.Add("Ticket", mConnection.Ticket);

                    //additional rule arguments to build rule conditions evaluating Vault lifecycle information, properties, etc.
                    if (mSettings.PropagateProps == "True")
                    {
                        ACW.PropInst[] mSourcePropInsts = mWsMgr.PropertyService.GetPropertiesByEntityIds("FILE", new long[] { mFileIteration.EntityIterationId });
                        string         mPropDispName;
                        string         mThumbnailDispName = mPropDefs.Where(n => n.SysName == "Thumbnail").FirstOrDefault().DispName;
                        foreach (ACW.PropInst item in mSourcePropInsts)
                        {
                            mPropDispName = mPropDefs.Where(n => n.Id == item.PropDefId).FirstOrDefault().DispName;
                            //filter thumbnail property, as iLogic RuleArguments will fail reading it.
                            if (mPropDispName != mThumbnailDispName)
                            {
                                ruleArguments.Add(mPropDispName, item.Val);
                            }
                        }
                    }

                    //call external rule with arguments; return value = 0 in case of successful execution
                    mRuleSuccess = mAutomation.RunExternalRuleWithArguments(mDoc, mExtRule, ruleArguments);
                    if (mRuleSuccess != 0)
                    {
                        context.Log(null, "Job failed due to failure in external rule: " + mExtRule + ".");
                        mDoc.Close(true);
                        mConnection.FileManager.UndoCheckoutFile(mNewFileIteration);
                        mLogCtrl.SaveLogAs(mILogicLogFileFullName);
                        return(JobOutcome.Failure);
                    }
                    else
                    {
                        mAllRulesTextWrp = "External Rule: " + mExtRule;
                    }
                    mDoc.Save2(false);
                }


                //use case - run all, all active or filtered document rules
                dynamic        mDocRules    = mAutomation.Rules(mDoc);
                List <dynamic> mRulesToExec = new List <dynamic>();

                switch (mSettings.InternalRulesOption)
                {
                case "None":
                    break;

                case "Active":
                    if (mDocRules != null)
                    {
                        foreach (dynamic rule in mDocRules)
                        {
                            if (rule.IsActive == true)
                            {
                                mRulesToExec.Add(rule);
                            }
                        }
                    }
                    break;

                case "All":
                    if (mDocRules != null)
                    {
                        foreach (dynamic rule in mDocRules)
                        {
                            mRulesToExec.Add(rule);
                        }
                    }
                    break;

                default:
                    foreach (dynamic rule in mDocRules)
                    {
                        if (rule.Name.Contains(mSettings.InternalRulesOption))
                        {
                            mRulesToExec.Add(rule);
                        }
                    }
                    break;
                }
                if (mRulesToExec.Count >= 1)
                {
                    foreach (dynamic rule in mRulesToExec)
                    {
                        mRuleSuccess = mAutomation.RunRule(mDoc, rule.Name);
                        if (mRuleSuccess != 0)
                        {
                            context.Log(null, "Job failed due to failure in internal rule: " + rule.Name + ".");
                            mDoc.Close(true);
                            mConnection.FileManager.UndoCheckoutFile(mNewFileIteration);
                            mLogCtrl.SaveLogAs(mILogicLogFileFullName);
                            return(JobOutcome.Failure);
                        }
                        else
                        {
                            mAllRules.Add(rule.Name);
                        }
                    }
                }

                mDoc.Save2(false);
                mDoc.Close(true);
                mLogCtrl.SaveLogAs(mILogicLogFileFullName);

                if (mAllRules.Count > 0)
                {
                    mAllRulesTextWrp += "\n\r Internal Rule(s):";
                    foreach (string name in mAllRules)
                    {
                        mAllRulesTextWrp += "\r\n " + name;
                    }
                }

                #endregion Run iLogic Rules


                #region Check-in result

                // checkin new file version
                VDF.Currency.FilePathAbsolute vdfPath = new VDF.Currency.FilePathAbsolute(mLocalFileFullName);
                FileIteration mUploadedFile           = null;
                try
                {
                    if (mFileAssocParams.Count > 0)
                    {
                        mUploadedFile = mConnection.FileManager.CheckinFile(mNewFileIteration, "Created by Custom Job executing iLogic : " + mAllRulesTextWrp,
                                                                            false, mFileAssocParams.ToArray(), null, true, null, mFileIteration.FileClassification, false, vdfPath);
                    }
                    else
                    {
                        mUploadedFile = mConnection.FileManager.CheckinFile(mNewFileIteration, "Created by Custom Job executing iLogic : " + mAllRulesTextWrp,
                                                                            false, null, null, false, null, mFileIteration.FileClassification, false, vdfPath);
                    }
                }
                catch
                {
                    context.Log(null, "Job could not check-in updated file: " + mUploadedFile.EntityName + ".");
                    return(JobOutcome.Failure);
                }
                #endregion check-in result

                #region reset

                mInvDfltProject.Activate();
                //delete temporary working folder if imlemented here

                #endregion reset

                return(JobOutcome.Success);
            }
            catch (Exception ex)
            {
                context.Log(ex, "Job failed by unhandled exception: " + ex.ToString() + " ");
                return(JobOutcome.Failure);
            }
        }
Beispiel #16
0
        private static void GetDrawingDimension()
        {
            try
            {
                inventorApp = (Inventor.Application)Marshal.GetActiveObject("Inventor.Application");
                Console.WriteLine("查找到可用的实例");
            }
            catch { Console.WriteLine("未打开Inventor"); return; }
            DrawingDocument drawingDocument = (DrawingDocument)inventorApp.ActiveDocument;

            //在Inventor当前正在显示的工程图不一样的时候,ActiveSheet也会发生变化
            Console.WriteLine("打开的图纸:" + drawingDocument.ActiveSheet.Name + " " + drawingDocument.FullFileName);
            DrawingView drawingView = drawingDocument.ActiveSheet.DrawingViews[1];

            //特别注明:该类及其方法仅针对模型和草图文件
            GeneralDimensionsEnumerator generalDimensionsEnumerator =
                drawingDocument.ActiveSheet.DrawingDimensions.GeneralDimensions.Retrieve(drawingView);

            Console.WriteLine("generalDimensionsEnumerator.Count = " + generalDimensionsEnumerator.Count);
            if (generalDimensionsEnumerator.Count != 0)
            {
                for (int i = 1; i <= generalDimensionsEnumerator.Count; i++)
                {
                    Console.WriteLine(generalDimensionsEnumerator[i].Text);
                }
            }

            ////////////////////////////////////////////////////////////////////////////////////////////////////////
            BaselineDimensionSets baselineDimensionSets = drawingDocument.ActiveSheet.DrawingDimensions.BaselineDimensionSets;

            Console.WriteLine("baselineDimensionSets.Count = " + baselineDimensionSets.Count);
            if (baselineDimensionSets.Count != 0)
            {
                for (int i = 1; i <= baselineDimensionSets.Count; i++)
                {
                    BaselineDimensionSet baselineDimensionSet = baselineDimensionSets[i];
                    Console.WriteLine("baselineDimensionSet.Members = " + baselineDimensionSet.Members);
                    Console.WriteLine("baselineDimensionSet.DimensionType" + baselineDimensionSet.DimensionType);
                }
            }

            ////////////////////////////////////////////////////////////////////////////////////////////////////////
            Balloons ballons = drawingDocument.ActiveSheet.Balloons;

            Console.WriteLine("ballons.Count = " + ballons.Count);
            Balloon balloon = null;

            if (ballons.Count != 0)
            {
                for (int i = 1; i <= ballons.Count; i++)
                {
                    Console.WriteLine("\n------------------------ballons[" + i + "]------------------------");
                    balloon = ballons[i];
                    //Console.WriteLine("balloon.Leader.RootNode = " + balloon.Leader.RootNode);  //打印出 System.__ComObject
                    //Console.WriteLine("balloon.Position = " + balloon.Position);  //打印出 System.__ComObject
                    AttributeSets attributeSets = balloon.AttributeSets;
                    Console.WriteLine("attributeSets.Count = " + attributeSets.Count);
                    for (int j = 1; j <= attributeSets.Count; j++)
                    {
                        AttributeSet attributeSet = attributeSets[j];
                        Console.WriteLine("attributeSet.Name = " + attributeSet.Name);
                    }

                    BalloonValueSets balloonValueSets = balloon.BalloonValueSets;
                    for (int j = 1; j <= balloonValueSets.Count; j++)
                    {
                        BalloonValueSet balloonValueSet = balloonValueSets[j];
                        Console.WriteLine("balloonValueSet.ItemNumber = " + balloonValueSet.ItemNumber);
                        Console.WriteLine("balloonValueSet.Value = " + balloonValueSet.Value);
                        Console.WriteLine("balloonValueSet.OverrideValue = " + balloonValueSet.OverrideValue);
                        //Console.WriteLine("balloonValueSet.ReferencedFiles = " + balloonValueSet.ReferencedFiles);
                        Console.WriteLine("balloonValueSet.Type = " + balloonValueSet.Type);
                    }

                    Leader leader = balloon.Leader;
                    Console.WriteLine("leader.ArrowheadType = " + leader.ArrowheadType);
                    Console.WriteLine("leader.Type = " + leader.Type);
                    AttributeSets attributeSets_leader = leader.AttributeSets;
                    Console.WriteLine("attributeSets_leader.Count = " + attributeSets_leader.Count);
                    for (int j = 0; j < attributeSets_leader.Count; j++)
                    {
                        AttributeSet attributeSet = attributeSets[j];
                        Console.WriteLine("attributeSet_leader.Name = " + attributeSet.Name);
                    }

                    Console.WriteLine("END------------------------ballons[" + i + "]------------------------\n");
                }
            }

            ////////////////////////////////////////////////////////////////////////////////////////////////////////
            //DrawingViews views = drawingDocument.ActiveSheet.DrawingViews;
            //Console.WriteLine("views.count = " + views.Count);

            Console.WriteLine("drawingDocument.SelectSet.Count = " + drawingDocument.SelectSet.Count);
            SelectSet           selectSet           = null;
            DrawingCurveSegment drawingCurveSegment = null;

            if (drawingDocument.SelectSet.Count == 0)
            {
                Console.WriteLine("Select a drawing view");
                DrawingView view = inventorApp.CommandManager.Pick(SelectionFilterEnum.kDrawingViewFilter, "Select a drawing view");
                //selectSet = inventorApp.CommandManager.Pick(SelectionFilterEnum.kDrawingSheetFilter, "Select drawing sheet!");
                drawingCurveSegment = inventorApp.CommandManager.Pick(SelectionFilterEnum.kDrawingCurveSegmentFilter, "Select drawing segment filter");
            }
            else
            {
                selectSet = drawingDocument.SelectSet;
            }

            //DrawingCurveSegment drawingCurveSegment = selectSet[1];//drawingDocument.SelectSet[1];
            DrawingCurve drawingCurve = drawingCurveSegment.Parent;

            //Get the mid point of the selected curve assuming that the selection curve is linear
            Point2d MidPoint = drawingCurve.MidPoint;

            //Set a reference to the TransientGeometry object.
            TransientGeometry TG = inventorApp.TransientGeometry;

            Console.WriteLine("TG : " + (TG == null));
            ObjectCollection LeaderPoints = inventorApp.TransientObjects.CreateObjectCollection();

            Console.WriteLine("LeaderPoints : " + (LeaderPoints == null));

            LeaderPoints.Add(TG.CreatePoint2d(MidPoint.X + 10, MidPoint.Y + 10));
            LeaderPoints.Add(TG.CreatePoint2d(MidPoint.X + 10, MidPoint.Y + 5));

            //Add the GeometryIntent to the leader points collection.
            //This is the geometry that the balloon will attach to.
            GeometryIntent geometryIntent = drawingDocument.ActiveSheet.CreateGeometryIntent(drawingCurve);

            LeaderPoints.Add(geometryIntent);

            //Set a reference to the parent drawing view of the selected curve
            //DrawingView
            drawingView = drawingCurve.Parent;

            //Set a reference to the referenced model document
            Document ModelDoc = drawingView.ReferencedDocumentDescriptor.ReferencedDocument;

            Console.WriteLine(ModelDoc.Type);
            //PartDocument ModelDoc = drawingView.ReferencedDocumentDescriptor.ReferencedDocument;
            //AssemblyDocument ModelDoc = drawingView.ReferencedDocumentDescriptor.ReferencedDocument;

            //Check if a partslist or a balloon has already been created for thie model
            Boolean IsDrawingBOMDefined = drawingDocument.DrawingBOMs.IsDrawingBOMDefined(ModelDoc.FullFileName);

            // Balloon balloon;

            if (IsDrawingBOMDefined)

            {   //当DrawingBOM已经被定义了
                //Just create the balloon with the leader points. All other arguments can be ignored
                Console.WriteLine("当DrawingBOM已经被定义了\n创建气泡标注");
                balloon = drawingDocument.ActiveSheet.Balloons.Add(LeaderPoints);
            }
            else
            {
                //当DrawingBOM没有被定义
                AssemblyDocument            assemblyDocument            = (AssemblyDocument)ModelDoc;
                AssemblyComponentDefinition assemblyComponentDefinition = assemblyDocument.ComponentDefinition;

                ///*
                //First check if the 'structured' BOM view has been enabled in the model
                //Set a reference to the model's BOM object
                //BOM bom = ModelDoc.ComponentDefinition.BOM;
                BOM bom = assemblyComponentDefinition.BOM;

                if (bom.StructuredViewEnabled)
                {
                    //Level needs to be specifieed. Numbering options jave already been defined.
                    //Get the Level('All levels' of 'First level only') from the model BOM view - must use the same here
                    PartsListLevelEnum Level;
                    if (bom.StructuredViewFirstLevelOnly)
                    {
                        Level = PartsListLevelEnum.kStructured;
                    }
                    else
                    {
                        Level = PartsListLevelEnum.kStructuredAllLevels;
                    }
                }
                else
                {
                    //Level and numbering options must be specifieed.
                    //The corresponding model BOM view will automatically be enabled
                    NameValueMap NumberingScheme = inventorApp.TransientObjects.CreateNameValueMap();
                    //Add the option for a comma delimiter
                    NumberingScheme.Add("Delimeter", ",");
                    //Create the balloon by specifying the level and numbering scheme
                    balloon = drawingDocument.ActiveSheet.Balloons.Add(LeaderPoints, PartsListLevelEnum.kStructuredAllLevels, NumberingScheme);
                }
                //*/
            }
        }
        public void Run(Document placeholder /*not used*/)
        {
            LogTrace("Running v16 - open active LOD with logging - openVisible = false");
            try
            {
                // !AA! Get project path and assembly from json passed in
                // !AA! Pass in output type, assembly or SVF
                using (new HeartBeat())
                {
                    string currDir = Directory.GetCurrentDirectory();

                    // Uncomment out for local debug
                    //string inputPath = System.IO.Path.Combine(currDir, @"../../inputFiles", "params.json");
                    //Dictionary<string, string> options = JsonConvert.DeserializeObject<Dictionary<string, string>>(System.IO.File.ReadAllText(inputPath));

                    Dictionary <string, string> options = JsonConvert.DeserializeObject <Dictionary <string, string> >(System.IO.File.ReadAllText("inputParams.json"));
                    string outputType   = options["outputType"];
                    string inputFile    = options["inputFile"];
                    string assemblyPath = Path.GetFullPath(Path.Combine(currDir, inputFile));

                    if (options.ContainsKey("verboseLogs"))
                    {
                        isVerbose = true;
                    }

                    if (options.ContainsKey("projectFile"))
                    {
                        string projectFile     = options["projectFile"];
                        string fullProjectPath = Path.GetFullPath(Path.Combine(currDir, projectFile));

                        // For debug of input data set
                        //DirPrint(currDir);
                        Console.WriteLine("fullProjectPath = " + fullProjectPath);

                        DesignProject dp = inventorApplication.DesignProjectManager.DesignProjects.AddExisting(fullProjectPath);
                        dp.Activate();
                    }

                    Console.WriteLine("assemblyPath = " + assemblyPath);

                    Document doc = null;
                    if (assemblyPath.ToUpper().EndsWith(".IAM"))
                    {
                        FileManager fm       = inventorApplication.FileManager;
                        string[]    dvReps   = fm.GetDesignViewRepresentations(assemblyPath);
                        string      dvActRep = fm.GetLastActiveDesignViewRepresentation(assemblyPath);
                        LogTrace($"LastActiveDesignViewRepresentation: {dvActRep}");

                        string[] lodReps   = fm.GetLevelOfDetailRepresentations(assemblyPath);
                        string   lodActRep = fm.GetLastActiveLevelOfDetailRepresentation(assemblyPath);
                        LogTrace($"LastActiveLevelOfDetailRepresentation: {lodActRep}");

                        //string[] posReps = fm.GetPositionalRepresentations(assemblyPath);
                        //string posActRep = fm.get

                        NameValueMap openOptions = inventorApplication.TransientObjects.CreateNameValueMap();
                        openOptions.Add("LevelOfDetailRepresentation", lodActRep);
                        openOptions.Add("DesignViewRepresentation", dvActRep);

                        doc = inventorApplication.Documents.OpenWithOptions(assemblyPath, openOptions, false);
                    }
                    else
                    {
                        doc = inventorApplication.Documents.Open(assemblyPath);
                    }
                    LogTrace($"Full document name: {doc.FullDocumentName}");

                    // Uncomment out for local debug
                    //string paramInputPath = System.IO.Path.Combine(currDir, @"../../inputFiles", "parameters.json");
                    //Dictionary<string, string> parameters = JsonConvert.DeserializeObject<Dictionary<string, string>>(System.IO.File.ReadAllText(paramInputPath));

                    Dictionary <string, string> parameters = JsonConvert.DeserializeObject <Dictionary <string, string> >(System.IO.File.ReadAllText("documentParams.json"));
                    foreach (KeyValuePair <string, string> entry in parameters)
                    {
                        var paramName  = entry.Key;
                        var paramValue = entry.Value;
                        LogTrace($" params: {paramName}, {paramValue}");
                        ChangeParam(doc, paramName, paramValue);
                    }

                    LogTrace($"Getting full file name of assembly");
                    var docDir   = Path.GetDirectoryName(doc.FullFileName);
                    var pathName = doc.FullFileName;
                    doc.Update2(true);

                    // Save both svf and iam for now. To optimize check output type to only save one or the other

                    // Save Forge Viewer format (SVF)
                    string viewableDir = SaveForgeViewable(doc);
                    //string viewableZip = Path.Combine(Directory.GetCurrentDirectory(), "viewable.zip");
                    //ZipOutput(viewableDir, viewableZip);

                    if (isVerbose)
                    {
                        LogTrace(">> Start of listing folder contents (before flatten)");
                        listFolderContents(currDir);
                        LogTrace(">> End of listing folder contents (before flatten)");
                    }

                    if (!options.ContainsKey("dontFlattenFolder"))
                    {
                        LogTrace($"Flattening SvfOutput folder");
                        flattenFolder(viewableDir, viewableDir, "");
                    }

                    if (isVerbose)
                    {
                        LogTrace(">> Start of listing folder contents (after flatten)");
                        listFolderContents(currDir);
                        LogTrace(">> End of listing folder contents (after flatten)");
                    }

                    LogTrace($"Code finished");

                    doc.Save2(true);
                    doc.Close(true);

                    // Zip up the output assembly
                    //
                    // assembly lives in own folder under WorkingDir. Get the WorkingDir. We want to zip up the original zip to include things like project
                    // files and libraries
                    //var zipInputDir = Path.GetDirectoryName(Path.GetDirectoryName(pathName) + "/../");
                    //var fileName = Path.Combine(Directory.GetCurrentDirectory(), "result.zip"); // the name must be in sync with OutputIam localName in Activity
                    //ZipOutput(zipInputDir, fileName);
                }
            }
            catch (Exception e)
            {
                LogError("Processing failed. " + e.ToString());
            }
        }