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

RegFree InventorViewControl

$
0
0

By Adam Nagy

As mentioned in this article, you can use the Inventor View Control in a registry-free way by embedding a manifest file that specifies the InventorViewControl as a dependency.

My InventorViewCtrl.ocx.manifest looks like this:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?><assembly 
  xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0"><file name="InventorViewCtrl.ocx" hashalg="SHA1"><comClass 
      clsid="{A6336AB8-D3E1-489A-8186-EE40F2E027FE}"
      tlbid="{E841EDA5-E54F-4492-B514-928713E659C7}"
      description="Autodesk Inventor View Control"></comClass><typelib 
      tlbid="{E841EDA5-E54F-4492-B514-928713E659C7}"
      resourceid="1" version="1.0" helpdir="" flags="HASDISKIMAGE"></typelib></file><comInterfaceExternalProxyStub 
    name="_DInventorViewControl"
    iid="{C767F39D-57B9-4163-ABAD-14FAE0F74D21}"
    tlbid="{E841EDA5-E54F-4492-B514-928713E659C7}"
    proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub><comInterfaceExternalProxyStub 
    name="_DInventorViewControlEvents"
    iid="{D7A91BA8-19C0-4E1B-99D7-F6B10448EF3B}"
    tlbid="{E841EDA5-E54F-4492-B514-928713E659C7}"
    proxyStubClsid32="{00020420-0000-0000-C000-000000000046}"></comInterfaceExternalProxyStub></assembly>

Inside the Project Settings you can specify to embed this manifest: 

ViewerRegFree

Here is the full source code of the sample project:
https://github.com/adamenagy/InventorView-FileDisplay-.NET-4.0-RegFree


Vault Browser control – icon column incorrect – call .Library.Initialize()

$
0
0

By Wayne Brill

This Login method used to log in to the Vault does not support a read-only login. 

Autodesk.DataManagement.Client.Framework.Vault.Forms Namespace > Library  Login Method

To log in read only you could use:

Autodesk.DataManagement.Client.Framework.Vault.Services Namespace > IVaultConnectionManagerService Interface > LogIn Method

Logging in this way adversely effects the Vault Browser control. Instead of the getting the icons in the icon column you get text with the ImageInfo type. (this behavior has been reported to Vault engineering).

The solution is to Initialize the library before logging in by making this call:

Autodesk.DataManagement.Client.Framework.Vault.Forms.Library.Initialize()

What object am I getting?

$
0
0

By Adam Nagy

The easiest way to check is by debugging into the code and see what object type the Watches window  shows. 

E.g. the following code ...

Sub TestObjects()
  Dim f As Face
  Set f = ThisApplication.ActiveDocument.SelectSet(1)

  Dim paramRange As Box2d
  Set paramRange = f.Evaluator.ParamRangeRect
  
  Dim oc As ObjectCollection
  Set oc = f.Evaluator.GetIsoCurve(paramRange.MinPoint.X, True)
End Sub

... would show this in the Watches window when I select the side face of a cylinder:

ObjectType

In case of VB and VB.NET you can also use the TypeName function to find out the type name of an object:

Sub TestObjects()
  Dim f As Face
  Set f = ThisApplication.ActiveDocument.SelectSet(1)

  Dim paramRange As Box2d
  Set paramRange = f.Evaluator.ParamRangeRect
  
  Dim oc As ObjectCollection
  Set oc = f.Evaluator.GetIsoCurve(paramRange.MinPoint.X, True)
  
  Dim item As Object
  Set item = oc(1)
  
  Call MsgBox(TypeName(item))
End Sub

Get COM object type name programmatically

$
0
0

By Adam Nagy

In different programming languages you can get the name of the object's type in different ways.

VBA, VB, VB.NET

Here you can use the TypeName built-in function and just pass in the object whose type name you want to know

C#

The object.GetType().Name property only return __ComObject for COM objects, and not the underlying type, so it is not that useful.
In C# you can either declare the ITypeInfo object and use that like in this article, or just take advantage of the VB.NET functionality by adding a reference to Microsoft.VisualBasic assembly and use Microsoft.VisualBasic.Information.TypeName() function.

TypeName

C++

Here you do need to use ITypeInfo interface as shown in this article.

Note: most Inventor object types also have a Type property that returns an ObjectTypeEnum which can also be useful when identifying object type.

Flipping direction of a Hem feature

$
0
0

By Balaji Ramamoorthy

The Hem feature relies on an edge to decide its direction. When editing the hem feature to flip its direction, Inventor identifies another edge and uses it for the hem feature. To do this programmatically, the HemDefinition.Edges collection is to be set. Currently the HemDefinition.Edges displays a "NotImplemented" error when trying to set it.

A workaround is to create a new Hem feature using the HemDefinition from the existing feature and use another edge in the process. The existing feature can be deleted after the new one is created. Also, it is important to set the end of part for retrieving the Edges collection from a Hem feature.

Here is a sample iLogic and C# code to flip the direction :

iLogic code snipet :

Dim  oPartDoc As  PartDocument
 oPartDoc = ThisApplication.ActiveDocument
