API - Simple Drill / Hole Function - (fromPoint3D, toPoint3D, double diameter)

kevin
Enthusiast

API - Simple Drill / Hole Function - (fromPoint3D, toPoint3D, double diameter)

kevin
Enthusiast
Enthusiast

There needs to be a simple way to make a hole without 3D faces, sketches, features, planes, vectors, circles etc...

All a hole requires is two points and a diameter.

If I'm wrong and there is a way could someone help me in C++

0 Likes
Reply
Accepted solutions (2)
4,514 Views
22 Replies
Replies (22)

TrippyLighting
Consultant
Consultant

@ekinsb Any chance you could help out here ?


EESignature

1 Like

marshaltu
Autodesk
Autodesk

Hello,

 

A hole needs position, diameter, depth and tip angle etc. What you gave would just be to create a circle. It would be good if you can give some snapshot to demonstrate your thoughts. Then we can see if it is doable or not by API.

 

Thanks,

Marshal



Marshal Tu
Fusion Developer
>
0 Likes

kevin
Enthusiast
Enthusiast

My thoughts are according to basic geometry I only need two points to create a line.

Add a diameter to that and you have a hole.

This is geometrically the easiest way you can make a basic cylinder with direction.

Why is it the hardest thing to do.
Over complication can be a flaw.

 

So I've written a C++ script that Im attaching that has all the holes calculated in a stack.

The only part left is to pop them off and drill them with the saved 3D coordinates.

I just can't figure out how to make a hole 😞

Should I be using extrude instead.

I'm not opposed to hard coding a drill bit angle.

 

Attached is some napkin geometry

C++ code

Dubug console output 

 

 

2 Points w Diameter.jpg

 

#define _USE_MATH_DEFINES

#include <Core/CoreAll.h>
#include <Fusion/FusionAll.h>
#include <CAM/CAMAll.h>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <stack>
#include <random>
#include <vector>

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

Ptr<Application> app;
Ptr<UserInterface> ui;

double _poleLength = 8 * 12 * 2.54; //cm
double _gapTop = 6 * 2.54; //cm
double _gapBottom = 6 * 2.54; //cm
double _poleOD = 2 * 2.54 / 2; //cm
double _poleID = 1.5 * 2.54 / 2; //cm
double _bitL = 2.54 * 5 / 8; //cm
double _bitM = 2.54 * 1 / 2; //cm
double _bitS = 2.54 * 3 / 8; //cm
int _numHolesL = 1000;
int _numHolesM = 1000;
int _numHolesS = 1000;
double _slices = 12;
double _sliceArcLength = M_PI * _poleOD / _slices;
double _radius = _poleOD + .1; //Makes a working radius so drilling starts above pole

struct hole {
	bool real = true;
	double x, y, z, diameter = 0;
};
vector <hole> holes;

struct light {
	double x, y, z, dia, real;
};
vector <light> lights;

