// Copyright (c) 2020 OPEN CASCADE SAS
//
// This file is part of the examples of the Open CASCADE Technology software library.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE



#include "OCCT_Test/MakeBottle.h"
#include "DocumentCommon.h"
#include "Transparency.h"
#include "AllHead.h"
#include <opencascade/BRepBndLib.hxx>




// =======================================================================
// function : Viewer
// purpose  :
// =======================================================================
Handle(V3d_Viewer) DocumentCommon::Viewer(const Standard_ExtString,
	const Standard_CString,
	const Standard_Real theViewSize,
	const V3d_TypeOfOrientation theViewProj,
	const Standard_Boolean theComputedMode,
	const Standard_Boolean theDefaultComputedMode)
{
	static Handle(OpenGl_GraphicDriver) aGraphicDriver;
	if (aGraphicDriver.IsNull())
	{
		Handle(Aspect_DisplayConnection) aDisplayConnection;
#if !defined(_WIN32) && !defined(__WIN32__) && (!defined(__APPLE__) || defined(MACOSX_USE_GLX))
		aDisplayConnection = new Aspect_DisplayConnection(OSD_Environment("DISPLAY").Value());
#endif
		aGraphicDriver = new OpenGl_GraphicDriver(aDisplayConnection);
}

	Handle(V3d_Viewer) aViewer = new V3d_Viewer(aGraphicDriver);
	aViewer->SetDefaultViewSize(theViewSize);
	aViewer->SetDefaultViewProj(theViewProj);
	aViewer->SetComputedMode(theComputedMode);
	aViewer->SetDefaultComputedMode(theDefaultComputedMode);
	return aViewer;
}

void DocumentCommon::ShowOrHideActivateGridMesh() {
	qDebug() << u8"切换平面网格显示 \n";
	if (this->isActivateGridMesh) {
		myViewer->DeactivateGrid();
		this->isActivateGridMesh = false;
	}
	else {
		// 设置XOY平面的网格
		myViewer->SetGridEcho(Standard_True);
		myViewer->ActivateGrid(Aspect_GT_Rectangular, Aspect_GDM_Lines);
		this->isActivateGridMesh = true;
	}
	myViewer->Redraw();
}

void DocumentCommon::ShowOrHideActivateAxisGris()
{
	qDebug() << u8"切换坐标轴网格显示 \n";
	if (this->isActivateAxisGrid) {

		for (NCollection_List<Handle(V3d_View)>::Iterator anIter(this->myViewer->ActiveViews());
			anIter.More(); anIter.Next())
		{
			const Handle(V3d_View)& anObject = anIter.Value();
			anObject->GraduatedTrihedronErase();
		}
		this->isActivateAxisGrid = false;
	}
	else {

		for (NCollection_List<Handle(V3d_View)>::Iterator anIter(this->myViewer->ActiveViews());
			anIter.More(); anIter.Next())
		{
			const Handle(V3d_View)& anObject = anIter.Value();
			// 创建立方体网格对象
			Graphic3d_GraduatedTrihedron grid;
			anObject->GraduatedTrihedronDisplay(grid);
		}

		this->isActivateAxisGrid = true;
	}

	myViewer->Redraw();
}

bool DocumentCommon::getActivateGridMesh()
{
	return this->isActivateGridMesh;
}

bool DocumentCommon::getActivateAxisGrid()
{
	return this->isActivateAxisGrid;
}


Handle(AIS_InteractiveObject)  DocumentCommon::ShowTopoDS_Shape(TopoDS_Shape& shape)  
{
	Handle(AIS_InteractiveObject) aShape = new AIS_Shape(shape);
	this->myContext->Display(aShape, Standard_True);
	return aShape;
}

bool DocumentCommon::HideTopoDS_Shape(Handle(AIS_InteractiveObject) aShape)
{
	 
	this->myContext->Erase(aShape, Standard_True);
	return true;
}

bool DocumentCommon::ShowTopoDs_ShapeAIS(Handle(AIS_InteractiveObject) aShape)
{
	this->myContext->Display(aShape, Standard_True);
	return true;
}

