Sign in to follow this  
coolsas

how to detect arc direction with chook

Recommended Posts

Hi there,

is there a quick and easy way to detect/determine the direction (cw or ccw) of a chained arc, depending of the active cplane with a chook?

In this Moment I use Mastercam 2019 an Visual Studio 2017.

Thank you for an answer an best wishes

Karsten

Share this post


Link to post
Share on other sites
1 hour ago, coolsas said:

Hi there,

is there a quick and easy way to detect/determine the direction (cw or ccw) of a chained arc, depending of the active cplane with a chook?

In this Moment I use Mastercam 2019 an Visual Studio 2017.

Thank you for an answer an best wishes

Karsten

Hi Karsten,

I believe you are looking for:

-> the ChainDIRECTION & reverse_chain function :

 

DllImpExp short ChainDIRECTION ( CHAIN chain,
    short  view_n 
  )

 

 

 

DllImpExp void reverse_chain ( CHAIN chain)
     
   

 

CHAIN *CreateChain(ent &entity, int flip)

{

	CHAIN *chain;

	short err = alloc_chain(&chain, FALSE /* partial*/);

	bool result = (err == 0 && chain != nullptr);



	if (result)

	{

		CHAIN_ENT *last_chain_ent = nullptr;

		short errCode = add_curve_to_chain(&entity, 0, TRUE, 0, chain, &last_chain_ent);

		if (errCode != CHAIN_OK) // bail out !

		{

			result = false;

		}

		if (ChainDIRECTION(chain, 1) == flip)// if our direction == 1 flip the direction

		{

			reverse_chain(chain);//flip the direction

		}

	}



	return (result ? chain : nullptr);

}

 

  • Like 1

Share this post


Link to post
Share on other sites

Hi Peter,

thank you for your answer. I have tried to use your proposal and changed it a little for my purpose. Unfortunately I get everytime "CCW" as an answer, no matter how I made the chaining. I have uploaded the VS2017 test-Project and the Mastercam 2019 test-file.

For the SDK directory in VS2017 I use a systemvariable "SDX_X" and my SDK-path is "C:\Mcam-SDK\sdk-2019". 

Perhaps you could take a look, what I have done wrong.

 

Thank you and best wishes

Karsten

testarcs.rar

TESTarc.mcam

Share this post


Link to post
Share on other sites
2 hours ago, coolsas said:

Hi Peter,

thank you for your answer. I have tried to use your proposal and changed it a little for my purpose. Unfortunately I get everytime "CCW" as an answer, no matter how I made the chaining. I have uploaded the VS2017 test-Project and the Mastercam 2019 test-file.

For the SDK directory in VS2017 I use a systemvariable "SDX_X" and my SDK-path is "C:\Mcam-SDK\sdk-2019". 

Perhaps you could take a look, what I have done wrong.

 

Thank you and best wishes

Karsten

testarcs.rar

TESTarc.mcam

Hi Karsten,

