Help with API in C++: Selecting a face and axis and revolving a sketch

Help with API in C++: Selecting a face and axis and revolving a sketch

ArjayHawco
Contributor Contributor
566 Views
4 Replies
Message 1 of 5

Help with API in C++: Selecting a face and axis and revolving a sketch

ArjayHawco
Contributor
Contributor

Hi, I'm trying to use the API to revolve a sketch around an axis of an existing extrusion.

 

The attached photo shows a cylinder created from a sketch off the XY plane and a sketch created from the face of the cylinder off the Z axis.


I need help to programmatically select the desired face and axis of the existing extrusion to begin the sketch and then revolve the sketch around the axis to form a new extrusion.

FusionApi.png

Your help is greatly appreciated.

Thanks

 

0 Likes
Accepted solutions (1)
567 Views
4 Replies
Replies (4)
Message 2 of 5

ArjayHawco
Contributor
Contributor

I'm clearly missing the fundamentals here.  Are there any step-by-step tutorials available that would walk a user through the basics and provide the c++ code for each step?

I'm looking for something more than the existing api samples that provide code but seem to be lacking explanation.

0 Likes
Message 3 of 5

ArjayHawco
Contributor
Contributor

I'm getting closer.  I was able to make the sketch but am having trouble getting the sketch profile so the revolve feature fails.  I'm getting the following error: "invalid profile(s) for Revolve Feature".  I'm retrieving the profile based on the revolve sample: https://help.autodesk.com/view/fusion360/ENU/?guid=GUID-407f1b28-fd08-11e4-a671-3417ebd3d5be (converted to C++). 

Thanks for the help.

 

#include <Core/CoreAll.h>
#include <Fusion/FusionAll.h>
#include <Cam/CamAll.h>

#include <sstream>
#define _USE_MATH_DEFINES
#include <math.h>
#include <numeric>
#include <cmath>
#include <memory>
#include <windows.h>

using namespace adsk::core;
using namespace adsk::fusion;
using namespace adsk::cam;

// Globals
const std::string _units = "mm";

Ptr<Application> _app;
Ptr<UserInterface> _ui;

Ptr<TextBoxCommandInput> _errMessage;

bool checkReturn(Ptr<Base> returnObj)
{
    if (returnObj)
        return true;
    else if (_app && _ui)
    {
        std::string errDesc;
        _app->getLastError(&errDesc);
        _ui->messageBox(errDesc);
        return false;
    }
    else
        return false;
}