bool DocumentCommon::RemoveTopoDS_Shape(Handle(AIS_InteractiveObject) aShape)
{
	this->myContext->Remove(aShape, Standard_True);
	return true;
}

DocumentCommon::DocumentCommon(QWidget* theApp)
	:myContextIsEmpty(true),
	QTreeWidget(theApp)
{
	this->ShapeInfomationWindows = nullptr;
	TCollection_ExtendedString a3DName("Visu3D");
	myViewer = Viewer(a3DName.ToExtString(), "", 1000.0, V3d_XposYnegZpos, Standard_True, Standard_True);
	myViewer->SetDefaultLights();
	myViewer->SetLightOn();
	myContext = new AIS_InteractiveContext(myViewer);
	this->setColumnCount(1);
	this->initTaskTreeRootNode();
	this->initDocumentCommonContextMenu(); // 初始化右键菜单
}

void DocumentCommon::SetObjects(const NCollection_Vector<Handle(AIS_InteractiveObject)>& theObjects,
	Standard_Boolean theDisplayShaded)
{
	myContext->RemoveAll(Standard_False); // 清空对象
	myContextIsEmpty = theObjects.IsEmpty();

	for (NCollection_Vector<Handle(AIS_InteractiveObject)>::Iterator anIter(theObjects);
		anIter.More(); anIter.Next())
	{
		const Handle(AIS_InteractiveObject)& anObject = anIter.Value();
		if (!theDisplayShaded)
		{
			myContext->Display(anObject, Standard_False);
		}
		else
		{
			myContext->Display(anObject, AIS_Shaded, 0, Standard_False);
		}
	}
	myViewer->Redraw();
}

void DocumentCommon::ClearShape()
{
	myContext->RemoveAll(Standard_True);
	myContextIsEmpty = true;
}

void DocumentCommon::AppendCube()
{
	qDebug() << u8"初始化坐标系 \n";
	Handle(AIS_ViewCube) aViewCube = new AIS_ViewCube();
	myObject3d.Append(aViewCube);

}

void DocumentCommon::InitAixs()
{
	this->AppendCube();

	myContext->RemoveAll(Standard_False);
	myContextIsEmpty = this->myObject3d.IsEmpty();

	for (NCollection_Vector<Handle(AIS_InteractiveObject)>::Iterator anIter(this->myObject3d);
		anIter.More(); anIter.Next())
	{
		const Handle(AIS_InteractiveObject)& anObject = anIter.Value();
		myContext->Display(anObject, Standard_False);
	}
	this->isActivateAxisGrid = false;
	this->isActivateGridMesh = false;
	//this->ShowOrHideActivateAxisGris();
	this->ShowOrHideActivateGridMesh();
	myViewer->Redraw();
}

TaskNode* DocumentCommon::getItemByName(QString name)
{
	if (this->dataMap.contains(name)) {
		QTreeWidgetItem* item = this->dataMap.value(name);
		TaskNode* obj = item->data(0, Qt::UserRole).value<TaskNode*>();
		return obj;
	}
	else {
		return nullptr;
	}
}

std::shared_ptr<Bnd_Box> DocumentCommon::getSenceExtend()
{
 
	std::shared_ptr<Bnd_Box> theOverallBox_ptr = std::make_shared<Bnd_Box>();;
	AIS_ListOfInteractive aListOfObjects;
	this->myContext->DisplayedObjects(aListOfObjects);

	AIS_ListIteratorOfListOfInteractive anIter(aListOfObjects);
	for (; anIter.More(); anIter.Next()) {
		Handle(AIS_InteractiveObject) anIO = anIter.Value();
		Handle_AIS_Shape aShape = Handle_AIS_Shape::DownCast(anIO);
		if (!aShape.IsNull()) {
			// Get the TopoDS_Shape
			TopoDS_Shape aTopoShape = aShape->Shape();
			BRepBndLib::Add(aTopoShape, *theOverallBox_ptr);
 
		}
	}
	return theOverallBox_ptr;
}