I am not sure exactly what you are trying to do, however here is a snippet of chains being  created from already selected arcs , then the chains being reversed and added into an operation :

	std::vector<CHAIN*>VectorOfChains;
			//get everything
			auto onlyVisible = false;
			
			auto succf = false, suc = false;
			//our current entity
			ent entity;

			DB_LIST_ENT_PTR foundPtr; 
			// the first entity in the database
			auto eptr = db_start;
			//loop through the database
			do
			{
				//get the next entity in the database
				get_raw_ent(onlyVisible, &eptr, &foundPtr, &entity, 0, A_ID, &succf);

				if (succf)
				{
					//if the entity is an arc
					if (entity.id == A_ID)
					{
						//if the entity is ALIVE
						if (sel_bit_is_on(&entity, ALIVE_BIT))
						{
							//if the entity is NOT BLANK
							if (sel_bit_is_off(&entity, BLANK_BIT))
							{
								//if the entity is SELECTED
								if (sel_bit_is_on(&entity, SELECT_BIT))
								{
									//unselect the entity
									sel_bit_turn_off(&entity, SELECT_BIT);
									//write to the entity that it is unselected
									write_ent_sel(&entity, entity.eptr);
									//update the graphics
									repaint_graphics();
									CHAIN *chain;
									short err = alloc_chain(&chain, FALSE /* partial*/);
									bool result = (err == 0 && chain != nullptr);

									if (result)
									{
										CHAIN_ENT *last_chain_ent = nullptr;
										short errCode = add_curve_to_chain(&entity, 0, TRUE, 0, chain, &last_chain_ent);
										if (errCode != CHAIN_OK) // bail out !
										{
											result = false;
										}
									}
									if (result)
									{
										VectorOfChains.push_back(chain);
									}
									//if (ChainDIRECTION(chain, 1) == flip)
									//{
									//	reverse_chain(chain);
									//}

								}

							}

						}

					}

				}

			} while (succf);
			//create a blank pocket operation
			operation op;
			op.opcode = TP_POCKET;
			DB_LIST_ENT_PTR ptr;
			bool bsuccf;
			operation_manager(&op, OPMGR_INIT_ADD, &ptr, &bsuccf);

			
			auto index = 1;
			CString chaininfo;
			for(auto chain : VectorOfChains)
			{ 
				

				switch (ChainDIRECTION(chain, 1))
				{
				case 0:
					chaininfo.Format(_T("Chain #%d is clockwise"), index);
					MessageBox(nullptr, chaininfo,_T("MESSAGE"),MB_OK);
					break;
				case 1:
					chaininfo.Format(_T("Chain #%d is counterclockwise"), index);
					MessageBox(nullptr, chaininfo, _T("MESSAGE"), MB_OK);
					break;
				}

				reverse_chain(chain);
				
				switch (ChainDIRECTION(chain, 1))
				{
				case 0:
					chaininfo.Format(_T("Chain #%d is clockwise"), index);
					MessageBox(nullptr, chaininfo, _T("MESSAGE"), MB_OK);
					break;
				case 1:
					chaininfo.Format(_T("Chain #%d is counterclockwise"), index);
					MessageBox(nullptr, chaininfo, _T("MESSAGE"), MB_OK);
					break;
				}
				//copy chains to operation
				chain_manager_info cmi;

				cmi.mode = CHNMGR_ADD;

				cmi.chns = chain;

				cmi.op_idn = op.op_idn;

				chain_manager(&cmi, TP_CHN_ALL, &succf);

				free_chain(&chain);

				index++;
      }

HTH

Share this post


Link to post
Share on other sites

Hi Peter,

my chook is for exporting geometry data from mastercam into mazatrol cycles. The user selects in a custom dialog a mazatrol-cycle and then he is asked to select the geometry he wants to export into this mazatrol cycle. The selected geometry (arcs, lines, splines, points) will be chained (via "chain_it") and then the chain is examined, which kind of geometry was selected. To recalcutate the coordinates depending of the active c-plane I need to know, if an arc is cw or ccw. If there is a better way to get the properties of a selected geometry, I will try it. I need something like the mastercam funktion "analyse ->contour".

My chook works quite well in the event that the active c-plane is top or front or free in space. But not when the active c-plane is parallel to standard bottom or standard back c-plane. Then my previous direction-calculation is wrong. If the arc is CW chained my calculation gives me CCW and vice versa.

Perhaps I should say that my chook is a mfc extension DLL.

Thank you and best wishes

Karsten

Share this post


Link to post
Share on other sites
1 hour ago, coolsas said:

If there is a better way to get the properties of a selected geometry, I will try it.

Check out the entity unions :

for example entity.u.ar is the arc union, that is where you will find information.

Share this post


Link to post
Share on other sites

Hi Peter,

I use from entity arc entity.u.ar.ep1,  entity.u.ar.ep1, entity.u.ar.r, entity.u.ar.sw.

I determine a factor depending the active c-plane and determine the arc direction

