Hey
I'm using the RangeBox method to return the XYZ values of some parts. My problem with this is that if the part was angled, I do not get the correct XYZ but instead, I get XYZ of the angled part as if it was flat. Hard to explain but let's say for example the part was 10" x 10" x 1". that's the RB set of values but if the same part was angled at 45 degrees, I then get something like 10" x 10" x 5"...
is there a method of routine available that would allow me to obtain the true XYX even if the part wasnt laid flat or angled?
thanks
Nacho
Nacho
Automation & Design Engineer
Inventor Programmer (C#, VB.Net / iLogic)
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Solved! Go to Solution.
Solved by Curtis_Waguespack. Go to Solution.
Solved by dba78. Go to Solution.
Solved by DRoam. Go to Solution.
Are you getting the range box of the component or the component definition?
Dim compOcc = Component.InventorComponent("Layout") 'you part name here Dim RBAssy As Box = compOcc.RangeBox Dim RBDef As Box = compOcc.Definition.RangeBox MessageBox.Show("RBAssy X = " & RBAssy.MaxPoint.X - RBAssy.MinPoint.X & " Y = " & RBAssy.MaxPoint.Y - RBAssy.MinPoint.Y & " Z = " & RBAssy.MaxPoint.Z - RBAssy.MinPoint.Z & vbCr _ & "RBDef X = " & RBDef.MaxPoint.X - RBDef.MinPoint.X & " Y = " & RBDef.MaxPoint.Y - RBDef.MinPoint.Y & " Z = " & RBDef.MaxPoint.Z - RBDef.MinPoint.Z, "Title")
Hi
i am getting the size from the ComponentDefinition. In your code, this doesnt appear to be part of the API
Dim compOcc = Component.InventorComponent("Layout") 'you part name here
i cant find anything related to Component or InventorComponent("") as you describe.
here is my current code that returns X, Y or Z dependent on what values i need
Private Function GetPartSize(oDoc As Document, axis As String) As Double Dim i As Long Dim rangeBox As Box Dim pxMin As Double, pyMin As Double, pzMin As Double Dim pxMax As Double, pyMax As Double, pzMax As Double Dim PartSizeX As Double, PartSizeY As Double, PartSizeZ As Double Dim oCompDef As ComponentDefinition Set oCompDef = oDoc.ComponentDefinition Dim oBox As Box Set oBox = oCompDef.rangeBox With oBox pxMin = .MinPoint.x: pyMin = .MinPoint.y: pzMin = .MinPoint.z pxMax = .MaxPoint.x: pyMax = .MaxPoint.y: pzMax = .MaxPoint.z End With Dim oUOM As UnitsOfMeasure Set oUOM = oDoc.UnitsOfMeasure PartSizeX = oUOM.ConvertUnits((pxMax - pxMin), kCentimeterLengthUnits, oUOM.LengthUnits) PartSizeY = oUOM.ConvertUnits((pyMax - pyMin), kCentimeterLengthUnits, oUOM.LengthUnits) PartSizeZ = oUOM.ConvertUnits((pzMax - pzMin), kCentimeterLengthUnits, oUOM.LengthUnits) Select Case axis Case "X" GetPartSize = SizeSort(2) Case "Y" GetPartSize = SizeSort(1) Case "Z" GetPartSize = SizeSort(0) End Select 'Set oDoc = Nothing End Function
but this doesnt return the true XYZ values, it returns the XYS of the rangebox which can be different based on the position / angle of the part
Thanks
Nacho
Automation & Design Engineer
Inventor Programmer (C#, VB.Net / iLogic)
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
My code was iLogic. Are you looking to figure out the size of the whole assembly or a part in the assembly?
This should help explain what you're seeing.
http://modthemachine.typepad.com/my_weblog/2017/06/getting-the-overall-size-of-parts.html
Try this... it defaults to using the first occurrence origin to orientate the assembly
Private Function GetPartSize(oDoc As Document, axis As String) As Double Dim i As Long Dim rangeBox As Box Dim pxMin As Double, pyMin As Double, pzMin As Double Dim pxMax As Double, pyMax As Double, pzMax As Double Dim PartSizeX As Double, PartSizeY As Double, PartSizeZ As Double Dim oCompDef As ComponentDefinition Set oCompDef = oDoc.ComponentDefinition Dim oOcc As ComponentOccurrence Set oOcc = oCompDef.Occurrences.Item(1) Dim oTransMatrix As Matrix Set oTransMatrix = oOcc.Transformation Dim oBox As Box Set oBox = oCompDef.rangeBox Dim NewMax As Point Dim NewMin As Point Set NewMax = oBox.MaxPoint Set NewMin = oBox.MinPoint Call NewMax.TransformBy(oTransMatrix) Call NewMin.TransformBy(oTransMatrix) pxMin = NewMin.x: pyMin = NewMin.y: pzMin = NewMin.Z pxMax = NewMax.x: pyMax = NewMax.y: pzMax = NewMax.Z Dim oUOM As UnitsOfMeasure Set oUOM = oDoc.UnitsOfMeasure PartSizeX = oUOM.ConvertUnits((pxMax - pxMin), kCentimeterLengthUnits, oUOM.LengthUnits) PartSizeY = oUOM.ConvertUnits((pyMax - pyMin), kCentimeterLengthUnits, oUOM.LengthUnits) PartSizeZ = oUOM.ConvertUnits((pzMax - pzMin), kCentimeterLengthUnits, oUOM.LengthUnits) Debug.Print (PartSizeX & " " & PartSizeY & " " & PartSizeZ) Select Case axis Case "X" GetPartSize = PartSizeX Case "Y" GetPartSize = PartSizeY Case "Z" GetPartSize = PartSizeZ End Select 'Set oDoc = Nothing End Function
Edit: never-mind this post. I was thinking on my drive home and realized that I'm only turning the box that is already the wrong size. This isn't going to work at all
Hey Clutsa
i am only really interested in getting the part sizes for a cut list
Thanks
Nacho
Automation & Design Engineer
Inventor Programmer (C#, VB.Net / iLogic)
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
Hey Brian
i had already found this post thanks and tried the coding which sort of results the same as my current method. In the post its mentioned that a user input to select the orientation could work so, i wondered if it would be worth exploring a method to loop through the edges and select the longest to make that selection? Obviously it would still have its pitfalls with some shapes but as we mainly work with flat panels, it certainly would suffice
thoughts?
Nacho
Nacho
Automation & Design Engineer
Inventor Programmer (C#, VB.Net / iLogic)
Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
@NachitoMax wrote:
...exploring a method to loop through the edges and select the longest to make that selection...
Hi @NachitoMax,
Here is a quick iLogic snippet to select the longest edge of a body. I'm not sure how you were thinking of using it once identified/selected though. Do you have more info?
I hope this helps.
Best of luck to you in all of your Inventor pursuits,
Curtis
http://inventortrenches.blogspot.com
' Get the active document. This assumes it is a part document. Dim oPartDoc As PartDocument oPartDoc = ThisApplication.ActiveDocument Dim oCompDef As PartComponentDefinition oCompDef = oPartDoc.ComponentDefinition Dim oBodies As ObjectCollection oBodies = ThisApplication.TransientObjects.CreateObjectCollection oBody = oCompDef.SurfaceBodies(1) 'add body to collection oBodies.Add (oBody) Dim oEdges as Edges oEdges = oBody.Edges oMaxLength = 0 Dim oMaxEdge As Edge For Each oEdge In oEdges oLength = ThisApplication.MeasureTools.GetMinimumDistance(oEdge.StartVertex, oEdge.StopVertex) If oLength > oMaxLength Then oMaxEdge = oEdge oMaxLength = oLength End If Next 'select the edge oPartDoc.SelectSet.Select(oMaxEdge)
Hi @NachitoMax
I messed around with this a bit and came up with this example.
Note that I ran it on a simple assembly file that was created from a Multibody base model using the Make Components tool to populate the assembly.
It looks at each occurrence in the assembly and does this:
Then it opens the BOM editor (I didn't see a way to add the custom iprop to BOM view, so that needs to be done manually (unless I missed something).
Note that I didn't test it much, so it might trip over sheet metal files, sub assemblies, Virtual Components, etc.... but it's something to start with.
I hope this helps.
Best of luck to you in all of your Inventor pursuits,
Curtis
http://inventortrenches.blogspot.com
' Get the active document. This assumes it is a part document. Dim oAsmCompDef As AssemblyComponentDefinition oAsmCompDef = ThisApplication.ActiveDocument.ComponentDefinition ' Set a reference to the transient geometry object. Dim oTG As TransientGeometry oTG = ThisApplication.TransientGeometry Dim oMatrix As Matrix oMatrix = oTG.CreateMatrix 'Iterate through all of the occurrences Dim oOccurrence As ComponentOccurrence For Each oOccurrence In oAsmCompDef.Occurrences.AllReferencedOccurrences(oAsmCompDef) 'insert new occurence Dim oOcc1 As ComponentOccurrence oOcc1 = oAsmCompDef.Occurrences.Add( _ oOccurrence.Definition.Document.FullFileName, oMatrix) 'rename occurence incase error causes it to 'be left behind oOcc1.Name = "iLogic_Temporary_Component_Remove_As_Needed |" & oOcc1.Name 'get the longest edge on the component Dim oMaxEdge As EdgeProxy oOcc1.Grounded = False oMaxLength = 0 For Each oEdge In oOcc1.SurfaceBodies(1).Edges oLengthValue = ThisApplication.MeasureTools.GetMinimumDistance( _ oEdge.StartVertex, oEdge.StopVertex) If oLengthValue > oMaxLength Then oMaxEdge = oEdge oMaxLength = oLengthValue End If Next 'get the 2 faces that include the longest edge oFaces = oMaxEdge.Faces 'create a face proxy for the first face Dim oAsmFace1 As FaceProxy Dim oFace1 As FaceProxy oFace1 = oFaces.Item(1) Call oOcc1.CreateGeometryProxy(oFace1, oAsmFace1) 'create a face proxy for the second face Dim oAsmFace2 As FaceProxy Dim oFace2 As FaceProxy oFace2 = oFaces.Item(2) Call oOcc1.CreateGeometryProxy(oFace2, oAsmFace2) 'create work plane proxies Dim oAsmPlane1 As WorkPlane Dim oAsmPlane2 As WorkPlane oAsmPlane1 = oAsmCompDef.WorkPlanes.Item(1) 'Assembly YZ Plane oAsmPlane2 = oAsmCompDef.WorkPlanes.Item(2) 'Assembly XZ Plane 'constrain the occurence to the assembly origin workplanes oConstraint1 = oAsmCompDef.Constraints.AddMateConstraint(oAsmFace1, oAsmPlane1, 0) oConstraint2 = oAsmCompDef.Constraints.AddMateConstraint(oAsmFace2, oAsmPlane2, 0) ' Create a new part, invisibly. Dim oTempDoc As PartDocument oTempDoc = ThisApplication.Documents.Add(DocumentTypeEnum.kPartDocumentObject, _ ThisApplication.FileManager.GetTemplateFile(kPartDocumentObject), False) 'get the first solid body in the occurence document Dim oBody As SurfaceBody oBody = oOcc1.Definition.Document.ComponentDefinition.SurfaceBodies.Item(1) oMatrix = oOcc1.Transformation 'copy the solid from the assembly occurence to the temporary file 'in the constrained orientation Call oTempDoc.ComponentDefinition.Features.NonParametricBaseFeatures.Add(oBody, oMatrix) 'get the range box oBox = oTempDoc.ComponentDefinition.SurfaceBodies.Item(1).RangeBox 'Get active document unit of measure Dim oUOM As UnitsOfMeasure oUOM = oOccurrence.Definition.Document.UnitsOfMeasure 'Converts length unit to a string Dim oUnits As String = oUOM.GetStringFromType(oUOM.LengthUnits) 'converts the units string If oUnits = "centimeter" Then oUnits = " cm" Else If oUnits = "millimeter" Then oUnits = " mm" Else If oUnits = "inch" Then oUnits = Chr(34) Else If oUnits = "foot" Then oUnits = " ft" Else If oUnits = "meter" Then oUnits = " m" End If 'get the range box's max point Dim oMax As point oMax = oBox.MaxPoint 'get the range box's min point Dim oMin As point oMin = oBox.MinPoint 'convert the value from Inventor's internal cm 'To the Umits Of Measure Of the orginal component file X = oUOM.ConvertUnits ((oMax.X - oMin.X), "cm", oUOM.LengthUnits) Y = oUOM.ConvertUnits ((oMax.Y - oMin.Y), "cm", oUOM.LengthUnits) Z = oUOM.ConvertUnits ((oMax.Z - oMin.Z), "cm", oUOM.LengthUnits) 'figure out which is length, width and thickness Dim oLength As Double = MaxOfMany (X,Y,Z) & " " Dim oWidth As Double = X + Y + Z - MaxOfMany (X,Y,Z) - MinOfMany(X,Y,Z) & " " Dim oThick As Double = MinOfMany (X,Y,Z) & " " 'round values Dim oDecimals As Integer = 3 oLength = Round(oLength,oDecimals) oWidth = Round(oWidth,oDecimals) oThick = Round(oThick,oDecimals) 'create string value oSize = oThick & oUnits & " x " & oWidth & oUnits & " x " & oLength & oUnits 'set custom iproperty in the component file iProperties.Value(oOccurrence.Name,"Custom", "Size") = oSize 'delete the temporariily constrained occurence oOcc1.Delete 'close the temporary new part file oTempDoc.Close Next 'occurence 'Open BOM editor dialog box Dim oCtrlDef As ControlDefinition oCtrlDef = ThisApplication.CommandManager.ControlDefinitions.Item("AssemblyBillOfMaterialsCmd") oCtrlDef.Execute
So I would like to add a little "swing" so to speak in this. We thought we could get piece size information from a drawing view by measuring the view width and height and doing some conversions with the scale. This is how we where getting by with having to deal with the rotation, axis, etc.. because our parts are rarely put on a drawing in the same direction they are modeled. This works well for some, however when you start putting full rounds, fillets, etc.. and radial type work the view dimension isn't technically accurate to what you would have as a result of placing a dimension on the drawing for say the length of the piece. Anyone have any suggestions and pointers to get this information without having to go through all the hoops of setting up custom planes/rotations, etc.. We run through 100's of custom parts a day and so are just trying to come up with a way to automate the dimensional display of the L, H, Thickness of a piece on our production tickets.
Coming here from this idea thread where @kmiller and I were talking about how this could be done.
One possible solution I threw out there was this: for any non-aligned parts, create a UCS that's aligned with the part's orientation, then have an iLogic rule in the part which would fire whenever its geometry changes, which does some Move Body commands to get the part aligned with the WCS, then captures the extents, then reverts the part back to its normal orientation.
Attached is a dataset (in Inventor 2017 format) that demonstrates just that. Now, this is extremely messy... the code, that is (although the models are messy, too ). It works, but as nothing more than a proof of concept. If you tried using the code on a different Derived part, it may run without errors, but it would probably rotate the part in all the wrong directions and spit out the wrong dimensions. However, I think someone more skilled with the mathematics of coordinate system transformations than I am could get it to be fully robust.
To test it out, open up "Unaligned Derived Part" and run the rule in it. It should spit out some measurements for the extents. They should correspond to the dimensions of the part, to a pretty high degree of accuracy.
Then, open "Multibody Master", change the dimensions of the part, then go back to the Unaligned Derived Part and hit update. It should spit out the correct new dimensions of the part.
If you want to see better what it's doing, open up the code and un-comment the MessageBox near the end. Then you'll be able to see the series of Move Body transformations it's used to get the part aligned with the WCS.
Not sure how useful this is, even if it can be made fully robust, because you still have to manually create a UCS for each un-aligned part...
@kmiller, is that a deal-breaker for you? Or is this worth investigating further?
Hi,
i have one simple (but not entirely correct) solution for that issue.. change all your model into sheetmetal and uncheck thickness from rule. Then you can use flat pattern extens + z dimmension. Flat pattern is always oriented along longest edge.
Of course uou will get big disadvantage because it will complicate recognision if part is sheet metal part, but you can accomplish it using check if thickness is from rule and if it match to z dimmension of flat pattern, or you can give some additional marking or check parent template.
One of companies i work do it this way and they are satisfied from this approach.
The UCS may be the way we need to go. Sorry I was out at Autodesk University this past week. If you haven't ever gone, I recommend that you do. 🙂 I am going to review what you have going on an posted for proof of concept. I also have another resource I can ask in terms of a solution which spiked this whole discussion for us in the first place.
I will also review the post about the sheet metal thickness. But I don't think that is going to help us at all. Worth a look at though.
Thanks everyone for your suggestions in this and all other posts. I will be sure to let you know what we ended up doing.
Very exciting news -- this was implemented in Inventor 2020.3! It was added very quietly for some reason -- I haven't seen an announcement or release note regarding it anywhere. But it works perfectly!
It should be available in 2020.3 and all later versions (2021+). The method to use is SurfaceBody.OrientedMinimumRangeBox. Here's a usage example:
' Get the current Part document.
Dim partDoc As PartDocument = ThisDoc.Document
' Get surface body to measure (assume it's the first body).
Dim body1 As SurfaceBody = partDoc.ComponentDefinition.SurfaceBodies.Item(1)
' Get the oriented mininum range box of the body.
' NOTE: "OrientedMinimumRangeBox" was added in Inventor 2020.3/2021.
Dim minBox As OrientedBox = body1.OrientedMinimumRangeBox
' Get length of each side of mininum range box.
Dim dir1 As Double = minBox.DirectionOne.Length
Dim dir2 As Double = minBox.DirectionTwo.Length
Dim dir3 As Double = minBox.DirectionThree.Length
' Convert lengths to document's length units.
Dim uom As UnitsOfMeasure = partDoc.UnitsOfMeasure
dir1 = uom.ConvertUnits(dir1, "cm", uom.LengthUnits)
dir2 = uom.ConvertUnits(dir2, "cm", uom.LengthUnits)
dir3 = uom.ConvertUnits(dir3, "cm", uom.LengthUnits)
' Sort lengths from smallest to largest.
Dim lengths As New List(Of Double) From {dir1, dir2, dir3 }
lengths.Sort
Dim minLength As Double = lengths(0)
Dim midLength As Double = lengths(1)
Dim maxLength As Double = lengths(2)
' Display minimum rangebox size.
MessageBox.Show("Oriented Minimum Rangebox Size: " &
minLength.ToString("#.###") & " x " & midLength.ToString("#.###") & " x " & maxLength.ToString("#.###"),
"Oriented Minimum Rangebox", MessageBoxButtons.OK, MessageBoxIcon.Information)
This works perfectly for getting the actual size of parts that were modeled skewed relative to the origin, either by accident or due to for skeletal modeling workflows.
Many thanks to Autodesk for getting this implemented! And feel free to brag a bit more about things like this 😉
That's great news. Whenever we finally get around to upgrading (still stuck on 2018 for various reasons), this will be a nice bonus. At my company, we have an illogic-based system for our part descriptions that works very well for parts that are parallel to the origin planes, but once you go to a part that is modelled askew, it forces you into various workarounds.
The most common is to use Move Body or Direct Edit features to reorient the part, which causes our existing rule to work properly again. However, this is an extra step. In addition to that extra work, the part (which is usually the result of multibody workflows) must then be manually constrained, adding even more extra work.
The skewed parts are a small enough minority of what we do that it isn't a major problem. But it is enough of a nuisance that I'll be glad to see a real solution to it.
Hi,
Any idea how to use this for assemblies too?
Regards,
Regards,
Arthur Knoors
Autodesk Affiliations:
Autodesk Software:Inventor Professional 2024 | Vault Professional 2022 | Autocad Mechanical 2022
Programming Skills:Vba | Vb.net (Add ins Vault / Inventor, Applications) | I-logic
Programming Examples:Drawing List!|Toggle Drawing Sheet!|Workplane Resize!|Drawing View Locker!|Multi Sheet to Mono Sheet!|Drawing Weld Symbols!|Drawing View Label Align!|Open From Balloon!|Model State Lock!
Posts and Ideas:Dimension Component!|Partlist Export!|Derive I-properties!|Vault Prompts Via API!|Vault Handbook/Manual!|Drawing Toggle Sheets!|Vault Defer Update!
! For administrative reasons, please mark a "Solution as solved" when the issue is solved !
WOW - Thanks for posting. I can't wait to check it out.
We also are stuck on 2019 as a department (due to things i can't control) but have access to 2020 and 2021 software. I don't think I would have ever found it. If anything thanks for the knowledge.
When I was looking for a macro to retrieve part dimensions (in 2018), I found an already started discussion about this here (from 2007). The math (vector and matrix) code behind the auto-orientation works like a charm. I had only to fix some issues in the code regarding design assumptions and evaluation conditions. It's a good start point in developing your own macro.
For retrieving the dimensions of an assembly, I re-used most of the code for parts. But I let the user select two pieces of geometry as reference to align the assembly correctly. It takes a user less time to select those references than the macro does analyzing all of the bodies in a large assembly.
Curtis_W in reply to: NachoUK <u+200e>10-18-2018 05:23 PM
It looks at each occurrence in the assembly and does this:
•places another occurrence of that component
•finds the longest edge
•then uses the 2 faces that share the longest edge to mate to the assembly work planes
...
@Curtis_Waguespack nbsp;_W
And one that caused some confusion amongst and opposition from our draftsmen and work preparation dept.:
Thanks for posting this new feature. As I understand your code, this is unusable for looping through bodies in multi-body parts because it results per body only (and does not take spacing between bodies into account). Still may come in handy in particular situations.
Is there anything like this for folded sheet metal parts? I tried DRoam's bit of code and it works except not with sheet metal parts even in the flat pattern.
Can't find what you're looking for? Ask the community or share your knowledge.