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: 

Ilogic move bodies

15 REPLIES 15
SOLVED
Reply
Message 1 of 16
Dopey1993
3067 Views, 15 Replies

Ilogic move bodies

Hi All,

I would like a ilogic code so that it will move the center point or the origin point of the ipt and the iam file to the center of the body through move bodies command.

 

In other words I want to be able to design the part and once completed make it symmetrical about the origin coordinates.

15 REPLIES 15
Message 2 of 16
MechMachineMan
in reply to: Dopey1993

Soooo liiiiikeeee

 

"Center of the part"?

 - What about asymmetical features?

 - are you thinking make the C.O.G. the origin? 

 - or are you thinking of making the origin the center of the envelope

 - what if the part is rotated off? do you want to do the necessary functions/math to align the part with the principal axes?
 - Again, what about a-symmetrical features?

 

 - are you wanting to do this for parts AND assemblies?

 - what if the part is bent and the center of the envelope/ COG is in space, and not located on the part?

etc.

 

Probably just better to revise your modelling standards and redo files as necessary instead of using a band-aid....


--------------------------------------
Did you find this reply helpful ? If so please use the 'Accept as Solution' or 'Like' button below.

Justin K
Inventor 2018.2.3, Build 227 | Excel 2013+ VBA
ERP/CAD Communication | Custom Scripting
Machine Design | Process Optimization


iLogic/Inventor API: Autodesk Online Help | API Shortcut In Google Chrome | iLogic API Documentation
Vb.Net/VBA Programming: MSDN | Stackoverflow | Excel Object Model
Inventor API/VBA/Vb.Net Learning Resources: Forum Thread

Sample Solutions:Debugging in iLogic ( and Batch PDF Export Sample ) | API HasSaveCopyAs Issues |
BOM Export & Column Reorder | Reorient Skewed Part | Add Internal Profile Dogbones |
Run iLogic From VBA | Batch File Renaming| Continuous Pick/Rename Objects

Local Help: %PUBLIC%\Documents\Autodesk\Inventor 2018\Local Help

Ideas: Dockable/Customizable Property Browser | Section Line API/Thread Feature in Assembly/PartsList API Static Cells | Fourth BOM Type
Message 3 of 16
Dopey1993
in reply to: MechMachineMan

These codes will give me the height width and dept of a body now I would like to, somehow take this information and move my solid body so that the origin of the part is the center of the body.

 

SyntaxEditor Code Snippet

Measure.ExtentsLength
Measure.ExtentsWidth
Measure.ExtentsHeight

I can take these codes and divided them by 2. That will give me the center of the Body.
Now I would like to take another measurement from the origin point to the center of the body. Then move that body to match the center of the body to the origin of the file.

 

I'am more concerned about a .ipt file than an .iam file for now.

 

Thank you

 

Also the COG is pointless to me at this time. I would however be interested in rotating a part so that it is parallel with the origin planes.

Message 4 of 16
MechMachineMan
in reply to: Dopey1993

There are some nice resources out there that should you how to use the bulk of the features.

 

http://help.autodesk.com/view/INVNTOR/2018/ENU/?guid=GUID-9FDC9B07-E66C-4E08-B764-7D4AD1F6B95B


--------------------------------------
Did you find this reply helpful ? If so please use the 'Accept as Solution' or 'Like' button below.

Justin K
Inventor 2018.2.3, Build 227 | Excel 2013+ VBA
ERP/CAD Communication | Custom Scripting
Machine Design | Process Optimization


iLogic/Inventor API: Autodesk Online Help | API Shortcut In Google Chrome | iLogic API Documentation
Vb.Net/VBA Programming: MSDN | Stackoverflow | Excel Object Model
Inventor API/VBA/Vb.Net Learning Resources: Forum Thread

Sample Solutions:Debugging in iLogic ( and Batch PDF Export Sample ) | API HasSaveCopyAs Issues |
BOM Export & Column Reorder | Reorient Skewed Part | Add Internal Profile Dogbones |
Run iLogic From VBA | Batch File Renaming| Continuous Pick/Rename Objects

Local Help: %PUBLIC%\Documents\Autodesk\Inventor 2018\Local Help

Ideas: Dockable/Customizable Property Browser | Section Line API/Thread Feature in Assembly/PartsList API Static Cells | Fourth BOM Type
Message 5 of 16

So for a part, this code will move the FIRST Solid Body about the origin, and not rotate it.

 

