当前位置: 首页 > news >正文

个人备案网站可以做淘宝客做网站第一部

个人备案网站可以做淘宝客,做网站第一部,工作态度,爱站关键词挖掘查询工具一、VTK的框选支持类vtkInteractorStyleRubberBandPick FastCAE的鼠标事件交互类是PropPickerInteractionStyle,它扩展自vtkInteractorStyleRubberBandPick。vtkInteractorStyleRubberBandPick类可以实现鼠标框选物体,默认情况下按下键盘r键开启框选模式…

一、VTK的框选支持类vtkInteractorStyleRubberBandPick

FastCAE的鼠标事件交互类是PropPickerInteractionStyle,它扩展自vtkInteractorStyleRubberBandPick。vtkInteractorStyleRubberBandPick类可以实现鼠标框选物体,默认情况下按下键盘r键开启框选模式,这时拖动鼠标可拾取物体。VTK官网有其例子:HighlightSelection。

二、FastCAE框选产品设计

我们看FastCAE的鼠标拾取产品设计。其只支持框选网格点与网格单元,几何点、线、面都不支持。框选网格单元效果如下:
请添加图片描述

在VTK的给的案例中,按r键是为了打开vtkInteractorStyleRubberBandPick类的框选开关,设置vtkInteractorStyleRubberBandPick字段CurrentMode=1(VTKISRBP_SELECT),表示开启框选模式。VTK中vtkInteractorStyleRubberBandPick.cxx源码如下:

void vtkInteractorStyleRubberBandPick::OnChar()
{switch (this->Interactor->GetKeyCode()){case 'r':case 'R':// r toggles the rubber band selection mode for mouse button 1if (this->CurrentMode == VTKISRBP_ORIENT){this->CurrentMode = VTKISRBP_SELECT;}else{this->CurrentMode = VTKISRBP_ORIENT;}break;case 'p':case 'P':{vtkRenderWindowInteractor* rwi = this->Interactor;int* eventPos = rwi->GetEventPosition();this->FindPokedRenderer(eventPos[0], eventPos[1]);this->StartPosition[0] = eventPos[0];this->StartPosition[1] = eventPos[1];this->EndPosition[0] = eventPos[0];this->EndPosition[1] = eventPos[1];this->Pick();break;}default:this->Superclass::OnChar();}
}

而在FastCAE框选时,不需要按下r键,其原因在用切换拾取模式时,直接改掉了CurrentMode的值,源码如下(注意看这个函数最后一行):

void PropPickerInteractionStyle::setSelectModel(int m)
{_selectModel = (SelectModel)m;this->CurrentMode = 0;if (_actor != nullptr)_actor->GetProperty()->DeepCopy(_property);_actor = nullptr;_preGeoSeltctActor = nullptr;_selectItems.clear();emit grabKeyBoard(false);switch (_selectModel){case ModuleBase::MeshNode:case ModuleBase::MeshCell:case ModuleBase::GeometryWinPoint:case ModuleBase::GeometryWinCurve:case ModuleBase::GeometryWinSurface:case ModuleBase::GeometryWinBody:emit grabKeyBoard(true);break;case ModuleBase::GeometryPoint:case ModuleBase::GeometryCurve:case ModuleBase::GeometrySurface:case ModuleBase::GeometryBody:break;case ModuleBase::BoxMeshNode: // 当选择方式是框选时,直接设置开始框选case ModuleBase::BoxMeshCell:case ModuleBase::DrawSketch:this->CurrentMode = 1;break;}
}

这种设计的好处是不用按键盘进行交互,但造成激活框选按钮之后,视图的角度无法更改。本来按住左键拖拽可以旋转视图的,打开框选之后就失效了。

其框选还有一个比较严重的问题:框选会同时拾取物体的表面与背面单元,效果如下:
请添加图片描述

这种效果惊不惊喜,意不意外!?很多场景下,这种拾取是不满足要求的。进一步分析其框选逻辑就很好理解这种现象了。

三、框选计算逻辑

PropPickerInteractionStyle::OnLeftButtonUp()处理鼠标抬起事件,框选计算哪些物体要被选中的逻辑也在这里被触发。

void PropPickerInteractionStyle::OnLeftButtonUp()
{vtkInteractorStyleRubberBandPick::OnLeftButtonUp();if (_selectModel == None && !_mouseMoved)emit this->clearAllHighLight();if ((_selectModel != BoxMeshCell) && (_selectModel != BoxMeshNode) && (_selectModel != DrawSketch))return;if (this->CurrentMode == 0)return;//		_selectItemIDs->SetNumberOfValues(0);_selectItems.clear();int *endPos = this->GetInteractor()->GetEventPosition();_endPos[0] = endPos[0];_endPos[1] = endPos[1];//		qDebug() << "end  " << _endPos[0] << "   " << _endPos[1];if (_selectModel != DrawSketch){vtkActor *ac = nullptr;vtkAreaPicker *areaPicker = dynamic_cast<vtkAreaPicker *>(this->GetInteractor()->GetPicker());ac = areaPicker->GetActor();if (ac == nullptr)return;}switch (_selectModel){case ModuleBase::BoxMeshNode: // 计算哪些节点被选中boxSelectMeshNode();break;case ModuleBase::BoxMeshCell: // 计算哪些单元要被选中boxSelectMeshCell();break;case ModuleBase::DrawSketch:_coordinate->SetCoordinateSystemToDisplay();_coordinate->SetValue(endPos[0], endPos[1], 0);double *d = _coordinate->GetComputedWorldValue(_renderer);emit mouseReleasePoint(d);break;}_mouseMoved = false;_leftButtonDown = false;
}

boxSelectMeshNode()、boxSelectMeshCell()函数分别哪些节点、单元要被拾取。

void PropPickerInteractionStyle::boxSelectMeshNode()
{emit clearAllHighLight(); // 清除掉当前高亮_selectItems.clear(); // 清理当前选择项// Forward eventsint range[4];this->getBoxRange(range);  // 获取框选矩形的坐标vtkActorCollection *actors = _renderer->GetActors(); // 获取当前的场景中所有actoractors->InitTraversal();const int nac = actors->GetNumberOfItems();for (int i = 0; i < nac; ++i) // 对Actor进行遍历{vtkActor *actor = actors->GetNextActor();if (actor == nullptr)if (!actor->GetVisibility())continue;if (!actor->GetPickable())continue;vtkMapper *mapper = actor->GetMapper();if (mapper == nullptr)continue;vtkDataSet *dataset = mapper->GetInputAsDataSet();if (dataset == nullptr)continue;vtkDataArray *IDS = dataset->GetPointData()->GetArray("IDS"); // 提取Actor的点数据if (IDS == nullptr)continue;this->selectMesh(dataset, range);}emit highLight(&_selectItems);
}void PropPickerInteractionStyle::selectMesh(vtkDataSet *dataSet, int *range)
{vtkRenderer *render = this->GetInteractor()->GetRenderWindow()->GetRenderers()->GetFirstRenderer();vtkSmartPointer<vtkCoordinate> coordinate = vtkSmartPointer<vtkCoordinate>::New();coordinate->SetCoordinateSystemToWorld();coordinate->GetComputedDisplayValue(render);if (_selectModel == BoxMeshNode){vtkDataArray *ids = dataSet->GetPointData()->GetArray("IDS"); // 获取点集const int npoint = dataSet->GetNumberOfPoints();for (int i = 0; i < npoint; ++i){double coor[3];dataSet->GetPoint(i, coor); // 获取点的坐标coordinate->SetValue(coor); // 将点的坐标设置给coordinateint *va = coordinate->GetComputedDisplayValue(render); // 计算屏幕坐标if (isPointInRange(va, range)) // 是否在鼠标框内部{double *k_id = ids->GetTuple2(i); // 看不懂?_selectItems.insert(k_id[0], k_id[1]);}}}else if (_selectModel == BoxMeshCell){vtkDataArray *ids = dataSet->GetCellData()->GetArray("IDS"); // 获取cell数据const int ncell = dataSet->GetNumberOfCells();for (int i = 0; i < ncell; ++i) // 遍历cell{vtkCell *cell = dataSet->GetCell(i); // 当前的celldouble pcenter[3] = {0};cell->GetParametricCenter(pcenter); // 获取当前cell的中心点参数坐标int subid;double coor[3];double w[100];cell->EvaluateLocation(subid, pcenter, coor, w); // 根据参数坐标获取中心点世界空间坐标coordinate->SetValue(coor);int *va = coordinate->GetComputedDisplayValue(render); // 计算屏幕坐标if (isPointInRange(va, range)) // 屏幕坐标是否在选择框内{double *k_id = ids->GetTuple2(i);_selectItems.insert(k_id[0], k_id[1]);}}}
}

根据以上代码,框选点时,直接根据点坐标计算其投影到屏幕上的坐标,判断是否在选择框内。单元是判断中心点是否在选择框内部。因为投影之后,丢弃了深度方向的信息,没有考虑物体的遮挡信息,所以框选时表面、背面均可选择。而且其计算框选时遍历所有网格,没有借助一些加速结构,如BVH树等,造成框选效率较低,当网格数量较多时,这种方式很慢。

总结:

FastCAE的框选逻辑过于简单,只是demo阶段,实际的CAE软件的拾取逻辑要远比这复杂。

http://www.yayakq.cn/news/633961/

相关文章:

  • 如何给WordPress网站更换域名html5的推荐框架
  • 义乌本地网站开发代理公司注册企业
  • 青州网站网站建设如何做自助网站
  • 大庆市建设局网站市场营销培训机构排名
  • 网站开发软件怎么做thinkphp5微信公众号开发
  • 网站的建设求职简历全面的郑州网站建设
  • 焦作做网站公司电子商务企业网站建设前期规划方案
  • 软件公司网站模板图片广州aso优化
  • asp做网站主要技术体育新闻报道
  • 网站优化排名多少钱wp打开wordpress
  • 网站需要多大空间搭建个人博客要钱吗
  • 广州网站优化效果免费模板的软件
  • 网站做动态虚线临海企业网站设计
  • 哪个网站可以找做中厚板的公司山西利用模板建站
  • 余姚市建设局行政服务中心网站怎样做理财投资网站
  • 网站主页制作内容网站设计范例
  • 做动漫的游戏 迅雷下载网站海口网站建设多少钱
  • 洛浦县网站建设网络推广的方案怎么写
  • 专业电子科技网站建设苏州新区城乡建设网站
  • 关于建设招商网站的通知建设网站需要展示什么区别
  • 咸宁市做网站推广教程
  • 网站设计 现在流行的导航方式东戴河网站建设
  • 新网站seo方法什么叫做响应式网站
  • 网站建设.国风网络网站建设数据的保密性
  • 紫金网站建设公司沈阳免费seo关键词优化排名
  • 网站开发维护的好处网络推广网站公司推荐
  • 怎样设置个人网站西地那非片
  • 咸阳网站建设方案上海网络推广外包公司
  • icp备案网站信息修改wordpress显示大写
  • 各个视频网站怎么做原创作者毛坯房最便宜装修方法