Translating Points from Model Space to Assembly Space?

Translating Points from Model Space to Assembly Space?

Anonymous
Not applicable
618 Views
16 Replies
Message 1 of 17

Translating Points from Model Space to Assembly Space?

Anonymous
Not applicable
I'm knocking out a tool to copy componets in an Assembly.
I plan on making something more flexible than component patterns. (Lots of bells and whistles.)

I've set it up so the user select the component to copy and a Some component Edge (To define the vector to create the copies in.) I have a textbox for distance to translate along that vector.

So far my app can create the new component along the vector described (No control over distance yet.) , but it is in the component space vector.

Where I am stumbling is the the selected component edge start and end points are in the component defined Coordinate system. I need to convert that to Assembly space coordinates. (Not to mention calculating the new distance along that vector.) The goal is to create the copied component n distance from the original along the vector described.

I am having trouble locating the tools I need to do the job.

-- test code so far --
[pre]
Option Explicit

Private Sub CopyComponent(ByVal nCount As Integer)
Dim oDoc As AssemblyDocument
Dim oCompDef As AssemblyComponentDefinition
Dim oTG As TransientGeometry
Dim oSelectSet As SelectSet
Dim oMatrix As Matrix
Dim oEdge As Edge
Dim oOcc As ComponentOccurrence
Dim oOcc2 As ComponentOccurrence

Dim msg As String
Dim i As Integer

msg = "A Selected single component followed by a Selected single Edge (Vector)" & vbCrLf & _
"is required for this utility"

Set oDoc = ThisApplication.ActiveDocument
Set oSelectSet = oDoc.SelectSet

If oSelectSet.Count = 2 Then
If TypeOf oSelectSet(1) Is ComponentOccurrence Then
If TypeOf oSelectSet.Item(2) Is Edge Then
Set oOcc = oSelectSet(1)
Set oEdge = oSelectSet(2)

Set oTG = ThisApplication.TransientGeometry
Set oMatrix = oTG.CreateMatrix
Set oMatrix = oOcc.Transformation

Set oOcc2 = oDoc.ComponentDefinition.Occurrences. _
Add(oOcc.Definition.Document.fullfilename, oMatrix)

oMatrix.SetTranslation oEdge.StartVertex.Point.VectorTo(oEdge.StopVertex.Point), False
oOcc2.Transformation = oMatrix
Else
MsgBox msg
End If
Else
MsgBox msg
End If
Else
MsgBox msg
End If

Set oMatrix = Nothing
Set oOcc2 = Nothing
Set oOcc = Nothing
Set oEdge = Nothing
Set oSelectSet = Nothing
Set oTG = Nothing
Set oCompDef = Nothing
Set oDoc = Nothing
End Sub
[/pre]
0 Likes
619 Views
16 Replies
Replies (16)
Message 2 of 17

