Quantcast
Channel: Manufacturing DevBlog
Viewing all 516 articles
Browse latest View live

List user’s accessible vaults in Autodesk Vault Explorer Extension

$
0
0

By Daniel Du

One customer wants to know how the get the accessible vaults for a user group in a Vault Explorer Extension with API. As you know, we can get the list from Vault Explorer UI, Tools –> Administration –> Global Settings –> Groups… to open group management dialogue, double click one group and click “Vaults…” button to see the accessible vaults.

image

 

Now let’s do it with API, here is the code snippet to do the same with API:

using Autodesk.Connectivity.Explorer.Extensibility;
using Autodesk.Connectivity.WebServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using VDF = Autodesk.DataManagement.Client.Framework;

namespace HelloWorldVaultExplorer
{
    public class ListUserGroupVaults : IExplorerExtension
    {
        public IEnumerable<CommandSite> CommandSites()
        {
            CommandItem listGrougVaultsCmdItem = new CommandItem("HelloWorldVaultExplorer.ListUserGroupVaultsCmd",
                                                "List Group Vaults - Daniel");

            listGrougVaultsCmdItem.Execute += listGrougVaultsItem_Execute;

            CommandSite toolsMenuSite = new CommandSite("ListUserGroupVaultsCmd.Toolbar",
                                                    "List Group Vaults Menu- Daniel");
            toolsMenuSite.Location = CommandSiteLocation.ToolsMenu;
            toolsMenuSite.AddCommand(listGrougVaultsCmdItem);

            List<CommandSite> sites = new List<CommandSite>();
            sites.Add(toolsMenuSite);

            return sites;



        }

        void listGrougVaultsItem_Execute(object sender, CommandItemEventArgs e)
        {

           

            try
            {
                //using VDF = Autodesk.DataManagement.Client.Framework
                VDF.Vault.Currency.Connections.Connection connection =
                                e.Context.Application.Connection;

                string msg = "";
                Group[] groups = connection.WebServiceManager.AdminService.GetAllGroups();
                foreach (var group in groups)
                {
                    GroupInfo grpInfo = connection.WebServiceManager.AdminService
                            .GetGroupInfoByGroupId(group.Id);
                    msg += grpInfo.Group.Name + "\n";

                    msg += "Group accessable vaults : \n";
                    if (grpInfo.Vaults == null)
                    {
                        msg += " this group has no accessable vaults. \n";
                        continue;
                    }

                    foreach (var vault in grpInfo.Vaults)
                    {
                        msg += vault.Id + ": " + vault.Name + "\n";
                    }

                }

                MessageBox.Show(msg);



            }
            catch (Exception ex)
            {

                // If something goes wrong, we don't want the exception to bubble up to Vault Explorer.
                MessageBox.Show("Error: " + ex.Message);
            }

        }



    }
}

And here is the result:

image


AddAtCentroid does not work with EdgeLoop

$
0
0

By Adam Nagy

Though the help file suggests the opposite, AddAtCentroid does not seem to work with EdgeLoop. However the solution is very simple: create an EdgeCollection and fill it with the Edges of the EdgeLoop:

Sub AddWpToCenterOfEdgeloop()

Dim oDoc As PartDocument
Set oDoc = ThisApplication.ActiveDocument

Dim oFace As Face
Set oFace = ThisApplication.CommandManager.Pick( _
    kPartFaceFilter, "Select a face")

Dim oColl As EdgeCollection
Set oColl = ThisApplication.TransientObjects.CreateEdgeCollection

Dim oEdge As Edge
For Each oEdge In oFace.EdgeLoops(1).Edges
    oColl.Add oEdge
Next

Dim oWP As WorkPoint
Set oWP = oDoc.ComponentDefinition.WorkPoints.AddAtCentroid( _
    oColl, False)
oWP.name = "MyWorkpoint"

End Sub

Do selection from iLogic

$
0
0

By Adam Nagy

The only way you can do a selection from iLogic is using the Pick function. However, you can keep calling that in a loop to enable the user to select multiple components as well. Then you can do something with the selected components - in this specific case, we'll delete them:

Dim comps As ObjectCollection
Dim comp As Object

comps = ThisApplication.TransientObjects.CreateObjectCollection

While True
	comp = ThisApplication.CommandManager.Pick(
		SelectionFilterEnum.kAssemblyOccurrenceFilter, 
		"Select a component") ' If nothing gets selected then we're done	
	If IsNothing(comp) Then Exit While
	comps.Add(comp) 
End While' If there are selected components we can do something
For Each comp In comps
	comp.Delete()
Next

Handle Enter key from a MiniToolbar

$
0
0

By Adam Nagy

In case of built-in commands like the Extrude command when the user presses the Enter key it has the same effect as if the Apply button was clicked - the changes will be applied and the mini toolbar gets dismissed.

However, when using the MiniToolbar class of the API the Enter key does not dismiss the mini toolbar and there does not seem to be a way to catch the Enter key being pressed either, so that we could dismiss it ourselves. This seems to be an oversight which will be solved in the future, I hope.

In the meantime you can use a keyboard hook to watch out for the Enter key. You could use solutions like this: http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx

I used the MiniToolbar sample from the API Help file and then added the keyboard hook to it:

Imports Inventor

Imports System.Windows.Forms

Imports System.Runtime.InteropServices

 