std::shared_ptr<Bnd_Box> DocumentCommon::getSenceExtend(QString name)
{	
	TaskNode* temp = this->getItemByName(name);
	if (temp) {

		OCCTShapeModelNode* node= dynamic_cast<OCCTShapeModelNode*>(temp);


		TopoDS_Shape aTopoShape = node->Shape();
		std::shared_ptr<Bnd_Box> aBox_ptr = std::make_shared<Bnd_Box>();;
		BRepBndLib::Add(aTopoShape, *aBox_ptr);
		
		return aBox_ptr;
	}
	else {
		std::shared_ptr<Bnd_Box> aBox_ptr(nullptr);
		return aBox_ptr;
	}
}

void DocumentCommon::OpenOCCTShapeFile()
{
	qDebug() << u8"打开文件 \n";
	QString  stlpath = getOpenFilePath(
		nullptr,
		QString::fromUtf8(u8"导入模型"),
 
		QString::fromUtf8(u8"STL Files (*.stl);;STL Files (*.stla);;step Files (*.stp);;step Files (*.step);;IGES Files (*.iges);;IGES Files (*.igs)"));
	this->addShapeDsItem(stlpath);
}


// 打开模型
void DocumentCommon::addShapeDsItem(QString filepath)
{
	OCCTShapeModelNode* checkBox = new OCCTShapeModelNode(this);
	checkBox->setContext(this->myContext);
	if (checkBox->setDataFile(filepath)) {
		this->addOCCTObjectItem(checkBox);
	}
	else {
		qDebug() << u8"没有打开文件：" << filepath << "\n";
	}
}

void DocumentCommon::oncheckBoxStateChanged(int state) {

}

 
void DocumentCommon::initDocumentCommonContextMenu()
{
	qDebug() << u8"初始化initDocumentCommonContextMenu，模型编辑模块";
	this->m_undoStack = new QUndoStack(this); //存放命令的栈

	this->setContextMenuPolicy(Qt::CustomContextMenu);
	this->ContentListContextMenu = new QMenu(this); // 表格控件的右键菜单

	//QAction* m_undoAction = m_undoStack->createUndoAction(this, u8"撤销");//添加QAction，Ctrl-Z作为回撤的快捷键
	//m_undoAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Z));
	//QObject::connect(m_undoAction, SIGNAL(triggered()), this, SLOT(tableView_UndoAction()));

	//QAction* m_redoAction = m_undoStack->createRedoAction(this, u8"重做");//添加QAction，Ctrl-Y左右前进的快捷键
	//m_redoAction->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Y));
	//QObject::connect(m_redoAction, SIGNAL(triggered()), this, SLOT(tableView_RedoAction()));

	//this->ContentListContextMenu->addAction(m_undoAction);
	//this->ContentListContextMenu->addAction(m_redoAction);

	//QAction* TranslationdAction = this->ContentListContextMenu->addAction(u8"模型操作"); // 
	//QObject::connect(TranslationdAction, SIGNAL(triggered()), this, SLOT(TranslationObjectWindShow()));


	//QAction* BatchExportAction = this->ContentListContextMenu->addAction(u8"模型批量导出"); // 
	//QObject::connect(BatchExportAction, SIGNAL(triggered()), this, SLOT(ContentListContextMenu_BatchExportAction()));

	QObject::connect(this, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(ShowContentListContextMenu(QPoint)));
	qDebug() << u8"初始化contextMenu结束";

}
void DocumentCommon::initTaskTreeRootNode()
{	
	this->clear(); //删除所有节点
	this->setHeaderHidden(true); // 显示表头

	// 创建2个根节点 数据 任务
	dataRoot = new QTreeWidgetItem(this);
	dataRoot->setText(0, u8"数据");
	// 创建3个节点 模型 图像 点云
	modelRoot = new QTreeWidgetItem(dataRoot);
	modelRoot->setText(0, u8"模型");
	imageRoot = new QTreeWidgetItem(dataRoot);
	imageRoot->setText(0, u8"图像");

	pointCloudRoot = new QTreeWidgetItem(dataRoot);
	pointCloudRoot->setText(0, u8"属性数据库");
	atriTableRoot = new QTreeWidgetItem(dataRoot);
	atriTableRoot->setText(0, u8"属性数据库");

	taskRoot = new QTreeWidgetItem(this);
	taskRoot->setText(0, u8"任务");

	// 创建3个节点 仿真图像任务、后向散射系数导出任务、仿真后向散射任务
	fekoSimulationRoot = new QTreeWidgetItem(taskRoot);
	fekoSimulationRoot->setText(0, u8"仿真任务");
	exportScatteringRoot = new QTreeWidgetItem(taskRoot);
	exportScatteringRoot->setText(0, u8"后向散射系数导出任务");
	fekoScatteringRoot = new QTreeWidgetItem(taskRoot);
	fekoScatteringRoot->setText(0, u8"仿真后向散射任务");


	// 将根节点添加到 QTreeWidget 中
	this->addTopLevelItem(dataRoot);
	this->addTopLevelItem(taskRoot);
	this->show();
}

