Community
Fusion API and Scripts
Got a new add-in to share? Need something specialized to be scripted? Ask questions or share what you’ve discovered with the community.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

How to move a component or occurrence?

7 REPLIES 7
SOLVED
Reply
Message 1 of 8
RogerInHawaii
1558 Views, 7 Replies

How to move a component or occurrence?

I have a C++ script and in it I have a pointer to an existing component (or occurrence). I want to make that component move in the window. Initially it's just a simple move along the component's X-axis. But in general I may want to move it all over the place.

 

How do I do that? What property of the component do I need to change in order to accomplish the move?


I've looked all around the API reference and haven't come across the appropriate property or any examples of how to do it. I know how to manipulate joints, but not the simple act of moving an entire component.

7 REPLIES 7
Message 2 of 8
BrianEkins
in reply to: RogerInHawaii

The position of an occurrence can be obtained and set using the transform property of the Occurrence object. A 4x4 matrix is a common computer graphics method of defining a location and orientation of something in 3D space.

 

http://help.autodesk.com/view/fusion360/ENU/?guid=GUID-7fb9ea55-5c24-4c27-b1c4-2e92f42774f7

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 3 of 8
RogerInHawaii
in reply to: BrianEkins

I looked at that but, frankly, it doesn't really explain HOW to accomplish it.

After lots of looking around and trial and error, I wrote up a couple of C++ methods that does what I need. Since I suspect others may also encounter a need for moving things around, here's my code.

bool SetOccurrencePosition(Ptr<Occurrence> TheOccurrenceToPosition, double PositionX, double PositionY, double PositionZ)
{
	Ptr<Matrix3D> ExistingTransform;
	Ptr<Matrix3D> ModifiedTransform;
	Ptr<Vector3D> ExistingTranslation;

	// Retrieve the existing transform item from the occurrence.
	ExistingTransform = TheOccurrenceToPosition->transform();

	// Prepare a new transform which will be identical to the existing one but with its translation item modified
	// so that it provides the new, desired position.
	ModifiedTransform = ExistingTransform;
	ModifiedTransform->translation(Vector3D::create(PositionX, PositionY, PositionZ));

	// Set that modified transform into the specified occurrence.
	TheOccurrenceToPosition->transform(ModifiedTransform);

	// Do note that this will NOT cause the occurrence to appear on the screen in its newly specified location.
	// You'll need to do an :
	//		adsk::doEvents();
	// in order for that to happen.

	return TRUE;
}

bool MoveOccurrence(Ptr<Occurrence> TheOccurrenceToMove, double OffsetX, double OffsetY, double OffsetZ)
{
	// This causes the specified occurrence to move from its current X,Y,Z position to a new position
	// OFFSET from the current position as specified by OffsetX, OffsetY, and OffsetZ.
	Ptr<Matrix3D> ExistingTransform;
	Ptr<Matrix3D> ModifiedTransform;
	Ptr<Vector3D> ExistingTranslation;
	double ExistingXPosition;
	double ExistingYPosition;
	double ExistingZPosition;
	double NewXPosition;
	double NewYPosition;
	double NewZPosition;

	// Retrieve the existing transform item from the occurrence.
	ExistingTransform = TheOccurrenceToMove->transform();

	// Retrieve the translation item from the existing transform.
	ExistingTranslation = ExistingTransform->translation();

	// Extract the existing X, Y, and Z values from the existing translation
	// and calculate the new X, Y, and Z values.
	ExistingXPosition = ExistingTranslation->x();
	NewXPosition = ExistingXPosition + OffsetX;

	ExistingYPosition = ExistingTranslation->y();
	NewYPosition = ExistingYPosition + OffsetY;

	ExistingZPosition = ExistingTranslation->z();
	NewZPosition = ExistingXPosition + OffsetZ;

	// Prepare a new transform which will be identical to the existing one but with its translation item modified
	// so that it provides the new, desired position.
	ModifiedTransform = ExistingTransform;
	ModifiedTransform->translation(Vector3D::create(NewXPosition, NewYPosition, NewZPosition));

	// Set that modified transform into the specified occurrence.
	TheOccurrenceToMove->transform(ModifiedTransform);

	// Do note that this will NOT cause the occurrence to appear on the screen in its newly specified location.
	// You'll need to do an :
	//		adsk::doEvents();
	// in order for that to happen.

	return TRUE;
}
Message 4 of 8
BrianEkins
in reply to: RogerInHawaii