Sub Main()

    Dim oDoc As PartDocument
    oDoc = ThisApplication.ActiveDocument
    
    If oDoc Is Nothing Then
        MsgBox("No part document!" & vbCrLf & "Please open a part with solids in it for this sample to run.", vbCritical, "Autodesk Inventor")
        Exit Sub
    End If
    
    Dim oCompDef As PartComponentDefinition
    oCompDef = oDoc.ComponentDefinition
    
    If oCompDef.SurfaceBodies.Count = 0 Then
        MsgBox("No solids to move!" & vbCrLf & "Please open a part with solids in it for this sample to run.", vbCritical, "Autodesk Inventor")
        Exit Sub
    End If
    
    Dim oBodies As ObjectCollection
    oBodies = ThisApplication.TransientObjects.CreateObjectCollection
    
    ' Specify a body to move.
    oBodies.Add(oCompDef.SurfaceBodies(1))
    
    ' Create a MoveFeatureDefinition.
    Dim oMoveDef As MoveDefinition
    oMoveDef = oCompDef.Features.MoveFeatures.CreateMoveDefinition(oBodies)
    
	oRangeBox = oBodies.Item(1).RangeBox
	
	oMidX = (oRangeBox.MaxPoint.X + oRangeBox.MinPoint.X)/2
	oMidY = (oRangeBox.MaxPoint.Y + oRangeBox.MinPoint.Y)/2
	oMidZ = (oRangeBox.MaxPoint.Z + oRangeBox.MinPoint.Z)/2
    ' the move operations onto the bodies.
    Dim oFreeDrag As FreeDragMoveOperation
    oFreeDrag = oMoveDef.AddFreeDrag(-1*oMidX, -1*oMidY, -1*oMidZ)
    
    'Dim oMoveAlongRay As MoveAlongRayMoveOperation
    'oMoveAlongRay = oMoveDef.AddMoveAlongRay(oCompDef.WorkAxes(2), True, 2)
    
    'Dim oRotateAboutAxis As RotateAboutLineMoveOperation
    'oRotateAboutAxis = oMoveDef.AddRotateAboutAxis(oCompDef.WorkAxes(3), True, 0.5)
    
    ' Create the move feature.
    Dim oMoveFeature As MoveFeature
    oMoveFeature = oCompDef.Features.MoveFeatures.Add(oMoveDef)
End Sub

--------------------------------------
Did you find this reply helpful ? If so please use the 'Accept as Solution' or 'Like' button below.

Justin K
Inventor 2018.2.3, Build 227 | Excel 2013+ VBA
ERP/CAD Communication | Custom Scripting
Machine Design | Process Optimization


iLogic/Inventor API: Autodesk Online Help | API Shortcut In Google Chrome | iLogic API Documentation
Vb.Net/VBA Programming: MSDN | Stackoverflow | Excel Object Model
Inventor API/VBA/Vb.Net Learning Resources: Forum Thread

Sample Solutions:Debugging in iLogic ( and Batch PDF Export Sample ) | API HasSaveCopyAs Issues |
BOM Export & Column Reorder | Reorient Skewed Part | Add Internal Profile Dogbones |
Run iLogic From VBA | Batch File Renaming| Continuous Pick/Rename Objects

Local Help: %PUBLIC%\Documents\Autodesk\Inventor 2018\Local Help

Ideas: Dockable/Customizable Property Browser | Section Line API/Thread Feature in Assembly/PartsList API Static Cells | Fourth BOM Type
Message 6 of 16
Dopey1993
in reply to: MechMachineMan

This works great now I find my self wanting to make this code go a bit further and rotate the body by selecting face of the part of my choosing to be parallel with a plane of my choosing

Thank you!

Message 7 of 16
MechMachineMan
in reply to: Dopey1993

Having a reference face and a reference plane definitely makes it a lot easier to rotate the part. Although, you would probably end up wanting 2 faces and 2 reference planes so that you can properly align it with the first axis (ie; the one you are looking at) and then one to align it to (ie; making the rectangle parallel to the horiztonal plane instead of diamond shaped).

 

It might require some more complex matrix math to be able to make it work; haven't looked to much into the available methods, but I would think it's definitely doable.


--------------------------------------
Did you find this reply helpful ? If so please use the 'Accept as Solution' or 'Like' button below.

Justin K
Inventor 2018.2.3, Build 227 | Excel 2013+ VBA
ERP/CAD Communication | Custom Scripting
Machine Design | Process Optimization


iLogic/Inventor API: Autodesk Online Help | API Shortcut In Google Chrome | iLogic API Documentation
Vb.Net/VBA Programming: MSDN | Stackoverflow | Excel Object Model
Inventor API/VBA/Vb.Net Learning Resources: Forum Thread