void DocumentCommon::addTaskNode(TaskNode* node)
{
	if (node) {
		node->setParent(this);
		if (dynamic_cast<OCCTShapeModelNode*>(node) != nullptr) { // 模型数据节点
			this->addOCCTObjectItem(node);
		}
		else if (dynamic_cast<ComplexDataShowNode*>(node) != nullptr) { // 辅助图像节点
			this->addImageObjectItem(node);
		}
		else if (dynamic_cast<DataShowNode*>(node) != nullptr) { // 辅助图像节点
			this->addImageObjectItem(node);
		}
		else if (dynamic_cast<FEKOScatterSettingTaskNodeClass*>(node) != nullptr) { // 后向散射系数模拟任务节点
			this->addScatterSettingTaskItem(node);
		}
		else if (dynamic_cast<FEKOResultImportTaskNode*>(node) != nullptr) { // 后向散射导入
			this->addFEKOResultDataConvertItem(node);
		}
		else if (dynamic_cast<FEKOImageSettingTaskNodeClass*>(node) != nullptr) { // 仿真成像参数任务
			this->addFEKOSimulationImageSettingItem(node);
		}
		else {
			QMessageBox::warning(this, u8"警告", u8"未知任务节点");
			delete node;
			return;
		}

		// 添加信号连接
		QObject::connect(node, SIGNAL(renameNode(QString, QString)), this, SLOT(renameTaskNode(QString, QString)));
		QObject::connect(node, SIGNAL(deleteItem(QString)), this, SLOT(removeTaskNode(QString)));
		QObject::connect(node, SIGNAL(deleteNode(QString)), this, SLOT(removeTaskNode(QString)));
	}
	else {
		// nullptr
	}
}
void DocumentCommon::addOCCTObjectItem(TaskNode* node)
{

	QTreeWidgetItem* itemtemp = this->newQTaskTreeWidgetItem(node);
	if (itemtemp) {
		//if (this->addUniqueNode(itemtemp)) {
			this->UpdateItemParantNode(itemtemp, modelRoot);
		//}
	}
	else {

	}
}
void DocumentCommon::addImageObjectItem(TaskNode* node)
{
	QTreeWidgetItem* itemtemp = this->newQTaskTreeWidgetItem(node);
	if (itemtemp) {
		//if (this->addUniqueNode(itemtemp)) {
			this->UpdateItemParantNode(itemtemp, imageRoot);
		//}
	}
	else {

	}
}
void DocumentCommon::addPointCloudObjectItem(TaskNode* node)
{
	QTreeWidgetItem* itemtemp = this->newQTaskTreeWidgetItem(node);
	if (itemtemp) {
		//if (this->addUniqueNode(itemtemp)) {
 
			this->UpdateItemParantNode(itemtemp, pointCloudRoot);
	//	}
	}
	else {

	}
}
void DocumentCommon::addAtriTableObjectItem(TaskNode* node)
{
	QTreeWidgetItem* itemtemp = this->newQTaskTreeWidgetItem(node);
	if (itemtemp) {
		//if (this->addUniqueNode(itemtemp)) {
	 
			this->UpdateItemParantNode(itemtemp, atriTableRoot);
		//}
	}
	else {

	}
}
void DocumentCommon::addScatterSettingTaskItem(TaskNode* node)
{
	QTreeWidgetItem* itemtemp = this->newQTaskTreeWidgetItem(node);
	if (itemtemp) {
		//if (this->addUniqueNode(itemtemp)) {
 
			this->UpdateItemParantNode(itemtemp, fekoScatteringRoot);
	//	}
	}
	else {

	}
}
void DocumentCommon::addFEKOResultDataConvertItem(TaskNode* node)
{
	QTreeWidgetItem* itemtemp = this->newQTaskTreeWidgetItem(node);
	if (itemtemp) {
		//if (this->addUniqueNode(itemtemp)) {
 
			this->UpdateItemParantNode(itemtemp, exportScatteringRoot);
		//}
	}
	else {

	}
}
void DocumentCommon::addFEKOSimulationImageSettingItem(TaskNode* node)
{
	QTreeWidgetItem* itemtemp = this->newQTaskTreeWidgetItem(node);
	if (itemtemp) {
	//	if (this->addUniqueNode(itemtemp)) {
	 
			this->UpdateItemParantNode(itemtemp, fekoSimulationRoot);
	//	}
	}
	else {
	}
}