extern "C" XI_EXPORT bool run(const char* context)
{
	srand((unsigned)time(NULL));
	ofstream myfile;
	myfile.open("debug.txt");
	myfile << std::to_string(rand()) + " Random Initialized\n";
	myfile << M_PI << " Pi works\n";

	app = Application::get();
	if (!app)
		return false;
	myfile << "OK - Get Application\n";

	ui = app->userInterface();
	if (!ui)
		return false;
	myfile << "OK - Get User Interface\n";

	Ptr<Documents> documents = app->documents();
	if (!documents)
		return false;
	myfile << "OK - Get Documents\n";

	Ptr<Document> doc = documents->add(DocumentTypes::FusionDesignDocumentType);
	if (!doc)
		return false;
	myfile << "OK - Make Document Type Fusion Design\n";

	Ptr<Product> product = app->activeProduct();
	if (!product)
		return false;
	myfile << "OK - Select Active Product\n";

	Ptr<Design> design = product;
	if (!design)
		return false;
	myfile << "OK - Set Design to Active Product\n";

	// Get the root component of the active design
	Ptr<Component> rootComp = design->rootComponent();
	if (!rootComp)
		return false;
	myfile << "OK - Get the root component of the active design\n";

	// Get extrude features
	Ptr<Features> feats = rootComp->features();
	if (!feats)
		return false;
	myfile << "OK - Get extrude features\n";

	Ptr<ExtrudeFeatures> extrudes = feats->extrudeFeatures();
	if (!extrudes)
		return false;
	myfile << "OK - Set Extrudes with all extrude features\n";

	// Create sketch
	Ptr<Sketches> sketches = rootComp->sketches();
	if (!sketches)
		return false;
	myfile << "OK - Create a group of sketches\n";

	Ptr<ConstructionPlane> yz = rootComp->yZConstructionPlane();
	if (!yz)
		return false;
	myfile << "OK - Set Construction Plane to YZ\n";

	Ptr<Sketch> sketch = sketches->add(yz);
	if (!sketch)
		return false;
	myfile << "OK - Add YZ plane to sketch\n";

	Ptr<SketchCurves> sketchCurves = sketch->sketchCurves();
	if (!sketchCurves)
		return false;
	myfile << "OK - Create Sketch Curves\n";

	Ptr<SketchCircles> sketchCircles = sketchCurves->sketchCircles();
	if (!sketchCircles)
		return false;
	myfile << "OK - Create Sketch Circles\n";

	Ptr<Point3D> centerPoint = Point3D::create(0, 0, 0);
	if (!centerPoint)
		return false;
	myfile << "OK - Create Center Point (0,0,0)\n";

	// Created Circles
	Ptr<SketchCircle> circle1 = sketchCircles->addByCenterRadius(centerPoint, _poleID);
	myfile << _poleID << " Inside Diameter Circle\n";
	Ptr<SketchCircle> circle2 = sketchCircles->addByCenterRadius(centerPoint, _poleOD);
	myfile << _poleOD << " Outside Diameter Circle\n";
	Ptr<Profiles> profiles = sketch->profiles();
	Ptr<Profile> outerProfile = profiles->item(1);
	myfile << "OK - Circles created\n";

	//Extrude Pole
	Ptr<ValueInput> distance = ValueInput::createByReal(_poleLength);
	if (!distance)
		return false;
	Ptr<ExtrudeFeature> extrude1 = extrudes->addSimple(outerProfile, distance, adsk::fusion::FeatureOperations::NewBodyFeatureOperation);
	if (!extrude1)
		return false;
	myfile << _poleLength << " - Extruded Pole\n";

	//Initialize Hole Variables
	hole temp;
	temp.real = true;
	double degrees = 0;
	Ptr<Point3D> tempPoint = Point3D::create(0, 0, 0);
	myfile << "OK - Hole Variables Initialized\n";

	//Vector Array Testing / Initializing
	light tempLight;
	tempLight.x = 3;
	tempLight.y = 4;
	tempLight.z = 5;
	tempLight.dia = _bitL;
	tempLight.real = true;
	myfile << "\nTest Struct\t" << tempLight.x << tempLight.y << tempLight.z << tempLight.dia << tempLight.real << "\n";
	lights.push_back(tempLight);
	myfile << "Array Size " << lights.size() << "\n";
	myfile << "Contents\t" << lights[0].x << lights[0].y << lights[0].z << lights[0].dia << lights[0].real;
	lights.pop_back();
	myfile << "\nPOP\tsize " << lights.size();

	//Test Variables
	myfile << "Test Initialized Variables\n";
	tempLight.x = _gapBottom + _bitL / 2;
	tempLight.y = cos(degrees) * _radius;
	tempLight.z = sin(degrees) * _radius;
	tempLight.dia = 1.5875;
	lights.push_back(tempLight);
	myfile << "\n[" << lights.size() - 1 << "]\t" << lights[lights.size() - 1].x << "\t" << lights[lights.size() - 1].y << "\t" << lights[lights.size() - 1].z << "\t" << lights[lights.size() - 1].dia << "\t" << lights[lights.size() - 1].real;
	lights.pop_back();
	myfile << "\n Brill Bits\t" << _bitL << "\t" << _bitM << "\t" << _bitS;
	myfile << "\n Pole Length & Gaps\t" << _poleLength << "\t" << _gapBottom << "\t" << _gapTop;
	myfile << "\nPoleOD\t" << _poleOD << "\tPoleID\t" << _poleID;
	myfile << "\nNum Holes\t" << _numHolesL << "\t" << _numHolesM << "\t" << _numHolesS;
	myfile << "\nSlices " << _slices << "\tArcLength " << _sliceArcLength << "\tWorkingRadius " << _radius << "\n\n";

	//Create Candy Cane
	myfile << "Candy Cane Coordinates\n";
	for (tempLight.x = _bitL / 2 + _gapBottom; tempLight.x <= _poleLength - _gapTop - _bitL; tempLight.x += _bitL * 2, degrees += 360 / 12 / 2) {
		myfile << "\nX\t" << tempLight.x;
		tempLight.y = cos(degrees) * _radius;
		tempLight.z = sin(degrees) * _radius;
		lights.push_back(tempLight);
		myfile << "\n[" << lights.size() - 1 << "]\t" << lights[lights.size() - 1].x << "\t" << lights[lights.size() - 1].y << "\t" << lights[lights.size() - 1].z << "\t" << lights[lights.size() - 1].dia << "\t" << lights[lights.size() - 1].real;
		tempLight.y = cos(degrees + 15) * _radius;
		tempLight.z = sin(degrees + 15) * _radius;
		lights.push_back(tempLight);
		myfile << "\n[" << lights.size() - 1 << "]\t" << lights[lights.size() - 1].x << "\t" << lights[lights.size() - 1].y << "\t" << lights[lights.size() - 1].z << "\t" << lights[lights.size() - 1].dia << "\t" << lights[lights.size() - 1].real;
		tempLight.y = cos(degrees + 30) * _radius;
		tempLight.z = sin(degrees + 30) * _radius;
		lights.push_back(tempLight);
		myfile << "\n[" << lights.size() - 1 << "]\t" << lights[lights.size() - 1].x << "\t" << lights[lights.size() - 1].y << "\t" << lights[lights.size() - 1].z << "\t" << lights[lights.size() - 1].dia << "\t" << lights[lights.size() - 1].real;
	}

	//Create Phantom Candy Cane Holes
	myfile << "\n\nCreate Phantom Candy Cane Filer Holes\n";
	tempLight.real = false;
	double stop = (double)lights.size() - 3;
	for (int count = 0; count < stop; count += 3)
	{
		//(0)=>(1) left hole -> middle hole same row
		tempLight.x = (lights[count + 1].x - lights[count].x) / 2 + lights[count].x;
		tempLight.y = (lights[count + 1].y - lights[count].y) / 2 + lights[count].y;
		tempLight.z = (lights[count + 1].z - lights[count].z) / 2 + lights[count].z;
		lights.push_back(tempLight);
		myfile << "\n[" << lights.size() - 1 << "]\t" << lights[lights.size() - 1].x << "\t" << lights[lights.size() - 1].y << "\t" << lights[lights.size() - 1].z << "\t" << lights[lights.size() - 1].dia << "\t" << lights[lights.size() - 1].real;

		//(0)=>(3) left hole -> uprow left
		tempLight.x = (lights[count + 3].x - lights[count].x) / 2 + lights[count].x;
		tempLight.y = (lights[count + 3].y - lights[count].y) / 2 + lights[count].y;
		tempLight.z = (lights[count + 3].z - lights[count].z) / 2 + lights[count].z;
		lights.push_back(tempLight);
		myfile << "\n[" << lights.size() - 1 << "]\t" << lights[lights.size() - 1].x << "\t" << lights[lights.size() - 1].y << "\t" << lights[lights.size() - 1].z << "\t" << lights[lights.size() - 1].dia << "\t" << lights[lights.size() - 1].real;

		//(1)=>(3) middle hole -> uprow left
		tempLight.x = (lights[count + 3].x - lights[count + 1].x) / 2 + lights[count + 1].x;
		tempLight.y = (lights[count + 3].y - lights[count + 1].y) / 2 + lights[count + 1].y;
		tempLight.z = (lights[count + 3].z - lights[count + 1].z) / 2 + lights[count + 1].z;
		lights.push_back(tempLight);
		myfile << "\n[" << lights.size() - 1 << "]\t" << lights[lights.size() - 1].x << "\t" << lights[lights.size() - 1].y << "\t" << lights[lights.size() - 1].z << "\t" << lights[lights.size() - 1].dia << "\t" << lights[lights.size() - 1].real;

		//(1)=>(4) middle hole -> uprow middle
		tempLight.x = (lights[count + 4].x - lights[count + 1].x) / 2 + lights[count + 1].x;
		tempLight.y = (lights[count + 4].y - lights[count + 1].y) / 2 + lights[count + 1].y;
		tempLight.z = (lights[count + 4].z - lights[count + 1].z) / 2 + lights[count + 1].z;
		lights.push_back(tempLight);
		myfile << "\n[" << lights.size() - 1 << "]\t" << lights[lights.size() - 1].x << "\t" << lights[lights.size() - 1].y << "\t" << lights[lights.size() - 1].z << "\t" << lights[lights.size() - 1].dia << "\t" << lights[lights.size() - 1].real;

		//(1)=>(2) middle hole -> right same row
		tempLight.x = (lights[count + 2].x - lights[count + 1].x) / 2 + lights[count + 1].x;
		tempLight.y = (lights[count + 2].y - lights[count + 1].y) / 2 + lights[count + 1].y;
		tempLight.z = (lights[count + 2].z - lights[count + 1].z) / 2 + lights[count + 1].z;
		lights.push_back(tempLight);
		myfile << "\n[" << lights.size() - 1 << "]\t" << lights[lights.size() - 1].x << "\t" << lights[lights.size() - 1].y << "\t" << lights[lights.size() - 1].z << "\t" << lights[lights.size() - 1].dia << "\t" << lights[lights.size() - 1].real;

		//(2)=>(4) right hole -> uprow middle hole
		tempLight.x = (lights[count + 4].x - lights[count + 2].x) / 2 + lights[count + 2].x;
		tempLight.y = (lights[count + 4].y - lights[count + 2].y) / 2 + lights[count + 2].y;
		tempLight.z = (lights[count + 4].z - lights[count + 2].z) / 2 + lights[count + 2].z;
		lights.push_back(tempLight);
		myfile << "\n[" << lights.size() - 1 << "]\t" << lights[lights.size() - 1].x << "\t" << lights[lights.size() - 1].y << "\t" << lights[lights.size() - 1].z << "\t" << lights[lights.size() - 1].dia << "\t" << lights[lights.size() - 1].real;

		//(2)=>(5) right hole -> uprow right hole
		tempLight.x = (lights[count + 5].x - lights[count + 2].x) / 2 + lights[count + 2].x;
		tempLight.y = (lights[count + 5].y - lights[count + 2].y) / 2 + lights[count + 2].y;
		tempLight.z = (lights[count + 5].z - lights[count + 2].z) / 2 + lights[count + 2].z;
		lights.push_back(tempLight);
		myfile << "\n[" << lights.size() - 1 << "]\t" << lights[lights.size() - 1].x << "\t" << lights[lights.size() - 1].y << "\t" << lights[lights.size() - 1].z << "\t" << lights[lights.size() - 1].dia << "\t" << lights[lights.size() - 1].real;

		myfile << "\n Count " << count << "\t Lights Size " << lights.size() << "\n";

		if (count < stop && count > stop -6) {
			//Fill in last row of fake holes
			myfile << "\nFill last row of fake holes";
			//(3)=>(4) up left -> up middle
			tempLight.x = (lights[count + 4].x - lights[count + 3].x) / 2 + lights[count + 3].x;
			tempLight.y = (lights[count + 4].y - lights[count + 3].y) / 2 + lights[count + 3].y;
			tempLight.z = (lights[count + 4].z - lights[count + 3].z) / 2 + lights[count + 3].z;
			lights.push_back(tempLight);
			myfile << "\n[" << lights.size() - 1 << "]\t" << lights[lights.size() - 1].x << "\t" << lights[lights.size() - 1].y << "\t" << lights[lights.size() - 1].z << "\t" << lights[lights.size() - 1].dia << "\t" << lights[lights.size() - 1].real;

			//(4)=>(5) up middle -> up right
			tempLight.x = (lights[count + 5].x - lights[count + 4].x) / 2 + lights[count + 4].x;
			tempLight.y = (lights[count + 5].y - lights[count + 4].y) / 2 + lights[count + 4].y;
			tempLight.z = (lights[count + 5].z - lights[count + 4].z) / 2 + lights[count + 4].z;
			lights.push_back(tempLight);
			myfile << "\n[" << lights.size() - 1 << "]\t" << lights[lights.size() - 1].x << "\t" << lights[lights.size() - 1].y << "\t" << lights[lights.size() - 1].z << "\t" << lights[lights.size() - 1].dia << "\t" << lights[lights.size() - 1].real;
			myfile << "\n Count " << count << "\t Lights Size " << lights.size() << "\n"; myfile << "\n Count " << count << "\t Lights Size " << lights.size() << "\n";
		}
	}

	//Pick The Random large Holes
	for (int temp = 0; temp < _numHolesL; temp++) {
		//Pick Random X, Y & Z 3Dpoints
		//myfile << "\nCheck out Random Temp Light Hole";
		tempLight.real = true;
		tempLight.dia = _bitL;
		degrees = rand() % 360;
		tempLight.x = (double)(rand() % (int)(_poleLength - _gapBottom - _gapTop)) + _gapBottom;
		tempLight.y = cos(degrees) * _radius;
		tempLight.z = sin(degrees) * _radius;
		myfile << "\n[temp]\t" << tempLight.x << "\t" << tempLight.y << "\t" << tempLight.z << "\t" << tempLight.dia << "\t" << tempLight.real;
		//Check random point distance to all other current points
		for (int x = 0; x < lights.size(); x++) {
			if (sqrt(pow(tempLight.x - lights[x].x, 2) + pow(tempLight.y - lights[x].y, 2) + pow(tempLight.z - lights[x].z, 2)) > _bitL*2.5) {
				lights.push_back(tempLight);
				myfile << "\n["<<lights.size()<<"][" << x << "] Degrees " << degrees << "\t" << tempLight.x << "\t" << tempLight.y << "\t" << tempLight.z << "\t" << tempLight.dia << "\t" << tempLight.real;
				break;
			}
		}
	}

	//Pick The Random Medium Holes
	for (int temp = 0; temp < _numHolesM; temp++) {
		//Pick Random X, Y & Z 3Dpoints
		//myfile << "\nCheck out Random Temp Light Hole";
		tempLight.real = true;
		tempLight.dia = _bitM;
		degrees = rand() % 360;
		tempLight.x = (double)(rand() % (int)(_poleLength - _gapBottom - _gapTop)) + _gapBottom;
		tempLight.y = cos(degrees) * _radius;
		tempLight.z = sin(degrees) * _radius;
		myfile << "\n[temp]\t" << tempLight.x << "\t" << tempLight.y << "\t" << tempLight.z << "\t" << tempLight.dia << "\t" << tempLight.real;
		//Check random point distance to all other current points
		for (int x = 0; x < lights.size(); x++) {
			if (sqrt(pow(tempLight.x - lights[x].x, 2) + pow(tempLight.y - lights[x].y, 2) + pow(tempLight.z - lights[x].z, 2)) > _bitM*2.5) {
				lights.push_back(tempLight);
				myfile << "\n[" << lights.size() << "][" << x << "] Degrees " << degrees << "\t" << tempLight.x << "\t" << tempLight.y << "\t" << tempLight.z << "\t" << tempLight.dia << "\t" << tempLight.real;
				break;
			}
		}
	}

	//Pick The Random Small Holes
	for (int temp = 0; temp < _numHolesS; temp++) {
		//Pick Random X, Y & Z 3Dpoints
		//myfile << "\nCheck out Random Temp Light Hole";
		tempLight.real = true;
		tempLight.dia = _bitS;
		degrees = rand() % 360;
		tempLight.x = (double)(rand() % (int)(_poleLength - _gapBottom - _gapTop)) + _gapBottom;
		tempLight.y = cos(degrees) * _radius;
		tempLight.z = sin(degrees) * _radius;
		myfile << "\n[temp]\t" << tempLight.x << "\t" << tempLight.y << "\t" << tempLight.z << "\t" << tempLight.dia << "\t" << tempLight.real;
		//Check random point distance to all other current points
		for (int x = 0; x < lights.size(); x++) {
			if (sqrt(pow(tempLight.x - lights[x].x, 2) + pow(tempLight.y - lights[x].y, 2) + pow(tempLight.z - lights[x].z, 2)) > _bitS*2.5) {
				lights.push_back(tempLight);
				myfile << "\n[" << lights.size() << "][" << x << "] Degrees " << degrees << "\t" << tempLight.x << "\t" << tempLight.y << "\t" << tempLight.z << "\t" << tempLight.dia << "\t" << tempLight.real;
				break;
			}
		}
	}

	/*Make Holes popping of lights array*/

	//Ending
	ui->messageBox("Hey Kevin " + std::to_string(rand()));
	return true;
	myfile.close();
}

#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

kevin
Enthusiast
Enthusiast

