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: 

Ability to display a "direction" arrow using the API.

5 REPLIES 5
Reply
Message 1 of 6
AlexFielder
1075 Views, 5 Replies

Ability to display a "direction" arrow using the API.

Hi all,

 

I'm working through a problem and wanted to check I hadn't missed something obvious within the API.

 

When working with the built-in tools manually, you are occasionally presented with a "direction" arrow within the UI:

 

GUID-E0403436-1057-42FC-BE6C-5BB1B8766C03

 

These are client graphics I believe and I have found the following article useful:

 

http://adndevblog.typepad.com/manufacturing/2015/01/create-transient-3d-arrow-with-clientgraphics.ht...

 

But I have an issue and that is that I need to create a version of the arrow that can be flipped about a selected axis.

 

Is there something I am missing within the API that can do this for me or is it a manual task of creating/recreating the transient geometry as required?

 

here is a c# method I have cobbled together that takes several inputs I thought may be needed:

 

public class ClientGFX
    {
        private static readonly ILog log = LogManager.GetLogger(typeof(Parameters));

        public static void ClientGraphics3DPrimitives(string clientGraphicsCollectionId, Application InventorApp, 
            PartComponentDefinition compDef, Point origin, Point end, Line centreline, UnitVector arrowDirection)
        {
            try
            {
                Document oDoc = InventorApp.ActiveDocument;
                //  Set a reference to component definition of the active document.
                //  This assumes that a part or assembly document is active
                PartComponentDefinition oCompDef = compDef;
                //  Check to see if the test graphics data object already exists.
                //  If it does clean up by removing all associated of the client 
                //  graphics from the document. If it doesn't create it
                ClientGraphics oClientGraphics = null;
                try
                {
                    oClientGraphics = oCompDef.ClientGraphicsCollection[clientGraphicsCollectionId];
                }
                catch (Exception ex)
                {
                    //  An existing client graphics object was successfully 
                    //  obtained so clean up
                    oClientGraphics.Delete();
                    //  Update the display to see the results
                    InventorApp.ActiveView.Update();
                    log.Debug(ex.Message, ex);
                }
                finally
                {
                    TransientGeometry oTransGeom = InventorApp.TransientGeometry;
                    //  Create the ClientGraphics object.
                    if (oClientGraphics == null)
                    {
                        oClientGraphics = oCompDef.ClientGraphicsCollection.Add(clientGraphicsCollectionId);
                    }
                    //  Create a new graphics node within the client graphics objects
                    GraphicsNode oSurfacesNode = oClientGraphics.AddNode(1);
                    TransientBRep oTransientBRep = InventorApp.TransientBRep;


                    //  Create a point representing the center of the bottom of 
                    //  the cone
                    Point coneBottom = origin;
                    //Point coneBottom = InventorApp.TransientGeometry.CreatePoint(0, 0, 0);
                    //  Create a point representing the tip of the cone
                    //Point oTop = end;
                    Point coneTop = InventorApp.TransientGeometry.CreatePoint(0, 10, 0);
                    // Create a point representing the base of the cylinder
                    Point cylinderBottom = InventorApp.TransientGeometry.CreatePoint(0, -40, 0);

                    //sort out the direction we need to point.
                    Matrix conePos = InventorApp.TransientGeometry.CreateMatrix();
                    Vector conePosVector = InventorApp.TransientGeometry.CreateVector(arrowDirection.X, arrowDirection.Y, arrowDirection.Z);
                    conePos.SetTranslation(conePosVector);
                    conePos.SetToRotateTo(coneTop.VectorTo(coneBottom), conePosVector);
                    //move the necessary points
                    coneTop.TransformBy(conePos);
                    cylinderBottom.TransformBy(conePos);
                    //  Create a transient cone body
                    //SurfaceBody oBody = oTransientBRep.CreateSolidCylinderCone(oBottom, oTop, 5, 5, 0);
                    SurfaceBody oBody = oTransientBRep.CreateSolidCylinderCone(coneBottom, coneTop, 5, 5, 0);


                    //  Reset the top point indicating the center of the top of 
                    //  the cylinder
                    //oTop = InventorApp.TransientGeometry.CreatePoint(0, -40, 0);
                    coneTop = InventorApp.TransientGeometry.CreatePoint(0, -40, 0);
                    //  Create a transient cylinder body
                    //SurfaceBody oCylBody = oTransientBRep.CreateSolidCylinderCone(oBottom, oTop, 2.5, 2.5, 2.5);
                    SurfaceBody oCylBody = oTransientBRep.CreateSolidCylinderCone(coneBottom, cylinderBottom, 2.5, 2.5, 2.5);
                    //  Union the cone and cylinder bodies
                    oTransientBRep.DoBoolean(oBody, oCylBody, BooleanTypeEnum.kBooleanTypeUnion);

                    //  Create client graphics based on the transient body
                    SurfaceGraphics oSurfaceGraphics = oSurfacesNode.AddSurfaceGraphics(oBody);
                    //  Update the view to see the resulting curves
                    InventorApp.ActiveView.Update();
                }
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
            }
        }
    }