I didn't know how familiar you already were with using transformation matrices.  They're a general method of defining a transform and certainly not unique to Fusion 360 or Autodesk.  Admittedly though if you haven't encountered them in the past they do take quite a bit to get a grasp of.  Here's a simpler program that demonstrates moving an occurrence.  It has two modes depending on if the "if" statement is set to true or false.  In the first case, it moves the occurrence to a specific location and in the second it applies a delta move from the current location of the occurrence.  I didn't need a doEvents to see the result.  I suspect that's because your program is still doing something and has the main thread occupied so Fusion doesn't have a chance to update the screen.

 

#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();
	if (!app)
		return false;
	ui = app->userInterface();
	if (!ui)
		return false;

	// Have an occurrence selected.
	Ptr<Selection> occSel = ui->selectEntity("Select an occurrence.", "Occurrences");
	Ptr<Occurrence> occ = occSel->entity();

	Ptr<Matrix3D> trans = occ->transform();
	if (true)
	{
		// Define the coordinate of the new position of the occurrence.
		Ptr<Point3D> newPosition = adsk::core::Point3D::create(5, 10, 3);

		trans->setCell(0, 3, newPosition->x());
		trans->setCell(1, 3, newPosition->y());
		trans->setCell(2, 3, newPosition->z());
	}
	else
	{
		// Define the delta coordinates to move the occurrence.
		Ptr<Vector3D> delta = adsk::core::Vector3D::create(5, 1, 1);

		trans->setCell(0, 3, trans->getCell(0, 3) + delta->x());
		trans->setCell(1, 3, trans->getCell(1, 3) + delta->y());
		trans->setCell(2, 3, trans->getCell(2, 3) + delta->z());
	}

	occ->transform(trans);

	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
---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 5 of 8
BrianEkins
in reply to: BrianEkins

Attached is a handout for a class I presented at Autodesk University several years ago.  It's for Inventor but there is a section that provides an overview of what a matrix is and how it can be used to define the position of an occurrence.  The same concepts apply to Fusion 360.

 

---------------------------------------------------------------
Brian Ekins
Inventor and Fusion 360 API Expert
Website/Blog: https://EkinsSolutions.com
Message 6 of 8
RogerInHawaii
in reply to: BrianEkins

@BrianEkins  Actually I had NO familiarity with transformation matrices.  I just searched around and figured it out from what I found. There were no clean examples but I was able to put enough together and test a bunch of approaches (trial and error) to come up with a reasonable solution.

 

I REALLY wish the API Reference Manual had reasonable examples. Even the descriptions of the various methods are so brief as to be mostly un-usable.  You have to read them and think, well MAYBE this is what it means and then try out what you think to see if it works as expected. Trial-and-error should NOT be the approach for a Reference Manual.

You can see from the two methods that I wrote and posted here that I use lots of explanatory comments so that, hopefully, it's eminently clear what it's doing and how it's doing it.

 

/end-of-rant

Message 7 of 8
RogerInHawaii
in reply to: BrianEkins

As for needing to call doEvents() ... My program is intended to show a whole bunch of movements, kind of a short video that shows how everything works. It's a rocket that, when in orbit, discards the main fairings, revealing a Lunar Transport Vehicle which then deploys its engines and landing gear. Eventually it will show it actually landing and deploying its cargo pod and then taking off from the lunar lander. So my C++ script is running for a long time. As far as I can tell I MUST call doEvents() once in a while in order for the image to get updated in the window.

Yeah, I know, Fusion probably isn't the best for doing animations like this but I'm also 3D printing the various parts, so I need its modelling accuracy and exporting to STL and such. 

Message 8 of 8

I'm just trying to move a body to specified coordinates on the X, Y matrix. Ex. if my X is 100 mm, I want to set the body at the halfway point, 50 mm. When I enter X, Y coordinates into the dialog box fields, it moves the body, but it's not tied to the matrix, it's tied into where ever the body's starting point is.

 

I did not have this problem in FreeCAD; it would always do what I needed it to do.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report