zoukankan      html  css  js  c++  java
  • 关于数组元素(ArrayPlug)的增减使用,逻辑索引和物理索引,MArrayDataBuilder

    我们知道,Maya中接口(Plug)可以包含多个元素,另外每个元素也都可以再包含多个元素,形成一个多层数组接口。Maya SDK专门提供了 MArrayDataHandle 类用于处于数组接口(Array Plug)。但是我们看到,该类只能遍历读取数组元素,但是没有提供增加或者删除数组元素的方法,那如果要想对数组元素进行增减,这个该如何操作呢? 

    大家可能都知道 MArrayDataBuilder 这个类可以用于处理数组元素,但是这个Attribute 必须在初始化的时候用 MFnAttribute::setUsesArrayDataBuilder(true) 来指定。默认状态是无法使用MArrayDataBuilder来处理数组的。

    另外,该MArrayDataHandle 也必须从有效的data block中获得,如果是直接从接口获得的话,比如用 MPlug::getValue() 或者 MPlug::asMDataHandle()读取获得的话,也无法使用MArrayDataBuilder。

    那知道了通过MArrayDataBuilder 可以增减数组元素后,那如何才能正确的增加和删除数组元素呢?这里就涉及到操作 Maya 数组时使用的逻辑索引(Logic index)和物理索引(Physic Index)了。我们知道,Maya允许开发者通过两种不同的方式来操作数组元素,逻辑索引是指元素的逻辑位置,可以是非连续的,标明了某个特定的元素。物理索引的话是指元素的物理位置,是连续的,从【0:elementCount-1】,并且代表的数据有可能会变化。

    当需要添加新元素到数组中的时候,如果不清楚当前哪些逻辑索引已经被使用,那么一般推荐使用addLast() 或者addLastArray()函数,如果想要指定该元素的逻辑位置的话,那也可以使用addElement() 或者addLastArray().

    同样,在删除的时候,removeElement (unsigned int index) 可用于删除指定逻辑位置的元素。但如果我们要删除数组里面的所有元素,但是元素逻辑索引又是非连续的,那怎么处理呢?

    如果有MArrayDataBuilder::removeElementByPhysicIndex( unsigned int position ) 这种方法,那我们可以遍历整个数组,然后依次删除,但是遗憾的是,MArrayDataBuilder并没有提供用于删除指定物理位置元素的方法,那我们就必须找到每一个物理位置对应的逻辑位置,然后再用removeElement (unsigned int index)来删除,具体示例代码如下:

        MArrayDataBuilder outLightningBuilder =outLightningHandle.builder () ;
        uint numElements =outLightningBuilder.elementCount () ;
        for ( uint i =numElements - 1 ; i >= 0 ; --i )

        {
            outLightningHandle.jumpToArrayElement (i) ;
            uint index =outLightningHandle.elementIndex () ;
            outLightningBuilder.removeElement (index) ;
        }

        1. 使用outLightningHandle.jumpToArrayElement (i) 来指定当前元素的物理位置
        2. uint index =outLightningHandle.elementIndex () ; 用于获得该物理索引对应的逻辑索引
        3. outLightningBuilder.removeElement (index) ; 用于删除该元素

    另外,要注意的一点是,我们这里删除是从数组的最后一个元素开始删起,这样是为了提高删除的性能。因为我们知道该数组是动态调整的,并可以通过MArrayDataBuilder::growArray (unsigned int amount) 和MArrayDataBuilder::setGrowSize (unsigned int size) 来调整数组增加的大小。举例如果我们从其实位置0开始删除的话,当删除了size个元素后,那么数组可能会做一个move操作,把后面的元素移到前面来减少数组长度来提高空间利用率,这样就会导致额外性能开销。

  • 相关阅读:
    LeetCode Binary Tree Inorder Traversal
    LeetCode Populating Next Right Pointers in Each Node
    LeetCode Construct Binary Tree from Inorder and Postorder Traversal
    LeetCode Reverse Linked List II
    LeetCode Populating Next Right Pointers in Each Node II
    LeetCode Pascal's Triangle
    Palindrome Construct Binary Tree from Preorder and Inorder Traversal
    Pascal's Triangle II
    LeetCode Word Ladder
    LeetCode Binary Tree Zigzag Level Order Traversal
  • 原文地址:https://www.cnblogs.com/johnonsoftware/p/3564545.html
Copyright © 2011-2022 走看看