void DocumentCommon::removeTaskNode(QTreeWidgetItem* node)
{
	if (node) {
		node->parent()->removeChild(node);
		this->dataMap.remove(node->text(0));
	}
	else {
		QMessageBox::warning(this, u8"警告", u8"未知节点");
	}
}
void DocumentCommon::removeTaskNode(QString itemName)
{
	if (this->dataMap.contains(itemName)) {
		QTreeWidgetItem* item = this->dataMap.value(itemName);
		TaskNode* obj = item->data(0, Qt::UserRole).value<TaskNode*>();
		if (obj->status != TaskStatusEnum::finish) {
			obj->FinishTask(); // 调用执行结束流程
		}
		this->removeTaskNode(item);
	}
	else {
		QMessageBox::warning(this, u8"警告", u8"未找到节点："+ itemName);
	}

}
bool DocumentCommon::addUniqueNode(QTreeWidgetItem* item)
{
	if (this->dataMap.contains(item->text(0))) {
		QMessageBox::warning(this, u8"警告", u8"发现同名节点："+ item->text(0));
		return false;
	}
	else {
		this->dataMap.insert(item->text(0), item);
		return true;
	}
}

QTreeWidgetItem* DocumentCommon::newQTaskTreeWidgetItem(TaskNode* node)
{

	QTreeWidgetItem* itemtemp;

	if (node) {
		if (dynamic_cast<OCCTShapeModelNode*>(node) != nullptr) { // 模型数据节点
			itemtemp = new QTreeWidgetItem(this->modelRoot);
		}
		else if (dynamic_cast<ComplexDataShowNode*>(node) != nullptr) { // 辅助图像节点
			itemtemp = new QTreeWidgetItem(this->imageRoot);
		}
		else if (dynamic_cast<DataShowNode*>(node) != nullptr) { // 辅助图像节点
			itemtemp = new QTreeWidgetItem(this->imageRoot);
		}
		else if (dynamic_cast<FEKOScatterSettingTaskNodeClass*>(node) != nullptr) { // 后向散射系数模拟任务节点
			itemtemp = new QTreeWidgetItem(this->fekoScatteringRoot);
		}
		else if (dynamic_cast<FEKOResultImportTaskNode*>(node) != nullptr) { // 后向散射导入
			itemtemp = new QTreeWidgetItem(this->exportScatteringRoot);
		}
		else if (dynamic_cast<FEKOImageSettingTaskNodeClass*>(node) != nullptr) { // 仿真成像参数任务
			itemtemp = new QTreeWidgetItem(this->fekoSimulationRoot);
		}
		else {
			QMessageBox::warning(this, u8"警告", u8"未知任务节点");
			delete node;
			return nullptr;
		}

		// 添加信号连接
		QObject::connect(node, SIGNAL(renameNode(QString, QString)), this, SLOT(renameTaskNode(QString, QString)));
		QObject::connect(node, SIGNAL(deleteItem(QString)), this, SLOT(removeTaskNode(QString)));
	}
	else {
		QMessageBox::warning(this, u8"警告", u8"未知任务节点");
		delete node;
		return nullptr;
	}
	qDebug() << node->getTaskName();
	itemtemp->setText(0, node->getTaskName());
	itemtemp->setData(0, Qt::UserRole, QVariant::fromValue(node));

	// 处理事件绑定

	if (this->addUniqueNode(itemtemp)) {
		return itemtemp;
	}
	else {
		delete itemtemp;
		return nullptr;
	}
}

