Ejemplo n.º 1
0
int64 
GusdBoundsCache::Clear(const UT_Set<std::string>& paths)
{
    int64 freed = 0;

    UT_Array<Key> keys;
    for( auto const& entry : m_map ) {
        if( paths.contains( entry.first.path.GetString() ) ) {
            keys.append( entry.first );
        }
    }

    for( auto const& k : keys ) {
        m_map.erase( k );
    }
    return freed;    
}
void
SOP_PrimGroupCentroid::buildGroupData(UT_String &pattern,
                                      const GU_Detail *input_geo,
                                      UT_Array<GA_Range> &range_array,
                                      UT_StringArray &string_values)
{
    GA_Range                    pr_range;
    const GA_PrimitiveGroup     *group;
    GA_ElementGroupTable::ordered_iterator group_it;

    UT_String                   group_name;
    UT_WorkArgs                 tokens;

    // Tokenize the pattern.
    pattern.tokenize(tokens);

    // Get all the primitive groups.
    const GA_ElementGroupTable &prim_groups = input_geo->primitiveGroups();

    // For each primitive group in order.
    for (group_it=prim_groups.obegin(); !group_it.atEnd(); ++group_it)
    {
        // Get the group.
        group = static_cast<GA_PrimitiveGroup *>(*group_it);

        // Ensure the group is valid.
        if (!group)
            continue;

        // Skip internal groups.
        if (group->getInternal())
            continue;

        // Check to see if this group name matches the pattern.
        group_name = group->getName();
        if (!group_name.matchPattern(tokens))
            continue;

        // Get a range for the primitives in the group.
        pr_range = input_geo->getPrimitiveRange(group);

        // Add the primitive range and the group name to the arrays.
        range_array.append(pr_range);
        string_values.append(group_name);
    }
}
Ejemplo n.º 3
0
OP_ERROR
SOP_Smoke_Source::cookMySop(OP_Context &context)
{
    // We must lock our inputs before we try to access their geometry.
    // OP_AutoLockInputs will automatically unlock our inputs when we return.
    // NOTE: Don't call unlockInputs yourself when using this!
    OP_AutoLockInputs inputs(this);
    if (inputs.lock(context) >= UT_ERROR_ABORT)
        return error();

    fpreal now = context.getTime();

    duplicateSource(0, context);

    // These three lines enable the local variable support.  This allows
    // $CR to get the red colour, for example, as well as supporting
    // any varmap created by the Attribute Create SOP.
    // Note that if you override evalVariableValue for your own
    // local variables (like SOP_Star does) it is essential you
    // still call the SOP_Node::evalVariableValue or you'll not
    // get any of the benefit of the built in local variables.

    // The variable order controls precedence for which attribute will be
    // be bound first if the same named variable shows up in multiple
    // places.  This ordering ensures point attributes get precedence.
    setVariableOrder(3, 2, 0, 1);

    // The setCur* functions track which part of the gdp is currently
    // being processed - it is what is used in the evalVariableValue
    // callback as the current point.  The 0 is for the first input,
    // you can have two inputs so $CR2 would get the second input's
    // value.
    setCurGdh(0, myGdpHandle);

    // Builds the lookup table matching attributes to the local variables.
    setupLocalVars();

    // Here we determine which groups we have to work on.  We only
    //	handle point groups.
    if (error() < UT_ERROR_ABORT && cookInputGroups(context) < UT_ERROR_ABORT &&
        (!myGroup || !myGroup->isEmpty()))
    {
        UT_AutoInterrupt progress("Flattening Points");

        // Handle all position, normal, and vector attributes.
        // It's not entirely clear what to do for quaternion or transform attributes.
        // We bump the data IDs of the attributes to modify in advance,
        // since we're already looping over them, and we want to avoid
        // bumping them all for each point, in case that's slow.
        UT_Array<GA_RWHandleV3> positionattribs(1);
        UT_Array<GA_RWHandleV3> normalattribs;
        UT_Array<GA_RWHandleV3> vectorattribs;
        GA_Attribute *attrib;
        GA_FOR_ALL_POINT_ATTRIBUTES(gdp, attrib)
        {
            // Skip non-transforming attributes
            if (!attrib->needsTransform())
                continue;

            GA_TypeInfo typeinfo = attrib->getTypeInfo();
            if (typeinfo == GA_TYPE_POINT || typeinfo == GA_TYPE_HPOINT)
            {
                GA_RWHandleV3 handle(attrib);
                if (handle.isValid())
                {
                    positionattribs.append(handle);
                    attrib->bumpDataId();
                }
            }
            else if (typeinfo == GA_TYPE_NORMAL)
            {
                GA_RWHandleV3 handle(attrib);
                if (handle.isValid())
                {
                    normalattribs.append(handle);
                    attrib->bumpDataId();
                }
            }
            else if (typeinfo == GA_TYPE_VECTOR)
            {
                GA_RWHandleV3 handle(attrib);
                if (handle.isValid())
                {
                    vectorattribs.append(handle);
                    attrib->bumpDataId();
                }
            }
        }

        // Iterate over points up to GA_PAGE_SIZE at a time using blockAdvance.
        GA_Offset start;
        GA_Offset end;
        for (GA_Iterator it(gdp->getPointRange(myGroup)); it.blockAdvance(start, end);)
        {
            // Check if user requested abort
            if (progress.wasInterrupted())
                break;

            for (GA_Offset ptoff = start; ptoff < end; ++ptoff)
            {
                // This sets the current point that is beint processed to
                // ptoff.  This means that ptoff will be used for any
                // local variable for any parameter evaluation that occurs
                // after this point.
                // NOTE: Local variables and repeated parameter evaluation
                //       is significantly slower and sometimes more complicated
                //       than having a string parameter that specifies the name
                //       of an attribute whose values should be used instead.
                //       That parameter would only need to be evaluated once,
                //       the attribute could be looked up once, and quickly
                //       accessed; however, a separate point attribute would
                //       be needed for each property that varies per point.
                //       Local variable evaluation isn't threadsafe either,
                //       whereas attributes can be read safely from multiple
                //       threads.
                //
                //       Long story short: *Local variables are terrible.*
                myCurPtOff[0] = ptoff;
                float dist = DIST(now);
                UT_Vector3 normal;
                if (!DIRPOP())
                {
                    switch (ORIENT())
                    {
                        case 0 : // XY Plane
                            normal.assign(0, 0, 1);
                            break;
                        case 1 : // YZ Plane
                            normal.assign(1, 0, 0);
                            break;
                        case 2 : // XZ Plane
                            normal.assign(0, 1, 0);
                            break;
                    }
                }
                else
                {
                    normal.assign(NX(now), NY(now), NZ(now));
                    normal.normalize();
                }

                // Project positions onto the plane by subtracting
                // off the normal component.
                for (exint i = 0; i < positionattribs.size(); ++i)
                {
                    UT_Vector3 p = positionattribs(i).get(ptoff);
                    p -= normal * (dot(normal, p) - dist);
                    positionattribs(i).set(ptoff, p);
                }

                // Normals will now all either be normal or -normal.
                for (exint i = 0; i < normalattribs.size(); ++i)
                {
                    UT_Vector3 n = normalattribs(i).get(ptoff);
                    if (dot(normal, n) < 0)
                        n = -normal;
                    else
                        n = normal;
                    normalattribs(i).set(ptoff, n);
                }

                // Project vectors onto the plane through the origin by
                // subtracting off the normal component.
                for (exint i = 0; i < vectorattribs.size(); ++i)
                {
                    UT_Vector3 v = vectorattribs(i).get(ptoff);
                    v -= normal * dot(normal, v);
                    vectorattribs(i).set(ptoff, v);
                }
            }
        }
    }
int
SOP_PrimGroupCentroid::buildAttribData(int mode,
                                       const GU_Detail *input_geo,
                                       UT_Array<GA_Range> &range_array,
                                       UT_StringArray &string_values,
                                       UT_IntArray &int_values)
{
    int                         unique_count;
    exint                       int_value;

    GA_Range                    pr_range;

    GA_ROAttributeRef           source_gah;

    UT_String                   attr_name, str_value;

    // Determine the attribute name to use.
    attr_name = (mode == 1) ? "name": "class";

    // Find the attribute.
    source_gah = input_geo->findPrimitiveAttribute(attr_name);

    // If there is no attribute, add an error message and quit.
    if (source_gah.isInvalid())
    {
        addError(SOP_ATTRIBUTE_INVALID, attr_name);
        return 1;
    }

    // If the 'name' attribute isn't a string, add an error and quit.
    if (mode == 1 && !source_gah.isString())
    {
        addError(SOP_ATTRIBUTE_INVALID, "'name' must be a string.");
        return 1;
    }
    // If the 'class' attribute isn't an int, add an error and quit.
    else if (mode == 2 && !source_gah.isInt())
    {
        addError(SOP_ATTRIBUTE_INVALID, "'class' must be an integer.");
        return 1;
    }

    // The number of unique values for the attribute.
    unique_count = input_geo->getUniqueValueCount(source_gah);

    // Add all the ranges and unique values to the appropriate arrays.
    if (mode == 1)
    {
        for (int idx=0; idx<unique_count; ++idx)
        {
            // Get the unique string value.
            str_value = input_geo->getUniqueStringValue(source_gah, idx);
            // Get the primitive range corresponding to that value.
            pr_range = input_geo->getRangeByValue(source_gah, str_value);

            // Add the range to the array.
            range_array.append(pr_range);
            // Add the string value to the string value list.
            string_values.append(str_value);
        }
    }
    else
    {
        for (int idx=0; idx<unique_count; ++idx)
        {
            // Get the unique integer value.
            int_value = input_geo->getUniqueIntegerValue(source_gah, idx);
            // Get the primitive range corresponding to that value.
            pr_range = input_geo->getRangeByValue(source_gah, int_value);

            // Add the range to the array.
            range_array.append(pr_range);
            // Add the integer value to the integer value list.
            int_values.append(int_value);
        }
    }

    // Return 0 for success.
    return 0;
}