I keep trying to make a hole, don't get errors but can't figure out why they dont appear.

 

	//See if you can make funtion hole or extrude work
	myfile << "\n Start Fusion 360 geometric variables";
	Ptr<adsk::core::Point3D> fromPoint3D = adsk::core::Point3D::create(lights[0].x, lights[0].y, lights[0].z);
	Ptr<adsk::core::Point3D> toPoint3D = adsk::core::Point3D::create(lights[0].x, 0, 0);

	Ptr<adsk::core::Line3D> straightLine = adsk::core::Line3D::create(fromPoint3D, toPoint3D);
	Ptr<adsk::core::Line3D> reverseLine = adsk::core::Line3D::create(toPoint3D, fromPoint3D);

	Ptr<adsk::core::Vector3D> fromVector3D = adsk::core::Vector3D::create(lights[0].x, lights[0].y, lights[0].z);
	Ptr<adsk::core::Vector3D> toVector3D = adsk::core::Vector3D::create(lights[0].x, 0, 0);
	
	Ptr<adsk::core::Circle3D> toCircle3D = adsk::core::Circle3D::createByCenter(fromPoint3D, toVector3D, _bitL);
	Ptr<adsk::core::Circle3D> fromCircle3D = adsk::core::Circle3D::createByCenter(fromPoint3D, fromVector3D, _bitL); //Won't work?
	
	Ptr<adsk::core::Cylinder> fromCylinder = adsk::core::Cylinder::create(fromPoint3D, fromVector3D, _bitL);
	Ptr<adsk::core::Cylinder> toCylinder = adsk::core::Cylinder::create(toPoint3D, toVector3D, _bitL); //I think its backwards
	myfile << "\n End create Geometric Variables";


	// Create a hole input
	Ptr<ConstructionPlane> xPlane = rootComp->xConstructionAxis();
	Ptr<HoleFeatures> lightHoles = feats->holeFeatures();
	Ptr<HoleFeatureInput> lightHoleInput = lightHoles->createSimpleInput(ValueInput::createByReal(_bitL));//Hole Diameter
	lightHoleInput->setDistanceExtent(ValueInput::createByReal(sqrt(pow(tempLight.x - lights[0].x, 2) + pow(tempLight.y - lights[0].y, 2) + pow(tempLight.z - lights[0].z, 2))));
	myfile << "\nDistance Extent" << ValueInput::createByReal(sqrt(pow(tempLight.x - lights[0].x, 2) + pow(tempLight.y - lights[0].y, 2) + pow(tempLight.z - lights[0].z, 2)));
	lightHoleInput->setPositionByPoint(xPlane,fromPoint3D);
	Ptr<HoleFeature> lightHole = lightHoles->add(lightHoleInput);

	lightHoleInput->setPositionAtCenter(xPlane,fromCircle3D);
	Ptr<HoleFeature> lightHole2 = lightHoles->add(lightHoleInput);
0 Likes

marshaltu
Autodesk
Autodesk

Hello,

 

It is clearer for me what you were going to do. You had have some logic to deduce the depth/tip angle of hole. I ran your codes and get the following "tube" created in Fusion 360.

 

I am not clear where you are going to create "hole"? At least you need a plane to place the "hole" on? Though you wanted to create an extrude feature and cut to get the "hole".

 

Thanks,

Marshal

 

Hole.png



Marshal Tu
Fusion Developer
>
0 Likes

kevin
Enthusiast
Enthusiast

I extrude the pole which is basically just stock aluminum.

All the calculations push <stack> start(x,y,z) coordinates and when drilled will stop in the middle of the pole on the x axis endPoint(x,0,0)

I can't get the drill hole part to work for ~5,000 holes.

 

Here's a picture of a short test version.

Does that help you visualize?

 

Holy.jpg

0 Likes

marshaltu
Autodesk
Autodesk

Hello,

 

Thank you for the real picture. It is clear to me.

 

I would like to give a sample how to create hole based on a point on cylinder face. I hope it can give quick idea to you and help you on your real project.

 

I assume you have had cylinder face and its diameter. And you have had a series of points which are located at the cylinder face. You can create the hole with specific diameter/depth one by one based on every point. 

 

Thanks,

Marshal

 

#Author-
#Description-

import adsk.core, adsk.fusion, traceback
import math

def run(context):
    ui = None
    try:
        app = adsk.core.Application.get()
        ui  = app.userInterface
        
        design = adsk.fusion.Design.cast(app.activeProduct)
        root = design.rootComponent
        basesketch = root.sketches.add(root.xYConstructionPlane)
        basesketch.isVisible = False
        
        # Get outside cylinder face by radius (e.g. 2.5 cm)
        cylinderface = None
        for face in root.bRepBodies.item(0).faces:
            cylindersurface = adsk.core.Cylinder.cast(face.geometry)
            if cylindersurface and math.fabs(cylindersurface.radius - 2.5) < 1.0e-6:
                cylinderface = face
                break

        # Create hole based on a point(e.g. (2.5, 0, 2.5))
        # Place the point into sketch
        pt = adsk.core.Point3D.create(2.5, 0, 2.5)
        basesketchpoint = basesketch.sketchPoints.add(pt)
        
        if cylinderface:
        
            # Firstly we have to create a work plane
            workplaneinput = root.constructionPlanes.createInput()  
            workplaneinput.setByTangentAtPoint(cylinderface, basesketchpoint)
            workplane = root.constructionPlanes.add(workplaneinput)
            
            # Create hole with specific radius(e.g. 0.5 cm) and depth (e.g. 1 cm)
            holeinput = root.features.holeFeatures.createSimpleInput(adsk.core.ValueInput.createByString('1 cm'))
            holeinput.setPositionByPoint(workplane, pt)
            holeinput.setDistanceExtent(adsk.core.ValueInput.createByReal(1))
            root.features.holeFeatures.add(holeinput)
            
            # Hide workplane
            workplane.isLightBulbOn = False
        
    except:
        if ui:
            ui.messageBox('Failed:\n{}'.format(traceback.format_exc()))


Marshal Tu
Fusion Developer
>
1 Like

kevin
Enthusiast
Enthusiast

OMG Marshal you've been a ton of help today.

I can extrude fine & create tangent planes.

I've spent another day and still can't figure out how to not crash Fusion when trying to set a hole point.

You can see the two commented lines towards the bottom.

Do you think you can help me get this to actually drill a hole?

I can't think of whats wrong.

I feel like I'm so close, just one line of code away & then I can put the whole thing together

 

On the main topic though. I still think a SetPositionByPoints function would be great for cases like this that automatically create the needed tangent plane in the background.

 

Snap.png

 

#include <Core/CoreAll.h>
#include <Fusion/FusionAll.h>
#include <CAM/CAMAll.h>

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

Ptr<Application> app;
Ptr<UserInterface> ui;

