/// <summary>
        /// Destroy all generated data.
        /// </summary>
        public void DestroyAllData()
        {
            HEU_PartData.DestroyParts(_parts);

            if (_inputNode != null)
            {
                HEU_SessionBase session = null;
                if (ParentAsset != null)
                {
                    ParentAsset.RemoveInputNode(_inputNode);
                    session = ParentAsset.GetAssetSession(false);
                }

                _inputNode.DestroyAllData(session);
                HEU_GeneralUtility.DestroyImmediate(_inputNode);
                _inputNode = null;
            }

            if (_geoCurve != null)
            {
                if (ParentAsset != null)
                {
                    ParentAsset.RemoveCurve(_geoCurve);
                }
                _geoCurve.DestroyAllData();
                HEU_GeneralUtility.DestroyImmediate(_geoCurve);
                _geoCurve = null;
            }

            DestroyVolumeCache();
        }
        public void UpdateGeo(HEU_SessionBase session)
        {
            // Create or recreate parts.

            bool bObjectInstancer = _containerObjectNode.IsInstancer();

            // Save list of old parts. We'll destroy these after creating new parts.
            // The reason for temporarily keeping these is to transfer data (eg. instance overrides, attribute data)
            List <HEU_PartData> oldParts = new List <HEU_PartData>(_parts);

            _parts.Clear();

            try
            {
                if (!_geoInfo.isDisplayGeo)
                {
                    if (ParentAsset.IgnoreNonDisplayNodes)
                    {
                        return;
                    }
                    else if (!_geoInfo.isEditable ||
                             (_geoInfo.type != HAPI_GeoType.HAPI_GEOTYPE_DEFAULT &&
                              _geoInfo.type != HAPI_GeoType.HAPI_GEOTYPE_INTERMEDIATE &&
                              _geoInfo.type != HAPI_GeoType.HAPI_GEOTYPE_CURVE))
                    {
                        return;
                    }
                }

                if (IsGeoCurveType())
                {
                    ProcessGeoCurve(session);
                }
                else
                {
                    int numParts = _geoInfo.partCount;
                    //Debug.Log("Number of parts: " + numParts);
                    //Debug.LogFormat("GeoNode type {0}, isTemplated: {1}, isDisplayGeo: {2}, isEditable: {3}", _geoInfo.type, _geoInfo.isTemplated, _geoInfo.isDisplayGeo, _geoInfo.isEditable);
                    for (int i = 0; i < numParts; ++i)
                    {
                        HAPI_PartInfo partInfo = new HAPI_PartInfo();
                        if (!session.GetPartInfo(GeoID, i, ref partInfo))
                        {
                            Debug.LogErrorFormat("Unable to get PartInfo for geo node {0} and part {1}.", GeoID, i);
                            continue;
                        }

                        // Find the old part for this new part.
                        HEU_PartData part           = null;
                        HEU_PartData oldMatchedPart = null;

                        foreach (HEU_PartData oldPart in oldParts)
                        {
                            string partName = HEU_SessionManager.GetString(partInfo.nameSH, session);
                            if (oldPart.PartName.Equals(partName))
                            {
                                oldMatchedPart = oldPart;
                            }
                        }

                        if (oldMatchedPart != null)
                        {
                            //Debug.Log("Found matched part: " + oldMatchedPart.name);

                            List <HEU_ObjectInstanceInfo> sourceObjectInstanceInfos = null;
                            if (bObjectInstancer)
                            {
                                // ProcessPart will clear out the object instances, so hence why
                                // we keep a copy here, then restore after processing the parts.
                                sourceObjectInstanceInfos = oldMatchedPart.GetObjectInstanceInfos();
                            }

                            // Clear out old generated data
                            oldMatchedPart.ClearGeneratedData();

                            part = oldMatchedPart;
                            oldParts.Remove(oldMatchedPart);

                            ProcessPart(session, i, ref partInfo, ref part);

                            if (part != null && bObjectInstancer && sourceObjectInstanceInfos != null)
                            {
                                // Set object instances from old part into new. This keeps the user set object inputs around.
                                part.SetObjectInstanceInfos(sourceObjectInstanceInfos);
                            }
                        }
                        else
                        {
                            ProcessPart(session, i, ref partInfo, ref part);
                        }
                    }
                }
            }
            finally
            {
                HEU_PartData.DestroyParts(oldParts);
            }
        }