vtkObject & vtkAlgorithm

本文详细介绍了VTK中的vtkObject基类及其核心功能,包括对象信息修改分发、数据删除、对象修改时间及RTTI支持。vtkObject提供了访问类属性的接口,并通过macro.newInstance创建实例。此外,文章还探讨了vtkAlgorithm类,它是vtk数据工作流的基础,阐述了如何设置输入输出数据以及如何实现requestData接口以处理数据更新。setter方法的实现确保了数据修改的通知。
vtkObject
 
vtk类支持通过macro.newInstance实现,一个vtk类实例一般包括两部分 model对象和publicAPI对象,其中类的属性定义在model中,暴露的方法定义在publicAPI中
 
macro.newInstance
export function newInstance(extend, className) {
  const constructor = (initialValues = {}) => {
    const model = {};
    const publicAPI = {};
    extend(publicAPI, model, initialValues);
    return Object.freeze(publicAPI);
  };


  // Register constructor to factory
  if (className) {
    vtk.register(className, constructor);
  }


  return constructor;
}

 

vtkObject是vtk中一切类的基类,通过macro.obj()方法定义到对象中主要包括下面功能
 
//对象信息修改分发
modified()
onModified(callback)
//对象删除
delete()
isDeleted():boolean
//对象修改时间
getMTime();

//对象RTTI支持
isA(className);
getClassName();

//返回一个格式化对象用于序列化
getState()

 

 
vtkObject同时提供了对类属性的访问接口
get(...list);  list为要获取的属性名列表,list为空则返回整个model对象,list不为空则返回一个新对象包括了要查询属性的键值。     
getReferenceByName(propertyName); 返回model中对应属性值。    
因为vtkjs中类属性定义在model中,且是隐式定义,可读性不好,大多数类暴露的属性也同时通过getter 和 setter方法暴露,所以一般不用上面方法直接去访问类属性,而用getter和setter,
一个类暴露了哪些属性也直接通过观察getter和setter可以看出,如:
getter和setter的实现参考上一篇: vtkjs 学习笔记 二模块化与类(newInstance)
 
 
 
 
数据的更新通知
这个功能需要依赖vtkObject.modify这个事件来分发,
setter的实现中会默认调用对象modify方法来通知对象修改。
 

所有的setter都是通过findSetter去生成一个对应setter,一个setter在调用的时候会调用对象modify方法通知对象更新:

 

function findSetter(field) {
  if (typeof field === 'object') {
    const fn = objectSetterMap[field.type];
    if (fn) {
      return (publicAPI, model) => fn(publicAPI, model, field);
    }


    vtkErrorMacro(`No setter for field ${field}`);
    throw new TypeError('No setter for field');
  }
  return function getSetter(publicAPI, model) {
    return function setter(value) {
      if (model.deleted) {
        vtkErrorMacro('instance deleted - cannot call any method');
        return false;
      }


      if (model[field] !== value) {
        model[field] = value;
        publicAPI.modified();
        return true;
      }
      return false;
    };
  };
}

 

 

 
vtkAlgorithm
 
算法是vtk数据工作流的基础,vtk把数据处理部分抽象为一个个算法,每一个算法有Input Ouput,一个算法的OutPut可以作为下一个算法的Input,这样一系列算法串起来就是数据工作流。
vtkAlgorthm是通过macro.algo方法来实现的,主要实现了下面几个接口去表示输入输出数据:
 
abstract requestData()
setInputData(),     
setInputConnection(), 
getOutputData(), 
getOutputPort()

它的输入输出一般都是vtkDataSet(通常是vtkPolydata)

 
所有的filter类,数据源,mapper都需要继承它,由它作为一个数据处理节点去插入vtk工作流。
 
 
 
 
在定义的时候需要定义这个对象有多少个输入多少个输出
export function algo(publicAPI, model, numberOfInputs, numberOfOutputs)

如这个是Source类的定义,表示这个是数据源,有0个输入1个输出

 
这个是Mapper的定义,表示Mapper是数据流的最终接收者
 