extern "C" XI_EXPORT bool run(const char* context)
{
	Ptr<Application> app = Application::get();
	ui = app->userInterface();
	Ptr<Documents> docs = app->documents();

	// Create a document.
	Ptr<Document> doc = docs->add(DocumentTypes::FusionDesignDocumentType);
	Ptr<Design> design = app->activeProduct();
	
	// Get the root component of the active design
	Ptr<Component> rootComp = design->rootComponent();

	// Create sketch
	Ptr<Sketches> sketches = rootComp->sketches();
	Ptr<Sketch> sketch = sketches->add(rootComp->yZConstructionPlane());

	// Create sketch circle
	Ptr<SketchCurves> curves = sketch->sketchCurves();
	Ptr<SketchCircles> circles = curves->sketchCircles();
	Ptr<Point3D> centerPoint = Point3D::create(0, 0, 0);
	circles->addByCenterRadius(centerPoint, 0.75);
	circles->addByCenterRadius(centerPoint, 1);

	// Get the profile defined by the circle
	Ptr<Profiles> profs = sketch->profiles();
	Ptr<Profile> prof = profs->item(1);

	// Create an extrusion input
	Ptr<Features> features = rootComp->features();
	Ptr<ExtrudeFeatures> extrudes = features->extrudeFeatures();
	Ptr<ExtrudeFeatureInput> extInput = extrudes->createInput(prof, FeatureOperations::NewBodyFeatureOperation);

	// Define that the extent is a distance extent of 5 cm
	Ptr<ValueInput> distance = ValueInput::createByReal(5.0);

	// Set the distance extent to be one-way symmetric
	extInput->setDistanceExtent(false, distance);

	// Set the extrude to be a solid one
	extInput->isSolid(true);

	// Create an cylinder
	Ptr<ExtrudeFeature> extrude = extrudes->add(extInput);

	// Get construction planes
	Ptr<ConstructionPlanes> planes = rootComp->constructionPlanes();

	// Create construction plane input 
	Ptr<ConstructionPlaneInput> planeInput = planes->createInput();

	// Add construction plane by tangent #5
	Ptr<BRepFaces> extSideFaces = extrude->sideFaces();
	Ptr<BRepFace> cylinderFace = extSideFaces->item(1);

	extInput->setDistanceExtent(false, distance);
	planeInput->setByTangentAtPoint(cylinderFace, Point3D::create(2,0,1));
	planes->add(planeInput);

	// Create an extrusion input
	Ptr<Features> feats = rootComp->features();
	Ptr<SketchPoints> drillPoints = sketch->sketchPoints();
	Ptr<Point3D> pointFrom = Point3D::create(3, 1, 0);
	Ptr<SketchPoint> sketchPointFrom = drillPoints->add(pointFrom);
	Ptr<Point3D> pointTo = Point3D::create(3, 0, 0);
	Ptr<SketchPoint> sketchPointTo = drillPoints->add(pointTo);


	// Create a hole input
	double stroke = 1;
	Ptr<HoleFeatures> holes = feats->holeFeatures();
	Ptr<HoleFeatureInput> holeInput = holes->createSimpleInput(5/8);
	//holeInput->setPositionBySketchPoints(drillPoints);
	//holeInput->setPositionByPoint(planes, pointFrom);
	//holeInput->setDistanceExtent(adsk::core::ValueInput::createByReal(1));
	Ptr<HoleFeature> hole = holes->add(holeInput);

	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

marshaltu
Autodesk
Autodesk
Accepted solution

Hello,

 

There were a couple of errors in your codes:

 

1. The tangent work plane didn't created in correct position. You have to create sketch point based on the point you plan to drill and then create tangent plane on the sketch point.

2. "5 / 8" would be equal to zero. It took me quite some time to figure the error out.

3. You can pass "planes" to create hole instead of the work plane you created based on drill point.

 

However I run into another issue which I cannot create tangent work plane because of a bug in Fusion 360 (logged as UP-38447). I show the error with "ui->messageBox("Failed to create tangent work plane by cylinder face.")". So I have to work the bug around by saving the document and reopen it. Now the following codes would be able to create a hole for it on (2, 0, 1).

 

Thanks,

Marshal

 

 

#include <Core/CoreAll.h>
#include <Fusion/FusionAll.h>
#include <CAM/CAMAll.h>

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

Ptr<Application> app;
Ptr<UserInterface> ui;

bool createToolBody()
{
	Ptr<Documents> docs = app->documents();

	// Create a document.
	Ptr<Document> doc = docs->add(DocumentTypes::FusionDesignDocumentType);
	Ptr<Design> design = app->activeProduct();

	// Get the root component of the active design
	Ptr<Component> rootComp = design->rootComponent();

	// Create sketch
	Ptr<Sketches> sketches = rootComp->sketches();
	Ptr<Sketch> sketch = sketches->add(rootComp->yZConstructionPlane());

	// Create sketch circle
	Ptr<SketchCurves> curves = sketch->sketchCurves();
	Ptr<SketchCircles> circles = curves->sketchCircles();
	Ptr<Point3D> centerPoint = Point3D::create(0, 0, 0);
	circles->addByCenterRadius(centerPoint, 0.75);
	circles->addByCenterRadius(centerPoint, 1);

	// Get the profile defined by the circle
	Ptr<Profiles> profs = sketch->profiles();
	Ptr<Profile> prof = profs->item(1);

	//// Create an extrusion input
	Ptr<Features> features = rootComp->features();
	Ptr<ExtrudeFeatures> extrudes = features->extrudeFeatures();
	Ptr<ExtrudeFeatureInput> extInput = extrudes->createInput(prof, FeatureOperations::NewBodyFeatureOperation);

	// Define that the extent is a distance extent of 5 cm
	Ptr<ValueInput> distance = ValueInput::createByReal(5.0);

	// Set the distance extent to be one-way symmetric
	extInput->setDistanceExtent(false, distance);

	// Set the extrude to be a solid one
	extInput->isSolid(true);

	// Create an cylinder
	Ptr<ExtrudeFeature> extrude = extrudes->add(extInput);

	// Save and reopen the document to work a bug around.
	Ptr<ExportManager> exportMgr = design->exportManager();
	Ptr<FusionArchiveExportOptions> exportOption = exportMgr->createFusionArchiveExportOptions("C:\\temp.f3d");
	exportMgr->execute(exportOption);

	doc->close(false);

	Ptr<ImportManager> importMgr = app->importManager();
	Ptr<FusionArchiveImportOptions> importOption = importMgr->createFusionArchiveImportOptions("C:\\temp.f3d");
	importMgr->importToNewDocument(importOption);

	return true;
}

extern "C" XI_EXPORT bool run(const char* context)
{
	app = Application::get();
	ui = app->userInterface();

	if (!createToolBody())
		return false;

	Ptr<Design> design = app->activeProduct();

	// Get the root component of the active design
	Ptr<Component> rootComp = design->rootComponent();

	// Get construction planes
	Ptr<ConstructionPlanes> planes = rootComp->constructionPlanes();

	// Create construction plane input 
	Ptr<ConstructionPlaneInput> planeInput = planes->createInput();

	// Add construction plane by tangent #5
	Ptr<BRepBodies> bodies = rootComp->bRepBodies();
	Ptr<BRepBody> body = bodies->item(0);
	Ptr<BRepFaces> faces = body->faces();
	Ptr<BRepFace> cylinderFace;
	for (auto face : faces)
	{
		Ptr<Cylinder> cylinder = face->geometry();
		if (cylinder && std::fabs(cylinder->radius() - 1) < 1.0e-6)
		{
			cylinderFace = face;
			break;
		}
	}

	Ptr<Sketches> sketches = rootComp->sketches();
	Ptr<Sketch> sketch = sketches->add(rootComp->yZConstructionPlane());
	Ptr<SketchPoints> points = sketch->sketchPoints();

	Ptr<Point3D> pickPt = Point3D::create(2, 0, 1);
	Ptr<SketchPoint> pickSketchPt = points->add(sketch->modelToSketchSpace(pickPt));
	planeInput->setByTangentAtPoint(cylinderFace, pickSketchPt);
	Ptr<ConstructionPlane> plane = planes->add(planeInput);
	if (!plane)
	{
		ui->messageBox("Failed to create tangent work plane by cylinder face.");
		return false;
	}

	// Create a hole input
	double stroke = 1;
	Ptr<Features> features = rootComp->features();
	Ptr<HoleFeatures> holes = features->holeFeatures();
	Ptr<HoleFeatureInput> holeInput = holes->createSimpleInput(ValueInput::createByReal(5.0 / 8));
	holeInput->setPositionByPoint(plane, Point3D::create(2, 0, 1));
	holeInput->setDistanceExtent(adsk::core::ValueInput::createByReal(1));
	Ptr<HoleFeature> hole = holes->add(holeInput);

	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

 



Marshal Tu
Fusion Developer
>
1 Like

kevin
Enthusiast
Enthusiast

Hi Marshall,

Wow I wouldn't have thought about any of this except.

The 5/8, I should have known better.

I've can't seem to run the code you provided.

Every time Export Manager Export Executes it crashes.

I've verified this with Visual Studio 2012 V110 & Visual Studio 2017 V141

 

ExportMgr.png

undefined

 

Export Options.png

 

0 Likes

marshaltu
Autodesk
Autodesk
Hello,

I forgot to mention I hardcoded the path of export with "C:\\temp.f3d". You may have to change it if the path isn't available in your machine.

BTW: it would be better to check every result after call API. Sometimes you would get null object because some errors. It must make Fusion crash if you continue to use it. "Application::getLastError" can give detailed informatin when error is encountered.

Thanks,
Marshal


Marshal Tu
Fusion Developer
>
0 Likes

kevin
Enthusiast
Enthusiast

I saw that it was hard coded and tried several ways with no luck 😞

I don't even now the reason I'm opening and closing the document 5000's but I feel like that could crash or take an extremely long time.

The good news is. I'm finally getting these holes to work and can start adding logic 🙂

I don't know how I could have ever gotten even this far without you

I'll keep this post updated as I progress.

Also I still believe this could be a new hole function using two points and have the planes generated automatically.

 

Yes!!!.png

1 Like

BrianEkins
Mentor
Mentor
Accepted solution

Here's a totally different approach that does just what you asked about in the beginning.  It creates a bunch of cylinders using the coordinates of the ends of the cylinders and the radii.  It uses something called "Temporary B-Rep".  This is also much faster than creating standard features.  The sample code I wrote created the 2000 holes shown in the picture below in less than 20 seconds. I wrote about it in more detail here:

 

https://ekinssolutions.com/using-temporary-b-rep-in-fusion-360/

Holes.png

 

 

 

 

 

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
2 Likes

kevin
Enthusiast
Enthusiast

Brian,

 

That is really cool how you did that & I almost followed it.
Just need to convert it to C++.

& Yes it took over an hour to do 400 holes & I plan around 6000 😞

Bought a new thinkpad p52s w/ Quadro card today hopefully that helps since my laptop and Quadro card is 5 years old.

I'm also going to try NVidia's grid compute virtual machine trial to see if I can brute force it since I'm so close.
Can I delete planes after I create a hole? Will that make it faster? Because its simple and beautiful.

Cuz right now I have more planes than Howard Hughes.

 

Also using a different diameter for inside and outside hole. Will that cause problems with the CAM tooling/path?
Havent gotten that far yet.

 

Planes.pngPole.png

0 Likes

kevin
Enthusiast
Enthusiast

Would anyone be kind enough to generate this for me.

I've finished the program and have rendered it in sections just fine.But it's just too large for my computer even running it over night and eventually crashes.

Yesterday I purchased new hardware and a quadro card but it will still take weeks to come in.

 

-Kevin

0 Likes

marshaltu
Autodesk
Autodesk

Hello,

 

The problem which export manager didn't work was invalid file path. It should be "C:\\temp.f3d". Good news is that you should not need the workaround as I made a mistake in the codes I posted. I added a sketch point to that sketch which used for creating extrude feature. It caused cylinder faces became invalid. The codes as below should work well. 

 

Regarding to performance issue, Brain suggested a better approach and maybe you could give a try. 

 

Thanks,

Marshal

 

#include <Core/CoreAll.h>
#include <Fusion/FusionAll.h>
#include <CAM/CAMAll.h>

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

Ptr<Application> app;
Ptr<UserInterface> ui;

extern "C" XI_EXPORT bool run(const char* context)
{
	app = Application::get();
	ui = app->userInterface();

	Ptr<Documents> docs = app->documents();

	// Create a document.
	Ptr<Document> doc = docs->add(DocumentTypes::FusionDesignDocumentType);
	Ptr<Design> design = app->activeProduct();

	// Get the root component of the active design
	Ptr<Component> rootComp = design->rootComponent();

	// Create sketch
	Ptr<Sketches> sketches = rootComp->sketches();
	Ptr<Sketch> sketch = sketches->add(rootComp->yZConstructionPlane());
	Ptr<SketchPoints> points = sketch->sketchPoints();

	Ptr<Point3D> pickPt = Point3D::create(2, 0, 1);
	Ptr<SketchPoint> pickSketchPt = points->add(sketch->modelToSketchSpace(pickPt));

	// Create sketch circle
	Ptr<SketchCurves> curves = sketch->sketchCurves();
	Ptr<SketchCircles> circles = curves->sketchCircles();
	Ptr<Point3D> centerPoint = Point3D::create(0, 0, 0);
	circles->addByCenterRadius(centerPoint, 0.75);
	circles->addByCenterRadius(centerPoint, 1);

	// Get the profile defined by the circle
	Ptr<Profiles> profs = sketch->profiles();
	Ptr<Profile> prof = profs->item(1);

	//// Create an extrusion input
	Ptr<Features> features = rootComp->features();
	Ptr<ExtrudeFeatures> extrudes = features->extrudeFeatures();
	Ptr<ExtrudeFeatureInput> extInput = extrudes->createInput(prof, FeatureOperations::NewBodyFeatureOperation);

	// Define that the extent is a distance extent of 5 cm
	Ptr<ValueInput> distance = ValueInput::createByReal(5.0);

	// Set the distance extent to be one-way symmetric
	extInput->setDistanceExtent(false, distance);

	// Set the extrude to be a solid one
	extInput->isSolid(true);

	// Create an cylinder
	Ptr<ExtrudeFeature> extrude = extrudes->add(extInput);

	// Get construction planes
	Ptr<ConstructionPlanes> planes = rootComp->constructionPlanes();

	// Create construction plane input 
	Ptr<ConstructionPlaneInput> planeInput = planes->createInput();

	// Add construction plane by tangent #5
	Ptr<BRepFaces> faces = extrude->sideFaces();
	Ptr<BRepFace> cylinderFace;
	for (auto face : faces)
	{
		Ptr<Cylinder> cylinder = face->geometry();
		if (cylinder && std::fabs(cylinder->radius() - 1) < 1.0e-6)
		{
			cylinderFace = face;
			break;
		}
	}

	planeInput->setByTangentAtPoint(cylinderFace, pickSketchPt);
	Ptr<ConstructionPlane> plane = planes->add(planeInput);
	if (!plane)
	{
		ui->messageBox("Failed to create tangent work plane by cylinder face.");
		return false;
	}

	// Create a hole input
	double stroke = 1;
	Ptr<HoleFeatures> holes = features->holeFeatures();
	Ptr<HoleFeatureInput> holeInput = holes->createSimpleInput(ValueInput::createByReal(5.0 / 8));
	holeInput->setPositionByPoint(plane, pickPt);
	holeInput->setDistanceExtent(adsk::core::ValueInput::createByReal(1));
	Ptr<HoleFeature> hole = holes->add(holeInput);

	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


Marshal Tu
Fusion Developer
>
1 Like

kevin
Enthusiast
Enthusiast

I also forgot to mention that I got everything to work just be commenting out the export manager.

My problem now is rendering.

 

My computer crashes after it gets up to around 10GB of Ram while running the script.

I can generate it in parts but no all together without a GPU

Any ideas on how to run this thing?
Maybe somethings configured wrong

 

ram.pngstats.png

 

 

#define _USE_MATH_DEFINES

#include <Core/CoreAll.h>
#include <Fusion/FusionAll.h>
#include <CAM/CAMAll.h>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <stack>
#include <random>
#include <vector>

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

ofstream myfile;

struct hole {
	double x, y, z, dia;
	bool isReal;
};
vector<hole> holes;
hole temp;

double degrees = 0;

double _poleLength = 2.54 * 8 * 12;
double _gapTop = 2.54 * 6;
double _gapBottom = 2.54 * 6;
double _poleOD = 2.54 * 1;
double _poleID = 2.54 * .75;
double _slices = 12;
double _sliceArcLength = M_PI * _poleOD / _slices;
double _radius = _poleOD / 2;
double _bitL = 2.54 * 5 / 16;
double _bitM = 2.54 * 1 / 4;
double _bitS = 2.54 * 3 / 16;
int _numHolesL = 2000;
int _numHolesM = 1500;
int _numHolesS = 1000;

Ptr<Application> app = Application::get();
Ptr<UserInterface> ui = app->userInterface();

bool createToolBody()
{
	Ptr<Documents> docs = app->documents();

	// Create a document.
	Ptr<Document> doc = docs->add(DocumentTypes::FusionDesignDocumentType);
	Ptr<Design> design = app->activeProduct();

	// Get the root component of the active design
	Ptr<Component> rootComp = design->rootComponent();

	// Create sketch
	Ptr<Sketches> sketches = rootComp->sketches();
	Ptr<Sketch> sketch = sketches->add(rootComp->yZConstructionPlane());

	// Create sketch circle
	Ptr<SketchCurves> curves = sketch->sketchCurves();
	Ptr<SketchCircles> circles = curves->sketchCircles();
	Ptr<Point3D> centerPoint = Point3D::create(0, 0, 0);
	circles->addByCenterRadius(centerPoint, _poleID);
	circles->addByCenterRadius(centerPoint, _poleOD);

	// Get the profile defined by the circle
	Ptr<Profiles> profs = sketch->profiles();
	Ptr<Profile> prof = profs->item(1);

	//// Create an extrusion input
	Ptr<Features> features = rootComp->features();
	Ptr<ExtrudeFeatures> extrudes = features->extrudeFeatures();
	Ptr<ExtrudeFeatureInput> extInput = extrudes->createInput(prof, FeatureOperations::NewBodyFeatureOperation);

	// Define that the extent is a distance extent of 8 ft
	Ptr<ValueInput> distance = ValueInput::createByReal(_poleLength);

	// Set the distance extent to be one-way symmetric
	extInput->setDistanceExtent(false, distance);

	// Set the extrude to be a solid one
	extInput->isSolid(true);

	// Create an cylinder
	Ptr<ExtrudeFeature> extrude = extrudes->add(extInput);

	/*
	// Save and reopen the document to work a bug around.
	Ptr<ExportManager> exportMgr = design->exportManager();
	Ptr<FusionArchiveExportOptions> exportOption = exportMgr->createFusionArchiveExportOptions("C:\\temp.f3d");
	exportMgr->execute(exportOption);

	doc->close(false);

	Ptr<ImportManager> importMgr = app->importManager();
	Ptr<FusionArchiveImportOptions> importOption = importMgr->createFusionArchiveImportOptions("C:\\temp.f3d");
	importMgr->importToNewDocument(importOption);
	*/

	return true;
}

void makeCylinder() {
	Ptr<Design> design = app->activeProduct();
	Ptr<Component> rootComp = design->rootComponent();
	Ptr<ConstructionPlanes> planes = rootComp->constructionPlanes();
	Ptr<ConstructionPlaneInput> planeInput = planes->createInput();

	// Do the magic cylinder stuff
	Ptr<BRepBodies> bodies = rootComp->bRepBodies();
	Ptr<BRepBody> body = bodies->item(0);
	Ptr<BRepFaces> faces = body->faces();
	Ptr<BRepFace> cylinderFace;
	for (auto face : faces)
	{
		Ptr<Cylinder> cylinder = face->geometry();
		if (cylinder && std::fabs(cylinder->radius() - _poleOD) < 1.0e-6)
		{
			cylinderFace = face;
			break;
		}
	}

	Ptr<Sketches> sketches = rootComp->sketches();
	Ptr<Sketch> sketch = sketches->add(rootComp->yZConstructionPlane());
	Ptr<SketchPoints> points = sketch->sketchPoints();

	Ptr<Point3D> pickPt = Point3D::create(2, 0, 1);
	Ptr<SketchPoint> pickSketchPt = points->add(sketch->modelToSketchSpace(pickPt));
	planeInput->setByTangentAtPoint(cylinderFace, pickSketchPt);
	Ptr<ConstructionPlane> plane = planes->add(planeInput);
	if (!plane)
	{
		ui->messageBox("Failed to create tangent work plane by cylinder face.");
		//return false;
	}
}


/*
void drillHole(double x, double y, double z) {

Ptr<Design> design = app->activeProduct();
Ptr<Component> rootComp = design->rootComponent();
Ptr<ConstructionPlanes> planes = rootComp->constructionPlanes();

Ptr<SketchPoints> points = sketch->sketchPoints();


//Create new plane hole
planes->createInput();
Ptr<Point3D>pickPt = Point3D::create(x, y, z);
//points->release();
Ptr<SketchPoint>pickSketchPt = points->add(sketch->modelToSketchSpace(pickPt));
planeInput->setByTangentAtPoint(cylinderFace, pickSketchPt);
plane = planes->add(planeInput);
holeInput->setPositionByPoint(plane, Point3D::create(x, y, z));
holes->add(holeInput);
}
*/


void makeCandyCane(){
	//Candy Cane Coordinated
	for (temp.x = _gapBottom; temp.x <= _poleLength - _gapTop; temp.x += _bitL) {
		temp.y = cos(degrees);
		temp.z = sin(degrees);
		holes.push_back(temp);
		//holes.pop_back();
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;
		temp.y = cos(degrees + .5);
		temp.z = sin(degrees + .5);
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;
		temp.y = cos(degrees + 1);
		temp.z = sin(degrees + 1);
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;
		temp.x += _bitL;
		degrees += .25;
	}myfile << "\nOK - Candy Cane\n";
}

void makePhantomHoles(){
	//Create Phantom Candy Cane Holes
	myfile << "Create Phantom Holes\n";
	temp.isReal = false;
	double stop = (double)holes.size() - 3;

	for (int count = 0; count < stop; count += 3)
	{
		//(0)=>(1) left hole -> middle hole same row
		temp.x = (holes[count + 1].x - holes[count].x) / 2 + holes[count].x;
		temp.y = (holes[count + 1].y - holes[count].y) / 2 + holes[count].y;
		temp.z = (holes[count + 1].z - holes[count].z) / 2 + holes[count].z;
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

		//(0)=>(3) left hole -> uprow left
		temp.x = (holes[count + 3].x - holes[count].x) / 2 + holes[count].x;
		temp.y = (holes[count + 3].y - holes[count].y) / 2 + holes[count].y;
		temp.z = (holes[count + 3].z - holes[count].z) / 2 + holes[count].z;
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

		//(1)=>(3) middle hole -> uprow left
		temp.x = (holes[count + 3].x - holes[count + 1].x) / 2 + holes[count + 1].x;
		temp.y = (holes[count + 3].y - holes[count + 1].y) / 2 + holes[count + 1].y;
		temp.z = (holes[count + 3].z - holes[count + 1].z) / 2 + holes[count + 1].z;
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

		//(1)=>(4) middle hole -> uprow middle
		temp.x = (holes[count + 4].x - holes[count + 1].x) / 2 + holes[count + 1].x;
		temp.y = (holes[count + 4].y - holes[count + 1].y) / 2 + holes[count + 1].y;
		temp.z = (holes[count + 4].z - holes[count + 1].z) / 2 + holes[count + 1].z;
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

		//(1)=>(2) middle hole -> right same row
		temp.x = (holes[count + 2].x - holes[count + 1].x) / 2 + holes[count + 1].x;
		temp.y = (holes[count + 2].y - holes[count + 1].y) / 2 + holes[count + 1].y;
		temp.z = (holes[count + 2].z - holes[count + 1].z) / 2 + holes[count + 1].z;
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

		//(2)=>(4) right hole -> uprow middle hole
		temp.x = (holes[count + 4].x - holes[count + 2].x) / 2 + holes[count + 2].x;
		temp.y = (holes[count + 4].y - holes[count + 2].y) / 2 + holes[count + 2].y;
		temp.z = (holes[count + 4].z - holes[count + 2].z) / 2 + holes[count + 2].z;
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

		//(2)=>(5) right hole -> uprow right hole
		temp.x = (holes[count + 5].x - holes[count + 2].x) / 2 + holes[count + 2].x;
		temp.y = (holes[count + 5].y - holes[count + 2].y) / 2 + holes[count + 2].y;
		temp.z = (holes[count + 5].z - holes[count + 2].z) / 2 + holes[count + 2].z;
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

		myfile << "\n Count " << count << "\t Lights Size " << holes.size() << "\n";

		if (count < stop && count > stop - 6) {
			//Fill in last row of fake holes
			myfile << "\nFill last row of fake holes";
			//(3)=>(4) up left -> up middle
			temp.x = (holes[count + 4].x - holes[count + 3].x) / 2 + holes[count + 3].x;
			temp.y = (holes[count + 4].y - holes[count + 3].y) / 2 + holes[count + 3].y;
			temp.z = (holes[count + 4].z - holes[count + 3].z) / 2 + holes[count + 3].z;
			holes.push_back(temp);
			myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

			//(4)=>(5) up middle -> up right
			temp.x = (holes[count + 5].x - holes[count + 4].x) / 2 + holes[count + 4].x;
			temp.y = (holes[count + 5].y - holes[count + 4].y) / 2 + holes[count + 4].y;
			temp.z = (holes[count + 5].z - holes[count + 4].z) / 2 + holes[count + 4].z;
			holes.push_back(temp);
			myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;
			myfile << "\n Count " << count << "\t Lights Size " << holes.size() << "\n";
		}
	}


}

void makeRandomHoles(double num, double size) {
	temp.dia = size;
	temp.isReal = true;
	for (int  count = 0; count < num; count++) {
		//Pick Random X, Y & Z 3Dpoints
		//myfile << "\nCheck out Random Temp Light Hole";
		degrees = rand() % 360;
		temp.x = (double)(rand() % (int)(_poleLength - _gapBottom - _gapTop)) + _gapBottom;
		temp.y = cos(degrees) * _radius;
		temp.z = sin(degrees) * _radius;
		myfile << "\n[temp]\t" << temp.x << "\t" << temp.y << "\t" << temp.z << "\t" << temp.dia << "\t" << temp.isReal;
		//Check random point distance to all other current points
		for (int x = 0; x < holes.size(); x++) {
			if (sqrt(pow(temp.x - holes[x].x, 2) + pow(temp.y - holes[x].y, 2) + pow(temp.z - holes[x].z, 2)) > _bitL*2.5) {
				holes.push_back(temp);
				myfile << "\n[" << holes.size() << "][" << x << "] Degrees " << degrees << "\t" << temp.x << "\t" << temp.y << "\t" << temp.z << "\t" << temp.dia << "\t" << temp.isReal;
				break;
			}
		}
	}
}


void drillHole(double x, double y, double z, double drillBit) {
	Ptr<Design> design = app->activeProduct();
	Ptr<Component> rootComp = design->rootComponent();
	Ptr<ConstructionPlanes> planes = rootComp->constructionPlanes();
	Ptr<ConstructionPlaneInput> planeInput = planes->createInput();

	Ptr<BRepBodies> bodies = rootComp->bRepBodies();
	Ptr<BRepBody> body = bodies->item(0);
	Ptr<BRepFaces> faces = body->faces();
	Ptr<BRepFace> cylinderFace;
	for (auto face : faces)
	{
		Ptr<Cylinder> cylinder = face->geometry();
		if (cylinder && std::fabs(cylinder->radius() - _poleOD) < 1.0e-6)
		{
			cylinderFace = face;
			break;
		}
	}

	Ptr<Sketches> sketches = rootComp->sketches();
	Ptr<Sketch> sketch = sketches->add(rootComp->yZConstructionPlane());
	Ptr<SketchPoints> points = sketch->sketchPoints();
	Ptr<Point3D> pickPt = Point3D::create(x, y, z);
	Ptr<SketchPoint> pickSketchPt = points->add(sketch->modelToSketchSpace(pickPt));
	planeInput->setByTangentAtPoint(cylinderFace, pickSketchPt);
	Ptr<ConstructionPlane> plane = planes->add(planeInput);

	// Create a hole input
	double stroke = 1;
	Ptr<Features> features = rootComp->features();
	Ptr<HoleFeatures> holes = features->holeFeatures();
	Ptr<HoleFeatureInput> holeInput = holes->createSimpleInput(ValueInput::createByReal(drillBit)); // If you use a variable you don't get a hole
	holeInput->setPositionByPoint(plane, Point3D::create(x, y, z));
	holeInput->setDistanceExtent(adsk::core::ValueInput::createByReal(_poleOD / 2));
	Ptr<HoleFeature> hole = holes->add(holeInput);
}

extern "C" XI_EXPORT bool run(const char* context)
{
	myfile.open("debug033101.txt");
	srand((unsigned)time(NULL));
	myfile << std::to_string(rand()) + " Random Initialized\n";
	myfile << M_PI << " Pi works\n";

	
	//hole temp;
	temp.x = _gapBottom + _bitL / 2;
	temp.y = cos(degrees);
	temp.z = sin(degrees);
	temp.dia = _bitL;
	temp.isReal = true;
	myfile << temp.x << "\t" << temp.y << "\t" << temp.z << "\t" << temp.dia << "\t" << temp.isReal;
	myfile << "OK - Variable Initialization\n";

	if (!createToolBody()) return false;
	myfile << "OK - Created Pole\n";

	makeCylinder();
	myfile << "OK - Created Cylinder\n";

	makeCandyCane();

	makePhantomHoles();

	makeRandomHoles(_numHolesL, _bitL);
	makeRandomHoles(_numHolesM, _bitM);
	makeRandomHoles(_numHolesS, _bitS);

	//Pop drill stack
	for (int count = 0; count < holes.size(); count++) {
		if (holes[count].isReal == true) {
			drillHole(holes[count].x, holes[count].y, holes[count].z, holes[count].dia);
			myfile << "[" << count << "] Popped\t" << holes[count].x << "\t" << holes[count].y << "\t" << holes[count].z << "\n";
		}
	}/*
	for (int count = 405; count <455; count++) {
		if (holes[count].isReal == false) {
			drillHole(holes[count].x, holes[count].y, holes[count].z, holes[count].dia);
			myfile << "[" << count << "] Popped\t" << holes[count].x << "\t" << holes[count].y << "\t" << holes[count].z << "\n";
		}
	}*/
	/*
	for (int count = 1350; count <1450; count++) {
		if (holes[count].isReal == true) {
			drillHole(holes[count].x, holes[count].y, holes[count].z, holes[count].dia);
			myfile << "[" << count << "] Popped\t" << holes[count].x << "\t" << holes[count].y << "\t" << holes[count].z << "\n";
		}
	}*/


	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

marshaltu
Autodesk
Autodesk

Hello,

 

If the crash was because of capacity, I modified the script a little bit. For example: avoid to create sketch for every point, delete work plane/sketch point after hole is created. Please give a try and see if it makes any difference? 

 

BTW: the performance would be worse because more cleanup codes will be executed.

 

Thanks,

Marshal

 

#define _USE_MATH_DEFINES

#include <Core/CoreAll.h>
#include <Fusion/FusionAll.h>
#include <CAM/CAMAll.h>
#include <iostream>
#include <fstream>
#include <cstdlib>
#include <cmath>
#include <ctime>
#include <stack>
#include <random>
#include <vector>

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

ofstream myfile;

struct hole {
	double x, y, z, dia;
	bool isReal;
};
vector<hole> holes;
hole temp;

double degrees = 0;

double _poleLength = 2.54 * 8 * 12;
double _gapTop = 2.54 * 6;
double _gapBottom = 2.54 * 6;
double _poleOD = 2.54 * 1;
double _poleID = 2.54 * .75;
double _slices = 12;
double _sliceArcLength = M_PI * _poleOD / _slices;
double _radius = _poleOD / 2;
double _bitL = 2.54 * 5 / 16;
double _bitM = 2.54 * 1 / 4;
double _bitS = 2.54 * 3 / 16;
int _numHolesL = 2000;
int _numHolesM = 1500;
int _numHolesS = 1000;

Ptr<Application> app = Application::get();
Ptr<UserInterface> ui = app->userInterface();

bool createToolBody()
{
	Ptr<Documents> docs = app->documents();

	// Create a document.
	Ptr<Document> doc = docs->add(DocumentTypes::FusionDesignDocumentType);
	Ptr<Design> design = app->activeProduct();
	design->designType(adsk::fusion::DesignTypes::DirectDesignType);

	// Get the root component of the active design
	Ptr<Component> rootComp = design->rootComponent();

	// Create sketch
	Ptr<Sketches> sketches = rootComp->sketches();
	Ptr<Sketch> sketch = sketches->add(rootComp->yZConstructionPlane());

	// Create sketch circle
	Ptr<SketchCurves> curves = sketch->sketchCurves();
	Ptr<SketchCircles> circles = curves->sketchCircles();
	Ptr<Point3D> centerPoint = Point3D::create(0, 0, 0);
	circles->addByCenterRadius(centerPoint, _poleID);
	circles->addByCenterRadius(centerPoint, _poleOD);

	// Get the profile defined by the circle
	Ptr<Profiles> profs = sketch->profiles();
	Ptr<Profile> prof = profs->item(1);

	//// Create an extrusion input
	Ptr<Features> features = rootComp->features();
	Ptr<ExtrudeFeatures> extrudes = features->extrudeFeatures();
	Ptr<ExtrudeFeatureInput> extInput = extrudes->createInput(prof, FeatureOperations::NewBodyFeatureOperation);

	// Define that the extent is a distance extent of 8 ft
	Ptr<ValueInput> distance = ValueInput::createByReal(_poleLength);

	// Set the distance extent to be one-way symmetric
	extInput->setDistanceExtent(false, distance);

	// Set the extrude to be a solid one
	extInput->isSolid(true);

	// Create an cylinder
	Ptr<ExtrudeFeature> extrude = extrudes->add(extInput);

	return true;
}


/*
void drillHole(double x, double y, double z) {

Ptr<Design> design = app->activeProduct();
Ptr<Component> rootComp = design->rootComponent();
Ptr<ConstructionPlanes> planes = rootComp->constructionPlanes();

Ptr<SketchPoints> points = sketch->sketchPoints();


//Create new plane hole
planes->createInput();
Ptr<Point3D>pickPt = Point3D::create(x, y, z);
//points->release();
Ptr<SketchPoint>pickSketchPt = points->add(sketch->modelToSketchSpace(pickPt));
planeInput->setByTangentAtPoint(cylinderFace, pickSketchPt);
plane = planes->add(planeInput);
holeInput->setPositionByPoint(plane, Point3D::create(x, y, z));
holes->add(holeInput);
}
*/


void makeCandyCane() {
	//Candy Cane Coordinated
	for (temp.x = _gapBottom; temp.x <= _poleLength - _gapTop; temp.x += _bitL) {
		temp.y = cos(degrees);
		temp.z = sin(degrees);
		holes.push_back(temp);
		//holes.pop_back();
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;
		temp.y = cos(degrees + .5);
		temp.z = sin(degrees + .5);
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;
		temp.y = cos(degrees + 1);
		temp.z = sin(degrees + 1);
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;
		temp.x += _bitL;
		degrees += .25;
	}myfile << "\nOK - Candy Cane\n";
}

void makePhantomHoles() {
	//Create Phantom Candy Cane Holes
	myfile << "Create Phantom Holes\n";
	temp.isReal = false;
	double stop = (double)holes.size() - 3;

	for (int count = 0; count < stop; count += 3)
	{
		//(0)=>(1) left hole -> middle hole same row
		temp.x = (holes[count + 1].x - holes[count].x) / 2 + holes[count].x;
		temp.y = (holes[count + 1].y - holes[count].y) / 2 + holes[count].y;
		temp.z = (holes[count + 1].z - holes[count].z) / 2 + holes[count].z;
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

		//(0)=>(3) left hole -> uprow left
		temp.x = (holes[count + 3].x - holes[count].x) / 2 + holes[count].x;
		temp.y = (holes[count + 3].y - holes[count].y) / 2 + holes[count].y;
		temp.z = (holes[count + 3].z - holes[count].z) / 2 + holes[count].z;
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

		//(1)=>(3) middle hole -> uprow left
		temp.x = (holes[count + 3].x - holes[count + 1].x) / 2 + holes[count + 1].x;
		temp.y = (holes[count + 3].y - holes[count + 1].y) / 2 + holes[count + 1].y;
		temp.z = (holes[count + 3].z - holes[count + 1].z) / 2 + holes[count + 1].z;
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

		//(1)=>(4) middle hole -> uprow middle
		temp.x = (holes[count + 4].x - holes[count + 1].x) / 2 + holes[count + 1].x;
		temp.y = (holes[count + 4].y - holes[count + 1].y) / 2 + holes[count + 1].y;
		temp.z = (holes[count + 4].z - holes[count + 1].z) / 2 + holes[count + 1].z;
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

		//(1)=>(2) middle hole -> right same row
		temp.x = (holes[count + 2].x - holes[count + 1].x) / 2 + holes[count + 1].x;
		temp.y = (holes[count + 2].y - holes[count + 1].y) / 2 + holes[count + 1].y;
		temp.z = (holes[count + 2].z - holes[count + 1].z) / 2 + holes[count + 1].z;
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

		//(2)=>(4) right hole -> uprow middle hole
		temp.x = (holes[count + 4].x - holes[count + 2].x) / 2 + holes[count + 2].x;
		temp.y = (holes[count + 4].y - holes[count + 2].y) / 2 + holes[count + 2].y;
		temp.z = (holes[count + 4].z - holes[count + 2].z) / 2 + holes[count + 2].z;
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

		//(2)=>(5) right hole -> uprow right hole
		temp.x = (holes[count + 5].x - holes[count + 2].x) / 2 + holes[count + 2].x;
		temp.y = (holes[count + 5].y - holes[count + 2].y) / 2 + holes[count + 2].y;
		temp.z = (holes[count + 5].z - holes[count + 2].z) / 2 + holes[count + 2].z;
		holes.push_back(temp);
		myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

		myfile << "\n Count " << count << "\t Lights Size " << holes.size() << "\n";

		if (count < stop && count > stop - 6) {
			//Fill in last row of fake holes
			myfile << "\nFill last row of fake holes";
			//(3)=>(4) up left -> up middle
			temp.x = (holes[count + 4].x - holes[count + 3].x) / 2 + holes[count + 3].x;
			temp.y = (holes[count + 4].y - holes[count + 3].y) / 2 + holes[count + 3].y;
			temp.z = (holes[count + 4].z - holes[count + 3].z) / 2 + holes[count + 3].z;
			holes.push_back(temp);
			myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;

			//(4)=>(5) up middle -> up right
			temp.x = (holes[count + 5].x - holes[count + 4].x) / 2 + holes[count + 4].x;
			temp.y = (holes[count + 5].y - holes[count + 4].y) / 2 + holes[count + 4].y;
			temp.z = (holes[count + 5].z - holes[count + 4].z) / 2 + holes[count + 4].z;
			holes.push_back(temp);
			myfile << "\n[" << holes.size() - 1 << "]\t" << holes[holes.size() - 1].x << "\t" << holes[holes.size() - 1].y << "\t" << holes[holes.size() - 1].z << "\t" << holes[holes.size() - 1].dia << "\t" << holes[holes.size() - 1].isReal;
			myfile << "\n Count " << count << "\t Lights Size " << holes.size() << "\n";
		}
	}


}

void makeRandomHoles(double num, double size) {
	temp.dia = size;
	temp.isReal = true;
	for (int count = 0; count < num; count++) {
		//Pick Random X, Y & Z 3Dpoints
		//myfile << "\nCheck out Random Temp Light Hole";
		degrees = rand() % 360;
		temp.x = (double)(rand() % (int)(_poleLength - _gapBottom - _gapTop)) + _gapBottom;
		temp.y = cos(degrees) * _radius;
		temp.z = sin(degrees) * _radius;
		myfile << "\n[temp]\t" << temp.x << "\t" << temp.y << "\t" << temp.z << "\t" << temp.dia << "\t" << temp.isReal;
		//Check random point distance to all other current points
		for (int x = 0; x < holes.size(); x++) {
			if (sqrt(pow(temp.x - holes[x].x, 2) + pow(temp.y - holes[x].y, 2) + pow(temp.z - holes[x].z, 2)) > _bitL*2.5) {
				holes.push_back(temp);
				myfile << "\n[" << holes.size() << "][" << x << "] Degrees " << degrees << "\t" << temp.x << "\t" << temp.y << "\t" << temp.z << "\t" << temp.dia << "\t" << temp.isReal;
				break;
			}
		}
	}
}


void drillHole(double x, double y, double z, double drillBit) {
	Ptr<Design> design = app->activeProduct();
	Ptr<Component> rootComp = design->rootComponent();
	Ptr<ConstructionPlanes> planes = rootComp->constructionPlanes();
	Ptr<ConstructionPlaneInput> planeInput = planes->createInput();

	Ptr<BRepBodies> bodies = rootComp->bRepBodies();
	Ptr<BRepBody> body = bodies->item(0);
	Ptr<BRepFaces> faces = body->faces();
	Ptr<BRepFace> cylinderFace;
	for (auto face : faces)
	{
		Ptr<Cylinder> cylinder = face->geometry();
		if (cylinder && std::fabs(cylinder->radius() - _poleOD) < 1.0e-6)
		{
			cylinderFace = face;
			break;
		}
	}

	Ptr<Sketches> sketches = rootComp->sketches();
	Ptr<Sketch> sketch = sketches->itemByName("holePoints");
	if (!sketch)
	{
		sketch = sketches->add(rootComp->yZConstructionPlane());
		sketch->name("holePoints");
	}
	Ptr<SketchPoints> points = sketch->sketchPoints();
	Ptr<Point3D> pickPt = Point3D::create(x, y, z);
	Ptr<SketchPoint> pickSketchPt = points->add(sketch->modelToSketchSpace(pickPt));
	planeInput->setByTangentAtPoint(cylinderFace, pickSketchPt);
	Ptr<ConstructionPlane> plane = planes->add(planeInput);

	// Create a hole input
	double stroke = 1;
	Ptr<Features> features = rootComp->features();
	Ptr<HoleFeatures> holes = features->holeFeatures();
	Ptr<HoleFeatureInput> holeInput = holes->createSimpleInput(ValueInput::createByReal(drillBit)); // If you use a variable you don't get a hole
	holeInput->setPositionByPoint(plane, Point3D::create(x, y, z));
	holeInput->setDistanceExtent(adsk::core::ValueInput::createByReal(_poleOD / 2));
	Ptr<HoleFeature> hole = holes->add(holeInput);

	plane->deleteMe();
	pickSketchPt->deleteMe();
}

extern "C" XI_EXPORT bool run(const char* context)
{
	myfile.open("debug033101.txt");
	srand((unsigned)time(NULL));
	myfile << std::to_string(rand()) + " Random Initialized\n";
	myfile << M_PI << " Pi works\n";


	//hole temp;
	temp.x = _gapBottom + _bitL / 2;
	temp.y = cos(degrees);
	temp.z = sin(degrees);
	temp.dia = _bitL;
	temp.isReal = true;
	myfile << temp.x << "\t" << temp.y << "\t" << temp.z << "\t" << temp.dia << "\t" << temp.isReal;
	myfile << "OK - Variable Initialization\n";

	if (!createToolBody()) return false;
	myfile << "OK - Created Pole\n";

	myfile << "OK - Created Cylinder\n";

	makeCandyCane();

	makePhantomHoles();

	makeRandomHoles(_numHolesL, _bitL);
	makeRandomHoles(_numHolesM, _bitM);
	makeRandomHoles(_numHolesS, _bitS);

	//Pop drill stack
	for (int count = 0; count < holes.size(); count++) {
		if (holes[count].isReal == true) {
			drillHole(holes[count].x, holes[count].y, holes[count].z, holes[count].dia);
			myfile << "[" << count << "] Popped\t" << holes[count].x << "\t" << holes[count].y << "\t" << holes[count].z << "\n";
		}
	}/*
	 for (int count = 405; count <455; count++) {
	 if (holes[count].isReal == false) {
	 drillHole(holes[count].x, holes[count].y, holes[count].z, holes[count].dia);
	 myfile << "[" << count << "] Popped\t" << holes[count].x << "\t" << holes[count].y << "\t" << holes[count].z << "\n";
	 }
	 }*/
	 /*
	 for (int count = 1350; count <1450; count++) {
	 if (holes[count].isReal == true) {
	 drillHole(holes[count].x, holes[count].y, holes[count].z, holes[count].dia);
	 myfile << "[" << count << "] Popped\t" << holes[count].x << "\t" << holes[count].y << "\t" << holes[count].z << "\n";
	 }
	 }*/


	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


Marshal Tu
Fusion Developer
>
0 Likes

kevin
Enthusiast
Enthusiast

That almost worked.

 

However only 4400 of the holes were made out of 5844 that it should have.

It's such a round number, Is this a software limit?
Ugh

 

Limit.png

0 Likes
______
icon-svg-close-thick

Cookie preferences

Your privacy is important to us and so is an optimal experience. To help us customize information and build applications, we collect data about your use of this site.

May we collect and use your data?

Learn more about the Third Party Services we use and our Privacy Statement.

Strictly necessary – required for our site to work and to provide services to you

These cookies allow us to record your preferences or login information, respond to your requests or fulfill items in your shopping cart.

Improve your experience – allows us to show you what is relevant to you

These cookies enable us to provide enhanced functionality and personalization. They may be set by us or by third party providers whose services we use to deliver information and experiences tailored to you. If you do not allow these cookies, some or all of these services may not be available for you.

Customize your advertising – permits us to offer targeted advertising to you

These cookies collect data about you based on your activities and interests in order to show you relevant ads and to track effectiveness. By collecting this data, the ads you see will be more tailored to your interests. If you do not allow these cookies, you will experience less targeted advertising.

icon-svg-close-thick

THIRD PARTY SERVICES

Learn more about the Third-Party Services we use in each category, and how we use the data we collect from you online.

icon-svg-hide-thick

icon-svg-show-thick

Strictly necessary – required for our site to work and to provide services to you

Qualtrics
We use Qualtrics to let you give us feedback via surveys or online forms. You may be randomly selected to participate in a survey, or you can actively decide to give us feedback. We collect data to better understand what actions you took before filling out a survey. This helps us troubleshoot issues you may have experienced. Qualtrics Privacy Policy
Akamai mPulse
We use Akamai mPulse to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Akamai mPulse Privacy Policy
Digital River
We use Digital River to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Digital River Privacy Policy
Dynatrace
We use Dynatrace to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Dynatrace Privacy Policy
Khoros
We use Khoros to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Khoros Privacy Policy
Launch Darkly
We use Launch Darkly to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Launch Darkly Privacy Policy
New Relic
We use New Relic to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. New Relic Privacy Policy
Salesforce Live Agent
We use Salesforce Live Agent to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Salesforce Live Agent Privacy Policy
Wistia
We use Wistia to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Wistia Privacy Policy
Tealium
We use Tealium to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Tealium Privacy Policy
Upsellit
We use Upsellit to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Upsellit Privacy Policy
CJ Affiliates
We use CJ Affiliates to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. CJ Affiliates Privacy Policy
Commission Factory
We use Commission Factory to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Commission Factory Privacy Policy
Google Analytics (Strictly Necessary)
We use Google Analytics (Strictly Necessary) to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Google Analytics (Strictly Necessary) Privacy Policy
Typepad Stats
We use Typepad Stats to collect data about your behaviour on our sites. This may include pages you’ve visited. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our platform to provide the most relevant content. This allows us to enhance your overall user experience. Typepad Stats Privacy Policy
Geo Targetly
We use Geo Targetly to direct website visitors to the most appropriate web page and/or serve tailored content based on their location. Geo Targetly uses the IP address of a website visitor to determine the approximate location of the visitor’s device. This helps ensure that the visitor views content in their (most likely) local language.Geo Targetly Privacy Policy
SpeedCurve
We use SpeedCurve to monitor and measure the performance of your website experience by measuring web page load times as well as the responsiveness of subsequent elements such as images, scripts, and text.SpeedCurve Privacy Policy
Qualified
Qualified is the Autodesk Live Chat agent platform. This platform provides services to allow our customers to communicate in real-time with Autodesk support. We may collect unique ID for specific browser sessions during a chat. Qualified Privacy Policy

icon-svg-hide-thick

icon-svg-show-thick

Improve your experience – allows us to show you what is relevant to you

Google Optimize
We use Google Optimize to test new features on our sites and customize your experience of these features. To do this, we collect behavioral data while you’re on our sites. This data may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, your Autodesk ID, and others. You may experience a different version of our sites based on feature testing, or view personalized content based on your visitor attributes. Google Optimize Privacy Policy
ClickTale
We use ClickTale to better understand where you may encounter difficulties with our sites. We use session recording to help us see how you interact with our sites, including any elements on our pages. Your Personally Identifiable Information is masked and is not collected. ClickTale Privacy Policy
OneSignal
We use OneSignal to deploy digital advertising on sites supported by OneSignal. Ads are based on both OneSignal data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that OneSignal has collected from you. We use the data that we provide to OneSignal to better customize your digital advertising experience and present you with more relevant ads. OneSignal Privacy Policy
Optimizely
We use Optimizely to test new features on our sites and customize your experience of these features. To do this, we collect behavioral data while you’re on our sites. This data may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, your Autodesk ID, and others. You may experience a different version of our sites based on feature testing, or view personalized content based on your visitor attributes. Optimizely Privacy Policy
Amplitude
We use Amplitude to test new features on our sites and customize your experience of these features. To do this, we collect behavioral data while you’re on our sites. This data may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, your Autodesk ID, and others. You may experience a different version of our sites based on feature testing, or view personalized content based on your visitor attributes. Amplitude Privacy Policy
Snowplow
We use Snowplow to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Snowplow Privacy Policy
UserVoice
We use UserVoice to collect data about your behaviour on our sites. This may include pages you’ve visited. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our platform to provide the most relevant content. This allows us to enhance your overall user experience. UserVoice Privacy Policy
Clearbit
Clearbit allows real-time data enrichment to provide a personalized and relevant experience to our customers. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID.Clearbit Privacy Policy
YouTube
YouTube is a video sharing platform which allows users to view and share embedded videos on our websites. YouTube provides viewership metrics on video performance. YouTube Privacy Policy

icon-svg-hide-thick

icon-svg-show-thick

Customize your advertising – permits us to offer targeted advertising to you

Adobe Analytics
We use Adobe Analytics to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, and your Autodesk ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Adobe Analytics Privacy Policy
Google Analytics (Web Analytics)
We use Google Analytics (Web Analytics) to collect data about your behavior on our sites. This may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. We use this data to measure our site performance and evaluate the ease of your online experience, so we can enhance our features. We also use advanced analytics methods to optimize your experience with email, customer support, and sales. Google Analytics (Web Analytics) Privacy Policy
AdWords
We use AdWords to deploy digital advertising on sites supported by AdWords. Ads are based on both AdWords data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that AdWords has collected from you. We use the data that we provide to AdWords to better customize your digital advertising experience and present you with more relevant ads. AdWords Privacy Policy
Marketo
We use Marketo to send you more timely and relevant email content. To do this, we collect data about your online behavior and your interaction with the emails we send. Data collected may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, email open rates, links clicked, and others. We may combine this data with data collected from other sources to offer you improved sales or customer service experiences, as well as more relevant content based on advanced analytics processing. Marketo Privacy Policy
Doubleclick
We use Doubleclick to deploy digital advertising on sites supported by Doubleclick. Ads are based on both Doubleclick data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Doubleclick has collected from you. We use the data that we provide to Doubleclick to better customize your digital advertising experience and present you with more relevant ads. Doubleclick Privacy Policy
HubSpot
We use HubSpot to send you more timely and relevant email content. To do this, we collect data about your online behavior and your interaction with the emails we send. Data collected may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, email open rates, links clicked, and others. HubSpot Privacy Policy
Twitter
We use Twitter to deploy digital advertising on sites supported by Twitter. Ads are based on both Twitter data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Twitter has collected from you. We use the data that we provide to Twitter to better customize your digital advertising experience and present you with more relevant ads. Twitter Privacy Policy
Facebook
We use Facebook to deploy digital advertising on sites supported by Facebook. Ads are based on both Facebook data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Facebook has collected from you. We use the data that we provide to Facebook to better customize your digital advertising experience and present you with more relevant ads. Facebook Privacy Policy
LinkedIn
We use LinkedIn to deploy digital advertising on sites supported by LinkedIn. Ads are based on both LinkedIn data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that LinkedIn has collected from you. We use the data that we provide to LinkedIn to better customize your digital advertising experience and present you with more relevant ads. LinkedIn Privacy Policy
Yahoo! Japan
We use Yahoo! Japan to deploy digital advertising on sites supported by Yahoo! Japan. Ads are based on both Yahoo! Japan data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Yahoo! Japan has collected from you. We use the data that we provide to Yahoo! Japan to better customize your digital advertising experience and present you with more relevant ads. Yahoo! Japan Privacy Policy
Naver
We use Naver to deploy digital advertising on sites supported by Naver. Ads are based on both Naver data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Naver has collected from you. We use the data that we provide to Naver to better customize your digital advertising experience and present you with more relevant ads. Naver Privacy Policy
Quantcast
We use Quantcast to deploy digital advertising on sites supported by Quantcast. Ads are based on both Quantcast data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Quantcast has collected from you. We use the data that we provide to Quantcast to better customize your digital advertising experience and present you with more relevant ads. Quantcast Privacy Policy
Call Tracking
We use Call Tracking to provide customized phone numbers for our campaigns. This gives you faster access to our agents and helps us more accurately evaluate our performance. We may collect data about your behavior on our sites based on the phone number provided. Call Tracking Privacy Policy
Wunderkind
We use Wunderkind to deploy digital advertising on sites supported by Wunderkind. Ads are based on both Wunderkind data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Wunderkind has collected from you. We use the data that we provide to Wunderkind to better customize your digital advertising experience and present you with more relevant ads. Wunderkind Privacy Policy
ADC Media
We use ADC Media to deploy digital advertising on sites supported by ADC Media. Ads are based on both ADC Media data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that ADC Media has collected from you. We use the data that we provide to ADC Media to better customize your digital advertising experience and present you with more relevant ads. ADC Media Privacy Policy
AgrantSEM
We use AgrantSEM to deploy digital advertising on sites supported by AgrantSEM. Ads are based on both AgrantSEM data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that AgrantSEM has collected from you. We use the data that we provide to AgrantSEM to better customize your digital advertising experience and present you with more relevant ads. AgrantSEM Privacy Policy
Bidtellect
We use Bidtellect to deploy digital advertising on sites supported by Bidtellect. Ads are based on both Bidtellect data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Bidtellect has collected from you. We use the data that we provide to Bidtellect to better customize your digital advertising experience and present you with more relevant ads. Bidtellect Privacy Policy
Bing
We use Bing to deploy digital advertising on sites supported by Bing. Ads are based on both Bing data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Bing has collected from you. We use the data that we provide to Bing to better customize your digital advertising experience and present you with more relevant ads. Bing Privacy Policy
G2Crowd
We use G2Crowd to deploy digital advertising on sites supported by G2Crowd. Ads are based on both G2Crowd data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that G2Crowd has collected from you. We use the data that we provide to G2Crowd to better customize your digital advertising experience and present you with more relevant ads. G2Crowd Privacy Policy
NMPI Display
We use NMPI Display to deploy digital advertising on sites supported by NMPI Display. Ads are based on both NMPI Display data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that NMPI Display has collected from you. We use the data that we provide to NMPI Display to better customize your digital advertising experience and present you with more relevant ads. NMPI Display Privacy Policy
VK
We use VK to deploy digital advertising on sites supported by VK. Ads are based on both VK data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that VK has collected from you. We use the data that we provide to VK to better customize your digital advertising experience and present you with more relevant ads. VK Privacy Policy
Adobe Target
We use Adobe Target to test new features on our sites and customize your experience of these features. To do this, we collect behavioral data while you’re on our sites. This data may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, your IP address or device ID, your Autodesk ID, and others. You may experience a different version of our sites based on feature testing, or view personalized content based on your visitor attributes. Adobe Target Privacy Policy
Google Analytics (Advertising)
We use Google Analytics (Advertising) to deploy digital advertising on sites supported by Google Analytics (Advertising). Ads are based on both Google Analytics (Advertising) data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Google Analytics (Advertising) has collected from you. We use the data that we provide to Google Analytics (Advertising) to better customize your digital advertising experience and present you with more relevant ads. Google Analytics (Advertising) Privacy Policy
Trendkite
We use Trendkite to deploy digital advertising on sites supported by Trendkite. Ads are based on both Trendkite data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Trendkite has collected from you. We use the data that we provide to Trendkite to better customize your digital advertising experience and present you with more relevant ads. Trendkite Privacy Policy
Hotjar
We use Hotjar to deploy digital advertising on sites supported by Hotjar. Ads are based on both Hotjar data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Hotjar has collected from you. We use the data that we provide to Hotjar to better customize your digital advertising experience and present you with more relevant ads. Hotjar Privacy Policy
6 Sense
We use 6 Sense to deploy digital advertising on sites supported by 6 Sense. Ads are based on both 6 Sense data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that 6 Sense has collected from you. We use the data that we provide to 6 Sense to better customize your digital advertising experience and present you with more relevant ads. 6 Sense Privacy Policy
Terminus
We use Terminus to deploy digital advertising on sites supported by Terminus. Ads are based on both Terminus data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that Terminus has collected from you. We use the data that we provide to Terminus to better customize your digital advertising experience and present you with more relevant ads. Terminus Privacy Policy
StackAdapt
We use StackAdapt to deploy digital advertising on sites supported by StackAdapt. Ads are based on both StackAdapt data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that StackAdapt has collected from you. We use the data that we provide to StackAdapt to better customize your digital advertising experience and present you with more relevant ads. StackAdapt Privacy Policy
The Trade Desk
We use The Trade Desk to deploy digital advertising on sites supported by The Trade Desk. Ads are based on both The Trade Desk data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that The Trade Desk has collected from you. We use the data that we provide to The Trade Desk to better customize your digital advertising experience and present you with more relevant ads. The Trade Desk Privacy Policy
RollWorks
We use RollWorks to deploy digital advertising on sites supported by RollWorks. Ads are based on both RollWorks data and behavioral data that we collect while you’re on our sites. The data we collect may include pages you’ve visited, trials you’ve initiated, videos you’ve played, purchases you’ve made, and your IP address or device ID. This information may be combined with data that RollWorks has collected from you. We use the data that we provide to RollWorks to better customize your digital advertising experience and present you with more relevant ads. RollWorks Privacy Policy

Are you sure you want a less customized experience?

We can access your data only if you select "yes" for the categories on the previous screen. This lets us tailor our marketing so that it's more relevant for you. You can change your settings at any time by visiting our privacy statement

Your experience. Your choice.

We care about your privacy. The data we collect helps us understand how you use our products, what information you might be interested in, and what we can improve to make your engagement with Autodesk more rewarding.

May we collect and use your data to tailor your experience?

Explore the benefits of a customized experience by managing your privacy settings for this site or visit our Privacy Statement to learn more about your options.