实战项目中的新增功能具体实现记录

新增功能,记录


1.实现button点击按钮切换绘制曲线由:辐射强度、入瞳入射亮度、激光散射截面自由切换
       在main_win中新增点击响应函数 

    |-- 切换绘制 Itensity 曲线图像
        @pyqtSlot()
        def on_action_Itensity_triggered(self):
            # 利用变量 triggle_button 存储选择绘制的曲线类型
            # 1代表点辐射强度曲线,也是默认的曲线

            self.myCanvas.triggle_button = 1
            self.action_Itensity.setEnabled(False)
            self.action_LRCS.setEnabled(True)
            self.action_Irradiance.setEnabled(True)
            self.action_lightModel.setEnabled(False)
            # 将绘图axes中的内容清除
            self.myCanvas.axes.clear()
            # 通过定时器,定时调用绘图函数
            self.myCanvas.display_dynamic()
            # clock=60 ms的方式执行
            app.run(framerate=60)
            
    |-- 在myCanvus中绘制曲线中新增判断语句,实现根据响应的按钮绘制相应的曲线
            if self.triggle_button == 3:
                self.timer.timeout.connect(self.update_figure_Irradiance)  # 连接需要动态刷新的方法函数
            elif self.triggle_button == 2:
                self.timer.timeout.connect(self.update_figure_LRCS)
            else:
                self.timer.timeout.connect(self.update_figure_Itensity)

            遇到的问题:定时器刷新不知道连接什么绘制函数,如果在init中调用就会失败,最后统一写在 display_dynamic 函数中

    |-- 在myCanvus中增加绘制函数
            def update_figure_Itensity(self):
            def update_figure_LRCS(self):
            def update_figure_Irradiance(self):



2.实现button点击按钮,弹出 Dialog 改变光照模式
        备注:By532与 BySun 的区别 只需要修改 light_color是白光还是绿光,以及视角方向,sun_view 还是 target_view

    |-- 编写点击响应函数,打开对话框页面 LightDialog

        @pyqtSlot()
        def on_action_lightModel_triggered(self):
            dialog = LightDialog(parent=self)
            dialog.show()

    |-- LightDialog中点击确定按钮的事件处理函数

        def accept(self):
            取出复选框中的值,拼成shading,并修改 P_target.shading 的值
            判断语句,根据shading的值不一样,打开光照模式的参数设置 Dialog 


3.实现选择光照模式的 Dialog 参数设置,(光照的颜色,不需要修改),太阳光波长范围设置
        FSCookTorrenceBySun: d s f m color_using
        FSCookTorrenceBy532: d s f m color_using

        (朗伯模型的能量不守恒)
        FSLambertBy532:d反射率 a环境光强 color_using
        FSLambertBySun:d反射率 a环境光强 color_using

        FSPhoneBy532: d s n(高光模型) color_using
        FSPhoneBySun:d s n(高光模型) color_using

        FSBlinnPhoneBySun:d s n(高光模型) color_using
        FSBlinnPhoneBy532:d s n(高光模型) color_using

        WithoutLight: color_using

    |-- 在P_target中新增设置光照模式参数
        d=(0.5, 0.5, 0.5)
        s = (0.9, 0.9, 0.9)
        f = (0.9, 0.9, 0.9)
        m = 0.3
        n = 3.0
        color_using = 1
        light_color = (1.0, 1.0, 1.0)
        environment_a = (0.0, 0.0, 0.0)

    |-- 光照模式的参数设置 Dialog 对话框,新增确定按钮的事件处理函数
        获取复选框中的值,并修改P_target中对应的值,关闭页面
        def accept(self):
            if self.comboBox_colorUsing.currentText()=="纹理填充":
                color_using = 1
            else:
                color_using=0

            d = (self.doubleSpinBox_dR.value(),self.doubleSpinBox_dG.value(),self.doubleSpinBox_dB.value())
            s = (self.doubleSpinBox_sR.value(), self.doubleSpinBox_sG.value(), self.doubleSpinBox_sB.value())
            n = self.doubleSpinBox_n.value()
            P_target.d = d
            P_target.s = s
            P_target.n = n
            P_target.color_using = color_using

            init()  # 重置星体
            self.close()

    |-- 在accept函数中页面close之后,如果选择的模式时太阳光,设置太阳光波长的对话框
            if P_target.shading=="FSBlinnPhongBySun":
                # 打开太阳光波段设置
                dialog_light = SunDialog(parent=self)
                dialog_light.show()

    |-- myMath类中新增 参数E_sun + 根据波长计算太阳辐照度的积分函数
        # 计算太阳辐照度
        def cal(min, max):
            Re = 6378e3  # 地球半径,单位m
            Rs = 6.955e8  # 太阳半径,单位m
            D = 1.4959787e11  # 太阳地球距离

            T = 5800  # 太阳表面温度
            c1 = 3.74e-16
            c2 = 1.4398e-2

            def cal_prefix():
                return Rs ** 2 / ((D - Rs - Re) ** 2)

            def integrand(x):
                return (c1 / x ** 5) * (1 / (np.exp(c2 / (x * T)) - 1))

            return cal_prefix() * quad(integrand, min, max)[0]

        E_sun = cal(0,4000e-9)# 太阳辐射强度 W/m2

    |--SunDialog 获取复选框中选择的太阳波长范围,按钮的事件处理函数,修改E_sun
        def accept(self):
            lambda_min = self.doubleSpinBox_min.value()*1e-9
            lambda_max = self.doubleSpinBox_max.value()*1e-9
            myMath.E_sun = myMath.cal(lambda_min,lambda_max)
            #print(lambda_min,lambda_max,myMath.E_sun)

            init()  # 重置星体
            self.close()