Sample Solutions:Debugging in iLogic ( and Batch PDF Export Sample ) | API HasSaveCopyAs Issues |
BOM Export & Column Reorder | Reorient Skewed Part | Add Internal Profile Dogbones |
Run iLogic From VBA | Batch File Renaming| Continuous Pick/Rename Objects

Local Help: %PUBLIC%\Documents\Autodesk\Inventor 2018\Local Help

Ideas: Dockable/Customizable Property Browser | Section Line API/Thread Feature in Assembly/PartsList API Static Cells | Fourth BOM Type
Message 8 of 16
Dopey1993
in reply to: MechMachineMan

SyntaxEditor Code Snippet

Sub Main()

    Dim oDoc As PartDocument
    oDoc = ThisApplication.ActiveDocument
    
    If oDoc Is Nothing Then
        MsgBox("No part document!" & vbCrLf & "Please open a part with solids in it for this sample to run.", vbCritical, "Autodesk Inventor")
        Exit Sub
    End If
    
    Dim oCompDef As PartComponentDefinition
    oCompDef = oDoc.ComponentDefinition
    
    If oCompDef.SurfaceBodies.Count = 0 Then
        MsgBox("No solids to move!" & vbCrLf & "Please open a part with solids in it for this sample to run.", vbCritical, "Autodesk Inventor")
        Exit Sub
    End If
    
    Dim oBodies As ObjectCollection
    oBodies = ThisApplication.TransientObjects.CreateObjectCollection
    
    ' Specify a body to move.
    oBodies.Add(oCompDef.SurfaceBodies(1))
    
    ' Create a MoveFeatureDefinition.
    Dim oMoveDef As MoveDefinition
    oMoveDef = oCompDef.Features.MoveFeatures.CreateMoveDefinition(oBodies)
    
    oRangeBox = oBodies.Item(1).RangeBox
    
    oMidX = (oRangeBox.MaxPoint.X + oRangeBox.MinPoint.X)/2
    oMidY = (oRangeBox.MaxPoint.Y + oRangeBox.MinPoint.Y)/2
    oMidZ = (oRangeBox.MaxPoint.Z + oRangeBox.MinPoint.Z)/2
    ' the move operations onto the bodies.
    Dim oFreeDrag As FreeDragMoveOperation
    oFreeDrag = oMoveDef.AddFreeDrag(-1*oMidX, -1*oMidY, -1*oMidZ)

    
    
    
    
    oRangeBox = oBodies.Item(2).RangeBox
    
    oPlane1 = (oRangeBox.ReferenceParameter.Name(ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAllPlanarEntities, "Select Reference Plane 1:")))
    oPlane2 = (oRangeBox.ReferenceParameter.Name(ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAllPlanarEntities, "Select Reference Plane 2:")))
    oFace1 = (oRangeBox.ReferenceParameter.Name(ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAllPlanarEntities, "Select Reference Face 3:")))
    oFace2 = (oRangeBox.ReferenceParameter.Name(ThisApplication.CommandManager.Pick(SelectionFilterEnum.kAllPlanarEntities, "Select Reference Face 3:")))
    
     
    Dim oMoveAlongRay As MoveAlongRayMoveOperation
    oMoveAlongRay = oMoveDef.AddMoveAlongRay(oCompDef.WorkAxes(3), True, 2)
    
    Dim oRotateAboutAxis1 As RotateAboutLineMoveOperation
    oRotateAboutAxis1 = oMoveDef.AddRotateAboutAxis(oCompDef.WorkAxes(4), True, oPlane1+oFace1)
    
    
    Dim oRotateAboutAxis2 As RotateAboutLineMoveOperation
    oRotateAboutAxis2 = oMoveDef.AddRotateAboutAxis(oCompDef.WorkAxes(5), True, oPlane2+oFace2)
    
    
    
    
    
    ' Create the move feature.
    Dim oMoveFeature As MoveFeature
    oMoveFeature = oCompDef.Features.MoveFeatures.Add(oMoveDef)
End Sub

 

  receiving this error

 

Error in rule: Rule0, in document: Part5

The parameter is incorrect. (Exception from HRESULT: 0x80070057 (E_INVALIDARG))

 

 

 

Not sure what wrong. but I think this is close to what I want. 

 

Message 9 of 16
MechMachineMan
in reply to: Dopey1993

Sounds like it's time for debugging!

 

Either convert it to vba so you can step through lines to debug,

 

Or start at line (1), write MsgBox("here"). Run code. if you see the message box, you know the error occurs below there.

 

Find what line gives you errors and report back.

 

Good luck!


--------------------------------------
Did you find this reply helpful ? If so please use the 'Accept as Solution' or 'Like' button below.