void DocumentCommon::renameTaskNode(QString olditemName, QString newitemName)
{
	qDebug() << u8"正在执行重命名命令";
	if (this->dataMap.contains(newitemName)) {
		QMessageBox::warning(this, u8"警告", u8"存在同名节点");
	}
	else {
		QTreeWidgetItem* item = this->dataMap.value(olditemName);
		item->setText(0, newitemName);
		this->dataMap.remove(olditemName);
		this->dataMap.insert(newitemName, item);
		TaskNode* obj = item->data(0, Qt::UserRole).value<TaskNode*>();
		obj->setName(newitemName);
	}
}

void DocumentCommon::copyNewNode(TaskNode* newNode)
{
	if (newNode) {
		QString newName = QInputDialog::getText(this, u8"重命名", u8"请输入新的名称", QLineEdit::Normal, newNode->getName() + u8"_1");
		if (newName.isEmpty()) {
			QMessageBox::warning(this, u8"警告", u8"无效名称");
			delete newNode;// 无效对象，直接删除
		}
		else {
			newNode->setName(newName);
			this->addTaskNode(newNode);
		}

	}
	else {
		// nullptr
	}

}

void DocumentCommon::UpdateItemParantNode(QTreeWidgetItem* n, QTreeWidgetItem* p)
{
	if (n) {
		QTreeWidgetItem * parentOfn =n->parent();//获取节点 n 的父节点
		if (parentOfn) {
			parentOfn->removeChild(n);
			if (p) {
				p->addChild(n);
			}
			else {
				this->addTopLevelItem(n);
			}
		}
		else { 
			if (p) { 
				int index=this->indexOfTopLevelItem(n);
				this->takeTopLevelItem(index);
				p->addChild(n);
			}
			else { // 本身就是节点就是根节点，无须再提升
				return;
			}

		}
	}
	else {
		// 不是根节点，直接返回
	}
}




void DocumentCommon::addOCCTObjItem(TopoDS_Shape shape, QString name, bool ishow)
{
	OCCTShapeModelNode* checkBox = new OCCTShapeModelNode(this);
	checkBox->setContext(this->myContext);
	checkBox->setShape(shape);
	checkBox->setText(name);
	//QObject::connect(checkBox, SIGNAL(copyNew()), this, SLOT(copyOCCTObjectCheckBoxItem()));
	//QObject::connect(checkBox, SIGNAL(ShowFullExtend(const TopoDS_Shape&)), this, SLOT(SelectItemFullShow(const TopoDS_Shape&)));
	//QObject::connect(checkBox, SIGNAL(ModelModify(OCCTShapeModelNode*)), this, SLOT(ShapeModifyShape(OCCTShapeModelNode*)));
	this->addTaskNode(checkBox);
	if (ishow) {
		checkBox->ShowShape(); // 展示模型
	}
	else {
		checkBox->HideShape(); // 隐藏模型
	}
}


TopoDS_Shape DocumentCommon::MergeCOntextAllModels() {
	TopoDS_Compound compound;
	BRep_Builder builder;
	builder.MakeCompound(compound);

	this->myContext->InitSelected(); // 初始化模型
	for (; myContext->MoreSelected(); myContext->NextSelected()) {
		Handle(AIS_InteractiveObject) selectedObject = myContext->SelectedInteractive();

		if (!selectedObject.IsNull()) {
			TopoDS_Shape shape = this->getTopoDSShape(selectedObject);
			// 将每个形状添加到 Compound
			builder.Add(compound, shape);
		}
	}
	return compound;
}