Dim  oSheetMetalCompDef As  SheetMetalComponentDefinition
 oSheetMetalCompDef = oPartDoc.ComponentDefinition
Dim  smFeatures As  SheetMetalFeatures
 smFeatures = oSheetMetalCompDef.Features
Dim  oHems As  HemFeatures
 oHems = smFeatures.HemFeatures
Dim  oHemFeature As  HemFeature
 oHemFeature = oHems.Item(1)
Dim  oHemDef As  HemDefinition
 oHemDef = oHemFeature.Definition
 oHemFeature.SetEndOfPart(True)
Dim  currentHemEdge As  Edge
Dim  oHemEdgeColl As  EdgeCollection
 oHemEdgeColl = oHemDef.Edges
 currentHemEdge = oHemDef.Edges.Item(1)
Dim  oStartVertex As  Vertex
 oStartVertex = currentHemEdge.StartVertex
Dim  oStopVertex As  Vertex
 oStopVertex = currentHemEdge.StopVertex
Dim  edge1 As  Edge
 edge1 = oSheetMetalCompDef.SurfaceBodies(1).Edges(1)
Dim  edge2 As  Edge
 edge2 = oSheetMetalCompDef.SurfaceBodies(1).Edges(3)
Dim  oEdgeColl As  EdgeCollection
 = ThisApplication.TransientObjects.CreateEdgeCollection
If  edge1.StartVertex Is  oStartVertex  
And  edge1.StopVertex Is  oStopVertex Then
 	oEdgeColl.Add(edge2)
ElseIf  edge2.StartVertex Is  oStartVertex  
And  edge2.StopVertex Is  oStopVertex Then
 	oEdgeColl.Add(edge1)
Else
 	MessageBox.Show("Sorry, could not  flip direction. 
 	The hem Feature does Not  use a known edge", 
"iLogic HemFeature Flip direction")
 	oHemFeature.SetEndOfPart(False)
Return
EndIf
Dim  oHemDefNew As  HemDefinition
 oHemDefNew = oHemDef.Copy
 oHemDefNew.Edges = oEdgeColl
Dim  hemFeatureName AsString
 hemFeatureName = oHemFeature.Name
 oHemFeature.Delete 
Dim  oHemFeatureNew As  HemFeature
 oHemFeatureNew = oHems.Add(oHemDefNew)
 oHemFeatureNew.Name = hemFeatureName

C# code snipet :

 PartDocument oPartDoc 
 	= (PartDocument)_invApp.ActiveDocument;
 SheetMetalComponentDefinition oSheetMetalCompDef 
 	= oPartDoc.ComponentDefinition 
 	as SheetMetalComponentDefinition;
 SheetMetalFeatures smFeatures 
 	= oSheetMetalCompDef.Features as SheetMetalFeatures;
 HemFeatures oHems = smFeatures.HemFeatures;
 HemFeature oHemFeature = oHems[1];
 HemDefinition oHemDef = oHemFeature.Definition;
// Important to get the right edge from the HemDefinition
 oHemFeature.SetEndOfPart(true );
 EdgeCollection oHemEdgeColl = oHemDef.Edges;
 Edge currentHemEdge = oHemDef.Edges[1];
 Vertex oStartVertex = currentHemEdge.StartVertex;
 Vertex oStopVertex = currentHemEdge.StopVertex;
 Edge edge1 
 	= oSheetMetalCompDef.SurfaceBodies[1].Edges[1];
 Edge edge2 
 	= oSheetMetalCompDef.SurfaceBodies[1].Edges[3];
 EdgeCollection oEdgeColl = 
 	_invApp.TransientObjects.CreateEdgeCollection();
if  (object.ReferenceEquals(edge1.StartVertex, oStartVertex) && 
     object.ReferenceEquals(edge1.StopVertex, oStopVertex))
{
// edge1 is the hem edge. 
//'s use another edge to flip the hem feature
     oEdgeColl.Add(edge2);
}
elseif  (object.ReferenceEquals(edge2.StartVertex, oStartVertex) &&
     object.ReferenceEquals(edge2.StopVertex, oStopVertex))
{
// edge2 is the hem edge. 
//'s use another edge to flip the hem feature
     oEdgeColl.Add(edge1);
}
else
{
     MessageBox.Show(@"Sorry, could not flip direction. 
 		The hem feature does not use a known edge", 
"HemFeature Flip direction" );
     oHemFeature.SetEndOfPart(false );
return ;
}
 HemDefinition oHemDefNew = oHemDef.Copy();
 oHemDefNew.Edges = oEdgeColl;
 string hemFeatureName = null;
 hemFeatureName = oHemFeature.Name;
// Delete the existing hem feature
 oHemFeature.Delete();
 HemFeature oHemFeatureNew = default (HemFeature);
 oHemFeatureNew = oHems.Add(oHemDefNew);
 oHemFeatureNew.Name = hemFeatureName;

GetIsoCurve

$
0
0

By Adam Nagy

The SurfaceEvaluator object has a GetIsoCurve function that can return a curve on the surface running in the U or V parametric direction.

The function's UDirection parameter could be confusing. It tells the function if the curve should be along the U or V parametric direction, and not what the passed in parameter should be: i.e. in case of UDirection = True you get back a curve that runs in the U parametric direction, but the parameter you pass to the function should be a V parametric value.

