Community
Inventor Programming - iLogic, Macros, AddIns & Apprentice
Inventor iLogic, Macros, AddIns & Apprentice Forum. Share your knowledge, ask questions, and explore popular Inventor topics related to programming, creating add-ins, macros, working with the API or creating iLogic tools.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

[API] Traverse an Assembly and Print off minRange Location for Each Part

12 REPLIES 12
SOLVED
Reply
Message 1 of 13
lemensk
1201 Views, 12 Replies

[API] Traverse an Assembly and Print off minRange Location for Each Part

When you are tranversing through an assembly, how can you create a list with the part name and its GLOBAL minRange value?  How would you use proxies to accompolish this?

 

Thank you,

-lemensk

12 REPLIES 12
Message 2 of 13
xiaodong_liang
in reply to: lemensk

Hi,

 

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.

Message 3 of 13
lemensk
in reply to: xiaodong_liang

Mr. Liang,

 

Isn't your comment a 'half' truth?  Before I posted the question, I had operating code that extracted Rangebox.  However, my model had sub-assemblies and one particular sub-assembly was rotated 90degrees to the Global Assembly axis; so the 'x' minRange was the actually the Global 'z' value.

 

I beleive I can get around this by utilizing a proxy, but I was hoping for a simplified/error-proof technique.

 

Thank you,

-Kenny

Message 4 of 13
ajcampbell
in reply to: lemensk

Have you tried something like this? I've used this method for similar situations.

 

ComponentOccurrence myOccurance;
foreach(SurfaceBody body in myOccurance.SurfaceBodies)
{
   if (body is SurfaceBodyProxy)
   {
      SurfaceBodyProxy bodyProxy = (SurfaceBodyProxy)body;
      SurfaceBody NativeBody = bodyProxy.NativeObject;
      Box bodyRange = NativeBody.RangeBox;
      //whatever logic you need with the range box
   }
}

Message 5 of 13
xiaodong_liang
in reply to: lemensk

Hi Kenny,

 

The RangeBox is a rectangular box that is guaranteed to enclose this object. I tested with the attached part, sub-**** and top-****, placing the occurrences with different rotations. The RangeBox looks well to me. Their locations are in the context of the top assembly The code is as below. 

 

Or I misunderstood your question?

 

Sub getPartParam()

 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

 

 

Capture.JPG

Message 6 of 13
lemensk
in reply to: xiaodong_liang

I am trying to extract part locations.  Here is my model:

 

(IMAGE1)

 

 

You will notice that I have (6) posts, both comprised of Angle 1:1 and Angle 1:2.  Here is the result I get when I print off the parts MinRange and MaxRange Properties:

 

(IMAGE2)

 

As you will notice, they are all identical.  I understand your code in the context that the Min and MaxRange values provided by Occurrences of an Assembly all have the same datum, but when I try to access parts in a sub-assembly (i.e., a face of one of your cube) I only get the min/max values that pertain to it locally (i.e. x,y,z values pertaining to the cube origin, not the assembly origin).  Granted, I have created a coorolation between locaiton of a subassembly to the main assembly and add the difference between the two to the min/max range values, but this all falls apart when the subassembly itself has a different axis orientation then the main assembly.

 

I was hoping to use proxies, but I'm having trouble  at generating a vector between the global origin and a parts min/max range values.

 

-thanks, Ken

 

Message 7 of 13
adam.nagy
in reply to: lemensk

Hi Ken,

 

You should try to modify Xiao's code to make it work for your assembly and if it does not work as you need it then show us how you modified it.

I think you are retrieving the data in context of the subassembly you activated - i.e. "Support 2:1" -, but what you seem to want is the locaion in context of the topmost assembly.

 

Using proxies is not more complicated than getting the information in a different context and then doing transformations on them: http://adndevblog.typepad.com/manufacturing/2013/07/occurrences-contexts-definitions-proxies.html

 

I hope this helps.

 

Cheers,



Adam Nagy
Autodesk Platform Services
Message 8 of 13
lemensk
in reply to: lemensk

