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: 

Create UCS via API with defined origin point only

6 REPLIES 6
SOLVED
Reply
Message 1 of 7
Maciej365
304 Views, 6 Replies

Create UCS via API with defined origin point only

In a Part environment, it is possible to create a new UCS and provide origin point only (vertex, sketch point, etc.) and skip selection of the points for X and Y axes. All you have to do is after you pick the origin point, right click and pick "Finish" from the context menu. As a result a newly created UCS will have its X, Y, and Z axes parallel to corresponding axes of the PartDocument origin, and whenever the source origin point moves, the UCS will follow.

I want to achieve the same result with Inventor API in C#, but here I have only two options:

  • create a "grounded" UCS with transformation matrix
  • create a UCS by defining 3 points.

When I create new UCS via user interface command described at the beginning of my post, and then access it via API, this is what I see in its properties:

 

    private static void GetUcsInfo(UserCoordinateSystem ucs)
    {
        string ucsName = ucs.Name;
        HealthStatusEnum healthStatus = ucs.HealthStatus;
        UserCoordinateSystemDefinition ucsDefinition = ucs.Definition;
        UCSDefinitionTypeEnum ucsDefinitionType = ucsDefinition.DefinitionType;
        ucsDefinition.GetByThreePoints(out object originObj, out object xAxisObj, out object yAxisObj);

        Console.WriteLine($"ucs.HealthStatus: {healthStatus}");
        Console.WriteLine($"ucs.Definition.DefinitionType: {ucsDefinitionType}");
        Console.WriteLine($"originObj is null: {originObj is null}");
        Console.WriteLine($"xAxisObj is null: {xAxisObj is null}");
        Console.WriteLine($"yAxisObj is null: {yAxisObj is null}");
    }

 

 

Console output:

 

ucs.HealthStatus: kUpToDateHealth
ucs.Definition.DefinitionType: kTransformationDefinitionType
originObj is null: False
xAxisObj is null: True
yAxisObj is null: True

 

 

I'm using Inventor Professional 2021, Build 183. Thank you for your help.

 

Maciej.

Tags (2)
6 REPLIES 6
Message 2 of 7
JelteDeJong
in reply to: Maciej365

Have a look at this example iLogic rule. It will place a ucs on the coordinates given by the translationVector. I left out all rotations so it will be rotated the same way as the orign.

Dim doc As PartDocument = ThisDoc.Document
Dim def As PartComponentDefinition = doc.ComponentDefinition
Dim ucss As UserCoordinateSystems = def.UserCoordinateSystems


Dim ucsDef = ucss.CreateDefinition()

Dim translationVector As Vector = ThisApplication.TransientGeometry.CreateVector(10, 2, 3)

Dim transformMatrix = ThisApplication.TransientGeometry.CreateMatrix()
transformMatrix.SetTranslation(translationVector)


ucsDef.Transformation = transformMatrix

ucss.Add(ucsDef)

Jelte de Jong
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.

EESignature


Blog: hjalte.nl - github.com

Message 3 of 7
Maciej365
in reply to: JelteDeJong

Thank you for replying, @JelteDeJong. Unfortunately, this solution doesn't satisfy my needs. I want to be able to create UCS with origin attached to the SketchPoint, and whenever I move this SketchPoint (change dimension value that drives its position) i want the UCS to follow but never change its rotation which might happen if I'll define it with three points. What you propose is to create a "grounded" UCS with transformation matrix as a definition, which will not be connected to any geometry in the part.

Message 4 of 7
WCrihfield
in reply to: Maciej365

Hi @Maciej365.  Just some additional thoughts, but since all of the inputs for defining a UCS are 'transient', we essentially do not have a way to 'attach' it to anything real.  So, in order to create the behavior of it moving when something else moves, we would need to be able to 'track' the changes in location of the point that we want it to move with.  So, since you want it to move with a SketchPoint, it would be nice if there were 3 Parameter objects which directly dictate its location, then we could attempt to 'monitor' those 3 Parameters for when their values change.  And when their values change, then re-define the 'translation' of the UCS to match the SketchPoints new location. 

 

There are likely multiple ways to do something like that.  The first would be if we were using an internal iLogic rule, where we could use the blue, unquoted names of those 3 parameters within the rule, then the rule would automatically run when their values change.  Or use a 'dummy' internal iLogic rule, with those 3 blue parameter names in it, just as triggers, only to run an external iLogic rule with the 'real' code in it.  The alternative to using the blue, unquoted parameter names in an internal iLogic rule would be to create something like an Inventor add-in with a custom Event Handler code in it for monitoring parameter changes, filtered to only react when one of those 3 parameters changes within that document.  It might be possible to set-up the custom event handler stuff through multiple external iLogic rules, but it seems like it would be too much of a pain either way you go about it.  Another odd thought that came to mind was to have the UCS in another part that you have 'derived' into your current part.  That other part could have a body that would help with orientation, but the body could have its visibility turned off.  Then you could control the location of that body with a Move Bodies feature, which can be controlled by parameters that you could assign names to.  Pretty odd sounding, but I do not know why you need to include a UCS within a part, and be able to move it around either, so just throwing some ideas out there.

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 5 of 7
WCrihfield
in reply to: Maciej365