// faktor for c-plane
matrix_33 k_mat, a_mat;
get_view_matrix(CONSTR_VIEW_N,k_mat);
get_view_matrix(entity.u.ar.view,a_mat);
// compare ob z-vector
if(k_mat[2][0] == a_mat[2][0] && k_mat[2][1] == a_mat[2][1] && k_mat[2][2] == a_mat[2][2])
{
	kfaktor=1;
}
else
{
	//if not, is diff < 0,001
	if( ((k_mat[2][0]*1000) - (a_mat[2][0]*1000) <=1) && ((k_mat[2][1]*1000) - (a_mat[2][1]*1000) <=1) && ((k_mat[2][2]*1000) - (a_mat[2][2]*1000) <=1) )
	{
		kfaktor=1;
	}
	else
	{
		kfaktor=-1;
	}
}

//arc direction
richtung=int(fabs(entity.u.ar.sw)/entity.u.ar.sw);

then later I check which point is startingpoint EP1 or EP2 and determine my output.

//  ep1=Startpoint ?
if (ketten_elem->ep_n==0)
{	
	if ((-1*richtung*kfaktor) == 1)
	{
		swprintf_s(tempstr,_T("[CW]\n"));
	}
	else if ((-1*richtung*kfaktor) == -1)
	{
		swprintf_s(tempstr,_T("[CCW]\n"));
	}
	wcscat_s(MMA_chainstring,tempstr);
}
else
{
	// ep2=Startpoint
	if ((richtung*kfaktor) == 1)
	{
		swprintf_s(tempstr,_T("[CW]\n"));
	}
	else if ((richtung*kfaktor) == -1)
	{
		swprintf_s(tempstr,_T("[CCW]\n"));
	}
	wcscat_s(MMA_chainstring,tempstr);
}

All that works fine except when the active c-plane is parallel to standard bottom or standard back c-plane. Then my direction-calculation is wrong. If the arc is CW chained my calculation gives me CCW and vice versa. 

I think I have to check if the active c-plane is parallel to bottom or back c-plane and then change my factor.

Thank you and best wishes

Karsten

Share this post


Link to post
Share on other sites

I'm unfamiliar with how you are determining the arc's direction.

Below is something that works in my testing as long as the sweep's not 180 degrees (it will fail if the sweep is 180).  I'm not sure how helpful it will be.

extern "C" __declspec(dllexport) int ArcDirectionEntry (int param)
	{
	// Must call this prior to accessing any Resources in the C-Hook DLL !
	ChangeResCl res (GetChookResourceHandle ());

	LPCTSTR prompt(_T("Select a Chain"));
	CHAIN* selectedChain = nullptr;

	auto result = chain_1(prompt, &selectedChain);

	if (result == CHAIN_OK && &selectedChain != nullptr)
	{
		auto selectedChainPointer = selectedChain->start;

		p_3d arcStartVector;
		p_3d arcEndVector;
		p_3d crossProduct;

		double arcSweep;

		while (selectedChainPointer != nullptr)
		{
			auto entityPointer = selectedChainPointer->e_ptr->eptr;

			if (entityPointer->id == A_ID)
			{
				if (selectedChainPointer->ep_n)
				{
					arcStartVector = entityPointer->u.ar.ep2 - entityPointer->u.ar.c;
					arcEndVector = entityPointer->u.ar.ep1 - entityPointer->u.ar.c;
				}
				else
				{
					arcStartVector = entityPointer->u.ar.ep1 - entityPointer->u.ar.c;
					arcEndVector = entityPointer->u.ar.ep2 - entityPointer->u.ar.c;
				}

				crossProduct = Cross(arcStartVector, arcEndVector).NormalizeThis();

				arcSweep = entityPointer->u.ar.sw * (180.0 / PI);
				arcSweep = (int)(arcSweep * 1000.0) / 1000.0;

				if (crossProduct[2] < 0.0)
				{
					if (arcSweep <= 180.0)
					{
						::MessageBox(get_MainFrame()->GetSafeHwnd(), _T("CW ARC FOUND!"), _T("ArcDirection"), MB_OK);
					}
					else
					{
						::MessageBox(get_MainFrame()->GetSafeHwnd(), _T("CCW ARC FOUND!"), _T("ArcDirection"), MB_OK);
					}
					
				}
				else if (crossProduct[2] > 0.0)
				{
					if (arcSweep >= 180.0)
					{
						::MessageBox(get_MainFrame()->GetSafeHwnd(), _T("CW ARC FOUND!"), _T("ArcDirection"), MB_OK);
					}
					else
					{
						::MessageBox(get_MainFrame()->GetSafeHwnd(), _T("CCW ARC FOUND!"), _T("ArcDirection"), MB_OK);
					}
				}
				else
				{
					::MessageBox(get_MainFrame()->GetSafeHwnd(), _T("crossProduct = 0; arc direction could not be obtained."), _T("ArcDirection"), MB_OK);
				}
			}

			selectedChainPointer = selectedChainPointer->next;
		}

		free_chain(&selectedChain);
	}

	return MC_NOERROR | MC_UNLOADAPP;
	}

 

  • Like 1