PublicClassInterceptKeys

  PrivateConst WH_KEYBOARD_LL AsInteger = 13

  PrivateConst WM_KEYDOWN AsInteger = &H100

  PrivateShared _proc AsLowLevelKeyboardProc =

    NewLowLevelKeyboardProc(AddressOf HookCallback)

  PrivateShared _hookID AsIntPtr = IntPtr.Zero

  PrivateShared _mini AsMyMiniToolbar

 

  PublicSharedSub SetHook(mini AsMyMiniToolbar)

    _mini = mini

    _hookID = SetHook(_proc)

  EndSub

 

  PublicSharedSub UnhookWindowsHookEx()

    UnhookWindowsHookEx(_hookID)

  EndSub

 

  PrivateSharedFunction SetHook(

    proc AsLowLevelKeyboardProc) AsIntPtr

    Using curProcess AsProcess = Process.GetCurrentProcess()

      Using curModule AsProcessModule = curProcess.MainModule

        Return SetWindowsHookEx(WH_KEYBOARD_LL, proc,

          GetModuleHandle(curModule.ModuleName), 0)

      EndUsing

    EndUsing

  EndFunction

 

  PrivateDelegateFunctionLowLevelKeyboardProc(

    nCode AsInteger, wParam AsIntPtr, lParam AsIntPtr) AsIntPtr

 

  PrivateSharedFunction HookCallback(

    nCode AsInteger, wParam AsIntPtr, lParam AsIntPtr) AsIntPtr

    If nCode >= 0 AndAlso wParam = NewIntPtr(WM_KEYDOWN) Then

      Dim vkCode AsInteger = Marshal.ReadInt32(lParam)

      Dim key AsKeys = DirectCast(vkCode, Keys)

      System.Diagnostics.Debug.WriteLine(key)

      If key = Keys.Enter Then

        _mini.m_MiniToolbar_OnOK()

      EndIf

    EndIf

    Return CallNextHookEx(_hookID, nCode, wParam, lParam)

  EndFunction

 

  <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>

  PrivateSharedFunction SetWindowsHookEx(

    idHook AsInteger, lpfn AsLowLevelKeyboardProc,

    hMod AsIntPtr, dwThreadId AsUInteger) AsIntPtr

  EndFunction

 

  <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>

  PrivateSharedFunction UnhookWindowsHookEx(hhk AsIntPtr) _

    As<MarshalAs(UnmanagedType.Bool)> Boolean

  EndFunction

 

  <DllImport("user32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>

  PrivateSharedFunction CallNextHookEx(

    hhk AsIntPtr, nCode AsInteger, wParam AsIntPtr, lParam AsIntPtr) _

    AsIntPtr

  EndFunction

 

  <DllImport("kernel32.dll", CharSet:=CharSet.Auto, SetLastError:=True)>

  PrivateSharedFunction GetModuleHandle(lpModuleName AsString) AsIntPtr

  EndFunction

EndClass

 

PublicClassMyMiniToolbar

  '*************************************************************

  ' The declarations and functions below need to be copied into

  ' a class module whose name is "clsMiniToolbarEvents". The name can be

  ' changed but you'll need to change the declaration in the

  ' calling function "CreateSketchSlotSample" to use the new name.

  PrivateWithEvents m_EndCenterOneX AsMiniToolbarValueEditor

  PrivateWithEvents m_EndCenterOneY AsMiniToolbarValueEditor

  PrivateWithEvents m_EndCenterTwoX AsMiniToolbarValueEditor

  PrivateWithEvents m_EndCenterTwoY AsMiniToolbarValueEditor

  PrivateWithEvents m_Width AsMiniToolbarValueEditor

  PrivateWithEvents m_MiniToolbar AsMiniToolbar

  Private m_DisplayCenterline AsMiniToolbarCheckBox

  Private m_Sketch AsSketch

  Private bCenterline AsBoolean

  Private bStop AsBoolean

 

  Private ThisApplication As Inventor.Application

 

  PublicSub Init(app As Inventor.Application)

    ThisApplication = app

 

    Dim oActiveEnv AsEnvironment =

      ThisApplication.UserInterfaceManager.ActiveEnvironment

 

    If oActiveEnv.InternalName <> "PMxPartSketchEnvironment"And

        oActiveEnv.InternalName <> "AMxAssemblySketchEnvironment"And

        oActiveEnv.InternalName <> "DLxDrawingSketchEnvironment"Then

      MsgBox("Please activate a sketch environment first!")

      Exit Sub

    EndIf

 

    m_MiniToolbar = ThisApplication.CommandManager.CreateMiniToolbar

 

    m_MiniToolbar.ShowOK = True

    m_MiniToolbar.ShowApply = True

    m_MiniToolbar.ShowCancel = True

 

    Dim oControls AsMiniToolbarControls

    oControls = m_MiniToolbar.Controls

    oControls.Item("MTB_Options").Visible = False

 

    Dim oDescriptionLabel AsMiniToolbarControl

    oDescriptionLabel = oControls.AddLabel(

      "Description",

      "This toolbar is to create sketch slot:",

      "MiniToolbar sample to show how to create sketch slot.")

    oControls.AddNewLine()

 

    ' Define the first center position.

    Dim oEndCenterOne AsMiniToolbarButton

    oEndCenterOne = oControls.AddButton(

      "FirstCenter: ",

      "First Center:     ",

      "Specify the first center of sketch slot")

 

    m_EndCenterOneX = oControls.AddValueEditor(

      "FirstCenterX", "", ValueUnitsTypeEnum.kLengthUnits, "", "X:")

    m_EndCenterOneX.Expression = "0"

    m_EndCenterOneX.SetFocus()

 

    m_EndCenterOneY = oControls.AddValueEditor(

      "FirstCenterY", "", ValueUnitsTypeEnum.kLengthUnits, "", "Y:")

    m_EndCenterOneY.Expression = "0"

    oControls.AddNewLine()

 

    ' Define the second center position.

    Dim oEndCenterTwo AsMiniToolbarButton

    oEndCenterTwo = oControls.AddButton(

      "SecondCenter:", "Second Center:",

      "Specify the second center of sketch slot")

 

    m_EndCenterTwoX = oControls.AddValueEditor(

      "SecondCenterX", "", ValueUnitsTypeEnum.kLengthUnits, "", "X:")

    m_EndCenterTwoX.Expression = "3"

 

 

    m_EndCenterTwoY = oControls.AddValueEditor(

      "SecondCenterY", "", ValueUnitsTypeEnum.kLengthUnits, "", "Y:")

    m_EndCenterTwoY.Expression = "0"

 

    oControls.AddNewLine()

 

    ' Define the width of sketch slot.

 

    m_Width = oControls.AddValueEditor(

      "WidthValue", "", ValueUnitsTypeEnum.kLengthUnits, "", "Width:")

    m_Width.Expression = "1"

 

    ' Define if display the center line of sketch slot.

    m_DisplayCenterline = oControls.AddCheckBox(

      "DisplayCenterline", "Display center line",

      "Check this to display center line of slot", True)

 

    ' the position of mini-toolbar

    Dim oPosition AsPoint2d

    oPosition = ThisApplication.TransientGeometry.CreatePoint2d(

      ThisApplication.ActiveView.Left, ThisApplication.ActiveView.Top)

    m_MiniToolbar.Position = oPosition

 

    m_MiniToolbar.Visible = True

 

    m_MiniToolbar = m_MiniToolbar

 

    m_Sketch = ThisApplication.ActiveEditObject

    bStop = False

 

    InterceptKeys.SetHook(Me)

 

    Do

      ThisApplication.UserInterfaceManager.DoEvents()

    LoopUntil bStop

 

    InterceptKeys.UnhookWindowsHookEx()

  EndSub

 

  PrivateSub m_MiniToolbar_OnApply() Handles m_MiniToolbar.OnApply

    CreateSlot()

  EndSub

 

  PrivateSub m_MiniToolbar_OnCancel() Handles m_MiniToolbar.OnCancel

    bStop = True

  EndSub

 

  PublicSub m_MiniToolbar_OnOK() Handles m_MiniToolbar.OnOK

    bStop = True

    CreateSlot()

    m_MiniToolbar.Delete()

  EndSub

 

  PrivateSub CreateSlot()

 

    IfNot (m_EndCenterOneX.IsExpressionValid And

            m_EndCenterOneY.IsExpressionValid And

            m_EndCenterTwoX.IsExpressionValid And

            m_EndCenterTwoY.IsExpressionValid) Then

      MsgBox("Invalid values for end center positions!")

      Exit Sub

    EndIf

 

    bCenterline = m_DisplayCenterline.Checked

 

    Dim oTG AsTransientGeometry

    oTG = ThisApplication.TransientGeometry

 

    Dim oEndCenterOne AsPoint2d

    Dim oEndCenterTwo AsPoint2d

    Dim oEndArcOne AsSketchArc

    Dim oEndArcTwo AsSketchArc

 

    ' Start transaction for creating slot.

    Dim oTransaction AsTransaction =

      ThisApplication.TransactionManager.StartTransaction(

        ThisApplication.ActiveDocument, "Create slot")

 

    ' If the two centers are vertical

    IfMath.Abs(

      m_EndCenterOneX.Value - m_EndCenterTwoX.Value) < 0.000001 Then

      If (m_EndCenterOneY.Value > m_EndCenterTwoY.Value) Then

        oEndCenterOne = oTG.CreatePoint2d(

          m_EndCenterOneX.Value, m_EndCenterOneY.Value)

        oEndCenterTwo = oTG.CreatePoint2d(

          m_EndCenterTwoX.Value, m_EndCenterTwoY.Value)

      Else

        oEndCenterOne = oTG.CreatePoint2d(

          m_EndCenterTwoX.Value, m_EndCenterTwoY.Value)

        oEndCenterTwo = oTG.CreatePoint2d(

          m_EndCenterOneX.Value, m_EndCenterOneY.Value)

      EndIf

 

      If oEndCenterOne.IsEqualTo(oEndCenterTwo, 0.000001) Then

        MsgBox("The two centers are coincident!")

        Exit Sub

      EndIf

 

      ' Create the top arc

      oEndArcOne = m_Sketch.SketchArcs.AddByCenterStartEndPoint(

        oEndCenterOne,

        oTG.CreatePoint2d(oEndCenterOne.X + 0.1, oEndCenterOne.Y),

        oTG.CreatePoint2d(oEndCenterOne.X - 0.1, oEndCenterOne.Y))

      ' Create the bottom arc

      oEndArcTwo = m_Sketch.SketchArcs.AddByCenterStartEndPoint(

        oEndCenterTwo,

        oTG.CreatePoint2d(oEndCenterTwo.X - 0.1, oEndCenterTwo.Y),

        oTG.CreatePoint2d(oEndCenterTwo.X + 0.1, oEndCenterTwo.Y))

      'If the two centers are not vertical

    Else

      If m_EndCenterOneX.Value < m_EndCenterTwoX.Value Then

        oEndCenterOne = oTG.CreatePoint2d(

          m_EndCenterOneX.Value, m_EndCenterOneY.Value)

        oEndCenterTwo = oTG.CreatePoint2d(

          m_EndCenterTwoX.Value, m_EndCenterTwoY.Value)

      ElseIf m_EndCenterOneX.Value > m_EndCenterTwoX.Value Then

        oEndCenterOne = oTG.CreatePoint2d(

          m_EndCenterTwoX.Value, m_EndCenterTwoY.Value)

        oEndCenterTwo = oTG.CreatePoint2d(

          m_EndCenterOneX.Value, m_EndCenterOneY.Value)

      EndIf

 

      If oEndCenterOne.IsEqualTo(oEndCenterTwo, 0.000001) Then

        MsgBox("The two centers are coincident!")

        Exit Sub

      EndIf

 

      oEndArcOne = m_Sketch.SketchArcs.AddByCenterStartEndPoint(

        oEndCenterOne,

        oTG.CreatePoint2d(

          m_EndCenterOneX.Value, m_EndCenterOneY.Value + 0.1),

        oTG.CreatePoint2d(

          m_EndCenterOneX.Value, m_EndCenterOneY.Value - 0.1))

      oEndArcTwo = m_Sketch.SketchArcs.AddByCenterStartEndPoint(

        oEndCenterTwo,

        oTG.CreatePoint2d(

          m_EndCenterTwoX.Value, m_EndCenterTwoY.Value + 0.1),

        oTG.CreatePoint2d(

          m_EndCenterTwoX.Value, m_EndCenterTwoY.Value - 0.1),

        False)

    EndIf

 

    Dim dWidth AsDouble

    dWidth = m_Width.Value

 

    ' Create center line if required

    If bCenterline Then

      Dim oCenterline AsSketchLine

      oCenterline = m_Sketch.SketchLines.AddByTwoPoints(

        oEndArcOne.CenterSketchPoint, oEndArcTwo.CenterSketchPoint)

 

      oCenterline.Construction = True

    EndIf

 

    Dim oGround1 AsGroundConstraint

    Dim oGround2 AsGroundConstraint

    oGround1 = m_Sketch.GeometricConstraints.AddGround(

      oEndArcOne.CenterSketchPoint)

    oGround2 = m_Sketch.GeometricConstraints.AddGround(

      oEndArcTwo.CenterSketchPoint)

 

    ' Create sketch lines of slot

    Dim oLine1 AsSketchLine

    Dim oLine2 AsSketchLine

    oLine1 = m_Sketch.SketchLines.AddByTwoPoints(

      oEndArcOne.StartSketchPoint, oEndArcTwo.EndSketchPoint)

    oLine2 = m_Sketch.SketchLines.AddByTwoPoints(

      oEndArcOne.EndSketchPoint, oEndArcTwo.StartSketchPoint)

 

    ' Add geometric constraints to the sketch entities

    Call m_Sketch.GeometricConstraints.AddEqualRadius(

      oEndArcOne, oEndArcTwo)

    Call m_Sketch.GeometricConstraints.AddTangent(

      oLine1, oEndArcOne)

    Call m_Sketch.GeometricConstraints.AddTangent(

      oLine1, oEndArcTwo)

    Call m_Sketch.GeometricConstraints.AddTangent(

      oLine2, oEndArcOne)

    Call m_Sketch.GeometricConstraints.AddTangent(

      oLine2, oEndArcTwo)

 

    ' Add dimensional constraints to the sketch entities

    Dim oDiameter AsDiameterDimConstraint

    oDiameter = m_Sketch.DimensionConstraints.AddDiameter(

      oEndArcOne, oEndArcOne.CenterSketchPoint.Geometry)

    oDiameter.Parameter.Value = dWidth

 

    ThisApplication.ActiveDocument.Update()

    oDiameter.Delete()

    oGround1.Delete()

    oGround2.Delete()

 

    oTransaction.End()

 

  EndSub

 

EndClass

And then you can use it like this from your command's event handler:

ProtectedOverridesSub ButtonDefinition_OnExecute(
  ByVal context As Inventor.NameValueMap)

    Dim mtb AsNewMyMiniToolbar

    mtb.Init(InventorApplication)

EndSub

Create title border in AutoCAD Mechanical

$
0
0

By Adam Nagy

There is a comprehensive .NET sample using the AutoCAD Mechanical COM API in the SDK under "acadmapi\sample\dotNet" called "netTitleBorder": http://usa.autodesk.com/adsk/servlet/index?id=14952981&siteID=123112

Here is also a simpler VBA code that shows how the relevant API works:

Public Sub CreateTitleBorder()' Requires a reference to:' - Autodesk SymBBAuto Type Library' - Autodesk AutoCAD Mechanical Type Library'Get Application Object
Dim oApp As AcadmApplication
Set oApp = ThisDrawing.Application.GetInterfaceObject( _
"AcadmAuto.AcadmApplication")'Reference to the Symbol Manager Dim symMgr As McadSymbolBBMgr Set symMgr = ThisDrawing.Application.GetInterfaceObject( _
"SymBBAuto.McadSymbolBBMgr")'Reference to the TitleBorder Manager Dim oTitleBMng As McadTitleBorderMgr Set oTitleBMng = symMgr.TitleBorderMgr'Create New Descriptor Dim oDescriptor As McadTitleBorderDescriptor Set oDescriptor = oTitleBMng.NewDescriptor'Set Position oDescriptor.Position(0) = 0 oDescriptor.Position(1) = 41.7 oDescriptor.Position(2) = 0'Fill up Border properties oDescriptor.Border.Name = "ANSI_C" oDescriptor.Border.Extends(0)(0) = 1E+20 oDescriptor.Border.Extends(0)(1) = 1E+20 oDescriptor.Border.Extends(0)(2) = 1E+20 oDescriptor.Border.Extends(1)(0) = -1E+20 oDescriptor.Border.Extends(1)(1) = -1E+20 oDescriptor.Border.Extends(1)(2) = -1E+20 oDescriptor.Border.Position(0) = 0 oDescriptor.Border.Position(1) = 41.7 oDescriptor.Border.Position(2) = 0 'Fill up Title Properties oDescriptor.Title.Name = "ANSI_TITUS" oDescriptor.Title.Position(0) = 21.5 oDescriptor.Title.Position(1) = 42.443 oDescriptor.Title.Position(2) = 0'Create Title Attribute Values Dim Attributes(0 To 19, 0 To 1) As String Attributes(0, 0) = "GEN-TITLE-APPM": Attributes(0, 1) = "My Boss" Attributes(1, 0) = "GEN-TITLE-ISSD": Attributes(1, 1) = "02/02/2008" Attributes(2, 0) = "GEN-TITLE-NAME": Attributes(2, 1) = _
"Administrator" Attributes(3, 0) = "GEN-TITLE-CTRN": Attributes(3, 1) = "12358746" Attributes(4, 0) = "GEN-TITLE-DACT": Attributes(4, 1) = "" Attributes(5, 0) = "GEN-TITLE-CHKD": Attributes(5, 1) = "01/01/2008" Attributes(6, 0) = "GEN-TITLE-SCA": Attributes(6, 1) = "1'0""=1'0""" Attributes(7, 0) = "GEN-TITLE-DES1": Attributes(7, 1) = "Title1" Attributes(8, 0) = "GEN-TITLE-REV": Attributes(8, 1) = "rev1" Attributes(9, 0) = "GEN-TITLE-WT": Attributes(9, 1) = "Weight" Attributes(10, 0) = "GEN-TITLE-DES2": Attributes(10, 1) = "Subtitle1" Attributes(11, 0) = "GEN-TITLE-SIZ": Attributes(11, 1) = "C" Attributes(12, 0) = "GEN-TITLE-APPD": Attributes(12, 1) = "05/02/2008" Attributes(13, 0) = "GEN-TITLE-ISSM": Attributes(13, 1) = "Johnny" Attributes(14, 0) = "GEN-TITLE-DWG": Attributes(14, 1) = "Drawing1" Attributes(15, 0) = "GEN-TITLE-DAT": Attributes(15, 1) = "02/12/2008" Attributes(16, 0) = "GEN-TITLE-FSCM": Attributes(16, 1) = "-0125412" Attributes(17, 0) = "GEN-TITLE-CHKM": Attributes(17, 1) = "Joe" Attributes(18, 0) = "GEN-TITLE-NR": Attributes(18, 1) = "-0123654" Attributes(19, 0) = "GEN-TITLE-SHEET": Attributes(19, 1) = "Sheet1" oDescriptor.Title.Attributes = Attributes 'Set Scale oDescriptor.TitleBorderScale = 1'Create New Context Dim oContext As McadTitleBorderContext Set oContext = oTitleBMng.NewContext'oContext.AutomaticPlacement = True'oContext.BaseScale = True'oContext.DwgDefault = True'oContext.MoveObjects = True'oContext.Rescale = True'oContext.RetrieveFromAsmProp = True'oContext.RetrieveFromPartRef = True'oContext.ThawAllLayers = True'Create Title Border Dim oTitleBorder As McadTitleBorder Set oTitleBorder = oTitleBMng.CreateTitleBorder(oDescriptor, oContext) End Sub

