Do more with Less, ETO API’s

Do more with Less, ETO API’s

Ishwar Nagwani– Autodesk India Pvt. Ltd

CP1664

Engineer-to-order (ETO) systems, also known as sales force automation, are becoming increasingly popular. The ETO cannot be implemented without customization. The learning curve is steep due to lack of documentation and active blogs. This class focuses on creating smart designs, understanding Intent events, and creating rapid custom controls that can be tested in the Autodesk® Inventor® browser pane before implementing in a custom UI framework

Learning Objectives

At the end of this class, you will be able to:

  • Create Intent AddIns with UI
  • Use Client Graphics in your designs
  • Use Events effectively
  • Add Dimensions Smartly
  • Call Methods from an External DLL
  • Test your DLL’s with ETO server using Batch process

About the Speaker

Ishwar has solid 25 years of experience in customizing CAD products, be it AutoCAD, MDT, AutoCAD Mech, Inventor and ETO. With hardcore manufacturing background Ishwar was involved in customizing the manufacturing, design and drafting processes. Ishwar was also visiting CAD faculty to colleges teaching CAD/CAM. Ishwar took many classes for ADN developers in Singapore and Korea on Inventor API's.

Ishwar has successfully implemented complex projects for large corporations like Lockheed, Mammoth and Criterion furniture, to name a few.

Ishwar has certification in Industrial Automation from NITIE(National Institute of Industrial Engineering) . Recently Ishwar also completed Executive General Management Programme from IIT business school SJSOM along with his busy work schedule.

Create ETO Addins with UI

What is ETO Addin?

The ETO Addin is C# or VBA .NET Class Library project, to which we add a custom control. The UI is added to custom control. The custom control from Addin can be hosted in Inventor browser pane.

Add a custom control

To Add a custom control right click on project and select “Add->User Control”

Give suitable name to user control. The user control name would be used later to load the control in Inventor browser pane. Once the user control is added, resize it as required and double click on control to add control_load() event handler.

privatevoidmyUI_Load(object sender, EventArgs e)
{
MessageBox.Show("Hi I am in Control Load event");
}
Make the assembly COM aware so that it can be registered

What references should be added to access ETO .NET API?

The next step is to add reference files from ETO \Bin folder. Right click on “References” and select “AddReference”.

Select the following dll files:

  1. C:\Program Files\Autodesk\Inventor ETO Components 2012\Bin\Autodesk.Intent.API.dll
  2. Autodesk.IntentBase.dll
  3. Autodesk.Intent.HostServices.dll
  4. Autodesk.IntentSession.dll
  5. Autodesk.Inventor.Interop.dll
  6. Intent.Inventor.Addin.dll

Important: Set the Copy Local attribute to False for all above references.

Add the directives

Add the following directives:

using Inventor;
usingAutodesk.Intent;
usingAutodesk.Intent.HostServices;
usingAutodesk.Intent.IntentInventor;
usingAutodesk.Intent.IntentInventor.Automation;
Initialize class level variables

Declare the class level variables for Inventor Application and Root Part objects and Initialize them.

using System;
usingSystem.Collections.Generic;
usingSystem.ComponentModel;
usingSystem.Drawing;
usingSystem.Data;
usingSystem.Linq;
usingSystem.Text;
usingSystem.Windows.Forms;
using Inventor;
usingAutodesk.Intent;
usingAutodesk.Intent.HostServices;
usingAutodesk.Intent.IntentInventor;
usingAutodesk.Intent.IntentInventor.Automation;
namespaceTestUI
{
publicpartialclassmyUI : UserControl
{
// Define class level variables here
Part _rootPart = null;
IHostAPI _hostAPI = null;
Inventor.Application _inventorApplication = null;
publicmyUI()
{
InitializeComponent();
}
privatevoidmyUI_Load(object sender, EventArgs e)
{
MessageBox.Show("Hi I am in Control Load event");
_rootPart = IntentAPI.Instance.ActiveRoot;
_hostAPI = IntentSession.IntentAPI.HostAPIasIHostAPI ;
_inventorApplication = _hostAPI.HostApplication;
}
}
}
Build the DLL

Build the project. Setup the Post Build event to register the DLL. This way we can avoid additional batch file to register the DLL.

Add The UI to user control and test with sample ETO project Support Assembly

Go ahead and add some UI for modifying the sample Support Assembly, the parameters available at top level are Height, Load, Size and Width