Share this post


Link to post
Share on other sites

Hi Zaffin_D,

thank you for your proposal, I will give it a try.

Best wishes, Karsten

Share this post


Link to post
Share on other sites

Hi Zaffin_D,

I have tried your code, unfortunately I have similar problems, sometimes arc direction is correct, sometimes not. You can check that in my uploaded file Testarc.mcam the link is in my 2nd post. I select c-plane top and start your function, then I select the wireframe contour on top of the solid, I chain it clockwise (then all 4 arcs should be CW) then I get 3 CW and 1 CCW. When I select c-plane bottom, start your function and chain the geometry on bottom of the solid, then I get 2 CW and 2 CCW as message.

When I use the mastercam function analyze->contour then I get the correct data, chaining the contour clockwise I get 4 CW arcs, chaining counterclockwise I get 4 CCW arcs. That is what I need.

Unfortunatley I am not the mathematician to calculate it from entity data (ep1, ep2, c, r, sa, sw) depending the active c-plane.

I thank you Zaffin_D and Peter for trying to help me.

Best wishes Karsten

 

Share this post


Link to post
Share on other sites
2 hours ago, coolsas said:

Hi Zaffin_D,

I have tried your code, unfortunately I have similar problems, sometimes arc direction is correct, sometimes not. You can check that in my uploaded file Testarc.mcam the link is in my 2nd post. I select c-plane top and start your function, then I select the wireframe contour on top of the solid, I chain it clockwise (then all 4 arcs should be CW) then I get 3 CW and 1 CCW. When I select c-plane bottom, start your function and chain the geometry on bottom of the solid, then I get 2 CW and 2 CCW as message.

When I use the mastercam function analyze->contour then I get the correct data, chaining the contour clockwise I get 4 CW arcs, chaining counterclockwise I get 4 CCW arcs. That is what I need.

Unfortunatley I am not the mathematician to calculate it from entity data (ep1, ep2, c, r, sa, sw) depending the active c-plane.

I thank you Zaffin_D and Peter for trying to help me.

Best wishes Karsten

 

Funny arcs...