4.实现弹出文件选择,导入txt、xml、csv、json 四种文本格式的相机、卫星模型参数导入

    |-- 设置函数,根据文件位置和类型将文件中的数据读取出来,函数中分别判断是四种类型中的何种,然后分别实现数据的读取,并将数据存储在一个字典中
        # 导入相机参数文件
        def importCamOrbit(self,file_path,file_type):

        # 导入卫星参数文件
        def importSatOrbit(self,file_path,file_type):
        
    |--  页面点击按钮出发函数
        # 导入卫星轨道参数外部文本文件
        @pyqtSlot()
        def on_action_importSatOrbit_triggered(self):
            调用读取函数,返回字典,修改P_target 中对应参数的值

        # 导入相机轨道参数外部文本文件
        @pyqtSlot()
        def on_action_importCamOrbit_triggered(self):

    
5. 导入卫星3D模型
    |-- 先将原有的东方红和风云4 导出成npz 格式的 numpy 数据

        mySat = FongYun4()
        xyz = mySat.xyz
        xy_texture = mySat.xy_texture
        tex_index = mySat.tex_index
        normal = mySat.normal
        draw_mode = mySat.draw_mode

        np.savez("Dongfanghong.npz", xyz=xyz,xy_texture =xy_texture,
                tex_index =tex_index,normal =normal,draw_mode =draw_mode)

        # 加载一次即可
        r = np.load("D:/MyLearning/PyCharm/myQt01/test/FongYun4.npz")

    |-- 点击按钮触发槽函数,函数打开ImportModelTypeDialog 对话框

        # 导入卫星3D模型
        @pyqtSlot()
        def on_action_importSatModel_triggered(self):

            dialog = ImportModelTypeDialog(parent=self)
            dialog.show()

    |-- ImportModelTypeDialog 对话框 
        1.确定导入的模型是东方红还是风云4
            myMath 中新增模型类型:modelType = 0 为东方红

        2.P_target 中新增参数
            isImport = False #传递信息,是否导入了模型
            xyz = None
            xy_texture = None
            tex_index = None
            normal = None
            draw_mode = gl.GL_TRIANGLES

        3.确定之后选择文件,并将模型中的值赋给 P_target
            def accept(self):
                myMath.modelType = self.comboBox_modelType.currentIndex()
                self.close()

                file_path, file_type = QFileDialog.getOpenFileName(self, '选择文件', '', 'Text files (*.npz)')

                if file_path == '':
                    pass  # 防止关闭或取消导入关闭所有页面
                else:
                    # 将是否导入模型状态改为true
                    P_target.isImport = True
                    satModel = np.load(file_path)

                    if (satModel["draw_mode"] == 7):
                        P_target.draw_mode = gl.GL_QUADS

                    if (satModel["draw_mode"] == 4):
                        P_target.draw_mode = gl.GL_TRIANGLES

                    P_target.xyz = satModel["xyz"]
                    P_target.xy_texture = satModel["xy_texture"]
                    P_target.tex_index = satModel["tex_index"]
                    P_target.normal = satModel["normal"]

                    init()  # 重置星体
                    self.close()

        4.sat_target = SatelliteTarget().getClass(P_target)
        初始化创建卫星类实例,SatelliteTarget,根据模型类型,返回类实例
            def getClass(self,paramters):
                if myMath.modelType==0: 
                    return SatelliteTargetDongFH(paramters)
                else:
                    return SatelliteTargetFY(paramters)
            
            class SatelliteTargetFY(myMath.FongYun4):
            class SatelliteTargetDongFH(myMath.Dongfanghong)5.实例中init函数,新增判断,如果导入了模型,才进行赋值,否则,以默认值

            # 有模型文件导入时才赋值
            if(not parameters.isImport):
                pass
            else:
                self.normal = parameters.normal
                self.xyz = parameters.xyz
                self.xy_texture = parameters.xy_texture
                self.tex_index = parameters.tex_index
            