The result:

Mfgnews2

 

Disable BOMs of a 3D-model in a DWF

$
0
0

By Xiaodong Liang

Question:

I'm writing a small tool for Inventor 2012 in VB.net, using the TranslatorAddIn, to export a drawing and its 3D-model to DWF. Unfortunately, when I export the drawing of an assembly, the BOM of the model is included as well, wich I would like to disable. The options "BOM_Structured" and "BOM_Parts_Only" seem to work only if I export the 3D-model, not the drawing...

Solution:

There is not such option for the DWF translator currently. The workaround is to disable the top assembly’s BOMs temporarily before exporting the drawing to DWF in this case. The following is a VBA demo. It disables the BOM view of all assemblies in the drawing before exporting to DWF, and restore after exporting.

 

Public Sub PublishDWFWithoutBOM()
    ' Get the DWF translator Add-In.
    Dim DWFAddIn As TranslatorAddIn
    Set DWFAddIn = ThisApplication.ApplicationAddIns.ItemById("{0AC6FD95-2F4D-42CE-8BE0-8AEA580399E4}")

    'Set a reference to the active document (the document to be published).
    Dim oDocument As DrawingDocument
    Set oDocument = ThisApplication.ActiveDocument
   
    'disables the BOM view of all assemblies in the drawing before exporting to DWF
    Dim oEachRefDoc As Document
    For Each oEachRefDoc In oDocument.ReferencedDocuments
        If TypeOf oEachRefDoc Is AssemblyDocument Then
            Dim oAssDoc As AssemblyDocument
            Set oAssDoc = oEachRefDoc
           
            Dim oBOM As BOM
            Set oBOM = oAssDoc.ComponentDefinition.BOM
           
            oBOM.StructuredViewEnabled = False
            oBOM.StructuredViewFirstLevelOnly = False
            oBOM.PartsOnlyViewEnabled = False
           
            oAssDoc.Save
           
        End If
       
    Next   

    oDocument.Update   
   

    Dim oContext As TranslationContext
    Set oContext = ThisApplication.TransientObjects.CreateTranslationContext
    oContext.Type = kFileBrowseIOMechanism

    ' Create a NameValueMap object
    Dim oOptions As NameValueMap
    Set oOptions = ThisApplication.TransientObjects.CreateNameValueMap

    ' Create a DataMedium object
    Dim oDataMedium As DataMedium
    Set oDataMedium = ThisApplication.TransientObjects.CreateDataMedium

    ' Check whether the translator has 'SaveCopyAs' options
    If DWFAddIn.HasSaveCopyAsOptions(oDocument, oContext, oOptions) Then

        oOptions.Value("Launch_Viewer") = 1

     
        If TypeOf oDocument Is DrawingDocument Then

            ' Drawing options
            oOptions.Value("Publish_Mode") = kCustomDWFPublish
            oOptions.Value("Publish_All_Sheets") = 0

            ' The specified sheets will be ignored if
            ' the option "Publish_All_Sheets" is True (1)
            Dim oSheets As NameValueMap
            Set oSheets = ThisApplication.TransientObjects.CreateNameValueMap

            ' Publish the first sheet AND its 3D model
            Dim oSheet1Options As NameValueMap
            Set oSheet1Options = ThisApplication.TransientObjects.CreateNameValueMap

            oSheet1Options.Add "Name", "Sheet:1"
            oSheet1Options.Add "3DModel", True
            oSheets.Value("Sheet1") = oSheet1Options
        End If

    End If

    'Set the destination file name
    oDataMedium.FileName = "c:\temp\temptest.dwf"

    'Publish document.
    Call DWFAddIn.SaveCopyAs(oDocument, oContext, oOptions, oDataMedium)
   
    'restore after exporting
     For Each oEachRefDoc In oDocument.ReferencedDocuments
        If TypeOf oEachRefDoc Is AssemblyDocument Then
            Set oAssDoc = oEachRefDoc

             
            Set oBOM = oAssDoc.ComponentDefinition.BOM
           
            oBOM.StructuredViewEnabled = True
            oBOM.StructuredViewFirstLevelOnly = True
            oBOM.PartsOnlyViewEnabled = True
           
             oAssDoc.Save
           
        End If
       
    Next
   