Here is my code:

'------------------------start


'Option Explicit
Dim partOccur As Inventor.ComponentOccurrence
Dim tempA As Inventor.ComponentOccurrence
Dim assemblyDoc As Inventor.AssemblyDocument
Dim fileName As String
Dim inventDoc As Inventor.AssemblyDocument
Dim partProxy As Inventor.WorkPointProxy
Dim partProxy2 As Inventor.WorkPointProxy
Dim partParentProxy As Inventor.WorkPointProxy
Dim partParentFatherProxy As Inventor.WorkPointProxy
Dim partParentGrandFatherProxy As Inventor.WorkPointProxy
Dim proxyToUse As Inventor.WorkPointProxy

Sub printPart()
   Dim inventDoc As Inventor.AssemblyDocument
   Set inventDoc = ThisApplication.ActiveDocument
   fileName = inventDoc.DisplayName

   For Each partOccur In inventDoc.ComponentDefinition.Occurrences
      printPartCoord partOccur, 0, 0, 0 'inventDoc.ComponentDefinition.RangeBox.MinPoint.Z
   Next
   
End Sub

Sub printPartCoord(assemblyObj As Object, xCoord As Double, yCoord As Double, zCoord As Double)
   Dim strg As String
   'Dim xDelta, yDelta, zCoord2 As Double
   
   Dim partVert1Proxy As Inventor.WorkPointProxy
   Dim partVert1 As Inventor.WorkPoint
   
   If TypeName(assemblyObj) = "AssemblyDocument" Then
      Set assemblyDoc = assemblyObj
      For Each partOccur In assemblyDoc.ComponentDefinition.Occurrences
            printPartCoord partOccur, xCoord, _
                                      yCoord, _
                                      zCoord
      Next
   ElseIf TypeName(assemblyObj) = "ComponentOccurrence" Then
      For Each partOccur In assemblyObj.Definition.Occurrences

         If partOccur.Definition.SurfaceBodies.Count > 0 Then
            Dim deltaX, deltaY, deltaZ, avgX, avgY, avgZ As Double
            Dim minRangePoint, maxRangePoint, minRangePoint1, maxRangePoint1 As WorkPoint
            Dim partVector As Vector
            deltaX = partOccur.RangeBox.MaxPoint.X - _
                     partOccur.RangeBox.MinPoint.X
            avgX = (deltaX / 2)
            deltaY = partOccur.RangeBox.MaxPoint.Y - _
                     partOccur.RangeBox.MinPoint.Y
            avgY = (deltaY / 2)
            deltaZ = partOccur.RangeBox.MaxPoint.Z - _
                     partOccur.RangeBox.MinPoint.Z
            avgZ = (deltaZ / 2)
            
            If deltaX > deltaY And deltaX > deltaZ Then
               Set minRangePoint1 = partOccur.Definition.WorkPoints.AddFixed(ThisApplication.TransientGeometry.CreatePoint(0, avgY, avgZ))
               Set maxRangePoint1 = partOccur.Definition.WorkPoints.AddFixed(ThisApplication.TransientGeometry.CreatePoint(deltaX, avgY, avgZ))
            ElseIf deltaY > deltaX And deltaY > deltaZ Then
               Set minRangePoint1 = partOccur.Definition.WorkPoints.AddFixed(ThisApplication.TransientGeometry.CreatePoint(avgX, 0, avgZ))
               Set maxRangePoint1 = partOccur.Definition.WorkPoints.AddFixed(ThisApplication.TransientGeometry.CreatePoint(avgX, deltaY, avgZ))
            Else
               Set minRangePoint1 = partOccur.Definition.WorkPoints.AddFixed(ThisApplication.TransientGeometry.CreatePoint(avgX, avgY, 0))
               Set maxRangePoint1 = partOccur.Definition.WorkPoints.AddFixed(ThisApplication.TransientGeometry.CreatePoint(avgX, avgY, deltaZ))
            End If
                
            Set partVector = minRangePoint1.Point.VectorTo(maxRangePoint1.Point)
          
            maxRangePoint1.Delete
            minRangePoint1.Delete

            'Set minRangePoint = partOccur.Definition.WorkPoints.AddFixed(partOccur.RangeBox.MinPoint)
            'Set maxRangePoint = partOccur.Definition.WorkPoints.AddFixed(partOccur.RangeBox.MaxPoint)
            Set minRangePoint = partOccur.Definition.WorkPoints(1)
            'Set maxRangePoint = partOccur.Definition.WorkPoints(2)

            Dim oMinWorkPointProxy As Inventor.WorkPointProxy
            Dim oMaxWorkPointProxy As Inventor.WorkPointProxy
            Dim oMinWorkPointProxy1 As Inventor.WorkPointProxy
            Dim oMaxWorkPointProxy1 As Inventor.WorkPointProxy
            Dim oMinWorkPointProxy2 As Inventor.WorkPointProxy
            Dim oMaxWorkPointProxy2 As Inventor.WorkPointProxy
            Dim oMinWorkPointUseProxy As Inventor.WorkPointProxy
            Dim oMaxWorkPointUseProxy As Inventor.WorkPointProxy
            Dim oMinWorkPointProxy3 As Inventor.WorkPointProxy
            Dim oMaxWorkPointProxy3 As Inventor.WorkPointProxy
            Dim oMinWorkPointProxy4 As Inventor.WorkPointProxy
            Dim oMaxWorkPointProxy4 As Inventor.WorkPointProxy

         Set tempA = assemblyObj
         
        Call partOccur.CreateGeometryProxy(minRangePoint, oMinWorkPointProxy)
        'Call partOccur.CreateGeometryProxy(maxRangePoint, oMaxWorkPointProxy)
        Set oMinWorkPointUseProxy = oMinWorkPointProxy
        'Set oMaxWorkPointUseProxy = oMaxWorkPointProxy
        Call assemblyObj.CreateGeometryProxy(oMinWorkPointProxy, oMinWorkPointProxy1)
        'Call assemblyObj.CreateGeometryProxy(oMaxWorkPointProxy, oMaxWorkPointProxy1)
        Set oMinWorkPointUseProxy = oMinWorkPointProxy1
        'Set oMaxWorkPointUseProxy = oMaxWorkPointProxy1
        If Not (tempA.Parent.ActiveOccurrence Is Nothing) Then
            Call tempA.Parent.ActiveOccurrence.CreateGeometryProxy(oMinWorkPointProxy1, oMinWorkPointProxy2)
            'Call tempA.Parent.ActiveOccurrence.CreateGeometryProxy(oMaxWorkPointProxy1, oMaxWorkPointProxy2)
            Set oMinWorkPointUseProxy = oMinWorkPointProxy2
            'Set oMaxWorkPointUseProxy = oMaxWorkPointProxy2
            If Not (tempA.Parent.Parent.ActiveOccurrence Is Nothing) Then
                Call tempA.Parent.Parent.ActiveOccurrence.CreateGeometryProxy(oMinWorkPointProxy2, oMinWorkPointProxy3)
                'Call tempA.Parent.Parent.ActiveOccurrence.CreateGeometryProxy(oMaxWorkPointProxy2, oMaxWorkPointProxy3)
                Set oMinWorkPointUseProxy = oMinWorkPointProxy3
                'Set oMaxWorkPointUseProxy = oMaxWorkPointProxy3
                If Not (tempA.Parent.Parent.Parent.ActiveOccurrence Is Nothing) Then
                    Call tempA.Parent.Parent.Parent.ActiveOccurrence.CreateGeometryProxy(oMinWorkPointProxy3, oMinWorkPointProxy4)
                    'Call tempA.Parent.Parent.Parent.ActiveOccurrence.CreateGeometryProxy(oMaxWorkPointProxy3, oMaxWorkPointProxy4)
                    Set oMinWorkPointUseProxy = oMinWorkPointProxy4
                    'Set oMaxWorkPointUseProxy = oMaxWorkPointProxy4
                End If
            End If
        End If


            
            Dim xMin As Double
            Dim yMin As Double
            Dim zMin As Double
            Dim xMax As Double
            Dim yMax As Double
            Dim zMax As Double


            xMin = oMinWorkPointUseProxy.Point.X + xCoord
            yMin = oMinWorkPointUseProxy.Point.Y + yCoord
            zMin = oMinWorkPointUseProxy.Point.Z + zCoord
            xMax = oMinWorkPointUseProxy.Point.X + partVector.X + xCoord
            yMax = oMinWorkPointUseProxy.Point.Y + partVector.Y + yCoord
            zMax = oMinWorkPointUseProxy.Point.Z + partVector.Z + zCoord

                
            strg = partOccur.Name & ";" & xMin & ";" & yMin & ";" & zMin & ";" & partOccur.Name & ";" & xMax & ";" & yMax & ";" & zMax
            

            Open "C:\Temp\" & fileName & ".txt" For Append As #1
            Print #1, strg
            Close #1

        Else
           printPartCoord partOccur, xCoord, _
                                      yCoord, _
                                      zCoord
           
        End If
      Next
   End If