Justin K
Inventor 2018.2.3, Build 227 | Excel 2013+ VBA
ERP/CAD Communication | Custom Scripting
Machine Design | Process Optimization


iLogic/Inventor API: Autodesk Online Help | API Shortcut In Google Chrome | iLogic API Documentation
Vb.Net/VBA Programming: MSDN | Stackoverflow | Excel Object Model
Inventor API/VBA/Vb.Net Learning Resources: Forum Thread

Sample Solutions:Debugging in iLogic ( and Batch PDF Export Sample ) | API HasSaveCopyAs Issues |
BOM Export & Column Reorder | Reorient Skewed Part | Add Internal Profile Dogbones |
Run iLogic From VBA | Batch File Renaming| Continuous Pick/Rename Objects

Local Help: %PUBLIC%\Documents\Autodesk\Inventor 2018\Local Help

Ideas: Dockable/Customizable Property Browser | Section Line API/Thread Feature in Assembly/PartsList API Static Cells | Fourth BOM Type
Message 10 of 16
Dopey1993
in reply to: MechMachineMan

Ok! I decided to try and simplify what I am trying to do I'm getting it to rotate, But when I use ilogic to measure the angle it spit out a CRAZY number.

 

I don't understand how it getting that number.

 

I know this is not exactly what I asked for but if I can get this to work exactly like I want it to its one step closer.

 

Here is the file I have 2 separate codes one moves the body and the other one put the measured angle in the description of the part witch is right but when I use the same code it when i rotate the part it come up with something completely different.

 

BTW sorry for the late response I have only been working on this on my free time.

 

Capture.PNGCapture1.PNG

Message 11 of 16
MechMachineMan
in reply to: Dopey1993

1. Initialize + declare variables properly

 

Dim angle As Decimal
angle = 0 

OR

Dim angle As Double
angle = 0
'Do things

2. Ensure you are converting units properly from/to database units.

 

Inventor's database units for angles is: RADIANS.

Therefore

Angle (degrees) = Angle (radians) x (180/pi)

This conversion factor is approximately 57.29578.

Further database unit reading:

    http://help.autodesk.com/view/INVNTOR/2018/ENU/?guid=GUID-60CADB1E-DB85-4A7D-8380-7C4FFFE558D8


--------------------------------------
Did you find this reply helpful ? If so please use the 'Accept as Solution' or 'Like' button below.

Justin K
Inventor 2018.2.3, Build 227 | Excel 2013+ VBA
ERP/CAD Communication | Custom Scripting
Machine Design | Process Optimization


iLogic/Inventor API: Autodesk Online Help | API Shortcut In Google Chrome | iLogic API Documentation
Vb.Net/VBA Programming: MSDN | Stackoverflow | Excel Object Model
Inventor API/VBA/Vb.Net Learning Resources: Forum Thread

Sample Solutions:Debugging in iLogic ( and Batch PDF Export Sample ) | API HasSaveCopyAs Issues |
BOM Export & Column Reorder | Reorient Skewed Part | Add Internal Profile Dogbones |
Run iLogic From VBA | Batch File Renaming| Continuous Pick/Rename Objects

Local Help: %PUBLIC%\Documents\Autodesk\Inventor 2018\Local Help

Ideas: Dockable/Customizable Property Browser | Section Line API/Thread Feature in Assembly/PartsList API Static Cells | Fourth BOM Type
Message 12 of 16
Dopey1993
in reply to: MechMachineMan

I have made a lot of progress however I don't understand what exactly its doing?

 

Thank you!

Message 13 of 16
MechMachineMan
in reply to: Dopey1993

Yeah... The physics of it gets very convoluted when dealing with complex rotations, and your code doesn't handle that.

 

Either you need to create a 3rd axis that is perpendicular to the 2 planes that the normals lie on to use as your basis of rotation, or you need to use projects to establish exactly how much you need to rotate it about the specified origin axes.

 

There is definitely a lot more math to figure out than what you have currently, which is necessary for being able to get the code up and running properly.


--------------------------------------
Did you find this reply helpful ? If so please use the 'Accept as Solution' or 'Like' button below.

Justin K
Inventor 2018.2.3, Build 227 | Excel 2013+ VBA
ERP/CAD Communication | Custom Scripting
Machine Design | Process Optimization


iLogic/Inventor API: Autodesk Online Help | API Shortcut In Google Chrome | iLogic API Documentation
Vb.Net/VBA Programming: MSDN | Stackoverflow | Excel Object Model
Inventor API/VBA/Vb.Net Learning Resources: Forum Thread

