Simple Exploration on CAM Simulation

By Xiaodong Liang

Autodesk provides solutions of CAM: Inventor CAM, CAM 360 etc. Some custom applications of Inventor would need to produce their own CAM process with the custom algorism.

I explored a bit with Inventor API. Basically, we need to get the update to date status of the base body that the tool has affected, by TransientBrep.DoBoolean, and display them by client graphics.

TransientBRep.DoBoolean(BlankBody As SurfaceBody,
    ToolBody As SurfaceBody,
    BooleanType As BooleanTypeEnum)

BlankBody: Input/Output SurfaceBody that will be modified as a result.

ToolBody: Input SurfaceBody that is used to operate on the blank body.

BooleanType: Input BooleanTypeEnum that specifies the type of Boolean operation to perform. Valid values are kBooleanTypeDifference, kBooleanTypeUnion, and kBooleanTypeIntersect.

In CAM simulation, the BooleanType is kBooleanTypeDifference which means the tool will remove the materials of the base body.

If you are not familiar with client graphics, I’d recommend with the tutorials we posted on Brian’s blog.

The following demo tests with the attached part in a standalone EXE, in which there are one plate which is base body and a small stick as a tool. The tool will move on X-Y plane and inside the base body along Z (depth = 1cm). It removes the material from the diameter = 4 cm and shrink to diameter = 0.

Download CamPart

Inventor.Application oInvApp;
Asset toolAppearance;
Asset baseAppearance;

void CamTest()
{
    //get active Inventor process
    oInvApp =
        System.Runtime.InteropServices.Marshal.
        GetActiveObject("Inventor.Application")
        as Inventor.Application;

    //get active document
    PartDocument oPartDoc =
        oInvApp.ActiveDocument as PartDocument;
    PartComponentDefinition oPartDef =
        oPartDoc.ComponentDefinition;

    //Transient Brep object
    TransientBRep oTBrep =
        oInvApp.TransientBRep;
    //Transient Geometry
    TransientGeometry oTG =
        oInvApp.TransientGeometry;

    //base body
    SurfaceBody oBaseBody =
        oPartDef.SurfaceBodies[1];
    //tool body
    SurfaceBody oToolBody =
        oPartDef.SurfaceBodies[2];

    //make base body and tool body invisible
    //we just show client graphics
    oBaseBody.Visible = false;
    oToolBody.Visible = false;

    //make a copy of base body and tool body
    //we will use them as client graphics
    SurfaceBody oBaseBody_Copy =
        oTBrep.Copy(oBaseBody);
    SurfaceBody oToolBody_Copy =
        oTBrep.Copy(oToolBody);

    //Client Graphics
    ClientGraphics oClientGraphics;
    try
    {
        //delete if the Client Graphics exists
        oClientGraphics =
            oPartDef.ClientGraphicsCollection["CAMDemo"];

        // An existing client graphics object
        // was successfully obtained so clean up.
        oClientGraphics.Delete();

        // update the display to see the results.
        oInvApp.ActiveView.Update();
    }
    catch
    {
        //get the appearance for tool
        toolAppearance =
            oPartDoc.Assets["Gold - Metal"];

        baseAppearance =
            oPartDoc.Assets["Plate"];

        // Create the ClientGraphics
        oClientGraphics =
            oPartDef.ClientGraphicsCollection.Add("CAMDemo");

        //add graphics node for base body
        GraphicsNode _oNode_BaseBody =
            oClientGraphics.AddNode(1);
        //add graphics of base body
        SurfaceGraphics _Gra_BaseBody =
            _oNode_BaseBody.AddSurfaceGraphics(oBaseBody_Copy);
        _oNode_BaseBody.Appearance = baseAppearance;

        //add graphics node for tool body
        GraphicsNode _oNode_ToolBody =
            oClientGraphics.AddNode(2);
        //add graphics of tool body
        SurfaceGraphics _Gra_ToolBody =
            _oNode_ToolBody.AddSurfaceGraphics(oToolBody_Copy);
        _oNode_ToolBody.Appearance = toolAppearance;

        //CAM Simulation starts:

        //move tool inside the base along Z
        Matrix oMovingM =
            oTG.CreateMatrix();
        oMovingM.SetTranslation(oTG.CreateVector(0, 0, -1));

        //move tool inside base body: depth = 1
        eachCAM(oMovingM,
            ref oBaseBody_Copy,
            ref oToolBody_Copy,
            ref _oNode_BaseBody,
            ref _oNode_ToolBody,
            ref _Gra_BaseBody,
            ref _Gra_ToolBody);

        // diameter of the tool body
        double toolDia = 0.5;

        // how many circle loops the tool will move
        int loopCount = 10;
        //from which diamater the tool starts to move
        double max_CAM_Dia = 4.0;

        //last matrix of the tool body
        Matrix oLastMovingM = oTG.CreateMatrix();
        oLastMovingM.SetToIdentity();

        //tool moves from max diameter to 0
        for (int circleLoop = loopCount;
             circleLoop > 0 ;
             circleLoop--)
        {
            //diameter of this loop
            double thisDia = max_CAM_Dia * circleLoop / loopCount;
            //the perimeter of this circle
            double perimeterofLoop = Math.PI * thisDia;
            //how many steps the tool needs to move for this loop
            int circleStepCount =
                (int)(perimeterofLoop / toolDia) * 2;

            //moving of each circle
            for (int angleIndex = 1;
                 angleIndex < circleStepCount;
                 angleIndex++)
            {
                //get the location the tool will move to
                double x = thisDia / 2.0 *
                           Math.Cos(angleIndex * Math.PI * 2 / circleStepCount);
                double y = thisDia / 2.0 *
                           Math.Sin(angleIndex * Math.PI * 2 / circleStepCount );

                //transform matrix
                Matrix oEachMovingM = oTG.CreateMatrix();
                oEachMovingM.SetTranslation(oTG.CreateVector(x, y, 0));
                //the last location of the tool affects
                //so invert and update with the new matrix
                oLastMovingM.Invert();
                oLastMovingM.TransformBy(oEachMovingM);
                oMovingM = oLastMovingM;

                //move
                eachCAM(oMovingM,
                    ref oBaseBody_Copy,
                    ref oToolBody_Copy,
                    ref _oNode_BaseBody,
                    ref _oNode_ToolBody,
                    ref _Gra_BaseBody,
                    ref _Gra_ToolBody);

                //record the current matrix for next use
                oLastMovingM = oEachMovingM;
            }
        }
    }
}

