/// <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();
        }
 /// <inheritdoc />
 public void Recook()
 {
     if (ParentAsset != null)
     {
         ParentAsset.RequestCook();
     }
 }
Exemple #3
0
        public void DestroyVolumeCache()
        {
            if (_volumeCache != null)
            {
                ParentAsset.RemoveVolumeCache(_volumeCache);

                HEU_GeneralUtility.DestroyImmediate(_volumeCache);
                _volumeCache = null;
            }
        }
 /// <inheritdoc />
 public HEU_SessionBase GetSession()
 {
     if (ParentAsset != null)
     {
         return(ParentAsset.GetAssetSession(true));
     }
     else
     {
         return(HEU_SessionManager.GetOrCreateDefaultSession());
     }
 }
Exemple #5
0
        public bool IsHiddenOrParentHidden()
        {
            var isHidden = IsHidden.Value();

            if (!isHidden && ParentAsset != null)
            {
                isHidden = ParentAsset.IsHiddenOrParentHidden();
            }

            return(isHidden);
        }
        public void DestroyVolumeCache()
        {
            if (_volumeCaches != null)
            {
                int numCaches = _volumeCaches.Count;
                for (int i = 0; i < numCaches; ++i)
                {
                    if (_volumeCaches[i] != null)
                    {
                        ParentAsset.RemoveVolumeCache(_volumeCaches[i]);
                        HEU_GeneralUtility.DestroyImmediate(_volumeCaches[i]);
                        _volumeCaches[i] = null;
                    }
                }

                _volumeCaches = null;
            }
        }