// 保存模型
void DocumentCommon::SaveModelFile() {

	// 选择保存文件
	qDebug() << u8"打开文件 \n";
	QString  filepath = getSaveFilePath(
		nullptr,
		QString::fromUtf8(u8"保存FEKO结果导入场景模型"),
		QString::fromUtf8(u8"STL Files (*.stl);;STL Files (*.stla);;step Files (*.stp);;step Files (*.step);;IGES Files (*.iges);;IGES Files (*.igs)"));
	QFileInfo fileinfo(filepath);
	QString filename = fileinfo.fileName();
	QString fileSuffix = fileinfo.suffix();
	TopoDS_Shape shape_TopoDs = this->MergeCOntextAllModels(); // 合并所有模型
	// 保存模型
	if (fileSuffix.compare(u8"stl") == 0 || fileSuffix.compare(u8"stla") == 0) {
		SaveTopoDs_Stl(filepath, shape_TopoDs);
	}
	else if (fileSuffix.compare(u8"step") == 0 || fileSuffix.compare(u8"stp") == 0) {
		SaveTopoDs_Step(filepath, shape_TopoDs);
	}
	else if (fileSuffix.compare(u8"iges") == 0 || fileSuffix.compare(u8"igs") == 0) {
		SaveTopoDs_IGES(filepath, shape_TopoDs);
	}
	else {

	}

}


void DocumentCommon::ShowContentListContextMenu(QPoint p) {
	qDebug() << u8"正在展示ShowContentListContextMenu 右键菜单";

 
	QList < QTreeWidgetItem* > selectitems =this->selectedItems();
	if (selectitems.count() == 0) {
		// 初始化右键菜单
		return;
	}
	else if (selectitems.count() == 1) {
		TaskNode* obj=this->getItemByName(selectitems[0]->text(0));
		if (obj) {
			obj->ShowContentListContextMenu(p);
		}
		else {}
		return;
	}else if(selectitems.count()>1){
		for (size_t i = 0; i < selectitems.count(); i++) {
			TaskNode* obj = this->getItemByName(selectitems[i]->text(0));
			obj->ContentListContextMenu->setTitle(obj->getTaskName());
			this->ContentListContextMenu->addMenu(obj->ContentListContextMenu);
		}
		this->ContentListContextMenu->exec(QCursor::pos());
	}
	else {
		return;
	}
}


void DocumentCommon::ContentListContextMenu_UndoAction()
{
	qDebug() << u8"正在撤销命令";
	int index = this->m_undoStack->index();
	this->m_undoStack->setIndex(index);
}

void DocumentCommon::ContentListContextMenu_RedoAction()
{
	qDebug() << u8"正在重做命令";
	int index = this->m_undoStack->index();
	this->m_undoStack->setIndex(index);
}

void DocumentCommon::ContentListContextMenu_BatchExportAction()
{
	qDebug() << u8"批量导出模型";
	DialogBatchExport* exportWindows = new DialogBatchExport();
	for (int i = 0; i < this->modelRoot->childCount(); ++i) {
		QTreeWidgetItem* item = this->modelRoot->child(i);
		TaskNode* obj = item->data(0, Qt::UserRole).value<TaskNode*>();
		if (obj) {
			OCCTShapeModelNode* checkBox = dynamic_cast<OCCTShapeModelNode*>(obj);
			exportWindows->addDataShape(checkBox->text(), checkBox->Shape());
		}
		else {
			QMessageBox::warning(this, u8"错误", u8"发现错误：" + item->text(0));
			continue;
		}
	}
	exportWindows->show();
}
 

///////////////////////////
//  窗口右键菜单
//////////////////////////


void DocumentCommon::VerticesSelect3dSample()
{
	qDebug() << u8"切换选择模式为：TopAbs_VERTEX";
	myContext->Deactivate();
	myContext->Activate(AIS_Shape::SelectionMode(TopAbs_VERTEX));
}