Sample Solutions:Debugging in iLogic ( and Batch PDF Export Sample ) | API HasSaveCopyAs Issues |
BOM Export & Column Reorder | Reorient Skewed Part | Add Internal Profile Dogbones |
Run iLogic From VBA | Batch File Renaming| Continuous Pick/Rename Objects

Local Help: %PUBLIC%\Documents\Autodesk\Inventor 2018\Local Help

Ideas: Dockable/Customizable Property Browser | Section Line API/Thread Feature in Assembly/PartsList API Static Cells | Fourth BOM Type
Message 14 of 16
MechMachineMan
in reply to: Dopey1993

Give this behemoth a whirl. Please note that it is a macro, so you will need to use the vba environment to run it.

 

From there you can add it to keyboard shortcuts to make it work, or run it from the Macro Menu.

 

What the rule does is force you to select 2 orthogonal faces and aligns the first one with the xy plane, and the 2nd one with the xz plane.

 

Sub Main()

    Dim oDoc As PartDocument
    Set oDoc = ThisApplication.ActiveDocument
    
    If oDoc Is Nothing Then
        MsgBox "No part document!" & vbCrLf & "Please open a part with solids in it for this sample to run.", vbCritical, "Autodesk Inventor"
        Exit Sub
    End If
    
    Dim oCompDef As PartComponentDefinition
    Set oCompDef = oDoc.ComponentDefinition
    
    If oCompDef.SurfaceBodies.Count = 0 Then
        MsgBox "No solids to move!" & vbCrLf & "Please open a part with solids in it for this sample to run.", vbCritical, "Autodesk Inventor"
        Exit Sub
    End If
    
    Dim oBodies As ObjectCollection
    Set oBodies = ThisApplication.TransientObjects.CreateObjectCollection
    
    ' Specify a body to move.
    oBodies.Add oCompDef.SurfaceBodies(1)
    
    Call RotatePart(oCompDef, oBodies)
    
    oBodies.Clear
    oBodies.Add oCompDef.SurfaceBodies(1)
    Call MovePart(oCompDef, oBodies)
   