Anonymous
Not applicable
If I understand you correctly, the problem with the code is in setting up the matrix. When you call oMatrix.SetTranslation, it clears all the data that the matrix previously contained and sets it to just this translation. What you need to do is create a new 'translation' matrix and transform oMatrix by this new matrix. Try this modified code. Sanjay- [pre] Option Explicit Private Sub CopyComponent(ByVal nCount As Integer) Dim oDoc As AssemblyDocument Dim oCompDef As AssemblyComponentDefinition Dim oTG As TransientGeometry Dim oSelectSet As SelectSet Dim oMatrix As Matrix Dim oEdge As Edge Dim oOcc As ComponentOccurrence Dim oOcc2 As ComponentOccurrence Dim msg As String Dim i As Integer msg = "A Selected single component followed by a Selected single Edge (Vector)" & vbCrLf & _ "is required for this utility" Set oDoc = ThisApplication.ActiveDocument Set oSelectSet = oDoc.SelectSet If oSelectSet.Count = 2 Then If TypeOf oSelectSet(1) Is ComponentOccurrence Then If TypeOf oSelectSet.Item(2) Is Edge Then Set oOcc = oSelectSet(1) Set oEdge = oSelectSet(2) Set oTG = ThisApplication.TransientGeometry Set oMatrix = oTG.CreateMatrix Set oMatrix = oOcc.Transformation Set oOcc2 = oDoc.ComponentDefinition.Occurrences. _ Add(oOcc.Definition.Document.FullFileName, oMatrix) Dim oTranslationMatrix As Matrix Set oTranslationMatrix = oTG.CreateMatrix oTranslationMatrix.SetTranslation oEdge.StartVertex.Point.VectorTo(oEdge.StopVertex.Point), False Call oMatrix.TransformBy(oTranslationMatrix) oOcc2.Transformation = oMatrix Else MsgBox msg End If Else MsgBox msg End If Else MsgBox msg End If Set oMatrix = Nothing Set oOcc2 = Nothing Set oOcc = Nothing Set oEdge = Nothing Set oSelectSet = Nothing Set oTG = Nothing Set oCompDef = Nothing Set oDoc = Nothing End Sub [/pre] "TGroff" wrote in message news:24388019.1102967546006.JavaMail.jive@jiveforum1.autodesk.com... > I'm knocking out a tool to copy componets in an Assembly. > I plan on making something more flexible than component patterns. (Lots of bells and whistles.) > > I've set it up so the user select the component to copy and a Some component Edge (To define the vector to create the copies in.) I have a textbox for distance to translate along that vector. > > So far my app can create the new component along the vector described (No control over distance yet.) , but it is in the component space vector. > > Where I am stumbling is the the selected component edge start and end points are in the component defined Coordinate system. I need to convert that to Assembly space coordinates. (Not to mention calculating the new distance along that vector.) The goal is to create the copied component n distance from the original along the vector described. > > I am having trouble locating the tools I need to do the job. > > -- test code so far -- > [pre] > Option Explicit > > Private Sub CopyComponent(ByVal nCount As Integer) > Dim oDoc As AssemblyDocument > Dim oCompDef As AssemblyComponentDefinition > Dim oTG As TransientGeometry > Dim oSelectSet As SelectSet > Dim oMatrix As Matrix > Dim oEdge As Edge > Dim oOcc As ComponentOccurrence > Dim oOcc2 As ComponentOccurrence > > Dim msg As String > Dim i As Integer > > msg = "A Selected single component followed by a Selected single Edge (Vector)" & vbCrLf & _ > "is required for this utility" > > Set oDoc = ThisApplication.ActiveDocument > Set oSelectSet = oDoc.SelectSet > > If oSelectSet.Count = 2 Then > If TypeOf oSelectSet(1) Is ComponentOccurrence Then > If TypeOf oSelectSet.Item(2) Is Edge Then > Set oOcc = oSelectSet(1) > Set oEdge = oSelectSet(2) > > Set oTG = ThisApplication.TransientGeometry > Set oMatrix = oTG.CreateMatrix > Set oMatrix = oOcc.Transformation > > Set oOcc2 = oDoc.ComponentDefinition.Occurrences. _ > Add(oOcc.Definition.Document.fullfilename, oMatrix) > > oMatrix.SetTranslation oEdge.StartVertex.Point.VectorTo(oEdge.StopVertex.Point), False > oOcc2.Transformation = oMatrix > Else > MsgBox msg > End If > Else > MsgBox msg > End If > Else > MsgBox msg > End If > > Set oMatrix = Nothing > Set oOcc2 = Nothing > Set oOcc = Nothing > Set oEdge = Nothing > Set oSelectSet = Nothing > Set oTG = Nothing > Set oCompDef = Nothing > Set oDoc = Nothing > End Sub > [/pre]
0 Likes
Message 3 of 17

Anonymous
Not applicable
Thank you Sanjay!

That gives me a better understanding of the Transformby() method.

One further question if you please.
Is there a method to calculate a new point along a 3D vector?

That seems like it might be the easiest way for me to set the desired distance with the code I have so far.

I assume I would use the vector gleaned from my edge and say the edge starting point as input for the function.

Is there such and animal?

~T
0 Likes
Message 4 of 17

Anonymous
Not applicable
Do you need this to set the correct vector in the oTranslationMatrix.SetTranslation method? Couldn't you just derive the unit vector from the edge start & edge points and multiply this unit vector by the distance (length)? Look in Vector, UnitVector and Point objects for utilities that might help. Sanjay- "TGroff" wrote in message news:6702929.1103056855990.JavaMail.jive@jiveforum1.autodesk.com... > Thank you Sanjay! > > That gives me a better understanding of the Transformby() method. > > One further question if you please. > Is there a method to calculate a new point along a 3D vector? > > That seems like it might be the easiest way for me to set the desired distance with the code I have so far. > > I assume I would use the vector gleaned from my edge and say the edge starting point as input for the function. > > Is there such and animal? > > ~T
0 Likes
Message 5 of 17

Anonymous
Not applicable
Yes, I would like to create my new occurance offset from the original at a given distance in the direction defined by the edge. Currently the distance is being derived from the start and end points of the edge. (I assume) I plan on allowing the user to enter an exact distance and use that instead.

I took some time and drilled down the objects you suggested.
Just became more confused by all the options.