The center point isn't mapped to the same view as the endpoints, try mapping the center to world with view_to_world as shown below.

			if (entityPointer->id == A_ID)
			{
				p_3d worldCenter;

				view_to_world(entityPointer->u.ar.c, entityPointer->u.ar.view, worldCenter);

				if (selectedChainPointer->ep_n)
				{
					arcStartVector = entityPointer->u.ar.ep2 - worldCenter;
					arcEndVector = entityPointer->u.ar.ep1 - worldCenter;
				}
				else
				{
					arcStartVector = entityPointer->u.ar.ep1 - worldCenter;
					arcEndVector = entityPointer->u.ar.ep2 - worldCenter;
				}

Also I think we should take the absolute sweep...

				arcSweep = fabs(entityPointer->u.ar.sw) * (180.0 / PI);

...but i'm not a math guru.

Share this post


Link to post
Share on other sites
13 hours ago, Zaffin_D said:

view_to_world(entityPointer->u.ar.c, entityPointer->u.ar.view, worldCenter);

instead, you could use this function to get the view, in the description it says it checks for more than one view on the arc,that sounds useful.

/**
 * @par Purpose:
 *			Find a view given a line or arc.
 *
 * @param[in]		entity	Line or arc
 * @param[out]		view	An existing view number
 * @param[out]		depth	A depth relative to view
 * @param[out]		succf	True if view is valid.	False if no existing
 *							view was found, or if arcs were found in more
 *							than one view
 * @param[in]		favor_cplane   If true and entity is a line, retrun CPlane if possible - default = false
 */
DllImpExp void find_view_from_ent (
	const ent *entity,
	short *view,
	double *depth,
	bool *succf,
	bool favor_cplane = false);

 

Share this post


Link to post
Share on other sites
On 4/3/2020 at 2:46 AM, coolsas said:

All that works fine except when the active c-plane is parallel to standard bottom or standard back c-plane. Then my direction-calculation is wrong. If the arc is CW chained my calculation gives me CCW and vice versa. 

You need to set the view you are using in the ChainDIRECTION function to your active Cplane view :

try this function that also uses creep to get the endpoint (and all the other points):

	void GetPointsFromWireframe(ent &entity, double &creepamount, std::vector<p_3d> &p3dvector)
	{
		creep_rec creep_info, creep_info_end; p_3d pt, ptend, lastpoint;
		init_creep(&entity, &creep_info);
		init_creep(&entity, &creep_info_end);
		bool inittracking = false;
		init_creep_info(&entity, false, &creep_info);
		init_creep_info(&entity, true, &creep_info_end);
		creep_along_ent(&entity, &creep_info_end, creepamount, ptend);
		DB_LIST_ENT_PTR ptout = nullptr;
		for (;;)
		{

			creep_along_ent(&entity, &creep_info, creepamount, pt);
			ent newentity;
			newentity.id = P_ID;
			newentity.u.pt = pt;
			bool succf;

			if (inittracking)
			{

				if (pt[0] > ptend[0] - .0015 && pt[0] < ptend[0] + .0015)
				{
					if (pt[1] > ptend[1] - .0015 && pt[1] < ptend[1] + .0015)
					{
						if (pt[2] > ptend[2] - .0015 && pt[2] < ptend[2] + .0015)
						{
							break;
						}
					}
				}

				p3dvector.push_back(pt);
			}
			else
			{
				inittracking = true;
			}
			lastpoint = pt;
			creepamount = creepamount + .001;
		}
	}
	CHAIN* SelectChain_1()
	{
		LPCSTR prompt(_T("Select A Chain"));
		CHAIN* SelectedChain;
		auto ErrorCode = alloc_chain(&SelectedChain, FALSE);
		auto Result = (ErrorCode == 0 && SelectedChain != nullptr);
		if (Result)
		{
			auto errcode = chain_1(prompt, &SelectedChain);
			if (errcode != CHAIN_OK)
			{
				Result = false;
			}
		}
		return(Result ? SelectedChain : nullptr);
	}
	void GetChainData()
	{
		auto SelectedChain = SelectChain_1();
		while (SelectedChain != nullptr)
		{
			auto SelectedChainPointer = SelectedChain->start;
			while (SelectedChainPointer != nullptr)
			{
				auto EntityPointer = SelectedChainPointer->e_ptr->eptr;
				if (EntityPointer != nullptr)
				{
					//everything is valid
					auto mcview = Mastercam::IO::ViewManager::CPlane;
					if (mcview != nullptr)
					{
						auto creepamount = .001;
						std::vector<p_3d> p3dvector;
						GetPointsFromWireframe(*EntityPointer, creepamount, p3dvector);
						p_3d firstpt;
						p_3d secondpt;
						if (!p3dvector.empty())
						{
							firstpt = p3dvector.front();
							secondpt = p3dvector.back();
						}
						auto viewnumber = mcview->ViewNumber;
						auto chaindir = ChainDIRECTION(SelectedChain, viewnumber);
						CString chaindirectionstr;
						if (chaindir == 0)
						{
							chaindirectionstr.Format(_T("Chain Direction Clockwise : %d firstpoint : x%lf,y%lf,z%lf secondpoint : x%lf,y%lf,z%lf")
								, chaindir, firstpt[0], firstpt[1], firstpt[2], secondpt[0], secondpt[1], secondpt[2]);
						}
						if (chaindir == 1)
						{
							chaindirectionstr.Format(_T("Chain Direction CounterClockwise : %d firstpoint : x%lf,y%lf,z%lf secondpoint : x%lf,y%lf,z%lf")
								, chaindir, firstpt[0], firstpt[1], firstpt[2], secondpt[0], secondpt[1], secondpt[2]);
						}
						if (chaindir == -2)
						{
							chaindirectionstr.Format(_T("Error Invalid Chain Detected!"), chaindir);
						}
						MessageBox(nullptr, chaindirectionstr, _T("Message"), MB_OK);
					}
				}
				SelectedChainPointer = SelectedChainPointer->next;
			}
			free_chain(&SelectedChain);
		}

	}

You need the project->properties->general->Common Language Runtime Support (/clr) to be set to use it. you will also need to link in the NEThook_3 DLL

Share this post


Link to post
Share on other sites
2 hours ago, Peter from S.C.C.C. said:

You need to set the view you are using in the ChainDIRECTION function to your active Cplane view :

Hi Peter,

That is what I have done in my version of your first proposal:

arcdir = ChainDIRECTION(chain, CONSTR_VIEW_N);

You can see that in the project testarcs.rar linked in my 2nd pst.

 

Hi Zaffin_D,

I changed your function as you posted, same Problems, if the c-plane is not top.

 

But I have found something during testing (rotation of the solid around wks x-axis):

My original calculation is correct  when the z-vector of the active c-plane points to positive Z (from WKS TOP).

When the z-vector of the active c-plane points to negative Z (from WKS TOP) then the arc direction is vice versa.

Active c-plane front and back seems to be correct also.

 

I think, thats it. Thank you very much for trying to help me I wish both of you all the best and stay healthy in these days.

Best wishes, Karsten

 

z-vector.png

Share this post


Link to post
Share on other sites

Hi there,

perhaps if somebody is interested, this is how it works for me:

extern "C" __declspec(dllexport) int m_main(int not_used)
{
	// Must call this prior to accessing any Resources in the C-Hook DLL !
	ChangeResCl res(GetChookResourceHandle());
	
	CHAIN_ENT *ketten_elem;
	CHAIN *ges_kette, *akt_kette;
	ent entity;
	CString str;
	short succf;

	int kfaktor;
	int richtung;

	alloc_chain(&ges_kette, FALSE);

	str = _T("select geo");
	succf = (chain_it(str, &ges_kette));
	if (succf == CHAIN_OK && ges_kette != NULL)
	{
		akt_kette = ges_kette;
		do
		{
			ketten_elem = akt_kette->start;
			do
			{
				get_ent_from_eptr(ketten_elem->e_ptr, &entity);
				switch (entity.id)
				{
				case L_ID:
				{
					break;
				}		//case L_ID
				case A_ID:
				{
					// factor for c-plane
					matrix_33 k_mat;
					get_view_matrix(CONSTR_VIEW_N, k_mat);
					// z-vector 0 or positive?
					if (k_mat[2][2] >= 0) kfaktor = 1;
					else kfaktor = -1;
					// arcdirection
					richtung = int(fabs(entity.u.ar.sw) / entity.u.ar.sw);
					// ep1=starting point
					if (ketten_elem->ep_n == 0)
					{
						if ((-1 * richtung*kfaktor) == 1)
						{
							AfxMessageBox(_T("[CW]\n"));
						}
						else if ((-1 * richtung*kfaktor) == -1)
						{
							AfxMessageBox(_T("[CCW]\n"));
						}
					}
					// ep2=starting point
					else
					{
						if ((richtung*kfaktor) == 1)
						{
							AfxMessageBox(_T("[CW]\n"));
						}
						else if ((richtung*kfaktor) == -1)
						{
							AfxMessageBox(_T("[CCW]\n"));
						}
					}
					break;
				}		//case A_ID
				case NB_ID:
				{
					break;
				}	//case NB_ID
				default:
					break;
				}		//Switch entity.id
				ketten_elem = (ketten_elem->next);
			} while (ketten_elem != NULL);
			akt_kette = (akt_kette->next);
		} while (akt_kette != NULL);
	}
	free_chains(&ges_kette);
	return MC_NOERROR | MC_UNLOADAPP;
}

Best wishes and Happy Easter

Karsten

Share this post


Link to post
Share on other sites
15 hours ago, coolsas said:

Hi there,

perhaps if somebody is interested, this is how it works for me:

Using the previously attached part file that function returns the arc direction of the upper profile as CCW when chained clockwise with the C-plane set to TOP; so I think somethings up.  I'm using 2020, but I don't think that would make a difference.

The below function matches the analyze contour results in my tests.

void GetChainDirection()
{
	LPCTSTR prompt(_T("Select a Chain"));
	CHAIN* selectedChain = nullptr;

	auto result = chain_1(prompt, &selectedChain);

	if (result == CHAIN_OK && &selectedChain != nullptr)
	{
		auto selectedChainPointer = selectedChain->start;

		while (selectedChainPointer != nullptr)
		{
			auto entityPointer = selectedChainPointer->e_ptr->eptr;

			if (entityPointer->id == A_ID)
			{
				p_3d arcStartVector;
				p_3d arcEndVector;
				p_3d crossProduct;
			
				p_3d arcStart;
				p_3d arcCenter;
				p_3d arcEnd;

				double arcSweep;

				view_to_world(entityPointer->u.ar.c, entityPointer->u.ar.view, arcCenter);

				view_to_view(entityPointer->u.ar.ep1, 1, CONSTR_VIEW_N, arcStart);
				view_to_view(arcCenter, 1, CONSTR_VIEW_N, arcCenter);
				view_to_view(entityPointer->u.ar.ep2, 1, CONSTR_VIEW_N, arcEnd);

				if (selectedChainPointer->ep_n)
				{
					arcStartVector = arcEnd - arcCenter;
					arcEndVector = arcStart - arcCenter;
				}
				else
				{
					arcStartVector = arcStart - arcCenter;
					arcEndVector = arcEnd - arcCenter;
				}

				crossProduct = Cross(arcStartVector, arcEndVector).NormalizeThis();

				arcSweep = std::abs(entityPointer->u.ar.sw) * (180.0 / PI);
				arcSweep = (int)(arcSweep * 1000.0) / 1000.0;

				if (crossProduct[Z] < 0.0)
				{
					if (arcSweep <= 180.0)
					{
						::MessageBox(get_MainFrame()->GetSafeHwnd(), _T("CW ARC FOUND!"), _T("ArcDirection"), MB_OK);
					}
					else
					{
						::MessageBox(get_MainFrame()->GetSafeHwnd(), _T("CCW ARC FOUND!"), _T("ArcDirection"), MB_OK);
					}

				}
				else if (crossProduct[Z] > 0.0)
				{
					if (arcSweep >= 180.0)
					{
						::MessageBox(get_MainFrame()->GetSafeHwnd(), _T("CW ARC FOUND!"), _T("ArcDirection"), MB_OK);
					}
					else
					{
						::MessageBox(get_MainFrame()->GetSafeHwnd(), _T("CCW ARC FOUND!"), _T("ArcDirection"), MB_OK);
					}
				}
				else
				{
					::MessageBox(get_MainFrame()->GetSafeHwnd(), _T("crossProduct = 0; arc direction could not be obtained."), _T("ArcDirection"), MB_OK);
				}
			}

			selectedChainPointer = selectedChainPointer->next;
		}

		free_chain(&selectedChain);
	}
}

 

  • Like 1

Share this post


Link to post
Share on other sites

Hi Zaffin_D,

Yes, your code is working within Mastercam 2019 too. I get the arcs correct.

Best wishes Karsten

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

Join us!

eMastercam - your online source for all things Mastercam.

Together, we are the strongest Mastercam community on the web with over 56,000 members, and our online store offers a wide selection of training materials for all applications and skill levels.

Follow us