The control has four UI elements for controlling Height, Load, Size and Width. The Size is a combo box having values 50, 75 and 100.

The control is initialized with existing values from assembly on Load event.

Add the following code to get the parameter values from root assembly and populate UI.

For rule value equivalentdata type in .Net isValue, and call GetRuleValue() method of Root Part to get value of a rule.

privatevoidmyUI_Load(object sender, EventArgs e)
{
_rootPart = IntentAPI.Instance.ActiveRoot;
_hostAPI = IntentSession.IntentAPI.HostAPIasIHostAPI ;
_inventorApplication = _hostAPI.HostApplication;
// Read the Height, Load, Size and Width parameters from root
Valueval = _rootPart.GetRuleValue("Height");
// Assign to control UI
textBoxHeight.Text = val.ToString();
val = _rootPart.GetRuleValue("Load");
textBoxLoad.Text = val.ToString();
val = _rootPart.GetRuleValue("Size");
comboBoxSize.Text = string.Format("{0:0}", val.ToNumber());
val = _rootPart.GetRuleValue("Width");
textBoxWidth.Text = val.ToString();
}

The above code only populates the control with existing parameter values.

We want user to modify values in UI and apply those back to parameters, the sample code below for “Apply button” does needful.

privatevoidbuttonApply_Click(object sender, EventArgs e)
{
// Apply values from UI to parameters/rules
_rootPart.SetRuleValue("Height",
Value.ValueFromObject(Convert.ToDouble(textBoxHeight.Text)));
_rootPart.SetRuleValue("Load",
Value.ValueFromObject(Convert.ToDouble(textBoxLoad.Text)));
_rootPart.SetRuleValue("Size",
Value.ValueFromObject(Convert.ToDouble(comboBoxSize.Text )));
_rootPart.SetRuleValue("Width",
Value.ValueFromObject(Convert.ToDouble(textBoxWidth.Text)));
// simulate the pressing of signal light to update the model
_hostAPI.IntentAPI.ActiveModel.Render();
}
Load the custom control in Inventor Browser Pane

Use the following VBA macro to load the custom control after opening the Support Assembly.

Subloadctl()
‘The first argument can be any name, the second is AssemblyName.ControlName
CallThisApplication.ActiveDocument.BrowserPanes.Add("TestUI", "TestUI.myUI")
End Sub
Add the leg assembly through UI

Let us add the leg assembly design in Support Assembly through UI, add one more button “Insert Leg” on control. See the sample code below, the design and parameter values are supplied using source and parameter name.

privatevoidbuttonInsertLeg_Click(object sender, EventArgs e)
{
// Create parameters and define source object
Autodesk.Intent.ParameterscParams = newAutodesk.Intent.Parameters();
Autodesk.Intent.SourcerSource = null;
// The first paramteter should be Design Name
rSource = newAutodesk.Intent.Source(":LegAssembly");
cParams.Add("Design", rSource);
// Supply the other parameters like Height, Load,Size and Width
rSource = newAutodesk.Intent.Source(textBoxHeight.Text);
cParams.Add("Height", rSource);
rSource = newAutodesk.Intent.Source(textBoxLoad.Text);
cParams.Add("Load", rSource);
rSource = newAutodesk.Intent.Source("True");
cParams.Add("ignorePosition", rSource);
// Now add the leg to Support assembly
// Create the unique name for leg assembly,
stringstrName = _hostAPI.IntentAPI.Utilities.UniqueName("LegAssembly");
// Add as dynamic child rule
IntentAPI.Instance.ActiveRoot.GetRuleValue
("Root").ToPart().GetDynamicRules().AddChild(strName, cParams);
// Update display
_hostAPI.IntentAPI.ActiveModel.Render();
}
Delete the leg assembly

Once the Leg has been added, how to delete it? The sample code shown below demonstrates deletion of Leg Assembly.

privatevoidbuttonDelete_Click(object sender, EventArgs e)
{
// Allow the user to pick the Leg Assembly
objectobj=
_inventorApplication.CommandManager.Pick
(
SelectionFilterEnum.kAssemblyOccurrenceFilter,
"Select a Leg Assembly:"
);
Inventor.ComponentOccurrenceocc = objasComponentOccurrence;
// Get the ref chain from occurrence so that it can be converted to Intent
// Part
stringlegRefChain = _hostAPI.RefChainFromHostObject(occ);
// Convert ref chain to part
PartlegtPart=_rootPart.GetRuleValue(legRefChain);
// The part is deleted through its parent
legtPart.Parent.GetRule(legtPart.Rule.Name).Delete();
// Update display
_hostAPI.IntentAPI.ActiveModel.Render();
}