Honestly I can not puzzle it out from the meager information provided in the Inventor API help. Something that explains the overall concept of the Inventor Object Tree and its components? Is there a book I can purchase from Autodesk that answers these questions?

---- Further SetTranslation Questions ----
Is this what you mean by deriving the unit vector?
How does one multiply it by a given distance as you suggest. Further, once you have it where would I use it?
Would it be in place of the Vector we are currently using?
[Pre]
Dim oVector As Vector
Dim UV As UnitVector

Set oVector = oEdge.StartVertex.Point.VectorTo(oEdge.StopVertex.Point)
Set UV = NewVector.AsUnitVector
'....???
[/Pre]
-----------
Thank you for all the effort
0 Likes
Message 6 of 17

Anonymous
Not applicable
Actually, you don't need to use the unit vector in your case. In the modified code that I sent earlier, replace the line: oTranslationMatrix.SetTranslation oEdge.StartVertex.Point.VectorTo(oEdge.StopVertex.Point), False with --------------- Dim oTransVector As Vector Set oTransVector = oEdge.StartVertex.Point.VectorTo(oEdge.StopVertex.Point) Call oTransVector.Normalize ' Normalizes length to 1.0 Call oTransVector.ScaleBy(5) ' Scales to the desired length oTranslationMatrix.SetTranslation oTransVector, False ---------------- This translates the component by a hard-coded distance of 5 cm. Sanjay- "TGroff" wrote in message news:7251208.1103212604597.JavaMail.jive@jiveforum1.autodesk.com... > Yes, I would like to create my new occurance offset from the original at a given distance in the direction defined by the edge. Currently the distance is being derived from the start and end points of the edge. (I assume) I plan on allowing the user to enter an exact distance and use that instead. > > I took some time and drilled down the objects you suggested. > Just became more confused by all the options. > > Honestly I can not puzzle it out from the meager information provided in the Inventor API help. Something that explains the overall concept of the Inventor Object Tree and its components? Is there a book I can purchase from Autodesk that answers these questions? > > ---- Further SetTranslation Questions ---- > Is this what you mean by deriving the unit vector? > How does one multiply it by a given distance as you suggest. Further, once you have it where would I use it? > Would it be in place of the Vector we are currently using? > [Pre] > Dim oVector As Vector > Dim UV As UnitVector > > Set oVector = oEdge.StartVertex.Point.VectorTo(oEdge.StopVertex.Point) > Set UV = NewVector.AsUnitVector > '....??? > [/Pre] > ----------- > Thank you for all the effort
0 Likes
Message 7 of 17

Anonymous
Not applicable
Thank you Sanjay,

I'm beginning to get a handle of the vector tools now.
Can you point me to the tool for displaying a vector direction on screen graphically? Is that available in the object tree as well?

~T
0 Likes
Message 8 of 17

Anonymous
Not applicable
I think you are looking for the client graphics functionality. There are a few samples in Programming Help as well as an overview. Sanjay- "TGroff" wrote in message news:14675894.1103301028406.JavaMail.jive@jiveforum2.autodesk.com... > Thank you Sanjay, > > I'm beginning to get a handle of the vector tools now. > Can you point me to the tool for displaying a vector direction on screen graphically? Is that available in the object tree as well? > > ~T
0 Likes
Message 9 of 17

Anonymous
Not applicable
After looking into client graphic I think I will skip that and insist the user select two vertices or point instead of an edge. It will determine the vector direction from that.

Sanjay, Has anyone at the Inventor group given thought to allowing a part to be loaded lightweight and used as 3D client graphics? They would show in the component tree browser of course. It would be great to be able to create your client geometry using the standard Inventor create ipt tools. I get that the way they are implemented currently is flexible. Perhaps this could be an addition. I invision one could use the add occurance similar to what I've been doing but perhaps have a 'Create_As _Client_Graphic' argument.
:)

---------------

Currently I am attempting to attach selected Constraints to the newly created occurances. I thought it would be easy at first. Where I see a problem is locating the same face feature in the copied part as was constrained in the original.

New Constraints require the Constraint.EntityOne (and Two)

~T
0 Likes
Message 10 of 17

Anonymous
Not applicable
Gah! Sorry but my fingers slipped on the last post. I meant to say the the imported client graphic would NOT show in the Component Tree browser.

It would be nice to be able to Edit these posts. 🙂
0 Likes
Message 11 of 17