Correction...  Some of what I said was not correct, such as when defining the UCS with 3 WorkPoints or Vertex or SketchPoints, which are 'real' enough.  But when defining one by Transformation (Matrix), that is transient, and therefore has no 'GeometryIntents' to keep it attached to any objects.  So, as a test, I created a simple new part, with a new WorkPlane offset from an origin plane, and a 2D sketch on that offset WorkPlane, with a single SketchPoint in it which is located with two dimensional constraints from projected origin axes.  Then I used some code in an internal iLogic rule, similar to what @JelteDeJong showed above to create the UCS.  And in that same rule I included some code to get that SketchPoint object, then its Point object, then use its coordinates as input for the Vector object.  Then used that Vector to set the translation of the Matrix.  Then used that Matrix to set the transformation of the UCS.  Then update the part.  I named all 3 of the model parameters along the way, then created 3 named user parameters to drive those model parameters.  Then I drug those 3 user parameters into a simple new internal iLogic Form to be able to drive them quickly.  And I included those 3 blue parameters in my internal iLogic rule just to trigger it to run when their values changed.  When that rule is enabled, the UCS moves with the SketchPoint when I change the parameter values, but when I suppress that rule, it stops moving when I change those parameter values.

 

The part file I tested with is attached, and I will attach the code here too, just in case you can not open the part file.

oTrigger = SketchPointXOffset
oTrigger = SketchPointYOffset
oTrigger = SketchPointZOffset
Dim oPDoc As PartDocument = ThisDoc.Document
Dim oPDef As PartComponentDefinition = oPDoc.ComponentDefinition
Dim oSPoint As SketchPoint = oPDef.Sketches.Item("SketchPoint Sketch").SketchPoints.Item(1)
Dim sPoint As Inventor.Point = oSPoint.Geometry3d
Dim oTG As TransientGeometry = ThisApplication.TransientGeometry
Dim oMatrix As Inventor.Matrix = oTG.CreateMatrix()
Dim oVector As Inventor.Vector = oTG.CreateVector(sPoint.X, sPoint.Y, sPoint.Z)
oMatrix.SetTranslation(oVector)
Dim oUCSs As UserCoordinateSystems = oPDef.UserCoordinateSystems
Dim oUCS As UserCoordinateSystem = Nothing
If oUCSs.Count = 0 Then
	Dim oUCSDef As UserCoordinateSystemDefinition = oUCSs.CreateDefinition()
	oUCSDef.Transformation = oMatrix
	oUCS = oUCSs.Add(oUCSDef)
Else
	oUCS = oUCSs.Item(1)
	oUCS.Transformation = oMatrix
End If
If oPDoc.RequiresUpdate Then oPDoc.Update2(True)

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

Message 6 of 7
Maciej365
in reply to: WCrihfield

Hi @WCrihfield, thank you for your input. In my scenario I'll need around 15 UCSs defined this way (dynamically via API) per part, so it will require a lot of iLogic code plus good tracking of the sketch point creation/deletion/move and I think it will be too complicated. I'm working on other solution to my actual problem and it will possibly not require UCS defined this way (based on only one 'real' point instead of three). I accept your solution because technically it works, but in too complicated way for my needs. Cheers.

Message 7 of 7
WCrihfield
in reply to: Maciej365

OK.  Sounds good.  But just in case it might be helpful, I dabbled a bit more with my earlier code to make it more convenient for updating the positions of multiple UCSs in a single run of the rule.  I moved just the code required for repositioning a UCS that is defined by Transformation into a custom Sub routine.  Then in the 'Main' portion of the code I created a Dictionary for storing pairs of UCS and Point objects, then just for a quickie example I am just attempting to fill a few of its entries with values (would do this part differently of course).  Then, if the Dictionary has any entries, it will iterate its entries, running the custom Sub routine on each pair to reposition them.  Then updating the document, if needed.  Just a quick, rough draft of an idea that came to mind.

 

Another thought was to use one or more Sketch3D objects and one or more SketchPoint3D within each of them, then use their SketchPoint3D.Geometry property to get the Point from.  Each SketchPoint3D could be controlled by 3 DimensionConstaints, which each have a Parameter we could use directly within the code, if needed.

Sub Main
	Dim oDoc As Inventor.Document = ThisDoc.Document
	Dim oCD As ComponentDefinition = oDoc.ComponentDefinition
	Dim oUCSs As UserCoordinateSystems = oCD.UserCoordinateSystems
	Dim oSketches As PlanarSketches = oCD.Sketches
	Dim oDict As New Dictionary(Of Inventor.UserCoordinateSystem, Inventor.Point)
	Try : oDict.Add(oUCSs.Item(1), oSketches.Item(1).SketchPoints.Item(1).Geometry3d) : Catch : End Try
	Try : oDict.Add(oUCSs.Item(2), oSketches.Item(2).SketchPoints.Item(1).Geometry3d) : Catch : End Try
	Try : oDict.Add(oUCSs.Item(3), oSketches.Item(3).SketchPoints.Item(1).Geometry3d) : Catch : End Try
	If oDict.Count > 0 Then
		For Each oEntry In oDict
			UpdateUCSPosition(oEntry.Key, oEntry.Value)
		Next 'oEntry
	End If
	If oDoc.RequiresUpdate Then oDoc.Update2(True)
End Sub

Sub UpdateUCSPosition(oUCS As UserCoordinateSystem, oNewPosition As Inventor.Point)
	If oUCS Is Nothing OrElse oNewPosition Is Nothing Then Return
	'Dim oDoc As Inventor.Document = oUCS.Parent.Document
	'If oDoc.IsModifiable = False Then Return
	Dim oTG As TransientGeometry = ThisApplication.TransientGeometry
	Dim oMatrix As Inventor.Matrix = oTG.CreateMatrix()
	Dim oVector As Inventor.Vector = oTG.CreateVector(oNewPosition.X, oNewPosition.Y, oNewPosition.Z)
	oMatrix.SetTranslation(oVector)
	Try : oUCS.Transformation = oMatrix : Catch : End Try
	'If oDoc.RequiresUpdate Then oDoc.Update2(True)
End Sub

Wesley Crihfield

EESignature

(Not an Autodesk Employee)

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

Post to forums  

Technology Administrators


Autodesk Design & Make Report