extern "C" XI_EXPORT bool run(const char* context)
{
    _app = Application::get();
    if (!checkReturn(_app))
        return false;

    _ui = _app->userInterface();
    if (!checkReturn(_ui))
        return false;

    double cmRadiusBase = 5.0;
    double cmRadiusHole = 1.0;
    double cmWidth = 2.0;

    Ptr<Documents> documents = _app->documents();
    if (!documents)
        return false;

    Ptr<Document> doc = documents->add(DocumentTypes::FusionDesignDocumentType);
    if (!doc)
        return false;

    Ptr<Product> product = _app->activeProduct();
    if (!product)
        return false;

    Ptr<Design> design = product;
    if (!checkReturn(design))
        return false;

    // Get the root component of the active design
    Ptr<Component> component = design->rootComponent();
    if (!checkReturn(component))
        return false;

    // Create a new sketch.
    Ptr<Sketches> sketches = component->sketches();
    if (!checkReturn(sketches))
        return nullptr;

    Ptr<ConstructionPlane> xyPlane = component->xYConstructionPlane();
    if (!checkReturn(xyPlane))
        return nullptr;

    Ptr<Sketch> baseSketch = sketches->add(xyPlane);
    if (!checkReturn(xyPlane))
        return nullptr;

    // Draw a circle for the base.
    baseSketch->sketchCurves()->sketchCircles()->addByCenterRadius(adsk::core::Point3D::create(0, 0, 0), cmRadiusBase);
    if (!checkReturn(baseSketch))
        return nullptr;

    // Draw a circle for the center hole, if the value is greater than 0.
    Ptr<Profile> prof = nullptr;
    if (cmRadiusHole - (_app->pointTolerance() * 2) > 0)
    {
        Ptr<SketchCircle> circ = baseSketch->sketchCurves()->sketchCircles()->addByCenterRadius(
            adsk::core::Point3D::create(0, 0, 0), cmRadiusHole);
        if (!checkReturn(circ))
            return nullptr;

        // Find the profile that uses both circles.
        for (Ptr<Profile> tempProf : baseSketch->profiles())
        {
            if (tempProf->profileLoops()->count() == 2)
            {
                prof = tempProf;
                break;
            }
        }
    }
    else
    {
        // Use the single profile.
        prof = baseSketch->profiles()->item(0);
    }

    if (!checkReturn(prof))
        return nullptr;

    // Extrude the circle to create the base of the pulley.

    // Create an extrusion input to be able to define the input needed for an extrusion
    // while specifying the profile and that a new component is to be created
    Ptr<ExtrudeFeatures> extrudes = component->features()->extrudeFeatures();
    if (!checkReturn(extrudes))
        return nullptr;

    Ptr<ExtrudeFeatureInput> extInput = extrudes->createInput(prof, NewBodyFeatureOperation);
    if (!checkReturn(extInput))
        return nullptr;

    // Define that the extent is a distance extent of the pulley width.
    Ptr<ValueInput> distance = adsk::core::ValueInput::createByReal(cmWidth);
    if (!checkReturn(distance))
        return nullptr;

    bool result = extInput->setDistanceExtent(false, distance);
    if (!result)
        return nullptr;

    // Create the extrusion.
    Ptr<ExtrudeFeature> baseExtrude = extrudes->add(extInput);
    if (!checkReturn(baseExtrude))
        return nullptr;

    // Create the revolve sketch (a rectangle)
    Ptr<ConstructionPlane> yzPlane = component->yZConstructionPlane();
    if (!checkReturn(yzPlane))
        return nullptr;

    Ptr<Sketch> sketchSideRailA = sketches->add(yzPlane);
    if (!checkReturn(sketchSideRailA))
        return nullptr;

    auto length = cmRadiusBase + 10.0;

    auto pointStart = Point3D::create(0, cmRadiusHole);
    auto pointEnd = Point3D::create(1.0, length);

    auto rect = sketchSideRailA->sketchCurves()->sketchLines()->addTwoPointRectangle(pointStart, pointEnd);

    // Create a revolve input.
    auto profile = sketchSideRailA->profiles()->item(0);

    auto axisLine = sketchSideRailA->sketchCurves()->sketchLines()->addByTwoPoints(Point3D::create(0, 0, 0), Point3D::create(1.0, 0, 0));
    axisLine->isConstruction(true);

    auto revolveFeatures = component->features()->revolveFeatures();
    auto revolveInput = revolveFeatures->createInput(profile, axisLine, FeatureOperations::NewBodyFeatureOperation);

    // Set the angle for the revolve.
    revolveInput->setAngleExtent(false, ValueInput::createByReal(2 * M_PI));

    // Create the revolve feature.
    Ptr<RevolveFeature> revolveFeature = revolveFeatures->add(revolveInput);

    if (!checkReturn(revolveFeature))
    {
        _ui->messageBox("Failed to create revolve feature");
        return false;
    }
}

extern "C" XI_EXPORT bool stop(const char* context)
{
    if (_ui)
    {
        _ui->messageBox("Stop addin");
        _ui = nullptr;
    }

    return true;
}

#ifdef XI_WIN

#include <windows.h>

BOOL APIENTRY DllMain(HMODULE hmodule, DWORD reason, LPVOID reserved)
{
    switch (reason)
    {
    case DLL_PROCESS_ATTACH:
    case DLL_THREAD_ATTACH:
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

#endif // XI_WIN

 

0 Likes
Message 4 of 5

boopathi.sivakumar
Autodesk
Autodesk
Accepted solution

Hi @ArjayHawco 

It seems like you are modifying the sketch after creating the profile for revlove input, seems like fusion didn't like that even though the profile don't have conflits with the new sketch entity. 
Instead of this 

    auto rect = sketchSideRailA->sketchCurves()->sketchLines()->addTwoPointRectangle(pointStart, pointEnd);

    // Create a revolve input.
    auto profile = sketchSideRailA->profiles()->item(0);

    auto axisLine = sketchSideRailA->sketchCurves()->sketchLines()->addByTwoPoints(Point3D::create(0, 0, 0), Point3D::create(1.0, 0, 0));
    axisLine->isConstruction(true);

    auto revolveFeatures = component->features()->revolveFeatures();

 Changing it to like below would solve the problem

    auto rect = sketchSideRailA->sketchCurves()->sketchLines()->addTwoPointRectangle(pointStart, pointEnd);

    auto axisLine = sketchSideRailA->sketchCurves()->sketchLines()->addByTwoPoints(Point3D::create(0, 0, 0), Point3D::create(1.0, 0, 0));
    axisLine->isConstruction(true);

    // Create a revolve input.
    auto profile = sketchSideRailA->profiles()->item(0);

    auto revolveFeatures = component->features()->revolveFeatures();

Boopathi Sivakumar
Senior Technology Consultant

0 Likes
Message 5 of 5

ArjayHawco
Contributor
Contributor
I appreciate the explanation - it makes sense. I was incorrectly assuming that a pointer was being returned when retrieving the profile rather than some sort of completed geometry.

Thanks much.
0 Likes