Here is a function that goes along the U direction of a Face and creates WorkPoints there plus creates a circle based on what GetIsoCurve(UDirection = False) returns:

Sub GetIsoCurveTest()
  Dim doc As PartDocument
  Set doc = ThisApplication.ActiveDocument
  Dim cd As PartComponentDefinition
  Set cd = doc.ComponentDefinition
  Dim f As Face
  For Each f In cd.SurfaceBodies(1).Faces' We only deal with the cylindrical side face now
    If TypeOf f.Geometry Is Cylinder Then
      Dim s As SurfaceEvaluator
      Set s = f.Evaluator
      Dim paramRange As Box2d
      Set paramRange = s.ParamRangeRect' Create points along U direction
      Dim uDif As Double
      uDif = (paramRange.MaxPoint.x - paramRange.MinPoint.x) / 5
      Dim tr As TransientGeometry
      Set tr = ThisApplication.TransientGeometry
      Dim wps As WorkPoints
      Set wps = cd.WorkPoints
      Dim i As Integer
      For i = 0 To 5
        Dim pt() As Double
        Dim params(1) As Double
        params(0) = paramRange.MinPoint.x + (uDif * i)
        params(1) = paramRange.MinPoint.y
        Call s.GetPointAtParam(params, pt)
        Call wps.AddFixed(tr.CreatePoint(pt(0), pt(1), pt(2)))
      Next' Get IsoCurve in the V direction (UDirection = False) ' at the mid U parametric position' In case of our model this should provide a Circle
      Dim midU As Double
      midU = (paramRange.MinPoint.x + paramRange.MaxPoint.x) / 2#
      Dim oc As ObjectCollection
      Set oc = s.GetIsoCurve(midU, False)

      Dim circ As Inventor.Circle
      Set circ = oc(1)
    
      Dim s3d As Sketch3D
      Set s3d = cd.Sketches3D.Add()
    
      ' Show it in the UI by adding it to a 3d sketch
      Call s3d.SketchCircles3D.AddByCenterRadius( _
        circ.Center, circ.Normal, circ.Radius)
    End If
  Next
End Sub

The result is:

GetIsoCurves

In case of the above cylinder's side Face if you call the GetIsoCurve with UDirection = True then you'll get back a straight LineSegment (and the passed in parameter should be along the V direction, Point2d.Y), but if pass in UDirection = False then the returned curve will be a Circle (and the passed in parameter should be along the direction, Point2d.X) - this is highlighted in blue in the above picture.    

Getting points of tangency to a circle

$
0
0

By Balaji Ramamoorthy

In a recent query, a developer wanted to retrieve the points of tangency of sketch lines with circles. The way to do get that information is to set up the sketch constraints right just as you would with the Inventor UI. The geometry can then be retrieved from the tangent lines using SketchLine.Geometry. Here is a sample code snippet and the screenshot of sketch that it generates.

Dim  partDoc As  PartDocument = _
TryCast (_invApp.ActiveDocument, PartDocument)
Dim  oCompDef As  PartComponentDefinition _
         = partDoc.ComponentDefinition
Dim  oSketch As  PlanarSketch = _
         oCompDef.Sketches.Add(oCompDef.WorkPlanes(3))
     oSketch.Name = "MySketch"
Dim  oTG As  TransientGeometry = _
         _invApp.TransientGeometry
Dim  geomConstraints As  GeometricConstraints _
         = oSketch.GeometricConstraints
Dim  points As  SketchPoints = oSketch.SketchPoints
Dim  skp0 As  SketchPoint = points.Add( _
         oTG.CreatePoint2d(0, 0), False )
Dim  skp1 As  SketchPoint = points.Add( _
         oTG.CreatePoint2d(10, 0), False )
Dim  oCenLine As  SketchLine = _
         oSketch.SketchLines.AddByTwoPoints(skp0, skp1)
     oCenLine.Construction = True
     geomConstraints.AddHorizontal(oCenLine)
Dim  oCircle1 As  SketchCircle = _
         oSketch.SketchCircles.AddByCenterRadius( _
             oCenLine.StartSketchPoint, 4)
Dim  oCircle2 As  SketchCircle = _
         oSketch.SketchCircles.AddByCenterRadius( _
             oCenLine.EndSketchPoint, 2)
     geomConstraints.AddGround(oCircle1.CenterSketchPoint)
     geomConstraints.AddGround(oCircle2.CenterSketchPoint)
Dim  skp2 As  SketchPoint = _
         points.Add(oTG.CreatePoint2d(0, 4), False )
Dim  skp3 As  SketchPoint = _
         points.Add(oTG.CreatePoint2d(10, 2), False )
Dim  oTanLine1 As  SketchLine = _
         oSketch.SketchLines.AddByTwoPoints(skp2, skp3)
Dim  skp4 As  SketchPoint = points.Add( _
         oTG.CreatePoint2d(0, -4), False )
Dim  skp5 As  SketchPoint = points.Add( _
         oTG.CreatePoint2d(10, -2), False )