Anonymous
Not applicable
Hi T - If you are entering the discussion groups from the HTTP web based side, you can edit your posts. Look for the pencil icon to the right of the post and click it. As long as no one has answered your post, you can edit it. You cannot edit from the NNTP newsgroup reader side of the groups. --- Anne Brown Discussion Groups Administrator Autodesk, Inc. TGroff wrote: (snip) > It would be nice to be able to Edit these posts. 🙂
0 Likes
Message 12 of 17

Anonymous
Not applicable
No pencils on this screen.

I am using the Web Browser option from the 'Autodesk Inventor Customization' Screen
0 Likes
Message 13 of 17

Anonymous
Not applicable
Sanjay,

What method does Inventor use to Identifiy faces or other geometry as a unique identifer in the Part Document?

I would like to apply the same constraint type to the newly imported copied component. To do that I need to get a handle to the same face that was used in the original part on the new component. Correct?

~T
0 Likes
Message 14 of 17

Anonymous
Not applicable
Use ReferenceKeys. There is an overview in the Programming Help. Sanjay- "TGroff" wrote in message news:5966073.1103578914619.JavaMail.jive@jiveforum1.autodesk.com... > Sanjay, > > What method does Inventor use to Identifiy faces or other geometry as a unique identifer in the Part Document? > > I would like to apply the same constraint type to the newly imported copied component. To do that I need to get a handle to the same face that was used in the original part on the new component. Correct? > > ~T
0 Likes
Message 15 of 17

Anonymous
Not applicable
Sorry to be a pain Sanjay,

I cannot get the GetReferenceKey method to work.
I can only assume I am using it wrong. As usual the Inventor API help was confusing or not that informative.
[Pre]
'Get FaceProxy from Entityone

Set oFaceProxy = oConst.EntityOne
Dim Refkey() As Byte
oFace.GetReferenceKey Refkey '<--- This fails with Invalid argument.
[/Pre]
0 Likes
Message 16 of 17

Anonymous
Not applicable
Sorry, my mistake. I was under the impression that there was an overview on reference keys. To obtain a ref key for all BRep entities (faces, edges, vertices, etc.), you will need to provide a 'Key Context'. You should store this 'Key Context' along with the reference key to bind back to the face object at a later time (using ReferenceKeyManager.BindKeyToObject). This should work... (replace odoc with the correct document object) [Pre] 'Get FaceProxy from Entityone Set oFaceProxy = oConst.EntityOne Dim Refkey() As Byte Dim KeyContext As Long KeyContext = odoc.ReferenceKeyManager.CreateKeyContext Call oFaceProxy.GetReferenceKey(Refkey(), KeyContext) [/Pre] "TGroff" wrote in message news:26008028.1103587451832.JavaMail.jive@jiveforum2.autodesk.com... > Sorry to be a pain Sanjay, > > I cannot get the GetReferenceKey method to work. > I can only assume I am using it wrong. As usual the Inventor API help was confusing or not that informative. > [Pre] > 'Get FaceProxy from Entityone > > Set oFaceProxy = oConst.EntityOne > Dim Refkey() As Byte > oFace.GetReferenceKey Refkey '<--- This fails with Invalid argument. > [/Pre]
0 Likes
Message 17 of 17

Anonymous
Not applicable
Hmmmm, So does the Persistant ID for the face already exist or are we creating one and applying it? If the latter then wouldn't we have to save our component to disk before creating a new occurence?

Re: using your code snippet
--------------

[Pre]
lblSelectedComponent.Caption = "Constraints for: " & oOcc.Name
Set oOccDoc = oOcc.Definition.Document

For Each oConst In oOcc.Constraints

If oConst.OccurrenceOne.Name = oOcc.Name Then
' Get the Copy Component feature referencekey
Set oFaceProxy = oConst.EntityOne
KeyContext = oOccDoc.ReferenceKeyManager.CreateKeyContext

oFaceProxy.GetReferenceKey Refkey, KeyContext

' Capture non-copy component name
s = oConst.OccurrenceTwo.Name
Else
' Capture non-copy component name
s = oConst.OccurrenceOne.Name
End If

' Testing tool
s2 = ""
For i = 0 To UBound(Refkey)
s2 = s2 & Refkey(i) & ", "
Next i
s2 = s2 & KeyContext

' Display Constraints.
lstConstraints.AddItem oConst.Name & " -- " & s & " /// " & s2

Next oConst

[/Pre]

Fails on: 'Call oFaceProxy.GetReferenceKey(Refkey, KeyContext)'
--------
Run-time Error '-2147418113(8000ffff)';
Method 'GetReferenceKey of object '_IRxFaceProxy' failed.
--------

In my small test assembly all the constraints are mates to faces.

~T
Message was edited by: TGroff
0 Likes