Exemple #7
0
        public void ProcessVolumeParts(HEU_SessionBase session, List <HEU_PartData> volumeParts)
        {
            int numVolumeParts = volumeParts.Count;

            if (_volumeCache == null)
            {
                if (numVolumeParts == 0)
                {
                    return;
                }

                _volumeCache = ScriptableObject.CreateInstance <HEU_VolumeCache>();
                _volumeCache.Initialize(this);

                ParentAsset.AddVolumeCache(_volumeCache);
            }
            else if (numVolumeParts == 0)
            {
                DestroyVolumeCache();
                return;
            }

            _volumeCache.GenerateFromParts(session, ParentAsset, volumeParts);
        }
        /// <summary>
        /// Process the part at the given index, creating its data (geometry),
        /// and adding it to the list of parts.
        /// </summary>
        /// <param name="session"></param>
        /// <param name="partID"></param>
        /// <returns>A valid HEU_PartData if it has been successfully processed.</returns>
        private void ProcessPart(HEU_SessionBase session, int partID, ref HAPI_PartInfo partInfo, ref HEU_PartData partData)
        {
            HEU_HoudiniAsset parentAsset = ParentAsset;
            bool             bResult     = true;

            //Debug.LogFormat("Part: name={0}, id={1}, type={2}, instanced={3}, instance count={4}, instance part count={5}", HEU_SessionManager.GetString(partInfo.nameSH, session), partID, partInfo.type, partInfo.isInstanced, partInfo.instanceCount, partInfo.instancedPartCount);

#if HEU_PROFILER_ON
            float processPartStartTime = Time.realtimeSinceStartup;
#endif

            bool isPartEditable    = IsIntermediateOrEditable();
            bool isAttribInstancer = false;

            if (IsGeoInputType())
            {
                // Setup for input node to accept inputs
                if (_inputNode == null)
                {
                    string partName = HEU_SessionManager.GetString(partInfo.nameSH, session);
                    _inputNode = HEU_InputNode.CreateSetupInput(GeoID, 0, partName, HEU_InputNode.InputNodeType.NODE, ParentAsset);
                    if (_inputNode != null)
                    {
                        ParentAsset.AddInputNode(_inputNode);
                    }
                }

                if (HEU_HAPIUtility.IsSupportedPolygonType(partInfo.type) && partInfo.vertexCount == 0)
                {
                    // No geometry for input asset

                    if (partData != null)
                    {
                        // Clean up existing part
                        HEU_PartData.DestroyPart(partData);
                        partData = null;
                    }

                    // No need to process further since we don't have geometry
                    return;
                }
            }
            else
            {
                // Preliminary check for attribute instancing (mesh type with no verts but has points with instances)
                if (HEU_HAPIUtility.IsSupportedPolygonType(partInfo.type) && partInfo.vertexCount == 0 && partInfo.pointCount > 0)
                {
                    HAPI_AttributeInfo instanceAttrInfo = new HAPI_AttributeInfo();
                    HEU_GeneralUtility.GetAttributeInfo(session, GeoID, partID, HEU_PluginSettings.UnityInstanceAttr, ref instanceAttrInfo);
                    if (instanceAttrInfo.exists && instanceAttrInfo.count > 0)
                    {
                        isAttribInstancer = true;
                    }
                }
            }

            if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_INVALID)
            {
                // Clean up invalid parts
                if (partData != null)
                {
                    HEU_PartData.DestroyPart(partData);
                    partData = null;
                }
            }
            else if (partInfo.type < HAPI_PartType.HAPI_PARTTYPE_MAX)
            {
                // Process the part based on type. Keep or ignore.

                // We treat parts of type curve as curves, along with geo nodes that are editable and type curves
                if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_CURVE)
                {
                    if (partData == null)
                    {
                        partData = ScriptableObject.CreateInstance <HEU_PartData>();
                    }

                    partData.Initialize(session, partID, GeoID, _containerObjectNode.ObjectID, this, ref partInfo,
                                        HEU_PartData.PartOutputType.CURVE, isPartEditable, _containerObjectNode.IsInstancer(), false);
                    SetupGameObjectAndTransform(partData, parentAsset);
                    partData.ProcessCurvePart(session);
                }
                else if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_VOLUME)
                {
                    // We only process "height" volume parts. Other volume parts are ignored for now.

#if TERRAIN_SUPPORTED
                    HAPI_VolumeInfo volumeInfo = new HAPI_VolumeInfo();
                    bResult = session.GetVolumeInfo(GeoID, partID, ref volumeInfo);
                    if (!bResult)
                    {
                        Debug.LogErrorFormat("Unable to get volume info for geo node {0} and part {1} ", GeoID, partID);
                    }
                    else
                    {
                        if (Displayable && !IsIntermediateOrEditable())
                        {
                            if (partData == null)
                            {
                                partData = ScriptableObject.CreateInstance <HEU_PartData>();
                            }
                            else
                            {
                                // Clear volume data (case where switching from polygonal mesh to volume output)
                                partData.ClearGeneratedMeshOutput();
                            }

                            partData.Initialize(session, partID, GeoID, _containerObjectNode.ObjectID, this, ref partInfo,
                                                HEU_PartData.PartOutputType.VOLUME, isPartEditable, _containerObjectNode.IsInstancer(), false);
                            SetupGameObjectAndTransform(partData, ParentAsset);
                        }
                    }
#else
                    Debug.LogWarningFormat("Terrain (heightfield volume) is not yet supported.");
#endif
                }
                else if (partInfo.type == HAPI_PartType.HAPI_PARTTYPE_INSTANCER || isAttribInstancer)
                {
                    if (partData == null)
                    {
                        partData = ScriptableObject.CreateInstance <HEU_PartData>();
                    }
                    else
                    {
                        partData.ClearGeneratedMeshOutput();
                        partData.ClearGeneratedVolumeOutput();
                    }

                    partData.Initialize(session, partID, GeoID, _containerObjectNode.ObjectID, this, ref partInfo,
                                        HEU_PartData.PartOutputType.INSTANCER, isPartEditable, _containerObjectNode.IsInstancer(), isAttribInstancer);
                    SetupGameObjectAndTransform(partData, parentAsset);
                }
                else if (HEU_HAPIUtility.IsSupportedPolygonType(partInfo.type))
                {
                    if (partData == null)
                    {
                        partData = ScriptableObject.CreateInstance <HEU_PartData>();
                    }
                    else
                    {
                        // Clear volume data (case where switching from something other output to mesh)
                        partData.ClearGeneratedVolumeOutput();
                    }

                    partData.Initialize(session, partID, GeoID, _containerObjectNode.ObjectID, this, ref partInfo,
                                        HEU_PartData.PartOutputType.MESH, isPartEditable, _containerObjectNode.IsInstancer(), false);

                    // This check allows to ignore editable non-display nodes by default, but commented out to allow
                    // them for now. Users can also ignore them by turning on IgnoreNonDisplayNodes
                    //if (Displayable || (Editable && ParentAsset.EditableNodesToolsEnabled))
                    {
                        SetupGameObjectAndTransform(partData, parentAsset);
                    }
                }
                else
                {
                    Debug.LogWarningFormat("Unsupported part type {0}", partInfo.type);
                }

                if (partData != null)
                {
                    // Success!
                    _parts.Add(partData);

                    // Set unique name for the part
                    string partName = HEU_PluginSettings.UseFullPathNamesForOutput ? GeneratePartFullName(partData.PartName) : partData.PartName;
                    partData.SetGameObjectName(partName);

                    // For intermediate or default-type editable nodes, setup the HEU_AttributeStore
                    if (isPartEditable)
                    {
                        partData.SyncAttributesStore(session, _geoInfo.nodeId, ref partInfo);
                    }
                    else
                    {
                        // Remove attributes store if it has it
                        partData.DestroyAttributesStore();
                    }
                }
            }