I think perhaps I have misunderstood the Matrix translation required in this instance.

 

Any pointers will be gratefully received!

 

Thanks,

 

Alex.

Tags (1)
5 REPLIES 5
Message 2 of 6
AlexFielder
in reply to: AlexFielder

Thinking about this overnight (in the car on the way home!) I might not need to do this after all - not that doing it in the future wouldn't be handy!

 

I have the following example component:

 

BEFOREBEFOREAFTERAFTER

The selections for which are as follows:

 

Hole Tool Selections.gif

 

Given that I select the end face:

 

2017-11-08 09_18_11-Autodesk Inventor Professional 2017 - [DBE200040.IPT].png

 

This essentially gives me the Y axis for the sketch I need to create tangentially to the outer face.

 

I'm sure I have seen in recent days an example of how to get the x/y/z axes when presented with another perpendicular vector/axis.

 

Does anyone have an example of getting the x axis given a Y Direction (UnitVector or Face Normal)

 

Thanks,

 

Alex.

Message 3 of 6

Hi @AlexFielder,

 

The following blog would be helpful which talks about face normal.

 

http://adndevblog.typepad.com/manufacturing/2012/08/what-is-the-best-way-to-compute-a-normal-of-a-fa...

 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



Message 4 of 6

Thanks @chandra.shekar.g,

 

I figured it out in the end with the following:

 