Dim  oTanLine2 As  SketchLine = _
         oSketch.SketchLines.AddByTwoPoints(skp4, skp5)
     geomConstraints.AddTangent(oCircle1, oTanLine1)
     geomConstraints.AddTangent(oCircle2, oTanLine1)
     geomConstraints.AddTangent(oCircle1, oTanLine2)
     geomConstraints.AddTangent(oCircle2, oTanLine2)
     geomConstraints.AddCoincident( _
         oTanLine1.StartSketchPoint, oCircle1)
     geomConstraints.AddCoincident( _
         oTanLine1.EndSketchPoint, oCircle2)
     geomConstraints.AddCoincident( _
         oTanLine2.StartSketchPoint, oCircle1)
     geomConstraints.AddCoincident( _
         oTanLine2.EndSketchPoint, oCircle2)
Dim  oTanLine1Geom As  LineSegment2d _
         = oTanLine1.Geometry
Dim  oTanLine2Geom As  LineSegment2d _
         = oTanLine2.Geometry
Dim  sp1 As  Point2d = oTanLine1Geom.StartPoint
Dim  ep1 As  Point2d = oTanLine1Geom.EndPoint
     MessageBox.Show(String .Format( _
"Tangent 1 SP : {0}{1} EP : {2}{3}" , _
         sp1.X, sp1.Y, ep1.X, ep1.Y))

Sketch

Autodesk Exchange Apps Store surpasses 1 million downloads


Autodesk Cloud Accelerator Extension in Prague

Endless loop when using IsFileInActiveProject inside OnFileResolution

$
0
0

By Adam Nagy

It seems that in Inventor 2016 the behaviour of IsFileInActiveProject has been modified in a way that now it triggers the OnFileResolution event. Which of course means that if you are calling IsFileInActiveProject from inside OnFileResolution then you are creating an endless loop that will bring Inventor down.

OnFileResolution

I'm not sure yet if this change in behaviour is by-design or not, but it could be. I can imagine that now we allow add-ins to chip in when finding files even in case of using IsFileInActiveProject.

In order to avoid the endless loop, you just need to use a flag variable to signal if OnFileResolution has been called as a result of IsFileInActiveProject or not. Here is my VBAclsEvents class that shows what I mean:

Dim WithEvents faEvents As FileAccessEvents' To avoid recursion
Private inside As Boolean

Private Sub Class_Initialize()
  Set faEvents = ThisApplication.FileAccessEvents
  inside = False
End Sub

Private Sub faEvents_OnFileResolution( _
ByVal RelativeFileName As String, _
ByVal LibraryName As String, _
CustomLogicalName() As Byte, _
ByVal BeforeOrAfter As EventTimingEnum, _
ByVal Context As NameValueMap, _
FullFileName As String, _
HandlingCode As HandlingCodeEnum)
    Dim str As String
    Dim loc As LocationTypeEnum
    
    ' To avoid recursion we use a flag variable' called "inside"
    If Not inside Theninside = True
        Dim dpm As DesignProjectManager
        Set dpm = ThisApplication.DesignProjectManager
        Call dpm.IsFileInActiveProject( _"1.ipt", _
            loc, _
            str)inside = False

        HandlingCode = HandlingCodeEnum.kEventHandled
    End If
End Sub

AnyCAD structure with original file names

$
0
0

By Adam Nagy

Inside Inventor 2016 you can reference other CAD file formats directly from an assembly. In this case you can also see the structure of the referenced assembly in the model tree. If you'd also need to get back the structure using the original file names - i.e. going from Occurrence to the original file - that is currently not exposed in the API: no direct access from"SubOccurrence1" to"AnyCAD Part1" in the blow picture.

Image001-6

One workaround could be finding the original files based on the Occurrence.Name, since both that and the Inventor document names created from the foreign file are based on the name of the original file. You can find the list of the original file names through Document.File.AllReferencedFiles:

Function GetFileName(filePath As String) As String
  Dim i1 As Integer
  i1 = InStrRev(filePath, "\")
  Dim i2 As Integer
  i2 = InStrRev(filePath, ".")' Check for occurrence name as well
  If i2 < 1 Then i2 = InStrRev(filePath, ":")
  GetFileName = Mid(filePath, i1 + 1, i2 - i1 - 1)
End Function

Function GetFullPath(fileName As String) As String
  Dim asm As AssemblyDocument
  Set asm = ThisApplication.ActiveDocument
  
  Dim f As File
  For Each f In asm.File.AllReferencedFiles
    If GetFileName(f.FullFileName) = fileName Then
      GetFullPath = f.FullFileName
      Exit Function
    End If
  Next
End Function

Sub PrintOccurrences( _
occs As ComponentOccurrences, _
i As Integer)
  Dim occ As ComponentOccurrence
  For Each occ In occs
    Debug.Print Space(i); occ.name
    
    Dim doc As Document
    Set doc = occ.Definition.Document
    
    Dim fullPath As String
    
    If doc.IsEmbeddedDocument Then
      Dim fileName As String
      fileName = GetFileName(occ.name)
      fullPath = GetFullPath(fileName)
    Else
      fullPath = doc.FullFileName
    End If
    
    Debug.Print Space(i); " - " + fullPath
    Call PrintOccurrences( _
      occ.SubOccurrences, _
      i + 2)
  Next
End Sub

Sub PrintStructure()
  Dim doc As AssemblyDocument
  Set doc = ThisApplication.ActiveDocument
  
  Dim acd As AssemblyComponentDefinition
  Set acd = doc.ComponentDefinition
  
  Call PrintOccurrences(acd.Occurrences, 1)
End Sub

I get this output in case of my assembly that is referencing a SolidWorks assembly file called gears.SLDASM:

Solidworksassembly

 gears:1
  - C:\SolidWorks\Gears\gears.SLDASM
   frame:1
    - C:\SolidWorks\Gears\frame.SLDPRT
   Internal Spur Gear:1
    - C:\SolidWorks\Gears\Internal Spur Gear.sldprt
   Spur Gear:1
    - C:\SolidWorks\Gears\Spur Gear.sldprt
   Spur Gear:2
    - C:\SolidWorks\Gears\Spur Gear.sldprt
   Spur Gear:3
    - C:\SolidWorks\Gears\Spur Gear.sldprt
   Spur Gear:4
    - C:\SolidWorks\Gears\Spur Gear.sldprt
   shaft1:1
    - C:\SolidWorks\Gears\shaft1.SLDPRT
   shaft2:1
    - C:\SolidWorks\Gears\shaft2.SLDPRT
   shaft2:2
    - C:\SolidWorks\Gears\shaft2.SLDPRT
   shaft2:3
    - C:\SolidWorks\Gears\shaft2.SLDPRT

Retrieving dimensions in a drawing view

$
0
0

By Balaji Ramamoorthy

To retrieve only a few of the dimensions, the “GeneralDimensions.Retrieve” method can be used with second parameter being a collection of dimensions to retrieve. In Inventor 2016, this also brings along other dimensions that were not in the collection. A request has been logged with our engineering team to address this.

As a workaround, all the dimensions can be retrieved in a drawing view and the ones that are not needed can be deleted. In the below code snippet, this workaround is demonstrated and it only retains the dimensions in the drawing view which were retrieved from dimensions which have parameter names matching a specific string.

Dim  oDoc As  DrawingDocument
 oDoc = ThisApplication.ActiveDocument
 oDrawDimsForView _
 = ThisApplication.TransientObjects.CreateObjectCollection
Dim  oSheet As  Sheet
 oSheet = oDoc.ActiveSheet
Dim  oDims As  GeneralDimensions
 oDims = oSheet.DrawingDimensions.GeneralDimensions
Dim  oView As  DrawingView
 oView = oSheet.DrawingViews(1)
Dim  oRetrievableDims As  ObjectCollection
 oRetrievableDims _
 = ThisApplication.TransientObjects.CreateObjectCollection
 oRetrievableDims = oDims.GetRetrievableDimensions(oView)
If  oRetrievableDims.Count > 0 Then
Dim  dimsEnum As  GeneralDimensionsEnumerator
     dimsEnum = oDims.Retrieve(oView)
Dim  paramName AsString
Dim  oDim As  GeneralDimension
ForEach  oDim In  dimsEnum
If  oDim.Retrieved Then
             paramName = oDim.retrievedFrom.Parameter.Name
If  paramName <> "ShoeWidth"And  _
             paramName <> "ShoeHeight"Then
                 oDim.Delete()
EndIf
EndIf
Next
EndIf

Toggle visibility of folders of Origins, Sketches and Constructions

$
0
0

By Xiaodong Liang

Although the items in the folders of Origins, Sketches and Constructions have the corresponding API objects, the visibility of the folders are controlled by the following flags:

rootComponent.isSketchFolderLightBulbOn
rootComponent. isOriginFolderLightBulbOn
rootComponent. isConstructionFolderLightBulbOn

The usage is quite straightforward. Just set True or False will be same to what end user clicks the folder bulb on / off.

 

image

Listing the Positional Representations in iLogic Form

$
0
0

By Balaji Ramamoorthy

The Positional Representations in an assembly document can change as you add or remove any of the representations. If you need to list the names of the representations in a combo-box inside your iLogic form, here is a way to do that.

Step-1 : Create a Multi-value user parameter of Text type. In the below example, we name this parameter as "PosReps"

Step-2 : In your iLogic form, drag the user-parameter created in Step-1. As it is a multi-value parameter, a combo-box will display its values

Step-3 : In your iLogic Rule, before you display the iLogic form, update the user parameter by iterating through the positional representation in the assembly document. Here is a sample iLogic rule that updates the user parameter named "PosReps" :

Dim  oAsmDoc AsAssemblyDocument
 oAsmDoc = ThisApplication.ActiveDocument
Dim  oAsmCompDef AsAssemblyComponentDefinition
 oAsmCompDef = oAsmDoc.ComponentDefinition
Dim  oPosReps AsPositionalRepresentations
 oPosReps = oAsmCompDef.RepresentationsManager _
 .PositionalRepresentations
Dim  List() AsString
ReDim  List(0 To  oPosReps.Count-1)
Dim  cnt AsInteger
 cnt = 0
Dim  oPosRep AsPositionalRepresentation
ForEach  oPosRep In  oPosReps
 	List(cnt) = oPosRep.Name
 	cnt = cnt + 1
Next
Dim  oPars AsUserParameters
 oPars = _
 oAsmDoc.ComponentDefinition.Parameters.UserParameters
Dim  oPar AsUserParameter
 oPar = oPars.Item("PosReps")
Dim  oExprList AsExpressionList
 oExprList = oPar.ExpressionList
Call  oExprList.SetExpressionList(List, False )
 oAsmDoc.Update
 iLogicForm.Show("Positional Reps")

Here is a screenshot of the iLogic form displaying the positional representations:

ILogic_PosReps

Attributes of ComponentOccurrence vs ComponentOccurrenceProxy

$
0
0

By Adam Nagy

Attributes are context sensitive because they are saved in the document which is hosting the object that has the attribute.

Let's say we have the following assembly structure:

Asm1
  + Asm2:1
    + Part1:1
    + Part2:1

If you open up Asm2.iam and add an attribute to Part1:1 then it will be stored in Asm2.iam, so if now you open up Asm1.iam and check the attributes on Asm2:1>> Part1:1, the attribute will not be there. However, you can easily move to the corresponding object in Asm2.iam using the NativeObject property of the ComponentOccurrenceProxy object. 

Some info on Proxies and Contexts: http://adndevblog.typepad.com/manufacturing/2013/07/occurrences-contexts-definitions-proxies.html

You can play with attributes using the following VBA code:
- SetAttribute adds an attribute to the selected occurrence with a value that also contains the display name of the assembly document that hosts the occurrence 
- GetAttribute gets back the attribute of the selected occurrence - if useNativeObject = True then it will look for the attribute inside the document that hosts the occurrence:

Sub SetAttribute()
  Dim doc As Document
  Set doc = ThisApplication.ActiveDocument

  Dim ent As Object
  Set ent = doc.SelectSet(1)

  Dim attSets As AttributeSets
  Set attSets = ent.AttributeSets
  
  Dim attSet As AttributeSet

  If attSets.NameIsUsed("MyAttSet") Then
    Set attSet = attSets("MyAttSet")
  Else
    Set attSet = attSets.Add("MyAttSet")
  End If
  Dim att As Attribute
  If attSet.NameIsUsed("MyAtt") Then
    Set att = attSet("MyAtt")
  Else
    Set att = attSet.Add("MyAtt", kStringType, _"MyAttValue in " + doc.DisplayName)
  End If
End Sub

Sub GetAttribute()
  Dim doc As Document
  Set doc = ThisApplication.ActiveDocument

  Dim ent As Object
  Set ent = doc.SelectSet(1)
  
  ' You can set this
  Dim useNativeObject As Boolean
  useNativeObject = False
  If TypeOf ent Is ComponentOccurrenceProxy _
  And useNativeObject Then
    Set ent = ent.NativeObject
  End If

  Dim attSets As AttributeSets
  Set attSets = ent.AttributeSets
  
  Dim attSet As AttributeSet

  If attSets.NameIsUsed("MyAttSet") Then
    Set attSet = attSets("MyAttSet")

    Dim att As Attribute
  
    If attSet.NameIsUsed("MyAtt") Then
      Set att = attSet("MyAtt")
    End If
    Call MsgBox(att.Value)
  End If
End Sub

Here is a pic showing what you get back using GetAttribute if both in Asm1 and Asm2 you added attributes to Part2:1 by selecting it and calling SetAttribute:

Proxyattributes

 


Toggle suppress state of FEA element

$
0
0

By Adam Nagy

This requires a technique similar to that shown here: http://adndevblog.typepad.com/manufacturing/2014/04/run-command-on-browser-item.html

In this case will have to work on another Browser Pane, the one created by the FEA addin: "Stress Analysis"

We just have to find the component we want to toggle the Suppress state of, then execute the "FeaSuppressCmD" command on it:

Function FindNode( _
node As BrowserNode, label As String) As BrowserNode
  Dim subNode As BrowserNode
  For Each subNode In node.BrowserNodes
    If subNode.BrowserNodeDefinition.label = label Then
      Set FindNode = subNode
      Exit Function
    End If
    Dim foundNode As BrowserNode
    Set foundNode = FindNode(subNode, label)
    If Not foundNode Is Nothing Then
      Set FindNode = foundNode
      Exit Function
    End If
  Next
End Function

Sub SuppressFeaElement()
  Dim doc As Document
  Set doc = ThisApplication.ActiveDocument

  ' Get the control definition we need
  Dim cm As CommandManager
  Set cm = ThisApplication.CommandManager
  Dim cds As ControlDefinitions
  Set cds = cm.ControlDefinitions
  Dim cd As ControlDefinition
  Set cd = cds("FeaSuppressCmD")' Find the item in the browser tree
  Dim elemName As String
  elemName = "Force:1"' Stress Analysis browser pane
  Dim bp As BrowserPane
  Set bp = doc.BrowserPanes( _"{B3D04494-EDD2-4FDC-9EC2-30BAF8D6B77B}")
  Dim node As BrowserNode
  Set node = FindNode(bp.topNode, elemName)' Select it
  node.EnsureVisible ' might be needed
  node.DoSelect' Run the command on it
  cd.Execute
End Sub

The code in action:

FEA

 

Splitting a HoleTable

$
0
0

By Balaji Ramamoorthy

Splitting a HoleTable using API is not possible at present. In this blog post we will look at a workaround that mimics a split HoleTable by creating two HoleTables each of which lists a certain hole information. Please note that this workaround creates two separate HoleTables both of which are unrelated and have Sheet as its parent. In case of splitting a HoleTable using Inventor UI, the split HoleTable is nested under a parent HoleTable. This structure provides the option to un-split the HoleTables at any time, if you need to. Such un-split option would not be available when using the workaround demonstrated in this blog post, as the two HoleTables are unrelated. As the HoleTables are separate and have Sheet as their parent, Inventor would not know that the two tables are related by a split.

Here is a VBA code snippet which should work with the attached drawing. If you are trying it on any other drawing, the index values may need to be modified accordingly.

Dim  oDoc As  DrawingDocument
Set  oDoc = ThisDocument
Dim  oSheet As  Sheet
Set  oSheet = oDoc.Sheets.Item(1)
Dim  oDrawingView As  DrawingView
Set  oDrawingView = oSheet.DrawingViews.Item(2)
'Modify the index to ensure that the right
'drawing curve is used to create the intent
'For the attached drawing, this will locate 
'the origin indicator at the lower left corner
Dim  oCurve As  DrawingCurve
Set  oCurve = oDrawingView.DrawingCurves.Item(53)
 Debug.Print oCurve.CurveType
Dim  oIntent As  GeometryIntent
Set  oIntent _
     = oSheet.CreateGeometryIntent(oCurve, oCurve.StartPoint)
'Create an origin indicator
IfNot  oDrawingView.HasOriginIndicator Then
Call  oDrawingView.CreateOriginIndicator(oIntent)
EndIf
'Positions of the hole tables
Dim  oPt1 As  Point2d
Set  oPt1 _
     = ThisApplication.TransientGeometry.CreatePoint2d(35, 45)
Dim  oPt2 As  Point2d
Set  oPt2 _
     = ThisApplication.TransientGeometry.CreatePoint2d(55, 45)
'Create a hole table for the drawing view
Dim  oHoleTable1 As  HoleTable
Set  oHoleTable1 = oSheet.HoleTables.Add(oDrawingView, oPt1)
Dim  oCollection1 As  ObjectCollection
Set  oCollection1 _
     = ThisApplication.TransientObjects.CreateObjectCollection()
Dim  oCollection2 As  ObjectCollection
Set  oCollection2 _
     = ThisApplication.TransientObjects.CreateObjectCollection()
'Identify the row to split
Dim  splitRow AsInteger
Dim  rowsCnt AsInteger
 rowsCnt = oHoleTable1.HoleTableRows.Count
If  rowsCnt Mod  2 = 0 Then
     splitRow = rowsCnt / 2
Else
     splitRow = (rowsCnt - 1) / 2
EndIf
'Get the hole curves for creating the hole tables
Dim  cnt AsInteger
 cnt = 1
ForEach  oRow In  oHoleTable1.HoleTableRows
     cnt = cnt + 1
If  cnt < splitRow Then
         oCollection1.Add oRow.ReferencedHole
Else
         oCollection2.Add oRow.ReferencedHole
EndIf
Next
 oHoleTable1.Delete
'Split hole table - 1
Dim  oSplitHoleTable1 As  HoleTable
Set  oSplitHoleTable1 _
     = oSheet.HoleTables.AddSelected(oCollection1, oPt1)
'Split hole table - 2
Dim  oSplitHoleTable2 As  HoleTable
Set  oSplitHoleTable2 _
     = oSheet.HoleTables.AddSelected(oCollection2, oPt2)
'Renumber the second hole table to mimic a split table
 cnt = oSplitHoleTable1.HoleTableRows.Count + 1
ForEach  oRow In  oSplitHoleTable2.HoleTableRows
     oRow.Item(1).FormattedText = "A" & CStr (cnt)
     cnt = cnt + 1
Next
Download BasePart.idw

Download BasePart.ipt

Change ActiveLightingStyle

$
0
0

By Adam Nagy

Just like in case of many other styles, first you need to find the given style inside the appropriate styles collection - in this case LightingStyles. Then you assign that to the settings parameter - in this case the ActiveLightingStyle property of the Document.

Sub ChangeLightingStyle()
  Dim doc As Document
  Set doc = ThisApplication.ActiveDocument
  Dim lss As LightingStyles
  Set lss = doc.LightingStyles' Let's just use the first style' InternalName: "1:Cool Light"
  doc.ActiveLightingStyle = lss("1:Cool Light")
End Sub

Code in action:

ActiveLightingStyle

Fusion C++ API and Fusion Hackathon

$
0
0

By Adam Nagy

As Brian mentioned it here, the latest release of Fusion 360 has a C++ API as well. This has been much awaited by developers who want to protect their Intellectual Property (IP). Your code in case of scripting languages is easily accessible, but the C++ code will be compiled so you only need to distribute your code in binary format, which is much more secure.
Note: the Mac App Store (MAS) version of the latest Fusion release is not available just yet, but is coming real soon

Having reached this milestone with the introduction of the C++ API, we are planning to organise an online Fusion Hackathon round September - October, running for about a month or so. As part of that we'll deliver presentations to help you get started with Fusion app development and will be there to answer your questions. 

If you need an incentive to take part in the hackathon then here is one: we are thinking of giving a reward of up to $500 to each of you for a finished submitted application that you develop by the end of the hackathon and is published in Autodesk Exchange Fusion App store.

Watch out for further information concerning the hackathon and start thinking about what you'd like to develop. :)

#FusionHackathon

Selecting holes in the drawing view filtered by orientation

$
0
0

by Vladimir Ananyev

Let’s suppose we should select all the hole features on the drawing view that are orthogonal to the view plane.

In other words, for every hole feature that is projected on the drawing view we should check its orientation and if this hole is orthogonal to the drawing view plane we should add all its drawing curve segments to the DrawingDocument.SelectSet collection.

image.

The part model used here has two non-parallel hole features.

There is a pair of places in the code that are worth noting.

1) DrawingView API provides the magic property that returns all the drawing curves within my drawing view filtered to the input model object. Here the HoleFeature objects were used.