How to use client graphics and do the interaction

The Client Graphics(CG) primitives were introduced in ETO 5.1. We can create the designs using CG primitives like lines, arcs, polylines, cylinder and cones etc.
Create a new CG design

In auxiliary system put IvComponentGroup

Add the following to CGRect design

DesignCGRect : SupportRootIvComponentGroup
Parameter Rule width As Number =100
Parameter Rule height As Number =100
Rule pt1 As Point = Point(0,0,0)
Rule pt3 As Point = Point( GetX(pt1)+width ,GetY(pt1)+height,0)
'Compute other 2 points for rectangle
Rule pt2 As Point = Point( GetX(pt3),GetY(pt1),0)
Rule pt4 As Point = Point( GetX(pt1),GetY(pt3),0)
' UseCGPolyline to create a rectangle. it needs the list of points
ChildpolyRectAs :CGPolyline
Points = {pt1,pt2,pt3,pt4,pt1}
color = "Red"
Selectable? = True
End Child
End Design

We have already seen how to instantiate and delete Intent design using .Net, the instantiation is similar for CG design. We will look at different approach of Instantiating CG, i.e. place the CG at user selected pick point in XY plane. This time we would add the CGRect instances to a branch “CGRectCollection” instead of root. There are advantages to adding to a separate branch, through branch we can iterate these instances and create additional data structures for using in other designs.

Create the above design and instantiate the child in Root Support Assembly design as shown below.

‘ Add child for branch CGRectCollection
ChildCGRectCollAs :CGRectCollection
End Child

You would now see a CGRectColl in Intent Tree

Add CGRect Instance and Setup the Mouse Events for addingAdd the new class “ClsMouseEvents”to your project, the final class with mouse interaction events setup looks as shown below.

using System;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
namespaceTestUI
{
classClsMouseEvents
{
// Define class level variables
privateInventor.Application _inventorApplication = null;
privateInventor.InteractionEvents _interactionEvents;
privateInventor.MouseEvents _mouseEvents;
privateBoolean _bpicking = false;
// For storing picked point
publicInventor.Point _insPoint;
// Default constructor
publicClsMouseEvents()
{
}
// Overriden constructor
publicClsMouseEvents(Inventor.Application _app)
{
_inventorApplication = _app;
_interactionEvents = _inventorApplication.CommandManager.
CreateInteractionEvents();
// Initialize Mouse Events
_mouseEvents = _interactionEvents.MouseEvents;
// Subscribe to Event Handlers
_mouseEvents.OnMouseClick += new
Inventor.MouseEventsSink_OnMouseClickEventHandler
(
_mouseEvents_OnMouseClick
);
_interactionEvents.OnTerminate += new
Inventor.InteractionEventsSink_OnTerminateEventHandler
(
_interactionEvents_OnTerminate
);
}
privatevoid _mouseEvents_OnMouseClick(Inventor.MouseButtonEnummbEnum,
Inventor.ShiftStateEnumssEnum,
Inventor.PointmodelPoint,
Inventor.Point2dviewPoint,
Inventor.View view)
{
_insPoint = modelPoint;
_interactionEvents.Stop();
// Unsubscribe Event Handlers
undoEvents();
_bpicking = false;
}
privatevoid _interactionEvents_OnTerminate()
{
if (_bpicking)
{
_bpicking = false;
undoEvents();
_interactionEvents = null;
_mouseEvents = null;
}
}
privatevoidundoEvents()
{
_mouseEvents.OnMouseClick -= new
Inventor.MouseEventsSink_OnMouseClickEventHandler
(
_mouseEvents_OnMouseClick
);
_interactionEvents.OnTerminate -= new
Inventor.InteractionEventsSink_OnTerminateEventHandler
(
_interactionEvents_OnTerminate
);
}
// This method is called from an instance of class to pick point
public voidSelectPickPoint()
{
// No selection
_interactionEvents.SelectionActive = false;
_mouseEvents.MouseMoveEnabled = true ;
_bpicking = true;
_interactionEvents.Start();
while (_bpicking)
{
System.Windows.Forms.Application.DoEvents();
}
}
}// End of class
}

