How -to: Create a custom operator to move/edit shell's vertex in 3DF

Below is sample code on how to edit shell’s vertex using a custom operator.


class MyOp : public HBaseOperator
{

public:

	HBaseView *myView;
	HC_KEY planeSegment;
	HC_KEY shellKey;

	bool operator_selected;

	MyOp(HBaseView* view, int DoRepeat = 0, int DoCapture = 1);
	void CreatePlane();
	int OnLButtonDown(HEventInfo &event);
	int OnLButtonDownAndMove(HEventInfo &event);
	int OnLButtonUp(HEventInfo &event);
};


MyOp::MyOp(HBaseView* view, int DoRepeat, int DoCapture) : HBaseOperator(view, DoRepeat, DoCapture)
{

	myView = view;	
	CreatePlane();

}



int MyOp::OnLButtonDown(HEventInfo &event)
{

	//  check to see if marker handles is selected
	HPoint window = event.GetMouseWindowPos();

	int count = 0;
	HC_KEY key;
	int offset1, offset2, offset3;
	float selection_offset = 0.01f;

	HC_Open_Segment_By_Key(m_pView->GetViewKey());
	{
		count = HC_Compute_Selection_By_Area(".", ".", "v", 
			window.x - selection_offset, window.x + selection_offset, 
			window.y - selection_offset, window.y + selection_offset);

		if (count > 0)
		{
			HC_Show_Selection_Element(&key, &offset1, &offset2, &offset3);
			
			char owner[128];
			HC_Show_Owner_By_Key(key, owner);

			if (strstr(owner, "marker_handles"))
			{
				operator_selected = true;
			}

			m_pView->Update();

		}
	}
	HC_Close_Segment();

	return HOP_OK;
}

int MyOp::OnLButtonDownAndMove(HEventInfo &event)
{

	HPoint window = event.GetMouseWindowPos();

	// if marker handles is selected, edit marker handle and shell's vertex base on the current mouse position
	if (operator_selected == true)
	{

			HC_KEY key = INVALID_KEY;
			int offset1[10];
			int offset2[10];
			int offset3[10];
			HC_Show_Selection_Element(&key, &offset1[0], &offset2[0], &offset3[0]);
			
			HPoint world;
			HC_Open_Segment_By_Key(myView->GetSceneKey()); {
				HC_Compute_Coordinates(".", "local window", &window, "world", &world);
			} HC_Close_Segment();

			char type[128];
			HC_Show_Key_Type(key, type);

			if (streq(type, "marker"))
			{
				// edit the position of marker
				HPoint markerPos;
				HC_Show_Marker(key, &markerPos.x, &markerPos.y, &markerPos.z);
				HC_Edit_Marker(key, world.x, world.y, world.z);


				// Find the vertex using the position of markers handle
				// Edit the position of the shell's vertex

				int		in_point_count, in_face_list_length;
				HPoint	*in_points;
				int			*in_face_list;


				HC_Show_Shell_Size(shellKey, &in_point_count, &in_face_list_length);
				in_points = new HPoint[in_point_count];
				in_face_list = new int[in_face_list_length];

				HC_Show_Shell(shellKey, &in_point_count, in_points, &in_face_list_length, in_face_list);

				int ii=0;
				for (ii = 0; ii < in_point_count; ii++)

				{

					if (in_points[ii] == markerPos)
					{
						HC_Edit_Shell_Points(shellKey, ii, 1, 1, &world);
					}
				}


			}
			m_pView->Update();


	}
	GetView()->Update();

	return HOP_OK;
}
int MyOp::OnLButtonUp(HEventInfo &event)
{
	operator_selected = false;
	return HOP_OK;
}


// create plane an marker handles on each vertex
// Markers position is equal to shells points
void  MyOp::CreatePlane()
{
	HC_Open_Segment_By_Key(myView->GetSceneKey());

	planeSegment = HC_Open_Segment("overwrite/plane"); {

		int pcount, flist_count;
		pcount = 4;
		flist_count = 5;
		HPoint pts[4];
		int faces[5] = { 4, 0, 1, 2, 3 };

		pts[0].Set(-1, -1, 0);
		pts[1].Set(1, -1, 0);
		pts[2].Set(1, 1, 0);
		pts[3].Set(-1, 1, 0);

		HC_Set_Visibility("faces=on,edges=on,vertices=off");
		shellKey = HC_Insert_Shell(pcount, pts, flist_count, faces);

		HC_Open_Segment("marker_handles"); {
			
			HC_Set_Visibility("markers=on");
			HC_Set_Rendering_Options("depth range=(0,0.1)");
			HC_Set_Marker_Size(1);

			HC_Insert_Marker(-1, -1, 0);
			HC_Insert_Marker(1, -1, 0);
			HC_Insert_Marker(1, 1, 0);
			HC_Insert_Marker(-1, 1, 0);

		} HC_Close_Segment();

	} HC_Close_Segment();

	HC_Close_Segment();

	myView->Update();
}


void CSolidHoopsView::OnExtraSlot1()
{

	HSelectionSet * selection = new HSelectionSet(m_pHView);
	selection->Init();
	m_pHView->SetViewSelectionLevel(HSelectionLevelEntity);
	m_pHView->SetSelection(selection);

	MyOp *my_operator = new MyOp(m_pHView);
	m_pHView->SetOperator(my_operator);

	m_pHView->SetViewMode(HViewXY);
	m_pHView->Update();

	
}

2023-04-12_11-49-08

1 Like