// each step of moving
void eachCAM(Matrix _oMovingM,
    ref SurfaceBody _BaseBody,
    ref SurfaceBody _ToolBody,
    ref GraphicsNode _BaseBodyNode,
    ref GraphicsNode _ToolBodyNode,
    ref SurfaceGraphics _BaseGrap,
    ref SurfaceGraphics _ToolGrap)
{
    TransientBRep oTBrep = oInvApp.TransientBRep;

    // we need to recreate the graphics.
    _BaseGrap.Delete();
    _ToolGrap.Delete();

    //transform the tool body
    oTBrep.Transform(_ToolBody, _oMovingM);
    //remove material of the base body
    oTBrep.DoBoolean(_BaseBody, _ToolBody,
        BooleanTypeEnum.kBooleanTypeDifference);

    //add the update bodies again
    _BaseGrap = _BaseBodyNode.AddSurfaceGraphics(_BaseBody);
    _ToolGrap = _ToolBodyNode.AddSurfaceGraphics(_ToolBody);
    //assign the appearance to the tool graphics

    _BaseBodyNode.Appearance = baseAppearance;
    _ToolBodyNode.Appearance = toolAppearance;
    //update the view
    oInvApp.ActiveView.Update();
}

Untitled

Note: the residual images in this gif is caused by the video production. There is no residual when working with Inventor.


Comments

One response to “Simple Exploration on CAM Simulation”

  1. all software keys download her!

Leave a Reply

Discover more from Autodesk Developer Blog

Subscribe now to keep reading and get access to the full archive.

Continue reading