How to create Sketches and Features using C++

By Philippe Leefsma

The sample code below is a C++ equivalent of “DrawBlockWithPocket” sample provided in the API Help files. It also illustrates how to use UnitsOfMeaure object to get string from a value.

#define pi 3.1415926535897932384626433832795

HRESULT DrawBlockWithPocket(CComPtr<Application> pApp)
{
    HRESULT hr = NOERROR;

    // Get part document template
    _bstr_t templateFilename = pApp->MethodGetTemplateFile(
        kPartDocumentObject,
        kDefaultSystemOfMeasure,
        kDefault_DraftingStandard,
        vtMissing);

    // Get Documents
    CComPtr<Documents> pDocs;
    hr = pApp->get_Documents(&pDocs);

    if (FAILED(hr))
        return hr;

    // Create a new part document
    CComPtr<Document> pDocument;
    hr = pDocs->Add(
        kPartDocumentObject,
        templateFilename,
        VARIANT_TRUE,
        &pDocument);

    if (FAILED(hr))
        return hr;

    // convert generic document to partdocument
    CComPtr<PartDocument> pPartDocument;
    hr = pDocument->QueryInterface(
        DIID_PartDocument,
        (void**)&pPartDocument);

    if (FAILED(hr))
        return hr;

    // Set a reference to the component definition.
    CComPtr<PartComponentDefinition>
        pPartComponentDefinition;
    hr = pPartDocument->get_ComponentDefinition(
        &pPartComponentDefinition);

    if (FAILED(hr))
        return hr;

    // Create a new sketch on the X-Y work plane
    //(Fixed predefined).
    // Since it's being created on one of the base
    //workplanes we know
    //the orientation it will be created
    // in and don't need to worry
    //about controlling it.
    // Because of this we also know the origin
    //of the sketch plane will be at (0,0,0) in model space.


    // Get PlanarSketches
    CComPtr<PlanarSketches> pSketches;
    hr = pPartComponentDefinition->get_Sketches(&pSketches);

    if (FAILED(hr)) return hr;

    // Get standard WorkPlanes
    CComPtr<WorkPlanes> pWorkPlanes ;
    hr = pPartComponentDefinition->get_WorkPlanes(&pWorkPlanes);
    if (FAILED(hr)) return hr;

    CComPtr<WorkPlane> pWorkPlane ;
    hr= pWorkPlanes->get_Item(
        _variant_t(3L, VT_I4),
        &pWorkPlane);

    if (FAILED(hr))
        return hr;

    CComPtr<PlanarSketch> pSketch;
    hr = pSketches->Add(
        _variant_t((IDispatch *) pWorkPlane),
        VARIANT_FALSE,
        &pSketch);

    if (FAILED(hr))
        return hr;

    // Set a reference to the transient geometry object.

    CComPtr<TransientGeometry> pTrGeom;
    pTrGeom = pApp->TransientGeometry;

    // Draw a 4cm x 3cm rectangle with the corner at (0,0)

    CComPtr<Point2d> pPt1;
    hr = pTrGeom->CreatePoint2d(0.0,0.0,&pPt1);

    if (FAILED(hr))
        return hr;

    CComPtr<Point2d> pPt2;
    hr = pTrGeom->CreatePoint2d(4.0,3.0,&pPt2);

    if (FAILED(hr))
        return hr;

    // Create sketch points from above points
    // Get SkecthPoints
    CComPtr<SketchPoints> pSkPoints;
    hr = pSketch->get_SketchPoints(&pSkPoints);

    if (FAILED(hr))
        return hr;

    CComPtr<SketchPoint> pSpt1;
    hr = pSkPoints->Add(pPt1,VARIANT_FALSE,&pSpt1);

    if (FAILED(hr))
        return hr;

    CComPtr<SketchPoint> pSpt2;
    hr = pSkPoints->Add(pPt2,VARIANT_FALSE,&pSpt2);

    if (FAILED(hr))
        return hr;

    CComPtr<SketchEntitiesEnumerator> pRectangleLines;
    // Get SketchLines
    CComPtr<SketchLines> pSkLines;
    hr = pSketch->get_SketchLines(&pSkLines);

    if (FAILED(hr))
        return hr;

    // Creat a rectangle from two points
    hr = pSkLines->AddAsTwoPointRectangle(
        _variant_t((IDispatch *) pSpt1),
        _variant_t((IDispatch *) pSpt2),
        &pRectangleLines);

    if (FAILED(hr))
        return hr;

    // Create a profile.
    // Get Profiles
    CComPtr<Profiles> pSkProfiles;
    hr = pSketch->get_Profiles(&pSkProfiles);

    if (FAILED(hr))
        return hr;

    CComPtr<ObjectCollection> pOC;
    hr = pApp->TransientObjects->CreateObjectCollection(vtMissing, &pOC);

    if (FAILED(hr))
        return hr;

    CComPtr<Profile> pSkProfile;
    hr = pSkProfiles->AddForSolid(
        VARIANT_FALSE,
        CComVariant(pOC),
        vtMissing,
        &pSkProfile);

    if (FAILED(hr))
        return hr;

    // Create a base extrusion 1cm thick.
    // Get Features
    CComPtr<PartFeatures> pFeatures;
    hr = pPartComponentDefinition->get_Features(&pFeatures);

    if (FAILED(hr))
        return hr;

    // Get Extrude Features
    CComPtr <ExtrudeFeatures> pExtrudeFeatures;
    hr = pFeatures->get_ExtrudeFeatures(&pExtrudeFeatures);

    if (FAILED(hr))
        return hr;

    // Create base extrusion

    // get Units object from document
    CComPtr<UnitsOfMeasure> pUOM;
    hr = pDocument->get_UnitsOfMeasure(&pUOM);

    if (FAILED(hr))
        return hr;

    CComBSTR pAngUnits;
    hr = pUOM->GetStringFromValue(10.0*(pi/180.0) , _variant_t("deg"), &pAngUnits);

    if (FAILED(hr))
        return hr;

    CComPtr<ExtrudeFeature> pExtrude;

    hr = pExtrudeFeatures->AddByDistanceExtent(
        pSkProfile,
        _variant_t(1.0)/* thickness in cm */,
        kNegativeExtentDirection,
        kJoinOperation,
        _variant_t(pAngUnits), /* taper in radians */
        &pExtrude);

    if (FAILED(hr))
        return hr;

    // Get the top face of the extrusion to use for creating the new sketch.

    // Get StartFaces from base Extrusion
    CComPtr<Faces> pFaces;
    hr = pExtrude->get_StartFaces(&pFaces);

    if (FAILED(hr))
        return hr;

    CComPtr<Face> pFace;
    hr = pFaces->get_Item(1L,&pFace);

    if (FAILED(hr))
        return hr;

    // Create a new sketch on this face, but use the method that allows you to
    // control the orientation and orgin of the new sketch.

    // Get the fixed work Axis (X)
    CComPtr<WorkAxes> pWorkAxes;
    hr = pPartComponentDefinition->get_WorkAxes(&pWorkAxes);

    if (FAILED(hr))
        return hr;

    CComPtr<WorkAxis> pWorkAxis;
    hr = pWorkAxes->get_Item(_variant_t(1L),&pWorkAxis);

    if (FAILED(hr))
        return hr;

    // Get the fixed work point (0,0,0)
    CComPtr<WorkPoints> pWorkPoints;
    hr = pPartComponentDefinition->get_WorkPoints(&pWorkPoints);

    if (FAILED(hr))
        return hr;

    CComPtr<WorkPoint> pWorkPoint;
    hr = pWorkPoints->get_Item(_variant_t(1L),&pWorkPoint);

    if (FAILED(hr))
        return hr;

    pSketch=NULL;
    hr = pSketches->AddWithOrientation(
        _variant_t((IDispatch*)pFace),
        _variant_t((IDispatch*)pWorkAxis),
        VARIANT_TRUE,
        VARIANT_TRUE,
        _variant_t((IDispatch*)pWorkPoint),
        VARIANT_FALSE,
        &pSketch);

    if (FAILED(hr))
        return hr;

    // Determine where in sketch space the point (0.5,0.5,0) is.
    CComPtr<Point> pPt;
    hr = pTrGeom->CreatePoint(0.5,0.5,0.0,&pPt);

    if (FAILED(hr))
        return hr;

    CComPtr<Point2d> pCorner1;
    hr = pSketch->ModelToSketchSpace(pPt,&pCorner1);

    if (FAILED(hr))
        return hr;

    CComPtr<Point2d> pCorner2;
    hr = pTrGeom->CreatePoint2d(pCorner1->GetX()+3,pCorner1->GetY()+2,&pCorner2);

    if (FAILED(hr))
        return hr;

    pSpt1 = NULL;
    pSpt2 = NULL;
    pSkPoints=NULL;

    hr = pSketch->get_SketchPoints(&pSkPoints);

    if (FAILED(hr))
        return hr;

    hr = pSkPoints->Add(pCorner1,VARIANT_FALSE,&pSpt1);

    if (FAILED(hr))
        return hr;

    hr = pSkPoints->Add(pCorner2,VARIANT_FALSE,&pSpt2);

    if (FAILED(hr))
        return hr;


    // Create the interior 3cm x 2cm rectangle for the pocket.
    pRectangleLines = NULL;
    pSkLines = NULL;
    hr = pSketch->get_SketchLines(&pSkLines);

    if (FAILED(hr))
        return hr;

    hr = pSkLines->AddAsTwoPointRectangle(
        _variant_t((IDispatch*)pSpt1),
        _variant_t((IDispatch*)pSpt2),
        &pRectangleLines);

    if (FAILED(hr))
        return hr;

    // Create a profile.
    pSkProfile = NULL;
    pSkProfiles = NULL;

    hr = pSketch->get_Profiles(&pSkProfiles);

    if (FAILED(hr))
        return hr;

    hr = pSkProfiles->AddForSolid(
        VARIANT_FALSE,
        CComVariant(pOC),
        vtMissing,
        &pSkProfile);

    if (FAILED(hr))
        return hr;

    //Create a pocket .25 cm deep with -10 deg taper.
    pExtrude = NULL;
    hr = pExtrudeFeatures->AddByDistanceExtent(
        pSkProfile,
        _variant_t(0.25),
        kNegativeExtentDirection,
        kCutOperation,
        _variant_t("-10.0 deg"), // taper
        &pExtrude);

    if (FAILED(hr))
        return hr;

    // Fit the view and set the camera to ISO TOP RIGHT
    CComPtr<View> pView;
    hr = pApp->get_ActiveView(&pView);
    hr = pView->Fit(VARIANT_TRUE);
    CComPtr<Camera> pCamera;
    hr = pView->get_Camera(&pCamera);
    hr = pCamera->put_ViewOrientationType(kIsoTopRightViewOrientation);
    hr = pCamera->Apply();

    return hr;
}

img


Comments

Leave a Reply

Discover more from Autodesk Developer Blog

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

Continue reading