/// <summary>
        /// Loads a blendshape from character card and sets it to the correct mesh
        /// </summary>
        /// <param name="data">The characters card data for this plugin</param>
        internal void LoadBlendShapes(PregnancyPlusData data)
        {
            if (data.meshBlendShape == null)
            {
                return;
            }
            if (PregnancyPlusPlugin.DebugLog.Value)
            {
                PregnancyPlusPlugin.Logger.LogInfo($" MeshBlendShape size > {data.meshBlendShape.Length/1024}KB ");
            }

            meshWithBlendShapes = new List <SkinnedMeshRenderer>();

            //Unserialize the blendshape from characters card
            var meshBlendShapes = MessagePack.LZ4MessagePackSerializer.Deserialize <List <MeshBlendShape> >(data.meshBlendShape);

            if (meshBlendShapes == null || meshBlendShapes.Count <= 0)
            {
                return;
            }

            //For each stores meshBlendShape
            foreach (var meshBlendShape in meshBlendShapes)
            {
                //Loop through all meshes and find matching name
                var clothRenderers = PregnancyPlusHelper.GetMeshRenderers(ChaControl.objClothes, true);
                LoopMeshAndAddExistingBlendShape(clothRenderers, meshBlendShape, true);

                //do the same for body meshs
                var bodyRenderers = PregnancyPlusHelper.GetMeshRenderers(ChaControl.objBody, true);
                LoopMeshAndAddExistingBlendShape(bodyRenderers, meshBlendShape);
            }
        }
        /// <summary>
        /// On user button click. Create blendshape from current belly state.  Add it to infConfig so it will be saved to char card if the user chooses save scene
        /// </summary>
        /// <param name="temporary">If Temporary, the blendshape will not be saved to char card</param>
        /// <returns>boolean true if any blendshapes were created</returns>
        internal bool OnCreateBlendShapeSelected(bool temporary = false)
        {
            if (PregnancyPlusPlugin.DebugLog.Value)
            {
                PregnancyPlusPlugin.Logger.LogInfo($" ");
            }
            if (PregnancyPlusPlugin.DebugLog.Value)
            {
                PregnancyPlusPlugin.Logger.LogInfo($" OnCreateBlendShapeSelected ");
            }

            var meshBlendShapes = new List <MeshBlendShape>();

            meshWithBlendShapes = new List <SkinnedMeshRenderer>();

            //Get all cloth renderes and attempt to create blendshapes from preset inflatedVerticies
            var clothRenderers = PregnancyPlusHelper.GetMeshRenderers(ChaControl.objClothes);

            meshBlendShapes = LoopAndCreateBlendShape(clothRenderers, meshBlendShapes, true);

            //do the same for body meshs
            var bodyRenderers = PregnancyPlusHelper.GetMeshRenderers(ChaControl.objBody);

            meshBlendShapes = LoopAndCreateBlendShape(bodyRenderers, meshBlendShapes);

            //Save any meshBlendShapes to card
            if (!temporary)
            {
                AddBlendShapesToData(meshBlendShapes);
            }

            //Reset belly size to 0 so the blendshape can be used with out interference
            PregnancyPlusGui.ResetSlider(PregnancyPlusGui.inflationSize, 0);

            //Append the smrs that have new blendspahes to the GUI to be seen
            blendShapeGui.OnSkinnedMeshRendererBlendShapesCreated(meshWithBlendShapes);

            return(meshBlendShapes.Count > 0);
        }
        /// <summary>
        /// Triggers belly mesh inflation for the current ChaControl for any active meshs (not hidden clothes)
        /// It will check the inflationSize dictionary for a valid value (last set via config slider or MeshInflate(value))
        /// If size 0 is used it will clear all active mesh inflations
        /// This will not run twice for the same parameters, a change of config value is required
        /// </summary>
        /// <param name="checkForNewMesh">Lets you force bypass the check for values changed to check for new meshes</param>
        /// <param name="freshStart">Will recalculate verts like a first time run</param>
        /// <param name="pluginConfigSliderChanged">Will treat as if some slider values changed, which they did in global plugin config</param>
        /// <returns>Will return True if the mesh was altered and False if not</returns>
        public bool MeshInflate(bool checkForNewMesh = false, bool freshStart = false, bool pluginConfigSliderChanged = false)
        {
            if (ChaControl.objBodyBone == null)
            {
                return(false);                               //Make sure chatacter objs exists first
            }
            if (!PregnancyPlusPlugin.AllowMale.Value && ChaControl.sex == 0)
            {
                return(false);                                                            // Only female characters, unless plugin config says otherwise
            }
            var sliderHaveChanged = NeedsMeshUpdate(pluginConfigSliderChanged);

            //Only continue if one of the config values changed
            if (!sliderHaveChanged)
            {
                //Only stop here, if no recalculation needed
                if (!freshStart && !checkForNewMesh)
                {
                    return(false);
                }
            }
            ResetInflation();

            if (!AllowedToInflate())
            {
                return(false);                    //if outside studio/maker, make sure StoryMode is enabled first
            }
            if (!infConfig.GameplayEnabled)
            {
                return(false);                           //Only if gameplay enabled
            }
            //Resets all stored vert values, so the script will have to recalculate all from base body
            if (freshStart)
            {
                CleanSlate();
            }

            //Only continue when size above 0
            if (infConfig.inflationSize <= 0)
            {
                infConfigHistory.inflationSize = 0;
                return(false);
            }

            if (PregnancyPlusPlugin.DebugLog.Value)
            {
                PregnancyPlusPlugin.Logger.LogInfo($" ---------- ");
            }
            if (PregnancyPlusPlugin.DebugLog.Value)
            {
                PregnancyPlusPlugin.Logger.LogInfo($" inflationSize > {infConfig.inflationSize} for {charaFileName} ");
            }

            //Get the measurements that determine the base belly size
            var hasMeasuerments = MeasureWaistAndSphere(ChaControl);

            if (!hasMeasuerments)
            {
                PregnancyPlusPlugin.errorCodeCtrl.LogErrorCode(ChaControl.chaID, ErrorCode.PregPlus_BadMeasurement,
                                                               $"Could not get belly measurements from character");
                return(false);
            }

            var anyMeshChanges = false;

            //Get and apply all clothes render mesh changes
            var clothRenderers = PregnancyPlusHelper.GetMeshRenderers(ChaControl.objClothes);

            anyMeshChanges = LoopAndApplyMeshChanges(clothRenderers, sliderHaveChanged, anyMeshChanges, true);

            //do the same for body meshs
            var bodyRenderers = PregnancyPlusHelper.GetMeshRenderers(ChaControl.objBody, true);

            anyMeshChanges = LoopAndApplyMeshChanges(bodyRenderers, sliderHaveChanged, anyMeshChanges);

            //If any changes were applied, updated the last used shape for the Restore GUI button
            if (infConfig.HasAnyValue())
            {
                PregnancyPlusPlugin.lastBellyState = (PregnancyPlusData)infConfig.Clone();//CLone so we don't accidently overwright the lastState later
            }

            //Update config history when mesh changes were made
            if (anyMeshChanges)
            {
                infConfigHistory = (PregnancyPlusData)infConfig.Clone();
            }

            return(anyMeshChanges);
        }