Now add the button “Add CGRect” to UI so that CGRect instance can be placed at selected point. The sample code below instantiates the class ClsMouseEvents and calls public method SelectPickPoint(). Also the view is switched to planbefore mouse interaction begins.

privatevoidbuttonAddCGRect_Click(object sender, EventArgs e)
{
// Switch to Plan View
PlanView();
// Create the Instance of Mouse Events Class
ClsMouseEventsmouseEvents = newClsMouseEvents(_inventorApplication);
mouseEvents.SelectPickPoint();
// Get selected point
Inventor.PointstartPt = mouseEvents._insPoint;
// Place the CGRect at picked point
Autodesk.Intent.ParameterscParams = newAutodesk.Intent.Parameters();
Autodesk.Intent.SourcerSource;
rSource = newAutodesk.Intent.Source(":CGRect");
cParams.Add("Design", rSource);
// Conver the mouse point units to MM or INCH depending on document units
if(
_inventorApplication.ActiveDocument.UnitsOfMeasure.LengthUnits ==
UnitsTypeEnum.kMillimeterLengthUnits
)
{
// Convert mouse coordinates to MM
rSource = newAutodesk.Intent.Source
("point(" + startPt.X * 10 + "," + startPt.Y * 10 + "," + "0)"
);
}
else
{
// Convert mouse coordinates to INCH
rSource = newAutodesk.Intent.Source
("point(" + startPt.X /2.54 + "," + startPt.Y / 2.54 + "," + "0)"
);
}
cParams.Add("pt1", rSource);
stringstrName = _hostAPI.IntentAPI.Utilities.UniqueName("CGRect");
IntentAPI.Instance.ActiveRoot.GetRuleValue
("Root").ToPart().GetDynamicRules().AddChild(strName, cParams);
_hostAPI.IntentAPI.ActiveModel.Render();
}
privatevoidPlanView()
{
// Get active camera
Inventor.Camera camera;
camera = _inventorApplication.ActiveView.Camera;
camera.ViewOrientationType = ViewOrientationTypeEnum.kFrontViewOrientation;
// Apply the changes to the view.
camera.ApplyWithoutTransition();
}

Delete CGRect instance

The CGRect instance is composed of CGPolyline which when selected through Inventor API returns object of type GraphicsNode. The GraphicsNode object should be converted to RefChainusing IHostAPI.RefChainFromHostObject() method,and from Refchainget Intent part using rootPart.GetRuleValue(). The CGRect object is obtained by getting Parent of part got from GraphicsNode as depicted in figure below.

The sample below demonstrates the selection and deletion of a CGRect instance.

privatevoidbuttonDeleteCGRect_Click(object sender, EventArgs e)
{
// Allow the use to pick the CGRect instance
objectobj = _inventorApplication.CommandManager.Pick
(
SelectionFilterEnum.kAllEntitiesFilter, "Select CGRect:"
);
// Handle on object of Type GraphicsNode
GraphicsNodegrNode = objasGraphicsNode;
if (grNode != null)
{
// Get the Refchain of primitive
stringcgrectRefChain=_hostAPI.RefChainFromHostObject(grNode);
// Get Intent Part from ref chain of primitive
PartcgrectPart = _rootPart.GetRuleValue(cgrectRefChain);
// Get Parent Part (CGRect)
cgrectPart = cgrectPart.Parent;
// Delete the CGRect
if (cgrectPart != null)
{
cgrectPart.Parent.GetRule(cgrectPart.Rule.Name).Delete();
}
// Update display
_hostAPI.IntentAPI.ActiveModel.Render();
}
}

Move the CGRect

Finally we would see how to move a CGRect instance using InteractionGraphics. Moving the CGRect needs selection, Mouse events and InteractionGraphics. Go ahead and add the class “ClsMouseMoveEvents”.

When aCGRect object is selected and inspected through VBA, it has DisplayName which is similar to Reference Chain of that object.


Paste the following code in class.

