/// <summary>
        /// Читает свойство FBX со специальным типом данных после прочтения кода типа данных
        ///
        /// Если свойство строковое, то
        /// Читает строку в UTF-8 по переданной длине в байтах.
        /// Если строка содержит заголовок Model, то
        /// Если имя модели не пустое
        /// (самая первая модель называется Environment и соответстует корневому узлу в navis),
        /// то редактирует согласно очереди.
        ///
        /// Записывает изменение длины строки в байтах
        /// Если заголовка Model нет или свойство не строковое или это узел без имени, то переписывает без изменений
        /// </summary>
        /// <param name="br"></param>
        /// <param name="bytesCount"></param>
        /// <param name="addToEnd"></param>
        /// <returns></returns>
        private void ReadFBXPropWithSpecialDataTypeEditModelName
            (BinaryReader br, BinaryWriter bw, bool isString, OffsetCounter offsetCounter)
        {
            int len = br.ReadInt32();

            if (isString)
            {
                byte[] value   = br.ReadBytes(len);//Строка в UTF-8
                string str     = System.Text.Encoding.UTF8.GetString(value);
                bool   changes = false;

                if (replacements.Count > 0 && str.EndsWith("\0\u0001Model") /*&& str.Length > 7*/)
                {
                    //Это свойство с именем модели
                    string modelName = str.Replace("\0\u0001Model", "");

                    //Последовательность узлов моделей, которые подлежат переименованию
                    //начинается только после узла, у которого имя совпадает
                    if (!renamingModelsStarted)
                    {
                        NameReplacement firstElem  = replacements.Peek();
                        NameReplacement secondElem = replacements.Count > 1 ?
                                                     replacements.ElementAt(1)
                                : null;
                        if (
                            //modelName.Equals("Environment")//УЗЕЛ Environment ЕСТЬ НЕ ВСЕГДА!!! В каких случаях его нет пока не понятно.
                            firstElem.OldName.Equals(modelName)
                            )
                        {
                            renamingModelsStarted = true;
                        }
                        else if (secondElem != null && secondElem.OldNameTrustable && secondElem.OldName.Equals(modelName))
                        {
                            // На всякий случай проверяем второй элемент в очереди (возможно 1-й вообще не появится в FBX?)
                            renamingModelsStarted = true;
                            replacements.Dequeue();//Удаляем узел, который должен был соответствовать Environment
                        }
                    }
                    if (renamingModelsStarted)
                    {
                        bool editAllowed = true;
                        #region hardcode
                        //hardcode//hardcode//hardcode//hardcode//hardcode//hardcode
                        //Замечено, что иногда при экспорте один узел Navis
                        //разбивается на несколько вложенных в FBX (они назывались "curve " и номер)
                        //if (strVal.StartsWith("curve "))
                        //{
                        //    editAllowed = false;
                        //}
                        //else
                        //{
                        //    curveSequenceStarted = false;
                        //}
                        //hardcode//hardcode//hardcode//hardcode//hardcode//hardcode
                        #endregion
                        //Более гибко - добавить сопоставление имен там, где оно надежно
                        //Это защищает от большинства узлов, которых не было в Navis, но они появились в FBX
                        NameReplacement currReplacement = replacements.Peek();
                        if (currReplacement.OldNameTrustable)
                        {
                            if (!modelName.Equals(currReplacement.OldName))
                            {
                                editAllowed = false;
                            }
                        }
                        if (editAllowed)//Не вытаскивать больше из очереди если идет последовательность несопоставляемых узлов
                        {
                            currReplacement = replacements.Dequeue();

                            if (!currReplacement.SkipNode)
                            {
                                changes = true;
                                //Строка редактируется, длина строки меняется
                                string strEdited = currReplacement.NewName + "\0\u0001Model";
                                byte[] newValue  = Encoding.UTF8.GetBytes(strEdited);
                                int    newLen    = newValue.Length;
                                int    lenDiff   = newLen - len;
                                offsetCounter.Incr(lenDiff);
                                bw.Write(newLen);
                                bw.Write(newValue);
                            }
                        }
                    }
                }

                if (!changes)
                {
                    //Ничего не меняется
                    bw.Write(len);
                    bw.Write(value);
                }
            }
            else
            {
                //Ничего не меняется
                bw.Write(len);
                ReadWriteBytes(br, bw, len);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Читает строки из текстового FBX
        /// Если строка содержит не пустое имя модели
        /// </summary>
        /// <param name="sw"></param>
        /// <param name="sr"></param>
        /// <returns></returns>
        private string ReplaceNextObjFBXLine(StreamWriter sw, StreamReader sr)
        {
            //Найти внутри узла Objects следующий подузел Model
            //До тех пор пока не найден, нужно записывать каждую строку в новый файл без изменений
            string fbxLine = null;

            while (replacements.Count > 0 && (fbxLine = sr.ReadLine()) != null)
            {
                bool changes = false;
                if (regex.IsMatch(fbxLine))
                {
                    //Найдена строка с именем объекта
                    string toReplace = regex2.Match(fbxLine).Value;
                    //string modelName = fbxLine.Split(' ')[2];//Пробелы могут быть в самом имени
                    int    len       = toReplace.Length > 10 ? toReplace.Length - 10 : 0;
                    string modelName = toReplace.Substring(8, len);

                    //Последовательность узлов моделей, которые подлежат переименованию
                    //начинается только после узла, у которого имя совпадает
                    if (!renamingModelsStarted)
                    {
                        NameReplacement firstElem  = replacements.Peek();
                        NameReplacement secondElem = replacements.ElementAt(1);
                        if (
                            //modelName.Equals("Environment")//УЗЕЛ Environment ЕСТЬ НЕ ВСЕГДА!!! В каких случаях его нет пока не понятно.
                            firstElem.OldName.Equals(modelName)
                            )
                        {
                            renamingModelsStarted = true;
                        }
                        else if (secondElem.OldNameTrustable && secondElem.OldName.Equals(modelName))
                        {
                            // На всякий случай проверяем второй элемент в очереди (возможно 1-й вообще не появится в FBX?)
                            renamingModelsStarted = true;
                            replacements.Dequeue();//Удаляем узел, который должен был соответствовать Environment
                        }
                    }
                    if (renamingModelsStarted)
                    {
                        bool            editAllowed     = true;
                        NameReplacement currReplacement = replacements.Peek();
                        if (currReplacement.OldNameTrustable)
                        {
                            if (!modelName.Equals(currReplacement.OldName))
                            {
                                editAllowed = false;
                            }
                        }

                        if (editAllowed)
                        {
                            currReplacement = replacements.Dequeue();
                            if (!currReplacement.SkipNode)
                            {
                                changes = true;
                                //Строка редактируется
                                string replacement
                                    = "\"Model::" + currReplacement.NewName + "\",";
                                string fbxLineEdited
                                    = fbxLine.Replace(toReplace, replacement);
                                sw.WriteLine(fbxLineEdited);
                            }
                        }
                    }
                }


                if (!changes)
                {
                    sw.WriteLine(fbxLine);
                }

                return(fbxLine);
            }
            return(null);
        }