AMCAX Kernel 1.0.0.0
NURBS Modeling Sample

Overview

This tutorial provides the basic usage of AMCAX NURBS module to model a pipe model.

Model Preview

This tutorial uses a pipe model to show some of main modeling functionalities in the AMCAX NURBS module. The model is shown in the figure below:

The pipe model

The model consists of three NURBS surfaces:

  1. The pipe at the left side.
  2. The blend pipe in the middle.
  3. The circular section pipe at the right side.

We will introduce the construction methods step-by-step.

Building the pipe at the left side

Creating the ellipse section curve

The first step is to create an ellipse using the AMCAX::Geom3Ellipse class.

std::shared_ptr<AMCAX::Geom3Ellipse> gellipse = std::make_shared<AMCAX::Geom3Ellipse>(AMCAX::Frame3(), 0.7, 0.5);
gellipse->Translate(AMCAX::Vector3(3.0, 0.0, 0.0));

Creating the B-Spline section curve

The second step is to create a B-Spline curve using the AMCAX::NURBSAPIBuildCurve class.

std::vector<AMCAX::Point3> sectionPoles;
sectionPoles.push_back(AMCAX::Point3(0.5, 0.5, 1.5));
sectionPoles.push_back(AMCAX::Point3(0.5, -0.25, 1.5));
sectionPoles.push_back(AMCAX::Point3(0.5, -0.75, 2.0));
sectionPoles.push_back(AMCAX::Point3(0.5, -0.25, 2.5));
sectionPoles.push_back(AMCAX::Point3(0.5, 0.5, 2.5));
sectionPoles.push_back(AMCAX::Point3(0.5, 0.0, 2.0));
std::shared_ptr<AMCAX::Geom3BSplineCurve> endingProfileCurve = AMCAX::NURBSAPIBuildCurve::BuildCurve(sectionPoles, 3, true);
static AMCAX_API std::shared_ptr< Geom3BSplineCurve > BuildCurve(const std::vector< Point3 > &poles, int degree, bool isPeriodic)
Build BSpline curve.

Creating the guide curve

The third step is to create a B-Spline guide curve using the AMCAX::NURBSAPIBuildCurve class.

std::vector<AMCAX::Point3> guidePoles;
guidePoles.push_back(AMCAX::Point3(3.0, 0.5, 0.0));
guidePoles.push_back(AMCAX::Point3(3.0, 0.5, 2.0));
guidePoles.push_back(AMCAX::Point3(0.5, 0.5, 2.0));
std::shared_ptr<AMCAX::Geom3BSplineCurve> guide = AMCAX::NURBSAPIBuildCurve::BuildCurve(guidePoles, 2, false);

Applying the one rail sweeping

Finally, create the swept surface by using the AMCAX::NURBSAPISweep class.

std::vector<std::pair<int, double>> guideCorrParams;
std::vector<AMCAX::NURBSCurveSection> profiles;
profiles.push_back(AMCAX::NURBSCurveSection(gellipse));
profiles.push_back(AMCAX::NURBSCurveSection(endingProfileCurve));
auto sweptSurfaces = AMCAX::NURBSAPISweep::SweepOneRail(profiles, guide, 0.0, guideCorrParams, false, true);
std::shared_ptr<AMCAX::Geom3BSplineSurface> complexPipe = sweptSurfaces.front();
static AMCAX_API std::vector< std::shared_ptr< Geom3BSplineSurface > > SweepOneRail(const std::shared_ptr< Geom3BSplineCurve > &profile, const std::shared_ptr< Geom3BSplineCurve > &spine, bool isParallel)
Sweep a profile along a spine.
Class of curve section.
Definition: NURBSCurveSection.hpp:17

Click here example01 to get the complete source code for the above example, which you can download according to your learning needs.

Building the circular section pipe at the right side

Construct the center curve

The shape of the center curve is similar to a quarter of an ellipse.