using System;
usingSystem.Collections.Generic;
usingSystem.Linq;
usingSystem.Text;
using Inventor;
usingAutodesk.Intent;
usingAutodesk.Intent.IntentInventor.Automation;
namespaceTestUI
{
classClsMouseMoveEvents
{
// Define class level variables
privateInventor.Application _inventorApplication = null;
privateInventor.InteractionEvents _interactionEvents;
privateInventor.MouseEvents _mouseEvents;
privateBoolean _bpicking = false;
// For storing picked point
publicInventor.Point _insPoint;
// Required for interactionGraphics
privateGraphicsNode _graphicsNode;
privateClientGraphics _clientGraphics;
privateInteractionGraphics _interactionGraphics;
privateInventor.Point _basePt;
// Default constructor
publicClsMouseMoveEvents()
{
}
// Overriden constructor
publicClsMouseMoveEvents(Inventor.Application _app)
{
_inventorApplication = _app;
_interactionEvents = _inventorApplication.CommandManager.
CreateInteractionEvents();
// Initialize Mouse Events
_mouseEvents = _interactionEvents.MouseEvents;
// Subscribe to Event Handlers
_mouseEvents.OnMouseClick += new
Inventor.MouseEventsSink_OnMouseClickEventHandler
(
_mouseEvents_OnMouseClick
);
_mouseEvents.OnMouseMove += new
Inventor.MouseEventsSink_OnMouseMoveEventHandler
(
_mouseEvents_OnMouseMove
);
_interactionEvents.OnTerminate += new
Inventor.InteractionEventsSink_OnTerminateEventHandler
(
_interactionEvents_OnTerminate
);
}
privatevoid _mouseEvents_OnMouseClick(Inventor.MouseButtonEnummbEnum,
Inventor.ShiftStateEnumssEnum,
Inventor.PointmodelPoint,
Inventor.Point2dviewPoint,
Inventor.View view)
{
_insPoint = modelPoint;
_interactionEvents.SelectionActive = false;
_interactionEvents.Stop();
// Unsubscribe Event Handlers
undoEvents();
_bpicking = false;
}
privatevoid _mouseEvents_OnMouseMove(Inventor.MouseButtonEnummbEnum,
Inventor.ShiftStateEnumssEnum,
Inventor.PointmodelPoint,
Inventor.Point2dviewPoint,
Inventor.View view)
{
Inventor.TransientGeometrytg = _inventorApplication.TransientGeometry;
Inventor.Matrix mat = tg.CreateMatrix();
// Calculate X and Y offset with respect to basept of CGRect
doublexOffset = modelPoint.X - _basePt.X;
doubleyOffset = modelPoint.Y - _basePt.Y;
mat.SetTranslation(tg.CreateVector(xOffset, yOffset, 0));
// Transform the GraphicsNode to new postion
_graphicsNode.Transformation = mat;
_interactionGraphics.UpdateOverlayGraphics(_inventorApplication.ActiveView);
}
// This is public method which is invoked from instance of this class
publicvoidMoveCGRect
(
Inventor.GraphicsNodegrNode,
stringcgrectRefChain,
Inventor.PointbasePt
)
{
// Assign CGRectbasept to class _basePt
_basePt = basePt;
// Set up interaction events
_interactionGraphics = _interactionEvents.InteractionGraphics;
_clientGraphics = _interactionGraphics.OverlayClientGraphics;
_graphicsNode = _clientGraphics.AddNode(1);
// Collect all graphics Node with same ref chain
Inventor.ObjectCollectiongrNodesColl =
_inventorApplication.
TransientObjects.
CreateObjectCollection(Type.Missing);
ClientGraphics clientGraphics = grNode.Parent;
// Get the position of "." in ref chain, after "." is name of CG child
// for e.g. Root.CGRectColl.CGRect_1.polyRect
intpos = cgrectRefChain.LastIndexOf(".");
// Get ref chain without CG child anme
stringnodeName = cgrectRefChain.Substring(0, pos);
// The CGRect could have been made using muliple CG Entities
// like Lines, Arcs , Circles and Text
grNodesColl.Add(grNode);
IHostAPI hostAPI = IntentSession.IntentAPI.HostAPIasIHostAPI;
// Check if CGRect is made of multiple CG Entities and
// add them to grNodesColl
foreach (GraphicsNode grninclientGraphics)
{
stringsname = hostAPI.RefChainFromHostObject(grn);
pos = sname.LastIndexOf(".");
if (string.Compare (sname.Substring(0, pos),nodeName,true ) == 0)
{
grNodesColl.Add(grn);
}
}
// Add the object from grNodesColl to OverlayClientGraphics
// These objects will be dragged during mouse move
foreach (GraphicsNodegrningrNodesColl)
{
if (grn[1] isCurveGraphics)
{
CurveGraphicscgr = grn[1] asCurveGraphics;
CurveGraphicscgr_temp = _graphicsNode.AddCurveGraphics(cgr.Curve);
}
elseif (grn[1] isTextGraphics)
{
TextGraphicstgr = grn[1] asTextGraphics;
TextGraphicstgr_temp = _graphicsNode.AddTextGraphics();
tgr_temp.Text = tgr.Text;
tgr_temp.FontSize = tgr.FontSize;
tgr_temp.Anchor = tgr.Anchor;
tgr_temp.HorizontalAlignment = tgr.HorizontalAlignment;
tgr_temp.VerticalAlignment = tgr.VerticalAlignment;
}
}
_interactionGraphics.UpdateOverlayGraphics(_inventorApplication.ActiveView);
_interactionEvents.SelectionActive = false;
_mouseEvents.MouseMoveEnabled = true;
_bpicking = true;
_interactionEvents.Start();
while (_bpicking)
{
System.Windows.Forms.Application.DoEvents();
}
}// End of MoveRect
privatevoid _interactionEvents_OnTerminate()
{
if (_bpicking)
{
_bpicking = false;
undoEvents();
}
}
privatevoidundoEvents()
{
_mouseEvents.OnMouseClick -= new
Inventor.MouseEventsSink_OnMouseClickEventHandler
(
_mouseEvents_OnMouseClick
);
_mouseEvents.OnMouseMove -= new
Inventor.MouseEventsSink_OnMouseMoveEventHandler
(
_mouseEvents_OnMouseMove
);
_interactionEvents.OnTerminate -= new
Inventor.InteractionEventsSink_OnTerminateEventHandler
(
_interactionEvents_OnTerminate
);
_interactionEvents = null;
_mouseEvents = null;
}
}// End of class
}