private static void CreateSketchForPoints()
        {
            try
            {
                if (selectedFace != null && selectedWorkPlane != null)
                {
                    CreateCylinderDatumPoint();
                    originWP = partCompDef.WorkPoints[1];
                    newSketch = partCompDef.Sketches.Add(selectedWorkPlane);
                    newSketch.Name = "Sketch: Imported Excel Points";
                    newSketch.OriginPoint = datumWorkPoint;
                    
                    //selectedAxis.GetSize(out Inventor.Point axisOrigin, out Inventor.Point axisEnd);
                    //selectedWorkPlane.GetPosition(out Inventor.Point wpOrigin, out UnitVector wpXAxis, out UnitVector wpYAxis);

                    Plane selectedFacePlane = selectedEndFace.Geometry;
                    //the cylindernormal is the reverse normal of the selectedEndFace.
                    cylinderNormal = TransGeom.CreateUnitVector(-selectedFacePlane.Normal.X, -selectedFacePlane.Normal.Y, -selectedFacePlane.Normal.Z);
                    Vector newVector = TransGeom.CreateVector(cylinderNormal.X, cylinderNormal.Y, cylinderNormal.Z);
                    //Cylinder cylinder = selectedFace.Geometry;

                    //newSketch.AxisEntity = cylinder.AxisVector;
                    newSketchYAxis = partCompDef.WorkAxes.AddByRevolvedFace(selectedFace);
                    newSketchYAxis.Name = "Axis: Imported Excel Points Y";
                    newSketch.AxisEntity = newSketchYAxis;
                    newSketch.AxisIsX = false;
                    //NaturalAxisDirection defaults to true so only change it if we need to.
                    if (!newSketchYAxis.Line.Direction.IsEqualTo(cylinderNormal, HoleTolerance))
                    {
                        newSketch.NaturalAxisDirection = false;
                    }

                    foreach (SketchPoint sketchPoint in newSketch.SketchPoints)
                    {
                        if (sketchPoint.ReferencedEntity == datumWorkPoint)
                        {
                            OriginSketchPoint = sketchPoint;
                            break;
                        }
                    }
                    if (OriginSketchPoint == null)
                    {
                        OriginSketchPoint = (SketchPoint)newSketch.AddByProjectingEntity(datumWorkPoint); // partCompDef.WorkPoints[1]);
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
            }
        }

I also had to do some Matrix translations/rotations to get the points going in the correct orientation:

 

private static void CreateGeomForHolePositionComparisons()
        {
            try
            {
//#if DEBUG
//                ClientGraphics debuggingGraphics = null;
//                try
//                {
//                    debuggingGraphics = partCompDef.ClientGraphicsCollection["debuggingGraphics"];
//                    if (debuggingGraphics != null)
//                    {
//                        //delete the existing graphics
//                        debuggingGraphics.Delete();
//                        //and then add new ones.
//                        debuggingGraphics = partCompDef.ClientGraphicsCollection.Add("debuggingGraphics");
//                    }
//                }
//                catch (Exception)
//                {
//                    debuggingGraphics = partCompDef.ClientGraphicsCollection.Add("debuggingGraphics");
//                }
//#endif
                ObjectCollection objCollection = PartDoc.AttributeManager.FindObjects("RadialHole", "HolePositionX");

                originWP = partCompDef.WorkPoints[1];

                double[] endfaceParams = new double[2];
                double[] endFaceNormals = new double[3];
                endfaceParams[0] = 0;
                endfaceParams[1] = 0;
                selectedEndFace.Evaluator.GetNormal(endfaceParams, endFaceNormals);

                Plane selectedFacePlane = selectedEndFace.Geometry;

                selectedFacePlane.Evaluator.GetNormal(endfaceParams, endFaceNormals);

                selectedWorkPlane.GetPosition(out Inventor.Point tmpWPPoint, out UnitVector tmpXAxis, out UnitVector tmpYAxis);
                double percent = 0;
                double progress = 0;

                for (int i = 1; i < objCollection.Count + 1; i++)
                {
                    if (objCollection[i] is SketchPoint skpoint)
                    {
                        percent = (progress / objCollection.Count);
                        Reporter.UpdateStatusBar(percent, "Creating 3D Points for comparison with Sketch Points.");
                        AttributeSet AttSet = skpoint.AttributeSets[1];
                        Inventor.Attribute xPosAtt = null;
                        double xPosition = 0;
                        Inventor.Attribute yPosAtt = null;
                        double yPosition = 0;
                        
                        xPosAtt = AttSet["HolePositionX"];
                        xPosition = Convert.ToDouble(xPosAtt.Value);
                        yPosAtt = AttSet["HolePositionY"];
                        yPosition = Convert.ToDouble(yPosAtt.Value);

                        Inventor.Attribute holeName = AttSet["HoleName"];
                        string ThisHoleName = holeName.Value.ToString();
                        //creates a basic point for translation.
                        Inventor.Point tmpOriginPoint = TransGeom.CreatePoint(0, yPosition, datumWorkPoint.Point.Z);
                        Matrix originMatrix = TransGeom.CreateMatrix();
                        Matrix destinationMatrix = TransGeom.CreateMatrix();
                        originMatrix.SetTranslation(originWP.Point.VectorTo(datumWorkPoint.Point));
                        Vector originYVector = TransGeom.CreateVector(0, 1, 0);
                        originMatrix.SetToRotateTo(originYVector, cylinderNormal.AsVector());
                        tmpOriginPoint.TransformBy(originMatrix);
                        tmpOriginPoint.TranslateBy(originWP.Point.VectorTo(datumWorkPoint.Point));
                        //Inventor.Point tmpOriginPoint = TransGeom.CreatePoint(datumWorkPoint.Point.X, yPosition, datumWorkPoint.Point.Z);

                        double radius = selectedFace.Geometry.Radius;
                        double pi = Math.PI;
                        double circumference = ((2 * pi) * radius);
                        double arcLength = xPosition;
                        double arcAngle = (arcLength / ((2 * radius) * pi)) * 360;

                        Arc3d tmpArc = null;
                        tmpArc = TransGeom.CreateArc3d(tmpOriginPoint, cylinderNormal, selectedWorkPlane.Plane.Normal, radius, 0, (arcAngle * (pi / 180)));
//#if DEBUG
//                        GraphicsNode graphicsNode = debuggingGraphics.AddNode(1);
//                        CurveGraphics curveGraphics2 = graphicsNode.AddCurveGraphics(tmpArc);
//#endif
                        RadialHoleDefinition holeDef = (from RadialHoleDefinition hole in radialHoles
                                                        where hole.HoleName == ThisHoleName
                                                        select hole).FirstOrDefault();
                        if (holeDef?.HoleName.Length > 0)
                        {
                            holeDef.ComparisonPoint = tmpArc.EndPoint;
                        }
                        else
                        {
                            log.Error("One of the HoleDefinitions is incomplete.");
                            Reporter.UpdateStatusBar("One of the HoleDefinitions is incomplete, check the spreadsheet and run again!");
                        }
                        RadialHoles.m_InventorApp.ActiveView.Update();
                        progress++;
                    }
                }
            }
            catch (Exception ex)
            {
                log.Error(ex.Message);
            }


            //new3DSketch.curves
        }

So I'm pretty happy with the results so far.

 

Like I said earlier though, it would still be nice to figure out how to create a flip-able direction arrow - something I'm fairly confident I can do given that Matrices don't seem quite as challenging now the above is working.

 

Thanks,

 

Alex.

Message 5 of 6

That's great @AlexFielder!!!

 

I think, flip-able direction arrow can be achieved by Inverting Matrix (Matrix.Invert() API).

 

Thanks and regards,


CHANDRA SHEKAR G
Developer Advocate
Autodesk Developer Network



Message 6 of 6

Hi, Chandra,

Given the graphics sample of https://adndevblog.typepad.com/manufacturing/2015/01/create-transient-3d-arrow-with-clientgraphics.h... how do you flip the arrow direction using Matrix.Invert? I am quite confused with the use of Matrix.Invert method.

Thanks
Limin
Inventor pro 2023 64 bit update 2.1; Windows 10 pro 64 bit version 21H2; Office 2013 32 bit

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

Post to forums  

Autodesk Design & Make Report