6.导入相机模型
   |-- 生成模型
        myCam = SatelliteCam(P_cam)
        cam_xyz = myCam.xyz
        cam_xy_texture = myCam.xy_texture
        cam_normal = myCam.normal
        cam_texture = myCam.texture
        np.savez("Cam.npz", cam_xyz=cam_xyz,cam_xy_texture =cam_xy_texture,
                cam_normal =cam_normal,cam_texture =cam_texture)
        
    |-- P_cam 中新增参数
        # 构造观测平台3D模型
        xyz = None
        xy_texture = None
        texture = None
        normal = None
        # 新增导入相机模型的参数
        isImport = False  # 传递信息,是否导入了模型

    |-- 点击按钮触发槽函数,导入观测平台3D模型
      @pyqtSlot()
      def on_action_importCamModel_triggered(self):

        file_path, file_type = QFileDialog.getOpenFileName(self, '选择文件', '', 'Text files (*.npz)')

        if file_path == '':
            pass  # 防止关闭或取消导入关闭所有页面
        else:
            P_cam.isImport = True
            camModel = np.load(file_path)

            P_cam.xyz = camModel["cam_xyz"]
            P_cam.xy_texture = camModel["cam_xy_texture"]
            P_cam.texture = camModel["cam_texture"]
            P_cam.normal = camModel["cam_normal"]

            init()  # 重置星体

    |-- init重置星体 中 sat_cam = SatelliteCam(P_cam),调用类的__init__函数
    增加判断,有模型文件导入时才赋值,不然默认值
    
        if (not parameters.isImport):
            pass
        else:
            self.normal = parameters.normal
            self.xyz = parameters.xyz
            self.xy_texture = parameters.xy_texture
            self.texture = parameters.texture
            print("进入导入模型操作",self.normal)
            











附录:各光照模式的参数默认初始值

BRDF(双向反射分布函数)   
d:漫反射比例
s:镜面反射比例
f:镜面反射率
m:微平面分布参数
color_using:0-color纯色;1-texture纹理;

FSCookTorrenceBy532
     d=(0.8, 0.8, 0.8),
     s=(0.2, 0.2, 0.2),
     f=(0.9, 0.9, 0.9),
     m=0.3, color_using=0,
     color=(189.0 / 255, 203.0 / 255, 216.0 / 255),
     light_color=(0.0,1.0,0.0))用绿光

FSCookTorrenceBySun
    d=(0.5,0.5,0.5),
    s=(0.9,0.9,0.9),
    f=(0.9,0.9,0.9),
    m=0.3, color_using=0,
    color=(189.0/255, 203.0/255, 216.0/255),
    light_color=(1.0,1.0,1.0)

FSLambertBy532: 

    d=(1.0, 1.0, 1.0),
    a=(0.0, 0.0, 0.0),
    color_using=0,
    color=(189.0 / 255, 203.0 / 255, 216.0 / 255),
    light_color=(0.0, 1.0, 0.0)