void DocumentCommon::EdgesSelect3dSample()
{
	qDebug() << u8"切换选择模式为：TopAbs_EDGE";
	myContext->Deactivate();
	myContext->Activate(AIS_Shape::SelectionMode(TopAbs_EDGE));
}

void DocumentCommon::FacesSelect3dSample()
{
	qDebug() << u8"切换选择模式为：TopAbs_FACE";
	myContext->Deactivate();
	myContext->Activate(AIS_Shape::SelectionMode(TopAbs_FACE));
}

void DocumentCommon::NeutralPointSelect3dSample()
{
	qDebug() << u8"切换选择模式为：TopAbs_COMPOUND";
	myContext->Deactivate();
	myContext->Activate(TopAbs_COMPOUND);
}

//void DocumentCommon::ShapeModifyShape(OCCTShapeModelNode* dataItem)
//{
//	qDebug() << u8"模型操作";
//	OCCTModelOperator* operatorWindows = new OCCTModelOperator(dataItem->text(), nullptr, this->myContext);
//	operatorWindows->setModal(false);
//	//operatorWindows->setTopoDs_Shape(dataItem->DataShape);
//	// 绑定模型
//	QObject::connect(operatorWindows, SIGNAL(ResultExportCopyAndCreateNew(OCCTModelOperator*)), this, SLOT(TranslationExportCopy(OCCTModelOperator*)));
//	QObject::connect(operatorWindows, SIGNAL(ResultExport(OCCTModelOperator*)), this, SLOT(TranslationExport(OCCTModelOperator*)));
//	QObject::connect(operatorWindows, SIGNAL(RefreshResult(OCCTModelOperator*)), this, SLOT(RefreshResult(OCCTModelOperator*)));
//	operatorWindows->show();
//}

////////////////////////////////////////////////////////////
// 模型界面的选择事件
////////////////////////////////////////////////////////////
void DocumentCommon::ViewerMousePressEvent(QMouseEvent* theEvent) {
	qDebug() << u8"view 窗体按键按下点击事件被激活 \n";
}

void DocumentCommon::ViewerMouseReleaseEvent(QMouseEvent* theEvent)
{
	qDebug() << u8"view 窗体按键释放事件被激活 \n";
	for (this->myContext->InitSelected(); this->myContext->MoreSelected(); this->myContext->NextSelected()) {
		Handle(AIS_InteractiveObject) selectedObject = this->myContext->SelectedInteractive();
		qDebug() << u8"view 发现选中对象 \n";
		TopoDS_Shape selectShape = this->getTopoDSShape(selectedObject);
		emit this->SelectObjectList(selectShape);
		this->showSelectShape(selectShape);
	}

}

void DocumentCommon::SelectItemFullShow(const TopoDS_Shape& shape)
{
	emit this->ShowSelectItemFullExtend(shape);
}



void DocumentCommon::setShapeInfomationWindows(OCCTopoShapeTreeViewer* ShapeInfomationWindows)
{
	this->ShapeInfomationWindows = ShapeInfomationWindows;
}

// Function to get TopoDS_Shape from AIS_InteractiveObject
TopoDS_Shape DocumentCommon::getTopoDSShape(const Handle(AIS_InteractiveObject)& aisObject)
{
	if (aisObject.IsNull() || !aisObject->HasInteractiveContext())
		return TopoDS_Shape();  // Return an empty shape if AIS_InteractiveObject is null or not associated with an interactive context

	Handle(AIS_Shape) aisShape = Handle(AIS_Shape)::DownCast(aisObject);
	if (aisShape.IsNull())
		return TopoDS_Shape();  // Return an empty shape if AIS_InteractiveObject is not a shape

	// Get the shape from AIS_Shape
	TopoDS_Shape topoShape = aisShape->Shape();

	return topoShape;
}

void DocumentCommon::showSelectShape(const TopoDS_Shape& selectShape)
{
	qDebug() << u8"显示选中的对象 \n";
	if (this->ShapeInfomationWindows) {
		this->ShapeInfomationWindows->setTopoShape(selectShape);
	}
	else {}
}

 
 

 