这个是所有filter的定义,表示是数据流中的处理算法,既有输入又有输出
macro . algo ( publicAPI model 1 1 );
 
 
 
setInputData & getOutputData
设置获取数据,数据一般都是vtkDataSet 如vtkPolyData
this.mapper.setInputData(this.coneSource.getOutputData());

这种方式获取的数据是一次性的,所以当数据修改后不会刷新显示

 
 setInputConnection & getOutputPort
 

setInputConnection设置的是一个输出函数,输出函数会调用getOutputData()来获取输出数据。

getOutputPort是获取一个输出函数

使用它们的好处是每次render都会通过调用输出函数调用getOutputData重新获取数据,这样如果数据源有修改则会同步渲染。

一般的用法是

this.mapper.setInputConnection(this.coneSource.getOutputPort());

输出函数定义如下,其直接执行可以获取输出数据,同时有filter属性,可以访问这个输出数据的算法对象

  function getOutputPort(port = 0) {

    const outputPortAccess = () => getOutputData(port);    //获取数据

    // Add reference to filter

    outputPortAccess.filter = publicAPI;

    return outputPortAccess;

  }

类似于下面这个接口的实现,下面这个是ts定义,

  interface vtkOutputPort{

    ():void;

  }

  interface vtkOutputPortAccess extends vtkOutputPort{

    filter:vtkAlgorithm;

  }

 

 
 
requestData接口
 
一个算法派生类需要实现requestData接口来生成 output数据
 
下面是vtkLineFilter的requestData的实现
  publicAPI.requestData = (inData, outData) => {
    const dataset = vtkPolyData.newInstance();


    dataset.getPoints().setData(inData[0].getPoints().getData());
    dataset.getLines().setData(inData[0].getLines().getData());


    outData[0] = dataset;
  };

requestData会在算法类对象update时调用请求重新计算输出数据,getOutputData()会调用update()

  
publicAPI.update = () => {
    const ins = [];
    if (model.numberOfInputs) {
      let count = 0;
      while (count < model.numberOfInputs) {
        ins[count] = publicAPI.getInputData(count);
        count++;
      }
    }
    if (publicAPI.shouldUpdate() && publicAPI.requestData) {
      publicAPI.requestData(ins, model.output);
    }
  };

  function getOutputData(port = 0) {
    if (model.deleted) {
      vtkErrorMacro('instance deleted - cannot call any method');
      return null;
    }
    if (publicAPI.shouldUpdate()) {
      publicAPI.update();
    }
    return model.output[port];
  }
 
内容概要:本文聚焦于高维多阶段随机规划问题的建模与求解方法,结合Python代码实现,系统研究了在不确定性环境下的复杂动态优化问题。重点探讨了正则化分解技术在缓解高维问题&ldquo;维度灾难&rdquo;中的作用,以及如何引入马尔可夫过程对系统状态转移的不确定性进行建模,从而提升优化模型的鲁棒性与实用性。文中详细阐述了算法设计思路与实现流程,涵盖场景生成、阶段划分、递推求解及收敛性分析等关键环节,适用于能源调度、电力系统规划等具有多阶段决策特征的实际应用场景。; 适合人群:具备一定运筹学基础、随机过程理论知识及Python编程能力,从事能源系统优化、电力调度、智能电网、低碳规划等领域的高校研究生、科研人员以及相关工程技术人员。; 使用场景及目标:①掌握高维多阶段随机规划问题的建模框架与求解策略;②学习如何利用马尔可夫链刻画动态不确定性并嵌入优化模型;③理解正则化方法在降低计算复杂度、加速算法收敛方面的技术优势;④借鉴完整代码实现在自身研究课题中复现或拓展相关算法; 其他说明:资源提供可运行的Python源码,建议结合具体案例数据进行调试与验证,并配合主流优化求解器(如Gurobi、CPLEX)进一步提升求解效率,同时推荐阅读相关文献以深化对分解算法与随机规划理论的理解。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值