End Sub

Disable BOMs of a 3D-model in a DWF

$
0
0

By Xiaodong Liang

Question:

I'm writing a small tool for Inventor 2012 in VB.net, using the TranslatorAddIn, to export a drawing and its 3D-model to DWF. Unfortunately, when I export the drawing of an assembly, the BOM of the model is included as well, wich I would like to disable. The options "BOM_Structured" and "BOM_Parts_Only" seem to work only if I export the 3D-model, not the drawing...

Solution:

There is not such option for the DWF translator currently. The workaround is to disable the top assembly’s BOMs temporarily before exporting the drawing to DWF in this case. The following is a VBA demo. It disables the BOM view of all assemblies in the drawing before exporting to DWF, and restore after exporting.

 

Public Sub PublishDWFWithoutBOM()
    ' Get the DWF translator Add-In.
    Dim DWFAddIn As TranslatorAddIn
    Set DWFAddIn = ThisApplication.ApplicationAddIns.ItemById("{0AC6FD95-2F4D-42CE-8BE0-8AEA580399E4}")

    'Set a reference to the active document (the document to be published).
    Dim oDocument As DrawingDocument
    Set oDocument = ThisApplication.ActiveDocument
   
    'disables the BOM view of all assemblies in the drawing before exporting to DWF
    Dim oEachRefDoc As Document
    For Each oEachRefDoc In oDocument.ReferencedDocuments
        If TypeOf oEachRefDoc Is AssemblyDocument Then
            Dim oAssDoc As AssemblyDocument
            Set oAssDoc = oEachRefDoc
           
            Dim oBOM As BOM
            Set oBOM = oAssDoc.ComponentDefinition.BOM
           
            oBOM.StructuredViewEnabled = False
            oBOM.StructuredViewFirstLevelOnly = False
            oBOM.PartsOnlyViewEnabled = False
           
            oAssDoc.Save
           
        End If
       
    Next   

    oDocument.Update   
   

    Dim oContext As TranslationContext
    Set oContext = ThisApplication.TransientObjects.CreateTranslationContext
    oContext.Type = kFileBrowseIOMechanism

    ' Create a NameValueMap object
    Dim oOptions As NameValueMap
    Set oOptions = ThisApplication.TransientObjects.CreateNameValueMap

    ' Create a DataMedium object
    Dim oDataMedium As DataMedium
    Set oDataMedium = ThisApplication.TransientObjects.CreateDataMedium

    ' Check whether the translator has 'SaveCopyAs' options
    If DWFAddIn.HasSaveCopyAsOptions(oDocument, oContext, oOptions) Then

        oOptions.Value("Launch_Viewer") = 1

     
        If TypeOf oDocument Is DrawingDocument Then

            ' Drawing options
            oOptions.Value("Publish_Mode") = kCustomDWFPublish
            oOptions.Value("Publish_All_Sheets") = 0

            ' The specified sheets will be ignored if
            ' the option "Publish_All_Sheets" is True (1)
            Dim oSheets As NameValueMap
            Set oSheets = ThisApplication.TransientObjects.CreateNameValueMap

            ' Publish the first sheet AND its 3D model
            Dim oSheet1Options As NameValueMap
            Set oSheet1Options = ThisApplication.TransientObjects.CreateNameValueMap

            oSheet1Options.Add "Name", "Sheet:1"
            oSheet1Options.Add "3DModel", True
            oSheets.Value("Sheet1") = oSheet1Options
        End If

    End If

    'Set the destination file name
    oDataMedium.FileName = "c:\temp\temptest.dwf"

    'Publish document.
    Call DWFAddIn.SaveCopyAs(oDocument, oContext, oOptions, oDataMedium)
   
    'restore after exporting
     For Each oEachRefDoc In oDocument.ReferencedDocuments
        If TypeOf oEachRefDoc Is AssemblyDocument Then
            Set oAssDoc = oEachRefDoc

             
            Set oBOM = oAssDoc.ComponentDefinition.BOM
           
            oBOM.StructuredViewEnabled = True
            oBOM.StructuredViewFirstLevelOnly = True
            oBOM.PartsOnlyViewEnabled = True
           
             oAssDoc.Save
           
        End If
       
    Next
   
End Sub

GetExistingFacets and CalculateFacets

$
0
0

By Adam Nagy

You can use these two functions to get the tessellated geometry of an Inventor model. If calculated values already exist then you can get the tolerance they are using via GetExistingFacetTolerances. If this gives back some values then you can use them to retrieve the associated facets through GetExistingFacets, where you would pass in the existing tolerance of your choice. 

If the existing facets used a tolerance that is not precise enough for you, then you need to use CalculateFacets

The relationship between the values that GetExistingFacets/CalculateFacets return can be explained using a simple rectangular face as an example - the order of the values could differ from the below example but the relationship between them should be the same. If we called CalculateFacets(Tolerance As Double, VertexCount As Long, FacetCount As Long, VertexCoordinates() As Double, NormalVectors() As Double, VertexIndices() As Long) on the below face, we would get these values:

CalculateFacets
There are some samples in the API Help file showing how to use these functions, but here is one that can be useful to debug things. This will show if an acceptable tolerance already exists, in which case the lines will be green otherwise red. You can also then examine the result to see if e.g. for some reason the vertices of neighbouring faces do not line up, like here:

CalculateFacets1
When using the same tolerance to retrieve existing facets, then they should line up between neighbouring faces. If not, then regenerating the model should put things right - i.e. PartDocument.Rebuild():

CalculateFacets2

Here is the VBA sample code for vertex checking:

Sub ShowFacetLines( _
  vCount As Long, fCount As Long, coords() As Double, _
  normals() As Double, indices() As Long, _
  oGraphicNode As GraphicsNode, oDataSets As GraphicsDataSets, _
  existing As Boolean)
  Dim oCoordSet As GraphicsCoordinateSet
  Set oCoordSet = oDataSets.CreateCoordinateSet(oDataSets.count + 1)
  Call oCoordSet.PutCoordinates(coords)

  Dim oCoordIndexSet As GraphicsIndexSet
  Set oCoordIndexSet = oDataSets.CreateIndexSet(oDataSets.count + 1)

  Dim oColorSet As GraphicsColorSet
  Set oColorSet = oDataSets.CreateColorSet(oDataSets.count + 1)

  If existing Then
    Call oColorSet.Add(1, 0, 255, 0)
  Else
    Call oColorSet.Add(1, 255, 0, 0)
  End If

  Dim oColorIndexSet As GraphicsIndexSet
  Set oColorIndexSet = oDataSets.CreateIndexSet(oDataSets.count + 1)

  Dim i As Integer
  For i = 0 To fCount - 1
    Call oCoordIndexSet.Add( _
      oCoordIndexSet.count + 1, indices(i * 3))
    Call oCoordIndexSet.Add( _
      oCoordIndexSet.count + 1, indices(i * 3 + 1))
    Call oCoordIndexSet.Add( _
      oCoordIndexSet.count + 1, indices(i * 3 + 1))
    Call oCoordIndexSet.Add( _
      oCoordIndexSet.count + 1, indices(i * 3 + 2))
    Call oCoordIndexSet.Add( _
      oCoordIndexSet.count + 1, indices(i * 3 + 2))
    Call oCoordIndexSet.Add( _
      oCoordIndexSet.count + 1, indices(i * 3))

    Call oColorIndexSet.Add(oColorIndexSet.count + 1, 1)
    Call oColorIndexSet.Add(oColorIndexSet.count + 1, 1)
    Call oColorIndexSet.Add(oColorIndexSet.count + 1, 1)
  Next

  Dim oLine As LineGraphics
  Set oLine = oGraphicNode.AddLineGraphics
  oLine.CoordinateSet = oCoordSet
  oLine.CoordinateIndexSet = oCoordIndexSet
  oLine.ColorSet = oColorSet
  oLine.ColorIndexSet = oColorIndexSet
End Sub

Sub ShowFacets()
  Dim oDoc As PartDocument
  Set oDoc = ThisApplication.ActiveDocument

  Dim oDef As PartComponentDefinition
  Set oDef = oDoc.ComponentDefinition

  Dim tol As Double
  tol = Val(InputBox("Tolerance", "Provide Facet Tolerance", "0.1"))

  Dim tr As Transaction
  Set tr = ThisApplication.TransactionManager.StartTransaction( _
    oDoc, "ShowFacets")' Get the object to draw into
  On Error Resume Next
  Dim oClientGraphics As ClientGraphics
  Set oClientGraphics = oDef.ClientGraphicsCollection("MyTest")
  If Err = 0 Then
    oClientGraphics.Delete
  End If
  Set oClientGraphics = _
    oDef.ClientGraphicsCollection.AddNonTransacting("MyTest")' Create the graphics data sets collection
  Dim oDataSets As GraphicsDataSets
  Set oDataSets = oDoc.GraphicsDataSetsCollection("MyTest")
  If Err = 0 Then
    oDataSets.Delete
  End If
  Set oDataSets = _
    oDoc.GraphicsDataSetsCollection.AddNonTransacting("MyTest")
  On Error GoTo 0
  Dim vCount As Long
  Dim fCount As Long
  Dim coords() As Double
  Dim normals() As Double
  Dim indices() As Long

  Dim oSurf As SurfaceBody
  For Each oSurf In oDef.SurfaceBodies
    Dim oGraphicNode As GraphicsNode
    Set oGraphicNode = oClientGraphics.AddNode( _
      oClientGraphics.count + 1)
      
    ' Check if a good enough tolerance already exists
    Dim tCount As Long
    Dim tols() As Double
    Call oSurf.GetExistingFacetTolerances( _
      tCount, tols)
    Dim usedTol As Double
    usedTol = 0
    Dim msg As String
    msg = "Available tolerances:" + vbCrLf' They seem to be ordered from' smallest to biggest
    Dim i As Integer
    For i = tCount - 1 To 0 Step -1
      msg = msg + str(tols(i)) + vbCrLf
      If usedTol = 0 And tols(i) <= tol Then
        usedTol = tols(i)
      End If
    Next' If we found good existing' tolerance
    If usedTol > 0 Then
      Call oSurf.GetExistingFacets( _
        usedTol, _
        vCount, _
        fCount, _
        coords, _
        normals, _
        indices)
      Call ShowFacetLines( _
        vCount, fCount, coords, _
        normals, indices, oGraphicNode, oDataSets, True)
      msg = msg + "Using tolerance: " + str(usedTol)
      Call MsgBox(msg, vbInformation, "Used existing tolerance")
    Else
      Call oSurf.CalculateFacets( _
        tol, _
        vCount, _
        fCount, _
        coords, _
        normals, _
        indices)
      Call ShowFacetLines( _
        vCount, fCount, coords, _
        normals, indices, oGraphicNode, oDataSets, False)
      Call MsgBox(str(tol), vbInformation, "Used new tolerance")
    End If
  Next

  Call tr.End
  
  oDoc.Update
End Sub

Table editing from iLogic

$
0
0

By Adam Nagy

You may have lots of data that you would like to make editable for the user. If it can be organized into a table then you could simply use a Form with a DataGridView on it. There is an article on providing custom dialogs from iLogic: http://adndevblog.typepad.com/manufacturing/2013/06/use-vbnet-dialog-in-ilogic.html

This will be the same, but here we will expose the DataGridView which is placed on the Form so you can take advantage of all its functionality: http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview(v=vs.100).aspx  

This is how you can use it from an iLogic Rule

Imports System.Windows.Forms
AddReference "C:\temp\MyTableForm.dll" 

Using mf As New MyTableForm.MyForm
  mf.Text = "Get Data"	
  Dim dgv As DataGridView = mf.dgvTable' set columns
  Dim c1 As Integer = dgv.Columns.Add("MyColumn1", "MyColumnHeader1")
  Dim c2 As Integer = dgv.Columns.Add("MyColumn2", "MyColumnHeader2")' add two rows
  Dim r1 As Integer = dgv.Rows.Add()
  Dim r2 As Integer = dgv.Rows.Add()' disable sorting
  dgv.Columns(c1).SortMode = DataGridViewColumnSortMode.NotSortable 
  dgv.Columns(c2).SortMode = DataGridViewColumnSortMode.NotSortable' set cell data
  dgv.Rows(r1).Cells(1).Value = "test1"
  dgv.Rows(r2).Cells(1).Value = "test2"' make one of them read-only
  dgv.Rows(r2).Cells(1).ReadOnly = True' show the dialog
  If mf.ShowDialog() = DialogResult.OK Then
    MsgBox(dgv.Rows(0).Cells(0).Value, MsgBoxStyle.Information, "Results")
  End If
End Using

The result:

MyTableForm

Here is the source code of the VB.NET 2010 project: Download MyTableForm_2013-11-18
The compiled dll is also part of the zip file in folder "MyTableForm\MyTableForm\bin\Release".

Vault 2014 API example getting property values of a file

$
0
0

By Wayne Brill

This VB example uses GetPropertyDefinitions() and the GetPropertyValue() of the the PropertyManager to retrieve the value of system and a user defined property (UDP) for a file. It may not be  obvious how to get the PropertyDefinition parameter that you need to pass to GetPropertyValue().

To get the PropertyDefinition you can use GetPropertyDefinitions() which returns a PropertyDefinitionDictionary which is a key value pair. The value of the KeyValuePair are property definitions. In this example the display name of the PropertyDefinition is used to find a user defined property to use with GetPropertyValue().

For system properties you can use one of the members of PropertyDefinitionIds.Server. This example is using PropertyDefinitionIds.Server.LifeCycleDefinition and PropertyDefinitionIds.Server.VersionNumber.

To try this code you can add a button to the VaultList SDK sample and copy in this code.