FSLambertBySun:
d漫反射:表面对入射光的反射为各向同性
    d=(1.0, 1.0, 1.0),
    a=(0.0, 0.0, 0.0),
    color_using=0,
    color=(189.0 / 255, 203.0 / 255, 216.0 / 255),
    light_color=(1.0,1.0,1.0)

FSPhongBySun:
    d=(0.5, 0.5, 0.5),
    a=(0.0, 0.0, 0.0),
    s=(0.5, 0.5, 0.5),
    n=3.0,
    color_using=0,
    color=(189.0 / 255, 203.0 / 255, 216.0 / 255),
    light_color=(1.0, 1.0, 1.0)

FSPhongBy532:
    d=(0.5, 0.5, 0.5),
    a=(0.0, 0.0, 0.0),
    s=(0.5, 0.5, 0.5),
    n=3.0,
    color_using=0,
    color=(189.0 / 255, 203.0 / 255, 216.0 / 255),
    light_color=(0.0, 1.0, 0.0)

FSBlinnPhongBySun:
    d=(0.5, 0.5, 0.5),
    a=(0.0, 0.0, 0.0),
    s=(0.5, 0.5, 0.5),
    n=6.0,
    color_using=0,
    color=(189.0 / 255, 203.0 / 255, 216.0 / 255),
    light_color=(1.0, 1.0, 1.0)

FSWithoutLight:
    d=(1.0, 1.0, 1.0),
    a=(0.0, 0.0, 0.0),
    color_using=0,
    color=(189.0 / 255, 203.0 / 255, 216.0 / 255),
    light_color=(1.0, 1.0, 1.0)

BySun
    vec3 l = normalize(sun_direction);
    vec3 v = normalize(view_direction);
    vec3 h = normalize(l+v);
    vec3 n = normalize(0*c*h+v_normal);
    

    vec3 lc = vec3""" + str(light_color) + """;                                   
    vec3 d = vec3"""+str(d)+""";
    vec3 s = vec3"""+str(s)+""";
    vec3 F = vec3"""+str(f)+""";
    F = F + (1-F)*pow((1-dot(h,v)),5);
    float m = """+str(m)+""";
    float pi =3.1415926;
    float dot_nv = dot(n,v);  
    float dot_nh = dot(n,h);  
    float dot_vh = dot(v,h);
    float dot_nl = dot(n,l);                        
    float G = min(1.0,min(2*dot_nh*dot_nv/dot_vh,2*dot_nh*dot_nl/dot_vh));
    float D = (1/m/m/pow(dot_nh,4))*exp((1-1/pow(dot_nh,2))/pow(m,2));
    
    gl_FragColor = vec4(4*c*lc*(d*dot_nl+s*F*D*G/(4*dot_nv))/pi,1.0);

By532
    vec3 v = normalize(view_direction);
    vec3 l = v;
    vec3 h = normalize(l+v);
    vec3 n = normalize(0*c*h+v_normal);
   
    vec3 lc = vec3""" + str(light_color) + """;                                   
    vec3 d = vec3""" + str(d) + """;
    vec3 s = vec3""" + str(s) + """;
    vec3 F = vec3""" + str(f) + """;
    //F = F + (1-F)*pow((1-dot(h,v)),5);
    float m = """ + str(m) + """;
    float pi =3.1415926;
    float dot_nv = dot(n,v);  
    float dot_nh = dot(n,h);  
    float dot_vh = dot(v,h);
    float dot_nl = dot(n,l);                        
    float G = min(1.0,min(2*dot_nh*dot_nv/dot_vh,2*dot_nh*dot_nl/dot_vh));
    float D = (1/m/m/pow(dot_nh,4))*exp((1-1/pow(dot_nh,2))/pow(m,2));
    gl_FragColor = vec4(4*c*lc*(d*dot_nl+s*F*D*G/(4*dot_nv))/pi,1.0); 


 # 选择光照模型:
    # Lambert模型:漫反射,表现粗糙表面的光照现象
    # Phong模型:光滑物体的镜面发射
    # Blin-Phong模型:基于Phone,优于Phone
    # CookTorrance模型:真实的漫反射和镜面反射都需要依据材质特征和物体表面微平面特征,
    # 光照模型将物体粗糙表面看作由很多微小平面(微平面)组成,每一个微平面都被看作一个
    # 理想的镜面反射体,物体表面的粗糙度由微平面斜率的变化来衡量。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值