std::vector<AMCAX::Point3> centerCurvePoles;
centerCurvePoles.push_back(AMCAX::Point3(-3.0, 0.0, 0.0));
centerCurvePoles.push_back(AMCAX::Point3(-3.0, 0.0, 2.0));
centerCurvePoles.push_back(AMCAX::Point3(-1.0, 0.0, 2.0));
std::shared_ptr<AMCAX::Geom3BSplineCurve> centerCurve = AMCAX::NURBSAPIBuildCurve::BuildCurve(centerCurvePoles, 2, false);

Setting the spine

Here, we simply set the center curve as the spine.

std::shared_ptr<AMCAX::Geom3BSplineCurve> spine = centerCurve;
double spineLeftBound = spine->FirstParameter();
double spineRightBound = spine->LastParameter();

Setting the circular section radius

Here, we simply set the radius of all the circular sections to a fixed value of 0.5.

radiusLaw.Set(0.5, 0.0, 1.0);
Class of constant law function.
Definition: LawConstant.hpp:12
AMCAX_API void Set(double r, double pf, double pl)
Set the parameters.

Creating swept surface

Next, we use the AMCAX::NURBSAPICircularSweep class to create the swept surface.

auto [status, circlePipe] = AMCAX::NURBSAPICircularSweep::SweepWithCenterAndRadius(centerCurve, radiusLaw, spine, spineLeftBound, spineRightBound);
if (status != AMCAX::NURBSSweepStatus::Success || !circlePipe)
{
return;
}
static AMCAX_API std::pair< NURBSSweepStatus, std::shared_ptr< Geom3BSplineSurface > > SweepWithCenterAndRadius(const std::shared_ptr< Geom3BSplineCurve > &centerCurve, const LawFunction &radiusLaw, const std::shared_ptr< Geom3BSplineCurve > &spine, double spineLeftBound, double spineRightBound)
Sweep with circular profile defined by a center curve and a radius.

Click here example02 to get the complete source code for the above example, which you can download according to your learning needs.

Creating the blend pipe in the middle

Finally, we build the blend pipe in the middle.

Setting the parameters of the blend surface

std::vector<double> parameters1 = {1.0, 1.0};
std::vector<double> parameters2 = {1.0, 1.0};
std::vector<double> tol = {0.001, 0.1 * M_PI / 180.0, 0.05};

Creating the blend pipe

std::shared_ptr<AMCAX::Geom3BSplineSurface> blendSurface = AMCAX::NURBSAPIBlend::BlendSurfaces(circlePipe, false, false, AMCAX::ContinuityType::G2, parameters1, complexPipe, false, false, AMCAX::ContinuityType::G2, parameters2, true, true, tol);
static AMCAX_API std::shared_ptr< Geom3BSplineSurface > BlendSurfaces(const std::shared_ptr< Geom3BSplineSurface > &surf1, bool isUIso1, bool isFront1, ContinuityType cont1, std::vector< double > &parameters1, const std::shared_ptr< Geom3BSplineSurface > &surf2, bool isUIso2, bool isFront2, ContinuityType cont2, std::vector< double > &parameters2, bool autoReverse, bool isPrecise, const std::vector< double > &tol)
Given two surfaces, a blend surface to connect the two surfaces is constructed.

Click here example03 to get the full source code of the NURBS modeling example, you can download it according to your learning needs.

Appendix

The complete code of this sample is listed here:

#include <memory>
#include <vector>
void TestPipe()
{
// build a complex pipe
// build section curves
std::shared_ptr<AMCAX::Geom3Ellipse> gellipse = std::make_shared<AMCAX::Geom3Ellipse>(AMCAX::Frame3(), 0.7, 0.5);
gellipse->Translate(AMCAX::Vector3(3.0, 0.0, 0.0));
std::vector<AMCAX::Point3> sectionPoles;
sectionPoles.push_back(AMCAX::Point3(0.5, 0.5, 1.5));
sectionPoles.push_back(AMCAX::Point3(0.5, -0.25, 1.5));
sectionPoles.push_back(AMCAX::Point3(0.5, -0.75, 2.0));
sectionPoles.push_back(AMCAX::Point3(0.5, -0.25, 2.5));
sectionPoles.push_back(AMCAX::Point3(0.5, 0.5, 2.5));
sectionPoles.push_back(AMCAX::Point3(0.5, 0.0, 2.0));
std::shared_ptr<AMCAX::Geom3BSplineCurve> endingProfileCurve = AMCAX::NURBSAPIBuildCurve::BuildCurve(sectionPoles, 3, true);
// build guide curves
std::vector<AMCAX::Point3> guidePoles;
guidePoles.push_back(AMCAX::Point3(3.0, 0.5, 0.0));
guidePoles.push_back(AMCAX::Point3(3.0, 0.5, 2.0));
guidePoles.push_back(AMCAX::Point3(0.5, 0.5, 2.0));
std::shared_ptr<AMCAX::Geom3BSplineCurve> guide = AMCAX::NURBSAPIBuildCurve::BuildCurve(guidePoles, 2, false);
// sweeping to build surface
std::vector<std::pair<int, double>> guideCorrParams;
std::vector<AMCAX::NURBSCurveSection> profiles;
profiles.push_back(AMCAX::NURBSCurveSection(gellipse));
profiles.push_back(AMCAX::NURBSCurveSection(endingProfileCurve));
auto sweptSurfaces = AMCAX::NURBSAPISweep::SweepOneRail(profiles, guide, 0.0, guideCorrParams, false, true);
std::shared_ptr<AMCAX::Geom3BSplineSurface> complexPipe = sweptSurfaces.front();
// build a circle section pipe
// build the pipe center curve
std::vector<AMCAX::Point3> centerCurvePoles;
centerCurvePoles.push_back(AMCAX::Point3(-3.0, 0.0, 0.0));
centerCurvePoles.push_back(AMCAX::Point3(-3.0, 0.0, 2.0));
centerCurvePoles.push_back(AMCAX::Point3(-1.0, 0.0, 2.0));
std::shared_ptr<AMCAX::Geom3BSplineCurve> centerCurve = AMCAX::NURBSAPIBuildCurve::BuildCurve(centerCurvePoles, 2, false);
// set the center curve as the spine
std::shared_ptr<AMCAX::Geom3BSplineCurve> spine = centerCurve;
double spineLeftBound = spine->FirstParameter();
double spineRightBound = spine->LastParameter();
// set the radius
AMCAX::LawConstant radiusLaw;
radiusLaw.Set(0.5, 0.0, 1.0);
// sweep to make the circle section pipe
auto [status, circlePipe] = AMCAX::NURBSAPICircularSweep::SweepWithCenterAndRadius(centerCurve, radiusLaw, spine, spineLeftBound, spineRightBound);
if (status != AMCAX::NURBSSweepStatus::Success || !circlePipe)
{
return;
}
// set the parameters
std::vector<double> parameters1 = {1.0, 1.0};
std::vector<double> parameters2 = {1.0, 1.0};
std::vector<double> tol = {0.001, 0.1 * M_PI / 180.0, 0.05};
std::shared_ptr<AMCAX::Geom3BSplineSurface> blendSurface = AMCAX::NURBSAPIBlend::BlendSurfaces(circlePipe, false, false, AMCAX::ContinuityType::G2, parameters1, complexPipe, false, false, AMCAX::ContinuityType::G2, parameters2, true, true, tol);
}
Class of 3D B spline curve.
Class of 3D B spline surface.
Class of 3D circle.
Class of 3D ellipse.
Class of constant law function.
Class of blending operation.
Class of NURBS curve building.
The class of NURBS sweeping with circular profile.
The class of one-rail sweeping.
Class of point.