DrawingView.DrawingCurves( [ModelObject] As Variant ) As DrawingCurvesEnumerator

2) How we can check if the hole is orthogonal to the view plane or not?  I did it comparing two vectors. One vector is defined by the view camera orientation. It could be created by two points – Eye and Target.  Calculations of the second vector depend on the hole placement definition. Here I used the normal to the sketch where the center points were created. Vector.IsParallelTo() method gives the answer if these two vectors are parallel or not. If they are parallel all drawing curve segments projected from this hole feature should be added to the SelectSet collection.

 

Sub HoleSelect()

   

    Dim oTG As TransientGeometry

    Set oTG = ThisApplication.TransientGeometry

   

    'active drawing doc

    Dim oDrawDoc As DrawingDocument

    Set oDrawDoc = ThisApplication.ActiveDocument

    'active sheet

    Dim oSheet As Sheet

    Set oSheet = oDrawDoc.ActiveSheet

    'the 1st drawing view

    Dim oView As DrawingView

    Set oView = oSheet.DrawingViews.Item(1)

   

    'camera

    Dim oCamera As Camera

    Set oCamera = oView.Camera

   

    Dim oEye As Point, oTarget As Point

    Set oEye = oCamera.Eye

    Set oTarget = oCamera.Target

    Dim oVec As Vector

    Set oVec = oTG.CreateVector( _

            oEye.x - oTarget.x, _

            oEye.y - oTarget.y, _

            oEye.z - oTarget.z)

   

    Dim oSSet As SelectSet

    Set oSSet = oDrawDoc.SelectSet

    Call oSSet.Clear

   

    'model document, need to find hole features

    Dim oDoc As PartDocument

    Set oDoc = oView.ReferencedDocumentDescriptor.ReferencedDocument

    Dim oDef As PartComponentDefinition

    Set oDef = oDoc.ComponentDefinition

    Dim oHoleFeatures As HoleFeatures

    Set oHoleFeatures = oDef.Features.HoleFeatures

   

    'collection for segments to be selected

    Dim oColl As ObjectCollection

    Set oColl = ThisApplication.TransientObjects.CreateObjectCollection

   

    Dim oHole As HoleFeature

    For Each oHole In oHoleFeatures

   

        Dim oCurves As DrawingCurvesEnumerator

        Set oCurves = oView.DrawingCurves(oHole)

        Debug.Print oHole.name, oCurves.Count

       

        If oCurves.Count > 0 Then

            'this hole feature is seen in the drawing view

            'so we need to check the hole orientation.

            'Method depends on the hole placement definition !

            Dim oSketch As PlanarSketch

            Set oSketch = oHole.PlacementDefinition.HoleCenterPoints.Item(1).Parent

           

            Dim oNormal As UnitVector

            Set oNormal = oSketch.PlanarEntity.Geometry.normal

           

            If oVec.IsParallelTo(oNormal.AsVector, 0.0000001) Then

           

                Debug.Print "Hole is orthogonal"

               

                'populate the collection to select segments later

                Dim oCurve As DrawingCurve

                Dim dcs As DrawingCurveSegment

                For Each oCurve In oCurves

                    For Each dcs In oCurve.Segments

                        Call oColl.Add(dcs)

                    Next

                Next

               

            Else

                Debug.Print "Hole is slanted"  'do nothing

            End If

       

        End If

    Next

   

    'select drawing curve segments found

    Beep

    If oColl.Count > 0 Then

        Call oSSet.SelectMultiple(oColl)

        MsgBox "Done :)"

    Else

        MsgBox "No orthogonal holes found"

    End If

   

End Sub

 

Output to the Immediate Window:

Hole1          8

Hole is slanted

Hole2          2

Hole is orthogonal

 

Selected curves:

image

Download HoleSelect

Viewing all 518 articles
Browse latest View live