Bootstrap

MeshLab源码阅读笔记

MeshLab源码阅读笔记

记录阅读MeshLab源码时的笔记:


重要的ui文件:

  • LayerDialog是渲染窗口设置页面的ui文件。MainWindow主界面(软件主界面)没有UI文件,是代码实现UI。

  • LayerDialog部分ui内容在ui文件中预设,并留有空白的QGroupBox,用于在代码中完成渲染选项卡的ui内容声明实现。


主程序部分:

  • main函数入口:
    打开MeshLab的控制台命令包括三种跟随文件格式:都能对应到MainWindow的函数功能中
    (1)打开项目文件,。
    (2)打开配置文件,对应摄像机镜头位置。
    (3)打开模型文件。

  • MeshLabApplication:
    MeshLabApplication是继承于QApplication的一个类,比QApplication额外多了什么呢?
    (1)首先是一些应用程序信息(名字,位数,版本等)。
    (2)获取插件和着色器的绝对地址信息。


参数数值部分:

  • value.h:
    自定义的数据类型和相关存取等基本功能函数,是对int,float这些基本数据类型的二次封装。

  • RichParameter:
    MeshLab中参数的抽象类,封装了Value,能提供参数的名称,描述等,构建可以通过构建(参数名+参数字+参数描述+提示信息)。

  • RichParameterList:
    (1)RichParameterList是存储参数的容器,是存储全局参数的参数列表。因为RichParameter是抽象类,没法直接创建对象实例,要从list中获取引用。提供容器操作。需要设置和提取参数时,都是对RichParameterList操作,而非RichParameter。
    (2)类里面没有给定有什么预设参数,需要通过addParam加入参数进入表中。
    (3)RichParameterList使用单例模式,由globals.h中声明创建获取,确保运行时只有一个RichParameterList对象。


插件部分:

  • MeshLabPlugin:
    MeshLabPlugin是插件抽象类,作为具体插件的基类,定义的都是插件的信息,以及启用状态。作为接口。Plugin有好多种,每种都继承MeshLabPlugin,包括:DecoratePlugin,EditPlugin,FilterPlugin,IOmeshPlugin,IOrasterPlugin,RenderPlugin(每个都是抽象类)。

  • FilterPlugin:
    FilterPlugin继承自MeshLabPlugin,各种filter插件的抽象类,作为接口。包括插件的具体细节,信息参数。具体每种filter插件都继承FilterPlugin类。

  • FilterPluginContainer:
    存放管理FilterPlugin的容器,内部用vector存储插件,并定义了遍历的iterator遍历器作为内部类。

  • PluginManager:
    (1)单例模式,由globals.h中声明创建获取
    (2)是无继承的,自己编写的插件管理器,包括检查、加载、卸载、使能等功能。
    (3)里面存储管理不同类型的插件容器,调用插件的时候,都要通过PluginManager去完成。(PluginManager的成员是FilterPluginContainer等,FilterPluginContainer的成员是继承FilterPlugin)。


主界面部分:

在这里插入图片描述

  • MainWindow.h:
    (1)头文件中定义了类MainWindowSetting,用于系统参数初始化和更新(gpu数量,精度,最大贴图内存等)
    (2)看看MainWindow窗口类中有什么:
    正常声明了信号和槽,信号很少,槽很多。正常声明成员函数和成员变量(包括菜单、工具栏和QAction操作,没有其他控件),都是主界面里的ui内容。 可以打开MeshLab软件对照着看,窗口上的元素都是在MainWindow窗口类中声明的成员变量,例如各种可以点击的元素,都是QAction类型的。

  • MainWindow_Init.cpp:(就是MainWindow类的实现,部分实现在MainWindow_Runtime.cpp文件中)
    (1)用于初始化的MainWindow,参数列表和插件管理器都以单例模式传入到构造函数参数中。
    (2)以下操作都是在构造函数中完成:创建QMdiArea,LayerDialog的ui控件。
    (3)接着加载插件管理器,通过调用PluginManager的加载函数完成,读取并获得插件文件所在的绝对路径来识别加载插件。
    (4)进行窗口图标的设置。
    (5)后续是设置ui上各个QAction的图标和文本,然后绑定槽函数。
    (6)在构造函数中调用创建窗口菜单的函数(实际上是把菜单部分的ui实现代码放到一个函数中),然后在函数中编辑菜单内容,调用填充菜单的函数,填充菜单项,菜单变量(QMenu)是MainWindow类的私有成员。
    (7)通过遍历插件管理器中的插件,将filter插件另外存入mapFilterPlugin这个map容器中。
    std::map<QString, FilterPlugin*> mapFilterPlugin)。不同类型的插件存入对应的map容器中。
    (8)再重新遍历mapFilterPlugin,对每个filterAction(每个filter都是一个QAction)设置filter提示等信息,然后再连接到startFilter槽函数(startFilter是同一个槽函数)。
    (9)然后判断插件类型(判断是Remesh还是Selection这些类型),并插入到对应的类别菜单控件下。
    (10)startFilter槽函数用于设置对话框ui和询问参数。(相当于触发filter这个QAction后,startFilter负责显示对应的参数设置窗口)
    (11)startFilter执行时会最先关闭编辑功能并更新菜单(实际上是菜单的使能操作)。利用sender函数获取发送信号的QAction,从而找出对应的FilterPlugin。
    (12)点击插件后创建的插件窗口是MeshlabStdDialog类

  • LayerDialog:
    (1)LayerDialog继承自QDockWidget,可以拖拽的窗口。该对话框是模型信息窗口,包括视角、渲染选项、层级等。
    (2)首先设置了不可见。选项卡窗口是使用QAction生成选项卡总数,然后根据QAction数量决定tab数量,再生成相应的页面。
    (3)根据点击的QAction来显示相应的参数设置页面,每个页面对应单独一个类(都放在同一个头文件中),控制切换的槽函数是在主页面MainWindow类中声明的槽函数(通过在LayerDialog构造函数创建一个MainWindow的引用,从而实现获取主页面类的槽函数)。


插件窗口部分:

在这里插入图片描述

  • MeshlabStdDialog:
    (1)MeshlabStdDialog是插件的窗口类,继承自QDockWidget。创建管理QFrame(内容是插件中具体的参数),其中loadFrameContent函数用来读取并填充插件参数窗口QFrame中的信息。
    (2)利用RichParameterListFrame类自动创建参数框架,并将框架加入到窗口layout中。
    (3)插件窗口分三大件,首先是QLabel的插件描述,然后是参数列表QFrame,最后是四个按钮QPushButton以及连接按钮相应的槽函数。
    (4)当前什么插件,执行时是什么功能,都通过插件窗口MeshlabStdDialog该对话框类里面的指针指着当前的函数。但是执行插件QAction的函数声明和代码是在MainWindow类下,供当前类调用(创建MainWindow的引用),执行插件的函数需要传入具体QAction和参数进去。

模型部分:

  • 模型是使用容器负责存储,每次修改完得到的新模型,都会加入到容器中。然后再调用MainWindow的GLA()等相关函数负责更新渲染窗口的内容。

  • MeshModel:
    无继承的模型类,具体模型的表示借助了第三方库vcg来实现。

  • MeshDocument:
    管理MeshModel的容器,内部使用list容器来存储,定义了存取和遍历等管理的函数。程序中实际是用到该容器来访问模型。


  • MeshLab重要的部分大致如下图,差不多总结了以上内容。
    在这里插入图片描述
;