<commit_before>#include "OutputGeometry.h"
#include "OutputGeometryPart.h"
#include "OutputObject.h"
#include "util.h"
#include "AssetNode.h"

OutputGeometry::OutputGeometry(HAPI_NodeId nodeId) :
    myNodeId(nodeId),
    myLastCookCount(0)
{
    update();
}

OutputGeometry::~OutputGeometry()
{
    for(int i = myParts.size(); i-- > 0;)
    {
        delete myParts.back();
        myParts.pop_back();
    }
}

void
OutputGeometry::update()
{
    HAPI_Result hapiResult;

    hapiResult = HAPI_GetNodeInfo(
            Util::theHAPISession.get(),
            myNodeId, &myNodeInfo
            );
    CHECK_HAPI(hapiResult);

    hapiResult = HAPI_GetGeoInfo(
            Util::theHAPISession.get(),
            myNodeId,
            &myGeoInfo);
    if(HAPI_FAIL(hapiResult))
    {
        // Make sre myGeoInfo is properly initialized.
        HAPI_GeoInfo_Init(&myGeoInfo);

        // Even when HAPI_GetGeoInfo() failed, there's always at least one
        // part. So we want the below code to initialize myParts.
    }

    if(myGeoInfo.type == HAPI_GEOTYPE_DEFAULT
            || myGeoInfo.type == HAPI_GEOTYPE_INTERMEDIATE
            || myGeoInfo.type == HAPI_GEOTYPE_CURVE)
    {
        // Create any new OutputGeometryPart
        myParts.reserve(myGeoInfo.partCount);
        for(int i = myParts.size(); i < myGeoInfo.partCount; i++)
        {
            OutputGeometryPart* outputGeometryPart = new OutputGeometryPart(
                    myNodeId,
                    i
                    );
            myParts.push_back(outputGeometryPart);
        }

        // Destroy the extra OutputGeometryPart
        for(int i = myParts.size(); i-- > myGeoInfo.partCount;)
        {
            delete myParts.back();
            myParts.pop_back();
        }
    }
}