PrivateSub Button5_Click(sender As System.Object, _

        e As System.EventArgs) Handles Button5.Click

 

    ' For demonstration purposes,

    'the information is hard-coded.

    Dim results As VDF.Vault.Results.LogInResult =

        VDF.Vault.Library.ConnectionManager.LogIn _

      ("localhost", "Vault", "Administrator", "", _

                  VDF.Vault.Currency.Connections. _

             AuthenticationFlags.Standard, Nothing)

 

    IfNot results.Success Then

        Return

    EndIf

 

    Dim m_conn As  _

        VDF.Vault.Currency.Connections.Connection _

                               = results.Connection

 

    Dim props AsPropertyDefinitionDictionary = _

     m_conn.PropertyManager.GetPropertyDefinitions(

   VDF.Vault.Currency.Entities.EntityClassIds.Files,

       Nothing, PropertyDefinitionFilter.IncludeAll)

 

    Dim myKeyValPair AsKeyValuePair _

                     (OfString, PropertyDefinition)

    Dim myUDP_DayOFSave AsPropertyDefinition _

                                           = Nothing

 

    Dim propDef AsPropertyDefinition

    ForEach myKeyValPair In props

        ' Property definition from KeyValuePair

        propDef = myKeyValPair.Value()

        ' Using the display name to identify

        ' the PropertyDefinition

        IfpropDef.DisplayName = _

                         "wb_Day_Of_IDW_Save"Then

            'It is the PropertyDefinition

            myUDP_DayOFSave = propDef

            Exit For

        EndIf

    Next

 

    Dim myLifeCycleDef AsPropertyDefinition = _

    props(PropertyDefinitionIds.Server. _

                            LifeCycleDefinition)

 

    Dim myVerNumDef AsPropertyDefinition = _

    props(PropertyDefinitionIds.Server. _

                                  VersionNumber)

 

    ' Get the FileIteration

    Dim fileIter As  _

VDF.Vault.Currency.Entities.FileIteration = Nothing

 

    'Change this to the name of a file in your vault

    fileIter = _

getFileIteration("wB_Assembly_9-23-13.idw", m_conn)

 

    'Name of the life cycle definition

    Dim strLifeCycleName AsString = _

        m_conn.PropertyManager.GetPropertyValue _

                  (fileIter, myLifeCycleDef, Nothing)

 

    'Version number

    Dim strVersionNumber AsString = _

        m_conn.PropertyManager.GetPropertyValue _

                    (fileIter, myVerNumDef, Nothing)

 

    'Get the user defined property value

    IfNot myUDP_DayOFSave IsNothingThen

        Dim strPropertyVal AsString = _

            m_conn.PropertyManager.GetPropertyValue _

                 (fileIter, myUDP_DayOFSave, Nothing)

 

        MessageBox.Show("Value of custom prop " _

            & myUDP_DayOFSave.DisplayName.ToString() _

            & " = "& strPropertyVal)

    EndIf

 

EndSub

Here is the code that gets the FileIteration.

PublicFunction getFileIteration _

          (nameOfFile AsString, _

                  connection As  _

             VDF.Vault.Currency. _

         Connections.Connection) _

          As VDF.Vault.Currency. _

           Entities.FileIteration

 

    Dim conditions As ACW.SrchCond()

 

    ReDim conditions(0)

 

    Dim lCode AsLong = 1

 

    Dim Defs As ACW.PropDef() = _

  connection.WebServiceManager. _

               PropertyService. _

GetPropertyDefinitionsByEntityClassId("FILE")

 

    Dim Prop As ACW.PropDef = Nothing

 

    ForEach def As ACW.PropDefIn Defs

        If def.DispName = _

                  "File Name"Then

            Prop = def

        EndIf

    Next def

 

    Dim searchCondition As  _

ACW.SrchCond = New ACW.SrchCond()

 

    searchCondition.PropDefId = _

                          Prop.Id

 

    searchCondition.PropTyp = _

ACW.PropertySearchType.SingleProperty

    searchCondition.SrchOper = lCode

 

    searchCondition.SrchTxt = nameOfFile

 

    conditions(0) = searchCondition

 

    ' search for files

    Dim FileList AsList _

(Of Autodesk.Connectivity.WebServices.File) = _

    NewList _

(Of Autodesk.Connectivity.WebServices.File) '()

    Dim sBookmark AsString = String.Empty

    Dim Status As ACW.SrchStatus = Nothing

 

    While (Status IsNothingOrElse _

         FileList.Count < Status.TotalHits)

 

        Dim files As Autodesk.Connectivity. _

WebServices.File() = connection.WebServiceManager.

DocumentService.FindFilesBySearchConditions _

                             (conditions, _

            Nothing, Nothing, True, True, _

                         sBookmark, Status)

 

        If (Not files IsNothing) Then

            FileList.AddRange(files)

        EndIf

    EndWhile

 

    Dim oFileIteration As  _

        VDF.Vault.Currency.Entities. _

               FileIteration = Nothing

    For i AsInteger = _

              0 To FileList.Count - 1

        If FileList(i).Name = _

                      nameOfFile Then

            oFileIteration = _

           New VDF.Vault.Currency. _

Entities.FileIteration(connection, _

                        FileList(i))

        EndIf

    Next

 

    Return oFileIteration

 

EndFunction

Saving a snapshot of a document’s view

$
0
0

By Philippe Leefsma

Here are three different approaches to save a snapshot picture of a document view.

1 - Simply saving the active view as is. Note that if you specify a top color, you will have to pass also a bottom one:

Sub SaveView1()

 

    Dim view As view

    Set view = ThisApplication.ActiveView

   

    Dim camera As camera

    Set camera = view.camera

   

    Dim topClr As color

    Set topClr = ThisApplication.TransientObjects.CreateColor(255, 0, 0)

   

    Dim bottomClr As color

    Set bottomClr = ThisApplication.TransientObjects.CreateColor(0, 255, 0)

   

    Call camera.SaveAsBitmap("C:\Temp\test.png", _

        view.width, view.height, topClr, bottomClr)

 

End Sub

 

2 - That second approach is creating an additional view and closing it at the end. You could use that approach if you plan to modify the view in any way to create the snapshot and want to conserve the active view intact for the user:

-

Sub SaveView2()

 

    Dim doc As Document

    Set doc = ThisApplication.ActiveDocument

   

    Dim view As view

    Set view = doc.views.Add

   

    Dim camera As camera

    Set camera = view.camera

   

    Dim topClr As color

    Set topClr = ThisApplication.TransientObjects.CreateColor(255, 0, 0)

   

    Dim bottomClr As color

    Set bottomClr = ThisApplication.TransientObjects.CreateColor(0, 255, 0)

   

    Call camera.SaveAsBitmap("C:\Temp\test.png", _

        view.width, view.height, topClr, bottomClr)

 

    view.Close

 

End Sub

 

3 - The third approach is creating a transient camera. It similar to the second way but probably better because you don’t have to create a temporary view:

-

Sub SaveView3()

 

    Dim doc As Document

    Set doc = ThisApplication.ActiveDocument

   

    Dim view As view

    Set view = ThisApplication.ActiveView

 

    Dim camera As camera

    Set camera = ThisApplication.TransientObjects.CreateCamera

   

    camera.SceneObject = doc.ComponentDefinition

   

    camera.ViewOrientationType = kIsoTopLeftViewOrientation

    camera.Fit

    camera.ApplyWithoutTransition

   

    Dim topClr As color

    Set topClr = ThisApplication.TransientObjects.CreateColor(255, 0, 0)

   

    Dim bottomClr As color

    Set bottomClr = ThisApplication.TransientObjects.CreateColor(0, 255, 0)

   

    Call camera.SaveAsBitmap("C:\Temp\test.png", _

        view.width, view.height, topClr, bottomClr)

 

End Sub

How to determine a point containment within a solid?

$
0
0

By Philippe Leefsma

This is a question asked recently by an ADN developer: how can you determine if a point is located inside a watertight solid or outside?

There is no API that would directly return the information in Inventor. However here is a simple approach:

- Create a tiny spherical transient solid centered on the point, using specified tolerance as radius

- Check the volume of each solids, let’s call them vol1 and vol2

- Do a Boolean union between both solids, the sphere and the original solid

- Check volume of the union, if its volume is smaller than the sum of the two volumes, the solids intersect: volUnion < vol1 + vol2 –> point is contained by original solid.

Here is the VBA code that implements that solution:

Function PointContainment( _

    point As point, _

    body As SurfaceBody, _

    tol As Double) As Boolean

   

    PointContainment = False

   

    Dim TxBrep As TransientBRep

    Set TxBrep = ThisApplication.TransientBRep

   

    Dim ptBody As SurfaceBody

    Set ptBody = TxBrep.CreateSolidSphere(point, tol)

   

    Dim vol1 As Double

    vol1 = ptBody.volume(tol)

   

    Dim vol2 As Double

    vol2 = body.volume(tol)

   

    Call TxBrep.DoBoolean(ptBody, body, kBooleanTypeUnion)

   

    Dim volRes As Double

    volRes = ptBody.volume(tol)

   

    If (volRes < vol1 + vol2) Then

        PointContainment = True

    End If

 