End Sub

 

'------------------------end

 

What it is supposed to do it print off (2) points for each part, the beginging of a member and the end of the member.

 

What would make this REALLY easy is if there is code out there to 'destory' and assembly and 'float' all the parts to the surface (i.e. one level).  Heck, I wouldn't even mind if it created a 10 MG file and took 2 days for run time

Message 9 of 13
adam.nagy
in reply to: lemensk

Hi,

 

I think that Xiao's code is pretty close to what you want. I think you just want to go down to the leaf occuurrences, the actual parts.

You just need to modify the following part in the getPartParam function from this:
For Each oOcc In oAssDoc.ComponentDefinition.Occurrences

to this:

For Each oOcc In oAssDoc.ComponentDefinition.Occurrences.AllLeafOccurrences

 

Note: you also need to add the "Clear" appearance style to the document in the "Appearance Browser" palette before running the code.

 

Cheers,



Adam Nagy
Autodesk Platform Services
Message 10 of 13
lemensk
in reply to: lemensk

Below is the answer to my question.  Surprised how hard it was to get such simple code:

 

'CODE START ---------------------------------

Sub printParts()
   Dim inventDoc As Inventor.AssemblyDocument
   Dim deltaX, deltaY, deltaZ, avgX, avgY, avgZ, minX, minY, minZ, maxX, maxY, maxZ As Double
   Dim fileName, strg As String

   Dim partOccur As Inventor.ComponentOccurrence

   Set inventDoc = ThisApplication.ActiveDocument
   fileName = inventDoc.DisplayName

   For Each partOccur In inventDoc.ComponentDefinition.Occurrences.AllLeafOccurrences   'For each part included in the assembly
       strg = partOccur.Name & ";" & partOccur.RangeBox.minPoint.X & ";" & partOccur.RangeBox.minPoint.Y & _

                 ";" & partOccur.RangeBox.minPoint.Z


      Open "C:\Temp\" & fileName & ".txt" For Append As #1 'Open txt file and Append
      Print #1, strg                                                                         'Print String
      Close #1                                                                                'Close txt file
   Next
   
End Sub


 

'CODE STOP ---------------------------------

Message 11 of 13
lemensk
in reply to: adam.nagy

How does "Appearance Browser" compromise code?
Message 12 of 13
adam.nagy
in reply to: lemensk

What do you mean exactly?



Adam Nagy
Autodesk Platform Services
Message 13 of 13
lemensk
in reply to: adam.nagy

Quote: "Note: you also need to add the "Clear" appearance style to the document in the "Appearance Browser" palette before running the code."

 

I don't access the Appearance Brower palette at all; would I NEED to do something with the Appearance Brower or fear unreliable/contaminated data from Leaf Occurrences?

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report