End Sub


    Sub RotatePart(ByVal oCompDef As ComponentDefinition, ByVal oBodies As ObjectCollection)
        'http://adndevblog.typepad.com/manufacturing/2012/08/what-is-the-best-way-to-compute-a-normal-of-a-face-in-inventor-api.html
        ' Create a MoveFeatureDefinition.
        Dim oMoveDef As MoveDefinition
        Set oMoveDef = oCompDef.Features.MoveFeatures.CreateMoveDefinition(oBodies)
        
        Dim Face1 As Face
        Dim Face2 As Face
    
        Dim boolFace1IsPlane As Boolean
        boolFace1IsPlane = False
        
        Do
           Set Face1 = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartFaceFilter, "Pick FACE to align with XY Plane (FRONT)")
           If (TypeOf Face1.Geometry Is Plane) Then
               boolFace1IsPlane = True
           End If
        Loop Until boolFace1IsPlane
    
        Dim oFace1Normal As Vector
        Set oFace1Normal = ThisApplication.TransientGeometry.CreateVector()
        Set oFace1Normal = GetFaceNormal(Face1)
    
        Dim boolFace2IsPlane As Boolean
        boolFace2IsPlane = False
        Dim boolPlanesat90 As Boolean
        boolPlanesat90 = False
        
        Dim oFace2Normal As Vector
        Set oFace2Normal = ThisApplication.TransientGeometry.CreateVector()
    
        Do
            boolFace2IsPlane = False
            Do
               Set Face2 = ThisApplication.CommandManager.Pick(SelectionFilterEnum.kPartFaceFilter, "Pick FACE to align with XZ Plane (TOP)")
               If (TypeOf Face2.Geometry Is Plane) Then
                   boolFace1IsPlane = True
               End If
            Loop Until boolFace1IsPlane
    
            Set oFace2Normal = GetFaceNormal(Face2)
    
            'Perpindicular vectors have dot product of zero.
            'Need to handle round of errors in doing the large vectors maths
            If VBA.Round(oFace1Normal.DotProduct(oFace2Normal), 8) = 0 Then
                boolPlanesat90 = True
            End If
    
        Loop Until boolPlanesat90
    
        Dim oYZPlane As WorkPlane
        Dim oXZPlane As WorkPlane
        Dim oXYPlane As WorkPlane
        Set oYZPlane = oCompDef.WorkPlanes.Item(1)
        Set oXZPlane = oCompDef.WorkPlanes.Item(2)
        Set oXYPlane = oCompDef.WorkPlanes.Item(3)
        
        Dim oXAxis As WorkAxis
        Set oXAxis = oCompDef.WorkAxes(1)
        Dim oYAxis As WorkAxis
        Set oYAxis = oCompDef.WorkAxes(2)
        Dim oZAxis As WorkAxis
        Set oZAxis = oCompDef.WorkAxes(3)
        
       'Perform first rotation to align with coord system
       Dim oRotationAngle As Double
       oRotationAngle = GetRotationAngleAboutAxisToPlane(oFace1Normal, oXAxis, oXYPlane)
        'oRotationAngle = GetRotationAngleAboutAxisToPlane(ThisApplication.TransientGeometry.CreateVector(oFace1Normal.X, oFace1Normal.Y, oFace1Normal.Z), oXAxis, oXYPlane)
        
        Dim oRotateAboutAxis As RotateAboutLineMoveOperation
        Set oRotateAboutAxis = oMoveDef.AddRotateAboutAxis(oXAxis, True, oRotationAngle)
        
            Dim oRes1Vector As Vector
            Set oRes1Vector = ThisApplication.TransientGeometry.CreateVector()
            Set oRes1Vector = RotateVectorAboutAnotherVector(oRotationAngle, oFace1Normal, ThisApplication.TransientGeometry.CreateVector(oXAxis.Line.Direction.X, oXAxis.Line.Direction.Y, oXAxis.Line.Direction.Z))
            
            Dim oRes1UpVector As Vector
            Set oRes1UpVector = ThisApplication.TransientGeometry.CreateVector()
            Set oRes1UpVector = RotateVectorAboutAnotherVector(oRotationAngle, oFace2Normal, ThisApplication.TransientGeometry.CreateVector(oXAxis.Line.Direction.X, oXAxis.Line.Direction.Y, oXAxis.Line.Direction.Z))
        
       'Perform 2nd rotation to align with coord system
        'oRotationAngle = GetRotationAngleAboutAxisToPlane(oFace1Normal, oYAxis, oXYPlane)
        oRotationAngle = GetRotationAngleAboutAxisToPlane(oRes1Vector, oYAxis, oXYPlane)
        Set oRotateAboutAxis = oMoveDef.AddRotateAboutAxis(oYAxis, True, oRotationAngle)
            
            Dim oRes2UpVector As Vector
            Set oRes2UpVector = ThisApplication.TransientGeometry.CreateVector()
            Set oRes2UpVector = RotateVectorAboutAnotherVector(oRotationAngle, oRes1UpVector, ThisApplication.TransientGeometry.CreateVector(oYAxis.Line.Direction.X, oYAxis.Line.Direction.Y, oYAxis.Line.Direction.Z))
       'Perform 3rd rotation to get Upvector oriented properly.
        oRotationAngle = GetRotationAngleAboutAxisToPlane(oRes2UpVector, oZAxis, oXZPlane)
        Set oRotateAboutAxis = oMoveDef.AddRotateAboutAxis(oZAxis, True, oRotationAngle)
        
        Dim oMoveFeature As MoveFeature
        Set oMoveFeature = oCompDef.Features.MoveFeatures.Add(oMoveDef)
    End Sub

        Function GetFaceNormal(ByVal oFace As Object) As Vector
            Dim oNormal As Vector
            Dim Params(1 To 2) As Double
            Dim Normals(1 To 3) As Double
    
            Params(1) = 0
            Params(2) = 0
            If TypeOf oFace Is WorkPlane Then
                Call oFace.Plane.Evaluator.GetNormal(Params, Normals)
                Set oNormal = ThisApplication.TransientGeometry.CreateVector(Normals(1), Normals(2), Normals(3))
            Else
                If (TypeOf oFace.Geometry Is Plane) Then
                    'Dim oEvalFace As Face
                    'Set oEvalFace = oFace
                    Call oFace.Evaluator.GetNormal(Params, Normals)
                    Set oNormal = ThisApplication.TransientGeometry.CreateVector(Normals(1), Normals(2), Normals(3))
                End If
            End If
            Set GetFaceNormal = oNormal
        End Function

        Function GetRotationAngleAboutAxisToPlane(ByVal oVector As Vector, ByVal oAxis As WorkAxis, ByVal oWorkPlane As WorkPlane) As Double
                ''http://onlinemschool.com/math/library/vector/angl/
                'This ProjectVectorToPlane removes the 1 of the 3 components in relation to the plane.
                'IN this case, to the YZ plane, it essentially removes the X component and scales it slightly.
                
                'Verified method below also works, but gives same results as the formulaic method.
                'Dim AltProject As Vector
                'Set AltProject = ThisApplication.TransientGeometry.CreateVector(0, oFace1Normal.Y, oFace1Normal.Z)
                
                'Angle is insufficient as it doesn't have a direction.
                'Use Cross product to find the angle and direction
                ' Length of this crossproduct is actually the area of the parallellogram of A & B
                ' The vector gives the direction
                'If the vectors x component is positive, it means that we need to rotate
                'it the same direction as the x axis (ie cw), and if its negative, we rotate it the negative direction
                
                Dim oLineDir As Variant
                Set oLineDir = oAxis.Line.Direction
                'oLine.Direction (oCoords)
                Dim oAxisVector As Vector
                Set oAxisVector = ThisApplication.TransientGeometry.CreateVector(oLineDir.X, oLineDir.Y, oLineDir.Z)
                
                'oRotationAngle = AltProject.AngleTo(oYVector)
                Dim oProjVec As Vector
                Set oProjVec = ThisApplication.TransientGeometry.CreateVector()
                
                'Project to plane perpindicular to plane
                Set oProjVec = ProjectVectorToPerpindicularPlaneOfAnAxis(oVector, oAxisVector)
                
                'Get the
                Dim oWorkPlaneNormal As Vector
                Set oWorkPlaneNormal = ThisApplication.TransientGeometry.CreateVector()
                Set oWorkPlaneNormal = GetFaceNormal(oWorkPlane)
            
                Dim oCrossProductVector As Vector
                Set oCrossProductVector = ThisApplication.TransientGeometry.CreateVector
                Set oCrossProductVector = oWorkPlaneNormal.CrossProduct(oProjVec)
            
                oAngle = ArcSin(oCrossProductVector.Length / (oWorkPlaneNormal.Length * oProjVec.Length))
                
                rotdir = 1
                If oAxisVector.DotProduct(oCrossProductVector) > 0 Then
                    rotdir = -1
                End If
                
                GetRotationAngleAboutAxisToPlane = rotdir * oAngle
        End Function

            Function ProjectVectorToPerpindicularPlaneOfAnAxis(ByVal oVector As Vector, ByVal oPlaneNormal As Vector) As Vector
        
                'https://www.maplesoft.com/support/help/maple/view.aspx?path=MathApps%2FProjectionOfVectorOntoPlane
                'Projected vector = orig vector(term1) - (dp(u*N)/mag(n)^2)*n
        
                Dim oByValVector As Vector
                Set oByValVector = ThisApplication.TransientGeometry.CreateVector(oVector.X, oVector.Y, oVector.Z)
                
                Dim oByValPlaneNormal As Vector
                Set oByValPlaneNormal = ThisApplication.TransientGeometry.CreateVector(oPlaneNormal.X, oPlaneNormal.Y, oPlaneNormal.Z)
            
                Dim oDotproductxun As Double
                oDotproductxun = oByValVector.DotProduct(oByValPlaneNormal)
                
                If oDotproductxun <> 0 Then
                    Dim magxn As Double
                    oMagxn = oByValPlaneNormal.Length
            
                    Dim oScalarComponent As Double
                    oScalarComponent = (oDotproductxun) / (oMagxn * oMagxn)
            
                    Call oByValPlaneNormal.ScaleBy(oScalarComponent)
                    Call oByValVector.SubtractVector(oByValPlaneNormal)
                End If
                
                Set ProjectVectorToPerpindicularPlaneOfAnAxis = oByValVector
            End Function

            Function ArcSin(ByVal X As Double) As Double
                'http://cuinl.tripod.com/Tips/math9.htm
                ArcSin = Atn(X / Sqr(-X * X + 1))
            End Function


    Function RotateVectorAboutAnotherVector(ByVal oTheta As Double, ByVal oRotatingVector As Vector, ByVal oStationaryVector As Vector) As Vector
        'Let A be the rotating vector
        'Let B be the stationary vector
        Dim oVectorA As Vector
        Dim oVectorB As Vector
        Set oVectorA = ThisApplication.TransientGeometry.CreateVector(oRotatingVector.X, oRotatingVector.Y, oRotatingVector.Z)
        Set oVectorB = ThisApplication.TransientGeometry.CreateVector(oStationaryVector.X, oStationaryVector.Y, oStationaryVector.Z)
    
        Dim oMatrix As Matrix
        Set oMatrix = ThisApplication.TransientGeometry.CreateMatrix
        
        Call oMatrix.SetToRotation(oTheta, oVectorB, ThisApplication.TransientGeometry.CreatePoint(0, 0, 0))

        Call oVectorA.TransformBy(oMatrix)
        
        Set RotateVectorAboutAnotherVector = oVectorA
    End Function