End Function

 

Sub TestPointContainment()

   

    Dim doc As PartDocument

    Set doc = ThisApplication.ActiveDocument

 

    Dim point As point

    Set point = ThisApplication.TransientGeometry.CreatePoint(0, 0, 0)

 

    Dim body As SurfaceBody

    Set body = ThisApplication.CommandManager.Pick( _

        kPartBodyFilter, "Pick a body: ")

   

    Dim res As Boolean

    res = PointContainment(point, body, 0.0001)

   

    Debug.Print "Point containment: " & res

   

End Sub

Setting Multi-Value Parameter from Excel Named Range Values

$
0
0

By Xiaodong Liang

Question:
I want to set multi values from Excel named range. I tested and got the failure: "Array was not a one-dimensional array." 

GoExcel.Open("C:\Temp\Book1.xlsx", "Sheet1")

MultiValue.List("myP")=GoExcel.NamedRangeValue("MyRange") 

Is there anything missed?

 

Solution:

In Excel, the named range is a X*Y dimensions. X is the rows, Y is the column. While the parameter of multi-values in Inventor is one dimension. Even you defined the named range with only one column, it is not a correct usage to set it to the multi-values directly. You need to extract the values of the column we are interested in.  e.g. the code below gets the values of the first column.

GoExcel.Open("C:\Temp\Book1.xlsx", "Sheet1")' this is an array X*Y dimensionrangeArray=GoExcel.NamedRangeValue("MyRange")'create a list to get the values of the first columnDimoListAsArrayListoList=NewArrayListDimoIndexAsInteger'rangeArray.GetLength(0)  means how many rowsForoIndex=1TorangeArray.GetLength(0)' add value of each row one by oneoList.Add(rangeArray(oIndex,1))Next'set it to the list parameterMultiValue.List("myP")=oList
GoExcel.Close

Get ItemNumber from a DrawingCurve

$
0
0

By Adam Nagy

If you want to find out which DrawingBOMRow / BOMRow a DrawingCurve belongs to in order to get e.g. the ItemNumber associated with the component that the DrawingCurve represents, the most straightforward way might be to let the Balloon object figure that out for us. 

We can temporarily create a Balloon that would reference that DrawingCurve. If it's done inside a Transaction that is Aborted, then it will look as if the Balloon has never been created at all.

Let's say we have a SketchedSymbol whose first TextBox is a prompted entry we want to set and an instance of it is already attached to the DrawingCurve, then we could update it using this code:

Public Sub SetSketchedSymbolNumber()
  Dim oDwg As DrawingDocument
  Set oDwg = ThisApplication.ActiveDocument' The SketchedSymbol needs to be selected
  Dim oSymbol As SketchedSymbol
  Set oSymbol = oDwg.SelectSet(1)' The symbol's leader needs to be' attached to the Component
  Dim oNode As LeaderNode
  Set oNode = oSymbol.Leader.AllLeafNodes(1)
  Dim oCurve As DrawingCurve
  Set oCurve = oNode.AttachedEntity.Geometry
  Dim oSheet As Sheet
  Set oSheet = oDwg.ActiveSheet
  Dim oTO As TransientObjects
  Set oTO = ThisApplication.TransientObjects
  Dim oTG As TransientGeometry
  Set oTG = ThisApplication.TransientGeometry
  Dim oLeaderPoints As ObjectCollection
  Set oLeaderPoints = oTO.CreateObjectCollection' Does not matter what we add as first point
  Call oLeaderPoints.Add(oTG.CreatePoint2d(0, 0))' Get item number from the temporary balloon
  Dim itemNumber As String
  Dim oTM As TransactionManager
  Set oTM = ThisApplication.TransactionManager
  Dim oTransaction As Transaction
  Set oTransaction = oTM.StartTransaction(oDwg, "TempTransaction")

  Dim oGeometryIntent As GeometryIntent
  Set oGeometryIntent = oSheet.CreateGeometryIntent(oCurve)
  Call oLeaderPoints.Add(oGeometryIntent)
  
  Dim oBalloon As Balloon
  Set oBalloon = oSheet.Balloons.Add(oLeaderPoints, , kStructured)
  
  ' We could also get the DrawingBOMRow and BOMRow' oBalloon.BalloonValueSets(1).ReferencedRow.BOMRow' but this time we just need the ItemNumber
  itemNumber = oBalloon.BalloonValueSets(1).itemNumber' This transaction will not show up in the Undo/Redo stack' and it will look as if the above balloon never existed
  Call oTransaction.Abort' Update the first textbox in the sketched symbol' with the item number
  Dim oBox As TextBox
  Set oBox = oSymbol.Definition.sketch.TextBoxes(1)
  Call oSymbol.SetPromptResultText( _
    oBox, itemNumber)
End Sub

SketchedSymbol

There is a more comprehensive sample on creating a Balloon in the API Help file"C:\Program Files\Autodesk\Inventor 2014\Local Help\admapi_18_0.chm" 

Iterate Structured BOMView

$
0
0

By Adam Nagy

Here is a sample VBA code that lists some information from the StructuredBOMView of an assembly: 

Public Sub IterateRows _
(oBOMRows As BOMRowsEnumerator, indent As Integer)
  Dim oBOMRow As BOMRow
  For Each oBOMRow In oBOMRows' Let's only get the first definition' It would only be more than one if rows were merged
    Dim oDef As ComponentDefinition
    Set oDef = oBOMRow.ComponentDefinitions(1)
    Dim partNumber As String
    partNumber = oDef.Document.PropertySets( _"{32853F0F-3444-11D1-9E93-0060B03C1CA6}")("Part Number").value
    Debug.Print Tab(indent); oBOMRow.itemNumber + " " + partNumber

    If Not oBOMRow.ChildRows Is Nothing Then
      Call IterateRows(oBOMRow.ChildRows, indent + 1)
    End If
  Next
End Sub

Public Sub IterateThroughStructuredBOM()
  Dim oAsm As AssemblyDocument
  Set oAsm = ThisApplication.ActiveDocument
  
  Dim oBOM As BOM
  Set oBOM = oAsm.ComponentDefinition.BOM
  
  ' Make sure it's enabled
  oBOM.StructuredViewEnabled = True
  oBOM.StructuredViewFirstLevelOnly = False
  Dim oBOMView As BOMView
  Set oBOMView = oBOM.BOMViews("Structured")
  Call IterateRows(oBOMView.BOMRows, 1)
End Sub

It prints out something like this:

1 SubAsm1
 1.1 Part11
 1.2 Part12
2 SubAsm2
 2.1 Part21
 2.2 Part22

Display range box of componenets in assembly context

$
0
0

By Xiaodong Liang

The RangeBox is a rectangular box that is guaranteed to enclose this object. If you access the range in the assembly context, you can use ComponentOccurrence.RangeBox without proxy because this has been transformed in the assembly context. The following code assumes there is a top assembly which has some sub assemblies. The sub assemblites are placed with different rotations intentionally. It gets the rangebox of each component and draws a box with transparent appearance. Their locations are in the context of the top assembly. You need to go to the "Appearance Browser" and add the "Clear" appearance to the document before running the code. Of course, you can also use API to add the appearance.

Sub drawComRange()

Dim oAssDoc As AssemblyDocument

Set oAssDoc = ThisApplication.ActiveDocument

Dim localAsset As Asset

Set localAsset = oAssDoc.Assets.Item("Clear")

Dim oCompDef As ComponentDefinition

Set oCompDef = oAssDoc.ComponentDefinition

Dim oTransientBRep As TransientBRep

Set oTransientBRep = ThisApplication.TransientBRep

On Error Resume Next

Dim oClientGraphics As ClientGraphics

Set oClientGraphics = oCompDef.ClientGraphicsCollection.Item("Sample3DGraphicsID")

If Err.Number = 0 Then

On Error GoTo 0

oClientGraphics.Delete

ThisApplication.ActiveView.Update

Err.Clear

Exit Sub

End If

Set oClientGraphics = oCompDef.ClientGraphicsCollection.Add("Sample3DGraphicsID")

Dim oSurfacesNode As GraphicsNode

Set oSurfacesNode = oClientGraphics.AddNode(1)

oSurfacesNode.Appearance = localAsset

Dim oOcc As ComponentOccurrence

For Each oOcc In oAssDoc.ComponentDefinition.Occurrences

Dim oRB As Box

Set oRB = oOcc.RangeBox

Dim oBody As SurfaceBody

Set oBody = oTransientBRep.CreateSolidBlock(oRB.Copy())