MStatus
OutputGeometry::compute(
        const MTime &time,
        const MPlug &geoPlug,
        MDataBlock &data,
        MDataHandle &geoHandle,
        AssetNodeOptions::AccessorDataBlock &options,
        bool &needToSyncOutputs
        )
{
    MStatus stat;

    data.setClean(geoPlug);

    update();

    MDataHandle geoNameHandle = geoHandle.child(AssetNode::outputGeoName);
    MString geoName;
    if(myGeoInfo.nameSH != 0)
    {
        geoName = Util::HAPIString(myGeoInfo.nameSH);
    }
    geoNameHandle.setString(geoName);

    MDataHandle isTemplatedHandle = geoHandle.child(AssetNode::outputGeoIsTemplated);
    isTemplatedHandle.setBool(myGeoInfo.isTemplated);

    MDataHandle isDisplayGeoHandle = geoHandle.child(AssetNode::outputGeoIsDisplayGeo);
    isDisplayGeoHandle.setBool(myGeoInfo.isDisplayGeo);

    MPlug partsPlug = geoPlug.child(AssetNode::outputParts);
    MDataHandle partsHandle = geoHandle.child(AssetNode::outputParts);
    MArrayDataHandle partsArrayHandle(partsHandle);

    bool partCountChanged = partsArrayHandle.elementCount() != (unsigned int)myGeoInfo.partCount;
    if(partCountChanged)
    {
        Util::resizeArrayDataHandle(partsArrayHandle, myGeoInfo.partCount);
        needToSyncOutputs = true;
    }

    bool forceCompute = false;
    for(int i = 0; i < myGeoInfo.partCount; i++)
    {
        forceCompute |= myParts[i]->needCompute(options);
    }

    if(myGeoInfo.type == HAPI_GEOTYPE_DEFAULT ||
            myGeoInfo.type == HAPI_GEOTYPE_INTERMEDIATE ||
            myGeoInfo.type == HAPI_GEOTYPE_CURVE)
    {
        if(myNodeInfo.totalCookCount > myLastCookCount
                || partCountChanged || forceCompute)
        {
            // Compute the OutputGeometryPart
            for(int i = 0; i < myGeoInfo.partCount; i++)
            {
                MPlug partPlug = partsPlug.elementByLogicalIndex(i);<commit_msg>fix for plugin crash when asset has an output null that HAPI has, for whatever reason, identified as an input.<commit_after>#include "OutputGeometry.h"
#include "OutputGeometryPart.h"
#include "OutputObject.h"
#include "util.h"
#include "AssetNode.h"

OutputGeometry::OutputGeometry(HAPI_NodeId nodeId) :
    myNodeId(nodeId),
    myLastCookCount(0)
{
    update();
}

OutputGeometry::~OutputGeometry()
{
    for(int i = myParts.size(); i-- > 0;)
    {
        delete myParts.back();
        myParts.pop_back();
    }
}

void
OutputGeometry::update()
{
    HAPI_Result hapiResult;

    hapiResult = HAPI_GetNodeInfo(
            Util::theHAPISession.get(),
            myNodeId, &myNodeInfo
            );
    CHECK_HAPI(hapiResult);

    hapiResult = HAPI_GetGeoInfo(
            Util::theHAPISession.get(),
            myNodeId,
            &myGeoInfo);
    if(HAPI_FAIL(hapiResult))
    {
        // Make sre myGeoInfo is properly initialized.
        HAPI_GeoInfo_Init(&myGeoInfo);

        // Even when HAPI_GetGeoInfo() failed, there's always at least one
        // part. So we want the below code to initialize myParts.
    }

    if(myGeoInfo.type == HAPI_GEOTYPE_DEFAULT
            || myGeoInfo.type == HAPI_GEOTYPE_INTERMEDIATE
            || myGeoInfo.type == HAPI_GEOTYPE_INPUT
            || myGeoInfo.type == HAPI_GEOTYPE_CURVE)
    {
        // Create any new OutputGeometryPart
        myParts.reserve(myGeoInfo.partCount);
        for(int i = myParts.size(); i < myGeoInfo.partCount; i++)
        {
            OutputGeometryPart* outputGeometryPart = new OutputGeometryPart(
                    myNodeId,
                    i
                    );
            myParts.push_back(outputGeometryPart);
        }

        // Destroy the extra OutputGeometryPart
        for(int i = myParts.size(); i-- > myGeoInfo.partCount;)
        {
            delete myParts.back();
            myParts.pop_back();
        }
    }
}

MStatus
OutputGeometry::compute(
        const MTime &time,
        const MPlug &geoPlug,
        MDataBlock &data,
        MDataHandle &geoHandle,
        AssetNodeOptions::AccessorDataBlock &options,
        bool &needToSyncOutputs
        )
{
    MStatus stat;

    data.setClean(geoPlug);

    update();

    MDataHandle geoNameHandle = geoHandle.child(AssetNode::outputGeoName);
    MString geoName;
    if(myGeoInfo.nameSH != 0)
    {
        geoName = Util::HAPIString(myGeoInfo.nameSH);
    }
    geoNameHandle.setString(geoName);

    MDataHandle isTemplatedHandle = geoHandle.child(AssetNode::outputGeoIsTemplated);
    isTemplatedHandle.setBool(myGeoInfo.isTemplated);

    MDataHandle isDisplayGeoHandle = geoHandle.child(AssetNode::outputGeoIsDisplayGeo);
    isDisplayGeoHandle.setBool(myGeoInfo.isDisplayGeo);

    MPlug partsPlug = geoPlug.child(AssetNode::outputParts);
    MDataHandle partsHandle = geoHandle.child(AssetNode::outputParts);
    MArrayDataHandle partsArrayHandle(partsHandle);

    bool partCountChanged = partsArrayHandle.elementCount() != (unsigned int)myGeoInfo.partCount;
    if(partCountChanged)
    {
        Util::resizeArrayDataHandle(partsArrayHandle, myGeoInfo.partCount);
        needToSyncOutputs = true;
    }

    bool forceCompute = false;
    for(int i = 0; i < myGeoInfo.partCount; i++)
    {
        forceCompute |= myParts[i]->needCompute(options);
    }

    // if we got here it's an output, even if HAPI thinks it's an input too
    if(myGeoInfo.type == HAPI_GEOTYPE_DEFAULT ||
            myGeoInfo.type == HAPI_GEOTYPE_INTERMEDIATE ||
            myGeoInfo.type == HAPI_GEOTYPE_INPUT ||
            myGeoInfo.type == HAPI_GEOTYPE_CURVE)
    {
        if(myNodeInfo.totalCookCount > myLastCookCount
                || partCountChanged || forceCompute)
        {
            // Compute the OutputGeometryPart
            for(int i = 0; i < myGeoInfo.partCount; i++)
            {
                MPlug partPlug = partsPlug.elementByLogicalIndex(i);
{'fraction_non_alphanumeric': 0.10093310553292154, 'fraction_numerical': 0.001314233144959916, 'mean_word_length': 2.54118194509074, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 11, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1496946', 'n_tokens_mistral': 2461, 'n_tokens_neox': 2378, 'n_words': 419}