Sub MovePart(ByVal oCompDef As ComponentDefinition, ByVal oBodies As ObjectCollection)
    Dim oMoveDef As MoveDefinition
    Set oMoveDef = oCompDef.Features.MoveFeatures.CreateMoveDefinition(oBodies)
    
    Set oRangeBox = oBodies.Item(1).RangeBox
    
    oMidX = (oRangeBox.MaxPoint.X + oRangeBox.MinPoint.X) / 2
    oMidY = (oRangeBox.MaxPoint.Y + oRangeBox.MinPoint.Y) / 2
    oMidZ = (oRangeBox.MaxPoint.Z + oRangeBox.MinPoint.Z) / 2


    Dim oFreeDrag As FreeDragMoveOperation
    Set oFreeDrag = oMoveDef.AddFreeDrag(-1 * oMidX, -1 * oMidY, -1 * oMidZ)

    Dim oMoveFeature As MoveFeature
    Set oMoveFeature = oCompDef.Features.MoveFeatures.Add(oMoveDef)
End Sub

--------------------------------------
Did you find this reply helpful ? If so please use the 'Accept as Solution' or 'Like' button below.

Justin K
Inventor 2018.2.3, Build 227 | Excel 2013+ VBA
ERP/CAD Communication | Custom Scripting
Machine Design | Process Optimization