' Create client graphics based on the transient body

Dim oSurfaceGraphics As SurfaceGraphics

Set oSurfaceGraphics = oSurfacesNode.AddSurfaceGraphics(oBody)

Next

oSurfacesNode.Appearance = localAsset

ThisApplication.ActiveView.Update

End Sub

 

image

 

 

image

column of BOM for “Area”of component

$
0
0

By Xiaodong Liang

Question:
Is there any way to get an area for the entire assembly on the BOM?  If you go to iProperties --> Physical it is shown there. But how to pull it from there and have it as Column in BOM? Can it be done using API ?

Solution:
Firstly, currently, no API to add/remove column of BOM. You have to add it manually in advance. The following is the steps to achieve your requirement. This also applies to Mass/Volume or other iProperties.

1. In the component file (such as a part), add one custom iProperty manually e.g. named  “Area”. The type is Text.

image

2. add a iLogic rule with the component file. It will get the Area value from iProperty, and update the custom iProperty.

image

'current documentdoc=ThisDoc.Document'unit manager of the documentoUOM=doc.UnitsOfMeasure'get the value of AreasurfaceArea=iProperties.Area'round the value with 4 valid numbers (optional)surfaceArea=Round(surfaceArea, 4)'convert the value to a string with the unit of the documentsurfaceArea=surfaceArea.ToString()+""+oUOM.GetStringFromType(oUOM.LengthUnits)+"^2"'update the custom property "Area" we creatediProperties.Value("Custom", "Area")=surfaceArea

3. add this rule with the iLogic trigger “Part Geometry Change”thus when the model changes, the rule will be executed automatically and update the custom property.

 

image

 

4. In the assembly >> BOM, add one custom column named “Area”.This column will read the custom property from the component.

image

 

image

BOM Item total quantity by sub-assemby

$
0
0

By Xiaodong Liang

Question:
I would like to obtain, in a structured parts list, the total number of ITEM in the sub-assembly.
I have found an iLogic rule to create an user ipropertie in each part, with the total nomber of this part in all the assemby (included all sub-assemblies).
I would like to know if it is possible to obtain the total of this part only in the sub-assembly. Is it possible with an iLogic rule or VBA ? 

Solution:
You can recurse the referenced documents of the top assembly, filter out the sub assemblies. And iterate the occurrences of the assemblies to count each part. iLogic is based on VB.NET, so you could take advantage the Dictionary object to make the worflow more clear.

The following code is a demo to dump an assembly, get the part count of each sub assembly.

SubMain()'get top assemblyDimoTopAssAsAssemblyDocumentoTopAss=ThisApplication.ActiveDocument'store part info for each sub assembly,' including decedent Sub AssemblyDimoTotalDictAs_NewDictionary(OfString, _Dictionary(OfString, Integer))DimoEachRefDocAsDocumentForEachoEachRefDocIn_oTopAss.ReferencedDocumentsIfTypeOfoEachRefDocIs_AssemblyDocumentThen'get full path of the assemblyDimoSubAssFullPathAsStringoSubAssFullPath=_oEachRefDoc.FullFileNameIfoTotalDict.ContainsKey(oSubAssFullPath)Then' should have iterated, do nothingElse'store each unique part per its full pathDimoSubDict=_NewDictionary(OfString, _Integer)'add a dictionary for the sub assemblyoTotalDict.Add(oSubAssFullPath, _oSubDict)'iterate the parts within the sub assemblyrecurseSubAss(oEachRefDoc, _oTotalDict, _oSubDict)EndIfEndIfNext'dump the count statistic of the assembliesDimoMsgAsStringDimiAssKeyAsStringDimoEachAssDicAs_Dictionary(OfString, Integer)=NothingForEachiAssKeyIn_oTotalDict.Keys'each sub assembly, including the decendent assemblyoMsg+=vbCr+"***"+_iAssKey+"***"oEachAssDic=_oTotalDict(iAssKey)DimiPartKeyAsStringForEachiPartKeyIn_oEachAssDic.KeysDimquantityAsInteger=_oEachAssDic(iPartKey)oMsg+=vbCr+""+_iPartKey+"  [count: "+_quantity .ToString()+"]"NextNext'message the infoSystem.Windows.Forms.MessageBox.Show(oMsg)End SubSubrecurseSubAss(ByValoParentDocAsAssemblyDocument, _ByRefoTotalDictAs_Dictionary(OfString, _Dictionary(OfString, Integer)), _ByRefoSubDictAs_Dictionary(OfString, _Integer))DimoAssDefAsAssemblyComponentDefinitionoAssDef=oParentDoc.ComponentDefinitionDimoEachOccAsComponentOccurrenceForEachoEachOccInoAssDef.OccurrencesDimoEachRefDocAsDocumentoEachRefDoc=oEachOcc.Definition.DocumentIfTypeOfoEachRefDocIs_AssemblyDocumentThen'get full path of the assemblyDimoSubAssFullPathAsStringoSubAssFullPath=_oEachRefDoc.FullFileNameIfoTotalDict.ContainsKey(oSubAssFullPath)Then' should have iterated, do nothingElse'store each unique part per its full pathDimoSubSubDict=_NewDictionary(OfString, Integer)'add a dictionary for the sub assemblyoTotalDict.Add(oSubAssFullPath, _oSubSubDict)'iterate the documents within the sub assemblyrecurseSubAss(oEachRefDoc, _oTotalDict, _oSubSubDict)EndIfElse' it is part'get full path of the partDimoPartFullPathAsStringoPartFullPath=oEachRefDoc.FullFileName'add this part to the dictionaryIfoSubDict.ContainsKey(oPartFullPath)Then' if the part has existed in the dictionary'quantity  + 1oSubDict(oPartFullPath)=_oSubDict(oPartFullPath)+1Else' add this part, quantity  =1oSubDict.Add(oPartFullPath, 1)EndIfEndIfNextEnd Sub

When FileUIEvents::OnPopulateFileMetadata is exactly invoked ?

$
0
0

By Xiaodong Liang

This event is invoked when internal workflow of Inventor sets the filename and properties. Currently, the support workflow contains frame generator, create substitute, shrink wrap, add assembly / part in assembly, copy component, mirror component etc.

The usage is very straightforward: delegate the event and suggest your custom name in the event, and tell Inventor this event is handled. The following is a small VBA code demo.

Event Class:

Private WithEvents fileUIEvts As FileUIEvents

Private Sub Class_Initialize()
    Set fileUIEvts = ThisApplication.FileUIEvents
End Sub

Private Sub Class_Terminate()
    Set fileUIEvts = Nothing
End Sub

Private Sub fileUIEvts_OnPopulateFileMetadata(ByVal FileMetadataObjects As ObjectsEnumerator, ByVal Formulae As String, ByVal Context As NameValueMap, HandlingCode As HandlingCodeEnum)
    Dim oMetaData As FileMetadata
    If FileMetadataObjects.Count > 0 Then
        For Each oMetaData In FileMetadataObjects
            'suggest custom name
            oMetaData.FileName = "asdk_" & oMetaData.FileName
            oMetaData.FileNameOverridden = True
        Next oMetaData
        'tell Inventor the event is handled
        HandlingCode = kEventHandled
    End If
End Sub

Module:

Private cls As clsFileE

Sub startcmd()
    Set cls = New clsFileE
End Sub

Sub Endcmd()
    Set cls = Nothing
End Sub


The figure below is a demo when the event suggests a custom name for "mirror component” command.

image

How to Set the Color of a Sketched Symbol

$
0
0

Q: I’m using the following code to set the color of a sketched symbol but nothing happens. How do I set the color of a sketched symbol?

   sketchedSym.Color.SetColor(255, 0, 0)

A: Properties that return transient objects return a "tear off" object that's not associated to the original object it was obtained from.  For example, if you have a work plane and call the Plane property, it returns a Plane object that provides the geometric information of the plane.  Or if you call the Geometry property of a cylindrical face it will return a Cylinder object which provides the geometric information for a cylinder.  These objects serve as a way to conveniently pass a set of related information.  A Color object is also a transient that provides a convenient way to pass color information in the API.

When Color property of the SketchedSymbol object is called the API creates a new Color object using the color information associated with the symbol and returns it.  The Color object returned is not associated with the symbol.  When you change any of the properties of the Color object, you are changing the color object but since it's not associated with the symbol, it doesn’t affect the sketched symbol and you don't see anything happen.  The way to set the color of the symbol is to use a Color object to set the Color property. A common way is to create a new Color object to pass in, as shown below.

   Dim transObjs As TransientObjects
   Set transObjs =
ThisApplication.TransientObjects
   sketchedSym.Color = transObjs.CreateColor(255, 0, 0)

Viewing all 516 articles
Browse latest View live