#if HEU_PROFILER_ON
            Debug.LogFormat("PART PROCESS TIME:: NAME={0}, TIME={1}", HEU_SessionManager.GetString(partInfo.nameSH, session), (Time.realtimeSinceStartup - processPartStartTime));
#endif
        }
Exemple #9
0
	/// <summary>
	/// Retrieves object info from Houdini session and updates internal state.
	/// New geo nodes are created, unused geo nodes are destroyed.
	/// Geo nodes are then refreshed to be in sync with Houdini session.
	/// </summary>
	/// <returns>True if internal state has changed (including geometry).</returns>
	internal void UpdateObject(HEU_SessionBase session, bool bForceUpdate)
	{
	    if (ParentAsset == null)
	    {
		return;
	    }

	    // Update the geo info
	    if (!session.GetObjectInfo(ObjectID, ref _objectInfo))
	    {
		return;
	    }
	    SyncWithObjectInfo(session);

	    // Update the object transform
	    _objectTransform = ParentAsset.GetObjectTransform(session, ObjectID);

	    // Container for existing geo nodes that are still in use
	    List<HEU_GeoNode> geoNodesToKeep = new List<HEU_GeoNode>();

	    // Container for new geo infos that need to be created
	    List<HAPI_GeoInfo> newGeoInfosToCreate = new List<HAPI_GeoInfo>();

	    if (_objectInfo.haveGeosChanged || bForceUpdate)
	    {
		// Indicates that the geometry nodes have changed
		//HEU_Logger.Log("Geos have changed!");

		// Form a list of geo infos that are now present after cooking
		List<HAPI_GeoInfo> postCookGeoInfos = new List<HAPI_GeoInfo>();


		bool useOutputNodes = true;
		if (ParentAsset) useOutputNodes = ParentAsset.UseOutputNodes;

		HEU_HAPIUtility.GatherAllAssetGeoInfos(session, ParentAsset.AssetInfo, _objectInfo, useOutputNodes, ref postCookGeoInfos);

		// Now for each geo node that are present after cooking, we check if its
		// new or whether we already have it prior to cooking.
		int numPostCookGeoInfos = postCookGeoInfos.Count;
		for (int i = 0; i < numPostCookGeoInfos; i++)
		{
		    bool bFound = false;
		    for (int j = 0; j < _geoNodes.Count; j++)
		    {
			string geoName = HEU_SessionManager.GetString(postCookGeoInfos[i].nameSH, session);
			if (geoName.Equals(_geoNodes[j].GeoName))
			{
			    _geoNodes[j].SetGeoInfo(postCookGeoInfos[i]);

			    geoNodesToKeep.Add(_geoNodes[j]);
			    _geoNodes.RemoveAt(j);

			    bFound = true;
			    break;
			}
		    }

		    if (!bFound)
		    {
			newGeoInfosToCreate.Add(postCookGeoInfos[i]);
		    }
		}

		// Whatever is left in _geoNodes is no longer needed so clean up
		int numCurrentGeos = _geoNodes.Count;
		for (int i = 0; i < numCurrentGeos; ++i)
		{
		    _geoNodes[i].DestroyAllData();
		}
	    }
	    else
	    {
		Debug.Assert(_objectInfo.geoCount == _geoNodes.Count, "Expected same number of geometry nodes.");
	    }

	    // Go through the old geo nodes that are still in use and update if necessary.
	    foreach (HEU_GeoNode geoNode in geoNodesToKeep)
	    {
		// Get geo info and check if geo changed
		bool bGeoChanged = bForceUpdate || geoNode.HasGeoNodeChanged(session);
		if (bGeoChanged)
		{
		    geoNode.UpdateGeo(session);
		}
		else
		{
		    if (_objectInfo.haveGeosChanged)
		    {
			// Clear object instances since the object info has changed.
			// Without this, the object instances were never getting updated
			// if only the inputs changed but not outputs (of instancers).
			geoNode.ClearObjectInstances();
		    }

		    // Visiblity might have changed, so update that
		    geoNode.CalculateVisiblity(IsVisible());
		    geoNode.CalculateColliderState();
		}
	    }

	    // Create the new geo infos and add to our keep list
	    foreach (HAPI_GeoInfo newGeoInfo in newGeoInfosToCreate)
	    {
		geoNodesToKeep.Add(CreateGeoNode(session, newGeoInfo));
	    }

	    // Overwrite the old list with new
	    _geoNodes = geoNodesToKeep;

	    // Updating the trasform is done in GenerateGeometry
	}