iLogic/Inventor API: Autodesk Online Help | API Shortcut In Google Chrome | iLogic API Documentation
Vb.Net/VBA Programming: MSDN | Stackoverflow | Excel Object Model
Inventor API/VBA/Vb.Net Learning Resources: Forum Thread

Sample Solutions:Debugging in iLogic ( and Batch PDF Export Sample ) | API HasSaveCopyAs Issues |
BOM Export & Column Reorder | Reorient Skewed Part | Add Internal Profile Dogbones |
Run iLogic From VBA | Batch File Renaming| Continuous Pick/Rename Objects

Local Help: %PUBLIC%\Documents\Autodesk\Inventor 2018\Local Help

Ideas: Dockable/Customizable Property Browser | Section Line API/Thread Feature in Assembly/PartsList API Static Cells | Fourth BOM Type
Message 15 of 16
jtylerbc
in reply to: MechMachineMan

@MechMachineMan,

 

I stumbled across a reference to this thread in another that we both had responded to.  My company regularly uses multisolid modeling (sometimes combined with Frame Generator) for designing steel weldments.  Occasionally this involves some plates at awkward orientations, which cause trouble for some of our iLogic rules.  Currently we use the Direct Edit tools to correct the orientation of such parts, which works just fine, but this macro will definitely save us some time.

 

One limitation I came across is that the macro can't handle a cylindrical body, since it requires two faces.  The macro is certainly useful as-is, but if you have the desire to tinker with it further, adding an option that lets you select a face and an axis (instead of two faces) might be beneficial.

 

Other than that odd case, the macro seems to work very well, and is more thorough than we normally are when doing this manually (fixing not just the orientation, but actually centering the part at the origin).  Nicely done.

Message 16 of 16
MechMachineMan
in reply to: jtylerbc

I suggest temporarily exctruding a flat face on one of the round edges of the cylinder so it has a reference, then deleting the temporary extrude after (as the macro does all the calcs and inputs the rotations as a fixed value). Smiley Very Happy

 

All joking aside - even though that workaround should technically work - thanks a bunch for testing it out and getting back to me on it! If there is more interest in the macro, I may review it in the future, but at least for now the bulk of it is out in the public realm for people to tweak and use as they want.

 

 


--------------------------------------
Did you find this reply helpful ? If so please use the 'Accept as Solution' or 'Like' button below.

Justin K
Inventor 2018.2.3, Build 227 | Excel 2013+ VBA
ERP/CAD Communication | Custom Scripting
Machine Design | Process Optimization


iLogic/Inventor API: Autodesk Online Help | API Shortcut In Google Chrome | iLogic API Documentation
Vb.Net/VBA Programming: MSDN | Stackoverflow | Excel Object Model
Inventor API/VBA/Vb.Net Learning Resources: Forum Thread

Sample Solutions:Debugging in iLogic ( and Batch PDF Export Sample ) | API HasSaveCopyAs Issues |
BOM Export & Column Reorder | Reorient Skewed Part | Add Internal Profile Dogbones |
Run iLogic From VBA | Batch File Renaming| Continuous Pick/Rename Objects

Local Help: %PUBLIC%\Documents\Autodesk\Inventor 2018\Local Help

Ideas: Dockable/Customizable Property Browser | Section Line API/Thread Feature in Assembly/PartsList API Static Cells | Fourth BOM Type

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

Post to forums  

Technology Administrators


Autodesk Design & Make Report