Now add the button “MoveCGRect” and paste the following code to instantiate the above Class ClsMouseMoveEvents and invoke the method MoveCGRect() button event handler.

privatevoidbuttonCGRectMove_Click(object sender, EventArgs e)
{
// Switch to Plan View
PlanView();
// Allow the use to pick the CGRect instance
objectobj = _inventorApplication.CommandManager.Pick
(
SelectionFilterEnum.kAllEntitiesFilter, "Select CGRect:"
);
// Handle on object of Type GraphicsNode
GraphicsNodegrNode = objasGraphicsNode;
if (grNode != null)
{
// Get the Ref chain of CG Primitive
stringcgrectRefChain = _hostAPI.RefChainFromHostObject(grNode);
// Get Intent Part corresponding to CG Primitive
PartcgrectPart = _rootPart.GetRuleValue(cgrectRefChain);
cgrectPart = cgrectPart.Parent; // CGRect instance
//Move the CGReect
if (cgrectPart != null)
{
// Get the insertion point of Intent children
Autodesk.Intent.Point pt1 = cgrectPart.GetRuleValue("pt1").ToPoint();
// Instantiate through overridden construct
ClsMouseMoveEventsmouseMoveEvents = newClsMouseMoveEvents
(_inventorApplication );
// Convert MM or Inch document units to CM
doublemfac = 0.1;
if (_inventorApplication.ActiveDocument.UnitsOfMeasure.LengthUnits ==
UnitsTypeEnum.kInchLengthUnits)
{
mfac = 2.54;
}
Inventor.PointbasePt = _inventorApplication.TransientGeometry.
CreatePoint(pt1.X * mfac, pt1.Y * mfac, 0);
mouseMoveEvents.MoveCGRect
(
grNode,
cgrectPart.RefChain.ToString() ,
basePt
);
// We have the user selected point
Inventor.PointpickPoint = mouseMoveEvents._insPoint;
// The selected point should be converted back to MM or INCH
// depending on document units
mfac = 10;
if (_inventorApplication.ActiveDocument.UnitsOfMeasure.LengthUnits ==
UnitsTypeEnum.kInchLengthUnits)
{
mfac = 1/2.54;
}
// Assign the user selected point to "pt1" parameter rule.
Valueval = newValue();
val.SetFromPoint(new
Autodesk.Intent.Point(pickPoint.X * mfac, pickPoint.Y * mfac, 0));
cgrectPart.SetRuleValue("pt1", val);
}
// Update the model
_hostAPI.IntentAPI.ActiveModel.Render();
}
}

At this point our UI control looks as shown below.

Using Intent Events

We saw how to use selection and mouse events which are specific to Inventor API. The Intent also has Events. The Intent has events for simple rules and child rules. Below is list of simple Rule events.