private void SetTreePropsRecurse(IEnumerable <ModelItem> items, ComApi.InwOpState3 oState, object parentId, Dictionary <string, bool> toOverwrite) { foreach (ModelItem item in items) { string defProperName = item.DisplayName; if (String.IsNullOrEmpty(defProperName)) { defProperName = item.ClassDisplayName; } if (Utils.SetS1NF0PropsToItem(oState, item, new Dictionary <string, object>() { { ID_PROP_DISPLAY_NAME, Utils.S1NF0PropSpecialValue.RandomGUID }, { MATERIAL_ID_PROP_DISPLAY_NAME, "_" }, { PROPER_NAME_PROP_DISPLAY_NAME, defProperName }, }, toOverwrite)) { editedCount++; } DataProperty idProp = item.PropertyCategories .FindPropertyByDisplayName(S1NF0_DATA_TAB_DISPLAY_NAME, ID_PROP_DISPLAY_NAME);//Ссылка на id этого элемента для передачи детям SetTreePropsRecurse(item.Children, oState, Utils.GetUserPropValue(idProp.Value), toOverwrite); } }
private void SetIdsRecurse(IEnumerable <ModelItem> items, ComApi.InwOpState3 oState) { foreach (ModelItem item in items) { //SetIdToItem(oState, item); SetIdsRecurse(item.Children, oState); } }
public static ComApi.InwOaProperty CopyProp(ComApi.InwOpState3 oState, ComApi.InwOaProperty propToCopy) { object value = propToCopy.value; if (value != null) { return(Utils.CreateNewUserProp(oState, propToCopy.UserName, value)); } return(null); }
/// <summary> /// Копировать пользовательское свойство для создания /// </summary> /// <param name="oState"></param> /// <param name="propsColl"></param> /// <param name="propToCopy"></param> public static ComApi.InwOaProperty CopyProp(ComApi.InwOpState3 oState, DataProperty propToCopy) { object value = GetUserPropValue(propToCopy.Value); if (value != null) { return(Utils.CreateNewUserProp(oState, propToCopy.DisplayName, value)); } return(null); }
public static int Execute() { try { Document doc = Application.ActiveDocument; ComApi.InwOpState3 oState = ComApiBridge.ComApiBridge.State; DataTabToDeleteWindow dataTabToDeleteWindow = new DataTabToDeleteWindow(); bool?result = dataTabToDeleteWindow.ShowDialog(); if (result != null && result.Value && !String.IsNullOrWhiteSpace(dataTabToDeleteWindow.DataTabName)) { Search searchForDataTabs = new Search(); searchForDataTabs.Selection.SelectAll(); searchForDataTabs.PruneBelowMatch = false; SearchCondition hasDataTabCondition = SearchCondition//.HasCategoryByDisplayName(dataTabToDeleteWindow.DataTabName); .HasCategoryByCombinedName(new NamedConstant("LcOaPropOverrideCat", dataTabToDeleteWindow.DataTabName)); searchForDataTabs.SearchConditions.Add(hasDataTabCondition); ModelItemCollection hasDataTabs = searchForDataTabs.FindAll(doc, false); foreach (ModelItem item in hasDataTabs) { ComApi.InwOaPath oPath = ComApiBridge.ComApiBridge.ToInwOaPath(item); ComApi.InwGUIPropertyNode2 propn = (ComApi.InwGUIPropertyNode2)oState.GetGUIPropertyNode(oPath, true); int i = 1; foreach (ComApi.InwGUIAttribute2 attr in propn.GUIAttributes()) { if (!attr.UserDefined) { continue; } if (attr.ClassUserName.Equals(dataTabToDeleteWindow.DataTabName)) { propn.RemoveUserDefined(i); break; } i++; } } } } catch (Exception ex) { CommonException(ex, "Ошибка при удалении панели в Navis"); } return(0); }
/// <summary> /// Создать новое свойство /// </summary> /// <param name="oState"></param> /// <param name="name"></param> /// <param name="value"></param> /// <returns></returns> public static ComApi.InwOaProperty CreateNewUserProp(ComApi.InwOpState3 oState, string name, object value) { // create new property ComApi.InwOaProperty newP = (ComApi.InwOaProperty)oState .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwOaProperty, null, null); // set the name, username and value of the new property newP.name = Common.Transliteration.Front(name); newP.UserName = name; if (value == null || (value is string && String.IsNullOrWhiteSpace(value as string))) { value = "_"; } newP.value = ObjectToSetAsUserPropertyValue(value); return(newP); }
public override int Execute(params string[] parameters) { try { //Все элементы модели получают свойство Id и Id материала (пустое) ComApi.InwOpState3 oState = ComApiBridge.ComApiBridge.State; Document doc = Application.ActiveDocument; ModelItemEnumerableCollection rootItems = doc.Models.RootItems; idCount = 0; SetIdsRecurse(rootItems, oState); Win.MessageBox.Show("Всего привязано уникальных id - " + idCount, "Готово", Win.MessageBoxButton.OK, Win.MessageBoxImage.Information); } catch (Exception ex) { CommonException(ex, "Ошибка при раздаче идентификаторов в Navis"); } return(0); }
/// <summary> /// Раздать свойства родитель и правильное имя узла /// </summary> /// <param name="parameters"></param> /// <returns></returns> public override int Execute(params string[] parameters) { //Win.MessageBoxResult result = Win.MessageBox.Show("Начать раздачу служебных свойств S1NF0?", "Добавить служебные свойства", Win.MessageBoxButton.YesNo); SetS1NF0PropsDialog dialog = new SetS1NF0PropsDialog( new Dictionary <string, bool>() { { ID_PROP_DISPLAY_NAME, false }, { MATERIAL_ID_PROP_DISPLAY_NAME, false }, { PROPER_NAME_PROP_DISPLAY_NAME, false }, } ); bool?result = dialog.ShowDialog(); if (result.HasValue && result.Value /*result == Win.MessageBoxResult.Yes*/) { try { //Все элементы модели получают свойство Id и Id материала (пустое) ComApi.InwOpState3 oState = ComApiBridge.ComApiBridge.State; Document doc = Application.ActiveDocument; ModelItemEnumerableCollection rootItems = doc.Models.RootItems; editedCount = 0; var toOverwrite = dialog.ToOverwrite; SetTreePropsRecurse(rootItems, oState, "ROOT", toOverwrite); Win.MessageBox.Show("Всего объектов с добавленными свойствами - " + editedCount, "Готово", Win.MessageBoxButton.OK, Win.MessageBoxImage.Information); } catch (Exception ex) { CommonException(ex, "Ошибка при раздаче служебных свойств S1NF0 в Navis"); } } return(0); }
private void NameReplacementQueue(IEnumerable <ModelItem> items, Queue <FBX.NameReplacement> replacements, ComApi.InwOpState3 oState) { foreach (ModelItem item in items) { if (item.IsHidden) { //Элемент в FBX должен быть пропущен (это будет элемент с пустым именем) replacements.Enqueue(new FBX.NameReplacement()); continue;//Не заходить во вложенные узлы } string baseName, exportName, replacementName; bool baseNameTrustable; object id; CreateReplacementName(oState, item, out baseName, out exportName, out baseNameTrustable, out replacementName, out id, true); replacements.Enqueue(new FBX.NameReplacement(baseName, baseNameTrustable, replacementName)); NameReplacementQueue(item.Children, replacements, oState); } }
/// <summary> /// Добавить служебные свойства S1NF0 если их еще нет /// Не меняет свойства если они уже есть если не передан параметр overwrite = true /// В любом случае может переписать только те свойства, которые переданы в словаре propsToWrite /// Возвращает true если свойства объекта отредактированы /// </summary> /// <param name="oState"></param> /// <param name="item"></param> /// <param name="propsToWrite"></param> /// <param name="overwrite">перезаписывать свойства если они уже есть</param> /// <returns></returns> public static bool SetS1NF0PropsToItem (ComApi.InwOpState3 oState, ModelItem item, Dictionary <string, object> propsToWrite, Dictionary <string, bool> toOverwrite) { ComApi.InwOaPropertyVec propsToSet = oState.ObjectFactory(ComApi.nwEObjectType.eObjectType_nwOaPropertyVec); //convert the .NET collection to COM object ComApi.InwOaPath oPath = ComApiBridge.ComApiBridge.ToInwOaPath(item); //Получить текущие свойства элемента ComApi.InwGUIPropertyNode2 propertyNode = (ComApi.InwGUIPropertyNode2)oState.GetGUIPropertyNode(oPath, true); //Поиск панели Id int indexToSet = 0; int i = 1; foreach (ComApi.InwGUIAttribute2 attr in propertyNode.GUIAttributes()) { if (attr.UserDefined) { if (attr.ClassUserName.Equals(S1NF0_DATA_TAB_DISPLAY_NAME)) { indexToSet = i; foreach (ComApi.InwOaProperty prop in attr.Properties()) { if (propsToWrite.ContainsKey(prop.UserName)) { if (toOverwrite.ContainsKey(prop.UserName) && !toOverwrite[prop.UserName]) { propsToWrite.Remove(prop.UserName); } else { continue;//Перейти к следующему свойству } } propsToSet.Properties().Add(Utils.CopyProp(oState, prop)); } } else { i++; } } } if (propsToWrite.Count > 0) { foreach (KeyValuePair <string, object> kvp in propsToWrite) { string propName = kvp.Key; object value = kvp.Value; if (value is S1NF0PropSpecialValue) { if ((S1NF0PropSpecialValue)value == S1NF0PropSpecialValue.RandomGUID) { value = Guid.NewGuid().ToString(); } else { value = "_"; } } propsToSet.Properties().Add(CreateNewUserProp(oState, propName, value)); } propertyNode.SetUserDefined(indexToSet, S1NF0_DATA_TAB_DISPLAY_NAME, "S1NF0", propsToSet); return(true); } return(false); }
public override int Execute(params string[] parameters) { Win.MessageBoxResult result = Win.MessageBoxResult.Yes; if (ManualUse) { result = Win.MessageBox.Show("Перед экспортом FBX, нужно скрыть те элементы модели, которые не нужно экспортировать. " + "А так же нужно настроить параметры экспорта в FBX на экспорт ЛИБО В ФОРМАТЕ ASCII, ЛИБО В ДВОИЧНОМ ФОРМАТЕ ВЕРСИИ НЕ НОВЕЕ 2018. " + "Рекомендуется так же отключить экспорт источников света и камер. " + "\n\nНачать выгрузку FBX?", "Выгрузка FBX", Win.MessageBoxButton.YesNo); } if (result == Win.MessageBoxResult.Yes) { try { PluginRecord FBXPluginrecord = Application.Plugins. FindPlugin("NativeExportPluginAdaptor_LcFbxExporterPlugin_Export.Navisworks"); if (FBXPluginrecord != null) { if (!FBXPluginrecord.IsLoaded) { FBXPluginrecord.LoadPlugin(); } NativeExportPluginAdaptor FBXplugin = FBXPluginrecord.LoadedPlugin as NativeExportPluginAdaptor; Document doc = Application.ActiveDocument; string fbxPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); string docPath = doc.FileName; string defFBXFileName = ""; if (!String.IsNullOrEmpty(docPath)) { fbxPath = Path.GetDirectoryName(docPath); defFBXFileName = Path.GetFileNameWithoutExtension(docPath) + ".fbx"; } //Указание пользователем имени файла для fbx string fbxFullFileName = null; if (ManualUse) { WinForms.SaveFileDialog sFD = new WinForms.SaveFileDialog(); sFD.InitialDirectory = fbxPath; sFD.Filter = "fbx files (*.fbx)|*.fbx"; sFD.FilterIndex = 1; sFD.RestoreDirectory = true; if (!String.IsNullOrWhiteSpace(defFBXFileName)) { sFD.FileName = defFBXFileName; } sFD.Title = "Укажите файл для записи fbx"; if (sFD.ShowDialog() == WinForms.DialogResult.OK) { fbxFullFileName = sFD.FileName; } } else { fbxFullFileName = FBXSavePath; FileAttributes attr = File.GetAttributes(fbxFullFileName); if (attr.HasFlag(FileAttributes.Directory)) { //добавить имя файла fbxFullFileName = Path.Combine(fbxFullFileName, FBXFileName); } } if (!String.IsNullOrEmpty(fbxFullFileName)) { string notEditedDirectory = Path.Combine(Path.GetDirectoryName(fbxFullFileName), "NotEdited"); if (!Directory.Exists(notEditedDirectory)) { Directory.CreateDirectory(notEditedDirectory); } string notEditedFileName = Path.Combine(notEditedDirectory, Path.GetFileName(fbxFullFileName)); if (ManualUse) { BusyIndicatorHelper.ShowBusyIndicator(); BusyIndicatorHelper.SetMessage("Стандартный экспорт FBX"); } if (FBXplugin.Execute(notEditedFileName) == 0)//Выполнить экспорт в FBX { if (ManualUse) { BusyIndicatorHelper.SetMessage("Редактирование FBX"); } bool isASCII = IsASCIIFBXFile(notEditedFileName); if (isASCII || GetBinaryVersionNum(notEditedFileName) <= 7500) { //Прочитать модель, составить очередь имен для подстановки в FBX Queue <FBX.NameReplacement> replacements = new Queue <FBX.NameReplacement>(); DocumentModels docModels = doc.Models; ModelItemEnumerableCollection rootItems = docModels.RootItems; //if (rootItems.Count() > 1) //{ // //Если в Navis несколько корневых узлов (как в nwf), // //то один узел в самом начале FBX должен быть пропущен // //Там появится узел Environment // replacements.Enqueue(new FBX.NameReplacement()); //} ComApi.InwOpState3 oState = ComApiBridge.ComApiBridge.State; NameReplacementQueue(rootItems, replacements, oState); if (rootItems.Count() == 1) { //Обозначить, что первый узел имеет ненадежное имя. //В FBX оно всегда - Environment, а в Navis - имя открытого файла //replacements.Peek().OldNameTrustable = false; //Если корневой узел один, то убрать его из списка. Его не будет в FBX replacements.Dequeue(); } //Первый узел в списке замены должен обязательно иметь верное имя //(в начале списка могут быть с пустым значением, которые отключены в Navis) while (!replacements.Peek().OldNameTrustable) { replacements.Dequeue(); } //Отредактировать FBX FBX.ModelNamesEditor fbxEditor = null; if (IsASCIIFBXFile(notEditedFileName)) { fbxEditor = new FBX.ASCIIModelNamesEditor(notEditedFileName, replacements); } else /*if (GetBinaryVersionNum(sFD.FileName) <= 7500)*/ { fbxEditor = new FBX.BinaryModelNamesEditor(notEditedFileName, replacements); } fbxEditor.FbxFileNameEdited = fbxFullFileName; fbxEditor.EditModelNames(); if (ManualUse) { BusyIndicatorHelper.CloseBusyIndicator(); Win.MessageBox.Show("Файл FBX с отредактированными именами моделей - " + fbxEditor.FbxFileNameEdited, "Готово", Win.MessageBoxButton.OK, Win.MessageBoxImage.Information); } } else { throw new Exception("Неподдерживаемый формат FBX"); } } else { throw new Exception("При экспорте FBX из NavisWorks произошли ошибки"); } if (ManualUse) { //на всякий случай BusyIndicatorHelper.CloseBusyIndicator(); } } } } catch (Exception ex) { CommonException(ex, "Ошибка при экспорте в FBX из Navis"); } } return(0); }
public override int Execute(params string[] parameters) { try { //get state object of COM API ComApi.InwOpState3 oState = ComApiBridge.ComApiBridge.State; Document doc = Application.ActiveDocument; ModelItemCollection currSelectionColl = doc.CurrentSelection.SelectedItems; if (currSelectionColl.Count > 0) { //Получить список свойств из первого выбранного объекта из пользовательской панели если она есть ModelItem sample = currSelectionColl.First; Debug.Print("\n[Item Display Name]: " + sample.DisplayName + "\n"); foreach (PropertyCategory oPC in sample.PropertyCategories) { Debug.Print("\n[Display Name]: " + oPC.DisplayName + " [Internal Name]: " + oPC.Name + "\n"); Debug.Print("\tProperties\n"); foreach (DataProperty oDP in oPC.Properties) { Debug.Print("\t[Display Name]: " + oDP.DisplayName + "\t[Internal Name]:" + oDP.Name + "\t[Value]: " + oDP.Value.ToString()); //if (oDP.Value.IsNamedConstant) //{ // NamedConstant namedConstant = oDP.Value.ToNamedConstant(); // int v = namedConstant.Value; // string bn = namedConstant.BaseName; // string dn = namedConstant.DisplayName; // NamedConstant clone = new NamedConstant(v, bn, dn); // bool eq1 = namedConstant.Equals(clone); // VariantData vd1 = new VariantData(namedConstant); // VariantData vd2 = new VariantData(clone); // bool eq2 = vd1.Equals(vd2); //} } } SetPropsWindow setPropsWindow = ConfigureAndOppenSetPropsWindow(doc, currSelectionColl); bool? result = setPropsWindow.ShowDialog(); if (result != null && result.Value) { if (setPropsWindow.LogFormToXML) { List <string> ids = new List <string>(); foreach (ModelItem item in currSelectionColl) { DataProperty idProp = item.PropertyCategories .FindPropertyByDisplayName(S1NF0_DATA_TAB_DISPLAY_NAME, ID_PROP_DISPLAY_NAME); if (idProp != null) { ids.Add(Utils.GetDisplayValue(idProp.Value)); } } //После подтверждения объекты DisplayDataTab и DisplayURL сохраняются в объект ObjectData //Объект ObjectsData сразу же сериализуется. Открывается окно сохранения файла //Имя XML по умолчанию - дата и время до минут + имя пользователя + имя файла ObjectsData objectsData = new ObjectsData() { PreserveExistingProperties = setPropsWindow.PreserveExistingProperties, OverwriteLinks = setPropsWindow.OverwriteLinks, OverwriteUserAttr = setPropsWindow.OverwriteUserAttr, Ids = ids, DataTabs = setPropsWindow.OverwriteUserAttr ? setPropsWindow.DataTabs : null, URLs = setPropsWindow.OverwriteLinks ? setPropsWindow.URLs : null }; string initialPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); string initialFileName = Environment.UserName + "_" + DateTime.Now.ToString("yyyyMMddHHmmss"); string docFileName = doc.FileName; if (!String.IsNullOrEmpty(docFileName)) { initialPath = Path.GetDirectoryName(docFileName); initialFileName += "_" + Path.GetFileNameWithoutExtension(docFileName); } WinForms.SaveFileDialog saveFileDialog = new WinForms.SaveFileDialog(); saveFileDialog.InitialDirectory = initialPath; saveFileDialog.Filter = "xml files (*.xml)|*.xml"; saveFileDialog.FilterIndex = 1; saveFileDialog.RestoreDirectory = true; if (!String.IsNullOrWhiteSpace(initialFileName)) { saveFileDialog.FileName = initialFileName; } saveFileDialog.Title = "Укажите файл для записи свойств"; if (saveFileDialog.ShowDialog() == WinForms.DialogResult.OK) { XmlSerializer xmlSerializer = new XmlSerializer(typeof(ObjectsData)); using (StreamWriter sw = new StreamWriter(saveFileDialog.FileName)) { xmlSerializer.Serialize(sw, objectsData); } } } List <DisplayDataTab> displayDataTabs = setPropsWindow.DataTabs; List <DisplayURL> displayURLs = setPropsWindow.URLs; bool overwriteUserAttr = setPropsWindow.OverwriteUserAttr; bool overwriteLinks = setPropsWindow.OverwriteLinks; bool preserveExistingProperties = setPropsWindow.PreserveExistingProperties; SetPropsMethod(oState, currSelectionColl, displayDataTabs, displayURLs, overwriteUserAttr, overwriteLinks, preserveExistingProperties); } } } catch (Exception ex) { CommonException(ex, "Ошибка при заполнении атрибутов в Navis"); } return(0); }
public static void SetPropsMethod(ComApi.InwOpState3 oState, ModelItemCollection modelItemColl, List <DisplayDataTab> displayDataTabs, List <DisplayURL> displayURLs, bool overwriteUserAttr, bool overwriteLinks, bool preserveExistingProperties) { //Удалить пустые строки из наборов displayDataTabs.RemoveAll(ddt => String.IsNullOrEmpty(ddt.DisplayName)); foreach (DisplayDataTab ddt in displayDataTabs) { ddt.DisplayProperties.RemoveAll(dp => String.IsNullOrEmpty(dp.DisplayName)); } displayURLs.RemoveAll(dUrl => String.IsNullOrEmpty(dUrl.DisplayName) || String.IsNullOrEmpty(dUrl.URL)); //Если пользователь зачем-то ввел значение нередактируемого свойства, то убрать его DisplayDataTab idDataTab = displayDataTabs.Find(ddt => ddt.DisplayName.Equals(S1NF0_DATA_TAB_DISPLAY_NAME)); if (idDataTab != null) { idDataTab.DisplayProperties.RemoveAll(p => propsNotModifiable.Contains(p.DisplayName)); } //Конвертировать значения всех свойств foreach (DisplayDataTab ddt in displayDataTabs) { foreach (DisplayProperty dp in ddt.DisplayProperties) { dp.ConvertValue(); } } #region Старое /* * //Заполнить список свойств, которые нужно будет добавить на панель Id * ComApi.InwOaPropertyVec idDataTabPropertyVec = (ComApi.InwOaPropertyVec)oState * .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwOaPropertyVec, * null, null); * * //Заполнить список свойств для панели Id * //(в ней хранятся уникальные Id для каждого элемента, которые не должны меняться этой командой) * if (idDataTab != null) * { * foreach (DisplayProperty dp in idDataTab.DisplayProperties) * { * idDataTabPropertyVec.Properties() * .Add(Utils.CreateNewUserProp(oState, dp.DisplayName, dp.Value)); * } * } */ //Заполнены ли списки свойств? //Если список пустой, то панели должны быть удалена //bool userPropsDefined = displayDataTabs.Count > 0; //Создание набора для присоединения к объектам модели //List<DisplayDataTab> propsToSet = new List<DisplayDataTab>(); #endregion //Словарь свойств, которые добавляются Dictionary <string, DisplayProperty> propsDefined = new Dictionary <string, DisplayProperty>(); //Создать базовые наборы свойств, которые будут привязываться к объектам foreach (DisplayDataTab ddt in displayDataTabs) { //if (!ddt.DisplayName.Equals(S1NF0_DATA_TAB_DISPLAY_NAME)) //{ //ddt.InwOaPropertyVec = (ComApi.InwOaPropertyVec)oState // .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwOaPropertyVec, // null, null); //propsToSet.Add(ddt); foreach (DisplayProperty dp in ddt.DisplayProperties) { //ComApi.InwOaProperty newP // = Utils.CreateNewUserProp(oState, dp.DisplayName, dp.Value); //// add the new property to the new property category //ddt.InwOaPropertyVec.Properties().Add(newP); string key = ddt.DisplayName + dp.DisplayName; if (!propsDefined.ContainsKey(key)) { propsDefined.Add(key, dp); } } //} } //словарь ссылок, которые добавляются Dictionary <string, string> linksDefined = new Dictionary <string, string>(); //Создание набора ссылок для привязки к объектам //ComApi.InwOpState10 state = ComApiBridge.ComApiBridge.State; //ComApi.InwURLOverride urlOverride // = (ComApi.InwURLOverride)state // .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwURLOverride, null, null); //ComApi.InwURLColl oURLColl = urlOverride.URLs(); foreach (DisplayURL dUrl in displayURLs) { //ComApi.InwURL2 oUrl = (ComApi.InwURL2)state // .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwURL, null, null); //oUrl.name = dUrl.DisplayName; //oUrl.URL = dUrl.URL; //oUrl.SetCategory("Hyperlink", "LcOaURLCategoryHyperlink");//Тип - всегда гиперссылка //oURLColl.Add(oUrl); string key = dUrl.DisplayName; if (!linksDefined.ContainsKey(key)) { linksDefined.Add(key, dUrl.URL); } } foreach (ModelItem item in modelItemColl.DescendantsAndSelf) { //convert the .NET object to COM object ComApi.InwOaPath oPath = ComApiBridge.ComApiBridge.ToInwOaPath(item); //Переделать панель атрибутов в соответствии с заполненными строками в окне if (overwriteUserAttr)//Только если стояла галка в окне!!! { //наборы свойств //ключ - имя панели, значение - набор свойств для привязки к объекту Dictionary <string, ComApi.InwOaPropertyVec> propVectorsCurr = new Dictionary <string, ComApi.InwOaPropertyVec>(); // Сначала скопировать базовые наборы свойств для каждой из заданных панелей в словарь //foreach (DisplayDataTab ddt in displayDataTabs) //{ // propVectorsCurr.Add(ddt.DisplayName, ddt.InwOaPropertyVec.Copy()); //} //Изучаются текущие свойства объекта модели //Сначала в наборы свойств нужно добавить если присутствуют: //- свойства, которые не редактируются данной командой //- если нажата галка "Не удалять свойства", то любые свойства, которых не было в окне SetProps //- свойства которые были заданы в окне SetProps, но они уже присутствуют в модели // (их значение задается как введено в окне, // если эти свойства добавлены на этом этапе, то они не должны добавляться на следующем) HashSet <string> alreadyAdded = new HashSet <string>();//набор ключей свойств, которые добавлены на этом этапе ComApi.InwGUIPropertyNode2 propn = (ComApi.InwGUIPropertyNode2)oState.GetGUIPropertyNode(oPath, true); foreach (ComApi.InwGUIAttribute2 attr in propn.GUIAttributes()) { if (attr.UserDefined) { foreach (ComApi.InwOaProperty prop in attr.Properties()) { string key = attr.ClassUserName + prop.UserName; if ( (attr.ClassUserName.Equals(S1NF0_DATA_TAB_DISPLAY_NAME) && propsNotModifiable.Contains(prop.UserName)) //- свойства, которые не редактируются данной командой || (preserveExistingProperties && !propsDefined.ContainsKey(key)) //- если нажата галка Не удалять свойства, то любые свойства, которых не было в окне || propsDefined.ContainsKey(key) //- свойства которые были заданы в окне SetProps, но они уже присутствуют в модели ) { ComApi.InwOaPropertyVec vec = null; propVectorsCurr.TryGetValue(attr.ClassUserName, out vec); if (vec == null) { vec = (ComApi.InwOaPropertyVec)oState .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwOaPropertyVec, null, null); propVectorsCurr.Add(attr.ClassUserName, vec); } if (!propsDefined.ContainsKey(key)) { vec.Properties().Add(Utils.CopyProp(oState, prop)); } else { //Учесть введенное значение DisplayProperty dp = propsDefined[key]; vec.Properties().Add(Utils.CreateNewUserProp(oState, dp.DisplayName, dp.Value)); alreadyAdded.Add(key); } } } } } //Затем добавить вновь создаваемые свойства, которых ранее не было в модели //(с учетом тех, которые были добавлены на предыдущем этапе) foreach (DisplayDataTab ddt in displayDataTabs) { ComApi.InwOaPropertyVec vec = null; propVectorsCurr.TryGetValue(ddt.DisplayName, out vec); if (vec == null) { vec = (ComApi.InwOaPropertyVec)oState .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwOaPropertyVec, null, null); propVectorsCurr.Add(ddt.DisplayName, vec); } foreach (DisplayProperty dp in ddt.DisplayProperties) { string key = ddt.DisplayName + dp.DisplayName; if (!alreadyAdded.Contains(key)) { ComApi.InwOaProperty newP = Utils.CreateNewUserProp(oState, dp.DisplayName, dp.Value); // add the new property to the new property category vec.Properties().Add(newP); } } } //Удалить старые панели try { propn.RemoveUserDefined(0); } catch (System.Runtime.InteropServices.COMException) { } //Создать новые foreach (KeyValuePair <string, ComApi.InwOaPropertyVec> kvp in propVectorsCurr) { propn.SetUserDefined(0, kvp.Key, "S1NF0", kvp.Value); } #region Старое /* * // get properties collection of the path * ComApi.InwGUIPropertyNode2 propn * = (ComApi.InwGUIPropertyNode2)oState.GetGUIPropertyNode(oPath, true); * * * * ComApi.InwOaPropertyVec idDataTabPropertyVecCurr = idDataTabPropertyVec.Copy(); * * //Добавить нередактируемые свойства если они есть в исходном * foreach (string dn in propsNotModifiable) * { * DataProperty prop = item.PropertyCategories * .FindPropertyByDisplayName(S1NF0_DATA_TAB_DISPLAY_NAME, dn); * * if (prop != null) * { * ComApi.InwOaProperty copyProp = Utils.CopyProp(oState, prop); * idDataTabPropertyVecCurr.Properties().Add(copyProp); * } * } * * * //Удалить старые панели * try * { propn.RemoveUserDefined(0); } * catch (System.Runtime.InteropServices.COMException) { } * //Создать новые * if (userPropsDefined) * { * foreach (DisplayDataTab ddt in propsToSet) * { * //Создание одной панели * propn.SetUserDefined(0, ddt.DisplayName, "S1NF0", * ddt.InwOaPropertyVec); * } * * //Создание панели Id * if (idDataTabPropertyVecCurr.Properties().Count > 0) * { * propn.SetUserDefined(0, S1NF0_DATA_TAB_DISPLAY_NAME, "S1NF0", * idDataTabPropertyVecCurr); * } * * * } */ #endregion } //Переделать все ссылки в соответствии с заполненными строками в окне if (overwriteLinks)//Только если стояла галка в окне!!! { ComApi.InwURLOverride urlOverrideCurr = (ComApi.InwURLOverride)oState .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwURLOverride, null, null);//urlOverride.Copy(); //Изучаются текущие ссылки //Сначала в набор ссылок нужно добавить если присутствуют: //- если нажата галка "Не удалять свойства", то любые ссылки, которых не было в окне SetProps //- ссылки которые были заданы в окне SetProps, но они уже присутствуют в модели // (их значение задается как введено в окне, // если эти ссылки добавлены на этом этапе, то они не должны добавляться на следующем) HashSet <string> alreadyAdded = new HashSet <string>();//набор ключей ссылок, которые добавлены на этом этапе PropertyCategory linksCat = item.PropertyCategories.FindCategoryByName("LcOaExURLAttribute"); if (linksCat != null) { int linksCount = linksCat.Properties.Count / 3; for (int i = 0; i < linksCount; i++) { string suffix = i == 0 ? "" : i.ToString(); DataProperty nameProp = item.PropertyCategories .FindPropertyByName("LcOaExURLAttribute", "LcOaURLAttributeName" + suffix); DataProperty urlProp = item.PropertyCategories .FindPropertyByName("LcOaExURLAttribute", "LcOaURLAttributeURL" + suffix); if (nameProp != null && urlProp != null) { string key = nameProp.Value.ToDisplayString(); if ((preserveExistingProperties && !linksDefined.ContainsKey(key))//- если нажата галка "Не удалять свойства", то любые ссылки, которых не было в окне SetProps || (linksDefined.ContainsKey(key))) { ComApi.InwURL2 oUrl = (ComApi.InwURL2)oState .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwURL, null, null); oUrl.name = nameProp.Value.ToDisplayString(); if (!linksDefined.ContainsKey(key)) { oUrl.URL = urlProp.Value.ToDisplayString();//Сохранить существующее значение } else { oUrl.URL = linksDefined[key];//присвоить заданное в окне значение ссылки alreadyAdded.Add(key); } oUrl.SetCategory("Hyperlink", "LcOaURLCategoryHyperlink");//Тип - всегда гиперссылка urlOverrideCurr.URLs().Add(oUrl); } } } } foreach (DisplayURL dUrl in displayURLs) { string key = dUrl.DisplayName; if (!alreadyAdded.Contains(key)) { ComApi.InwURL2 oUrl = (ComApi.InwURL2)oState .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwURL, null, null); oUrl.name = dUrl.DisplayName; oUrl.URL = dUrl.URL; oUrl.SetCategory("Hyperlink", "LcOaURLCategoryHyperlink");//Тип - всегда гиперссылка urlOverrideCurr.URLs().Add(oUrl); } } ComApi.InwOpSelection comSelectionOut = ComApiBridge.ComApiBridge.ToInwOpSelection(new ModelItemCollection() { item }); oState.SetOverrideURL(comSelectionOut, urlOverrideCurr); } } }
public static int Execute(/*params string[] parameters*/) { ComApi.InwOpState3 oState = ComApiBridge.ComApiBridge.State; Document doc = Application.ActiveDocument; ModelItemCollection currSelectionColl = doc.CurrentSelection.SelectedItems; if (currSelectionColl.Count > 0) { foreach (ModelItem item in currSelectionColl.DescendantsAndSelf) { if (item.HasGeometry) { ComApi.InwOaPath oPath = ComApiBridge.ComApiBridge.ToInwOaPath(item); Transform3D tr = item.Transform;//TODO: учитывать уже добавленную трансформацию!!! //tr.Factor() Transform3DComponents transform3DComponents = tr.Factor(); //transform3DComponents.ScaleOrientation Point3D center = item.Geometry.BoundingBox.Center; double z = center.Z; double zTransformed = z * 1.1; double correctionTrans = (z - zTransformed) /*/ 2*/; ComApi.InwOpSelection comSelectionOut = ComApiBridge.ComApiBridge.ToInwOpSelection(new ModelItemCollection() { item }); ComApi.InwLTransform3f3 oTrans1 = (ComApi.InwLTransform3f3)oState .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwLTransform3f, null, null); //растяжение по Z ComApi.InwLVec3f scale = (ComApi.InwLVec3f)oState .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwLVec3f, null, null); scale.SetValue(1, 1, 1.1); //смещение по Z ComApi.InwLVec3f trans = (ComApi.InwLVec3f)oState .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwLVec3f, null, null); trans.SetValue(0, 0, correctionTrans); //ComApi.InwLRotation3f scaleOrientation // = (ComApi.InwLRotation3f)oState // .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwLRotation3f, null, null); //ComApi.InwLUnitVec3f axis // = (ComApi.InwLUnitVec3f)oState // .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwLUnitVec3f, null, null); //axis.SetValue(0, 0, 1); //scaleOrientation.SetValue(axis, 0); //ComApi.InwLRotation3f Rotation // = (ComApi.InwLRotation3f)oState // .ObjectFactory(ComApi.nwEObjectType.eObjectType_nwLRotation3f, null, null); //Rotation.SetValue(axis, 0); //oTrans1.factor(scale, scaleOrientation, Rotation, trans); //double[] matrix = ConvertDoubleArray((Array)((object)oTrans1.Matrix)); //oTrans1.MakeScale(scale); //double[] matrix1 = ConvertDoubleArray((Array)((object)oTrans1.Matrix)); //oTrans1.MakeTranslation(trans); //double[] matrix2 = ConvertDoubleArray((Array)((object)oTrans1.Matrix)); oTrans1.SetMatrix(new double[] { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1.1, 0, 0, 0, correctionTrans, 1 }); //oTrans1.MakeScale(scaleVec); oState.OverrideTransform(comSelectionOut, oTrans1); } } } return(0); }
/// <summary> /// Создает имя с id для экспорта в fbx /// /// </summary> /// <param name="oState"></param> /// <param name="item"></param> /// <param name="baseName"></param> /// <param name="baseNameTrustable"></param> /// <param name="replacementName"></param> /// <param name="id"></param> /// <param name="createIdIfNotExists">ЕСЛИ У ОБЪЕКТА НЕТ ID, ТО ОН БУДЕТ СОЗДАН</param> public static void CreateReplacementName(ComApi.InwOpState3 oState, ModelItem item, out string baseName, out string exportName, out bool baseNameTrustable, out string replacementName, out object id, bool createIdIfNotExists) { DataProperty idProp = item.PropertyCategories .FindPropertyByDisplayName(S1NF0_DATA_TAB_DISPLAY_NAME, ID_PROP_DISPLAY_NAME); DataProperty matIdProp = item.PropertyCategories .FindPropertyByDisplayName(S1NF0_DATA_TAB_DISPLAY_NAME, MATERIAL_ID_PROP_DISPLAY_NAME); exportName = null; DataProperty exportNameProp = item.PropertyCategories .FindPropertyByDisplayName(S1NF0_DATA_TAB_DISPLAY_NAME, PROPER_NAME_PROP_DISPLAY_NAME); if (exportNameProp != null) { exportName = Utils.GetDisplayValue(exportNameProp.Value); } if (idProp == null || matIdProp == null) { if (createIdIfNotExists) { //Запускать простановку id перед выгрузкой в fbx, чтобы не решать проблему, когда частично не проставлены id Utils.SetS1NF0PropsToItem(oState, item, new Dictionary <string, object>() { { ID_PROP_DISPLAY_NAME, Utils.S1NF0PropSpecialValue.RandomGUID }, { MATERIAL_ID_PROP_DISPLAY_NAME, "_" } }, new Dictionary <string, bool>());//ничего не переписывать idProp = item.PropertyCategories .FindPropertyByDisplayName(S1NF0_DATA_TAB_DISPLAY_NAME, ID_PROP_DISPLAY_NAME); matIdProp = item.PropertyCategories .FindPropertyByDisplayName(S1NF0_DATA_TAB_DISPLAY_NAME, MATERIAL_ID_PROP_DISPLAY_NAME); } } //Один элемент в FBX должен быть переименован //item.DisplayName возвращает путую строку в 2 случаях: //- Если свойства имя нет //- Если имя - пустая строка //string baseName = item.DisplayName; //Проверить есть ли у элемента свойство имя //Если это свойство есть и оно не пустое, то имя узла в FBX будет таким же //Если этого свойства нет, то в большинстве случаев имя узла в FBX совпадет с item.ClassDisplayName baseName = null; DataProperty nameProp = item.PropertyCategories.FindPropertyByName("LcOaNode", "LcOaSceneBaseUserName"); if (nameProp != null) { baseName = nameProp.Value.ToDisplayString(); } baseNameTrustable = true; if (baseName == null /*String.IsNullOrEmpty(baseName)*/) { baseName = item.ClassDisplayName; //Если item.DisplayName не возвращает значения, то нет гарантии, что //item.ClassDisplayName совпадет с именем в FBX if (notReliableClassDisplayNames.Contains(baseName)) { baseNameTrustable = false; } } else if (baseName.Equals("")) { //Если объект имеет имя и оно пустое, //то в FBX оно будет заменено (была замечена замена на LcOaExGroup) //но точно не известно на что будет замена в каких случаях baseNameTrustable = false; } if (idProp != null && matIdProp != null) { id = Utils.GetDisplayValue(idProp.Value); replacementName = (!String.IsNullOrWhiteSpace(exportName) ? exportName : baseName) + "|" + id + "|" + Utils.GetDisplayValue(matIdProp.Value); } else { id = null; replacementName = null; } return; }
public override int Execute(params string[] parameters) { try { Document doc = Application.ActiveDocument; //ModelItemCollection currSelectionColl = doc.CurrentSelection.SelectedItems; string initialPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); string initialFileName = Environment.UserName + "_" + DateTime.Now.ToString("yyyyMMddHHmmss"); string docFileName = doc.FileName; if (!String.IsNullOrEmpty(docFileName)) { initialPath = Path.GetDirectoryName(docFileName); initialFileName += "_" + Path.GetFileNameWithoutExtension(docFileName); } //if (currSelectionColl.Count > 0) //{ // //Если выбран какой-либо объект в дереве (или несколько), то открывается такое же окно как в команде SetProps // //(но при этом у каждого объекта обязательно должен быть настроенный id) // //Объекты DisplayDataTab, DisplayProperty, DisplayURL должны быть serializable // List<string> ids = new List<string>(); // List<ModelItem> itemsToSetProps = new List<ModelItem>(); // foreach (ModelItem item in currSelectionColl) // { // DataProperty idProp = item.PropertyCategories // .FindPropertyByDisplayName(S1NF0_DATA_TAB_DISPLAY_NAME, // ID_PROP_DISPLAY_NAME); // if (idProp != null) // { // ids.Add(Utils.GetDisplayValue(idProp.Value)); // itemsToSetProps.Add(item); // } // } // if (ids.Count == 0) // { // Win.MessageBox.Show("Ни у одного из выбранных элементов нет id"); // return 0; // } // //Инициализация окна SetProps // SetPropsWindow setPropsWindow = SetProps.ConfigureAndOppenSetPropsWindow(doc, itemsToSetProps); // setPropsWindow.Loaded += (a, b) => // { // setPropsWindow.PreserveExistingProperties = true; // }; // bool? result = setPropsWindow.ShowDialog(); // if (result != null && result.Value) // { // //После подтверждения объекты DisplayDataTab и DisplayURL сохраняются в объект ObjectData // //Объект ObjectsData сразу же сериализуется. Открывается окно сохранения файла // //Имя XML по умолчанию - дата и время до минут + имя пользователя + имя файла // ObjectsData objectsData = new ObjectsData() // { // PreserveExistingProperties = setPropsWindow.PreserveExistingProperties, // OverwriteLinks = setPropsWindow.OverwriteLinks, // OverwriteUserAttr = setPropsWindow.OverwriteUserAttr, // Ids = ids, // DataTabs = setPropsWindow.OverwriteUserAttr ? setPropsWindow.DataTabs : null, // URLs = setPropsWindow.OverwriteLinks ? setPropsWindow.URLs : null // }; // WinForms.SaveFileDialog saveFileDialog = new WinForms.SaveFileDialog(); // saveFileDialog.InitialDirectory = initialPath; // saveFileDialog.Filter = "xml files (*.xml)|*.xml"; // saveFileDialog.FilterIndex = 1; // saveFileDialog.RestoreDirectory = true; // if (!String.IsNullOrWhiteSpace(initialFileName)) // saveFileDialog.FileName = initialFileName; // saveFileDialog.Title = "Укажите файл для записи свойств"; // if (saveFileDialog.ShowDialog() == WinForms.DialogResult.OK) // { // XmlSerializer xmlSerializer = new XmlSerializer(typeof(ObjectsData)); // using (StreamWriter sw = new StreamWriter(saveFileDialog.FileName)) // { // xmlSerializer.Serialize(sw, objectsData); // } // } // //выбранные объекты скрываются, чтобы пользователь не выбирал их по второму разу // doc.Models.SetHidden(itemsToSetProps, true); // } //} //else //{ //get state object of COM API ComApi.InwOpState3 oState = ComApiBridge.ComApiBridge.State; //предлагается выбрать несколько готовых XML для создания свойств в текущей модели WinForms.OpenFileDialog ofd = new WinForms.OpenFileDialog(); ofd.InitialDirectory = initialPath; ofd.Filter = "xml files (*.xml)|*.xml"; ofd.FilterIndex = 1; ofd.RestoreDirectory = true; ofd.Multiselect = true; ofd.Title = "Выберите файлы с данными о свойствах "; if (ofd.ShowDialog() == WinForms.DialogResult.OK) { List <string> filenames = ofd.FileNames.ToList(); filenames.Sort(); foreach (string filename in filenames) { ObjectsData objectsData = null; try { //Десериализуются объекты ObjectData. using (StreamReader sr = new StreamReader(filename)) { string serializedData = sr.ReadToEnd(); XmlSerializer xmlSerializer = new XmlSerializer(typeof(ObjectsData)); StringReader stringReader = new StringReader(serializedData); objectsData = (ObjectsData)xmlSerializer.Deserialize(stringReader); } } catch { } if (objectsData != null) { //Для каждого объекта ищется соответствующий объект по Id ModelItemCollection itemsToSetProps = new ModelItemCollection(); foreach (string id in objectsData.Ids) { //Search API VariantData idVd = VariantData.FromDisplayString(id); SearchCondition searchForIDCondition = new SearchCondition(tabCN, idCN, SearchConditionOptions.None, SearchConditionComparison.Equal, idVd); Search searchForCertainID = new Search(); searchForCertainID.Selection.SelectAll(); searchForCertainID.PruneBelowMatch = false; searchForCertainID.SearchConditions.Add(searchForIDCondition); ModelItem itemIdMatch = searchForCertainID.FindFirst(doc, false); if (itemIdMatch != null) { itemsToSetProps.Add(itemIdMatch); } } bool preserveExistingProperties = objectsData.PreserveExistingProperties; bool overwriteUserAttr = objectsData.OverwriteUserAttr; bool overwriteLinks = objectsData.OverwriteLinks; List <DisplayDataTab> displayDataTabs = objectsData.DataTabs; List <DisplayURL> displayURLs = objectsData.URLs; //и для этого набора объектов запускается процедура создания свойств как в команде SetProps SetProps.SetPropsMethod(oState, itemsToSetProps, displayDataTabs, displayURLs, overwriteUserAttr, overwriteLinks, preserveExistingProperties); } } } //} } catch (Exception ex) { CommonException(ex, "Ошибка при заполнении атрибутов в Navis"); } return(0); }
public StructureDataStorage(Document doc, string stPath, string clPath, Structure structure, Classifier classifier, bool newStructureCreationBySelSets = false, List <string> propCategories = null) { this.doc = doc; this.stPath = stPath; this.clPath = clPath; this.oState = ComApiBridge.ComApiBridge.State; this.Structure = structure; this.Classifier = classifier; if (propCategories != null) { this.propCategories = propCategories; } //Все новые классы будут создаваться на 2 DetailLevel. 1 - папки, 2 - конечные элементы //(это относится только к вновь создаваемым объектам) //Значит должно быть 2 класса без свойств. 1 - для папок, второй для конечных элементов! //если уровней меньше, чем должно быть, то нужно добавить недостающие for (int i = classifier.DetailLevels.Count; i < DefDetailLevels.Length; i++) { classifier.DetailLevels.Add(DefDetailLevels[i]); } DefDetailLevels[0] = classifier.DetailLevels[0]; DefDetailLevels[1] = classifier.DetailLevels[1]; foreach (string lvlName in DefDetailLevels) { if (String.IsNullOrWhiteSpace(lvlName)) { throw new Exception("DetailLevel должен быть не пустой строкой"); } } //Построить словари для быстрого поиска классов foreach (Class c in classifier.NestedClasses) { SurveyClass(c); } //Всегда должны быть заданы все необходимые DefaultClass (сейчас их 2 - для папок и для конечных элементов) for (int i = 0; i < DefClassesWithNoProps.Length; i++) { if (DefClassesWithNoProps[i] == null) { DefClassesWithNoProps[i] = CreateNewClass(Classifier.DefaultClasses[i] /*DEFAULT_CLASS_NAME[i]*/, Classifier.DefaultClasses[i] /*DEFAULT_CLASS_NAME_IN_PLURAL[i]*/, i); } } #region Поиск всех объектов геометрии с id с помощью Search API. Нельзя настроить на поиск только не скрытых элементов /* * //Все объекты модели геометрии с id * Search searchForAllIDs = new Search(); * searchForAllIDs.Selection.SelectAll(); * //searchForIDs.PruneBelowMatch = false; * * ConfigureSearchForAllNotHiddenGeometryItemsWithIds(searchForAllIDs); * * //ModelItemCollection allModelItemCollection; * AllNotHiddenGeometryModelItems = searchForAllIDs.FindAll(doc, false); * * int n = AllNotHiddenGeometryModelItems.Count; * * * //Сформировать объект Search для поиска конкретного значения Id. МНОГОКРАТНЫЙ ПОИСК РАБОТАЕТ МЕДЛЕННО * //searchForCertainID = new Search(); * //searchForCertainID.Selection.CopyFrom(allModelItemCollection); * //searchForCertainIDCondition = new SearchCondition(tabCN, idCN, SearchConditionOptions.None, SearchConditionComparison.Equal, new VariantData()); * * //ПОЧЕМУ-ТО ОБХОД ОБЪЕКТОВ ПРОИСХОДИТ ОЧЕНЬ МЕДЛЕННО НА БОЛЬЩИХ МОДЕЛЯХ * //Поэтому у пользователя есть возможность скрыть часть модели, чтобы не загружать ее всю в словарь за один раз * allItemsLookup = new Dictionary<string, ModelItem>(); * foreach (ModelItem item in AllNotHiddenGeometryModelItems) * { * DataProperty idProp = item.PropertyCategories * .FindPropertyByDisplayName(S1NF0_DATA_TAB_DISPLAY_NAME, * ID_PROP_DISPLAY_NAME); * string key = Utils.GetDisplayValue(idProp.Value); * allItemsLookup[key] = item; * } */ #endregion //Обход всей модели через рекурсию НЕ БЫСТРЕЕ. Но можно искать только не скрытые элементы if (!newStructureCreationBySelSets)//если структура создается с нуля, то этот шаг не нужен! { AllItemsLookup = new Dictionary <string, ModelItem>(); RecurseSearchForAllNotHiddenGeometryItemsWithIds(doc.Models.RootItems, AllItemsLookup); //Обход всех объектов //Просмотреть все объекты, не имеющие вложенных. Какие из них уже присутствуют в документе? //Построить словарь для быстрого поиска объектов, уже добавленных в дерево List <XML.St.Object> nestedObjectsValid; List <XML.St.Object> geometryObjectsCurrDoc; List <XML.St.Object> geometryObjectsOtherDoc; List <XML.St.Object> displayObjects; List <XML.St.Object> resetObjects; SurveyNestedObjects(structure.NestedObjects, out nestedObjectsValid, out geometryObjectsCurrDoc, out geometryObjectsOtherDoc, out displayObjects, out resetObjects); structure.NestedObjects = nestedObjectsValid; //Если какие-то объекты уже присутствуют в дереве, то уточнить набор свойств и класс для них согласно модели Navis foreach (XML.St.Object o in AddedGeometryItemsLookUp.Values) { PropertyCategoryCollection categories = o.NavisItem.PropertyCategories; SetObjectProps(o, categories, 1, 1); } //Создать окно и заполнить TreeView. StructureWindow = new StructureWindow(this); } }
public override int Execute(params string[] parameters) { SetPropsByExcelWindow setPropsByExcelWindow = null; try { Document doc = Application.ActiveDocument; ModelItemCollection selection = doc.CurrentSelection.SelectedItems; if (selection.Count != 1) { Win.MessageBox.Show("Перед вызовом этой команды нужно выбрать 1 из элементов модели, " + "к которым должны быть привязаны данные из Excel", "Подсказка"); return(0); } ModelItem sampleItem = selection.First; string initialPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); string docFileName = doc.FileName; if (!String.IsNullOrEmpty(docFileName)) { initialPath = Path.GetDirectoryName(docFileName); } setPropsByExcelWindow = new SetPropsByExcelWindow(sampleItem, initialPath); bool?result = null; result = setPropsByExcelWindow.ShowDialog(); if (result != null && result.Value) { Common.Timer timer = new Common.Timer(); timer.Start(); PropertyCategory propertyCategory = setPropsByExcelWindow.SelectedPropertyCategory; /*NamedConstant*/ string keyCatName = propertyCategory.DisplayName; //.CombinedName;//.DisplayName; DataProperty dataProperty = setPropsByExcelWindow.SelectedDataProperty; /*NamedConstant*/ string keyPropName = dataProperty.DisplayName; //.CombinedName;// Excel._Worksheet worksheet = setPropsByExcelWindow.SelectedWorkSheet; Common.ExcelInterop.CellValue excelColumn = setPropsByExcelWindow.SelectedColumn; //Перенести все значения из столбца в словарь - не ускоряет работу //Dictionary<string, int> keyValues // = Common.ExcelInterop.Utils.GetColumnValues(worksheet, excelColumn.ColumnNum); Excel.Range columns = worksheet.Columns; Excel.Range keyColumn = columns[excelColumn.ColumnNum]; string tabName = setPropsByExcelWindow.TabName; bool ignoreNonVisible = setPropsByExcelWindow.IgnoreNonVisible; SortedDictionary <int, Common.ExcelInterop.CellValue> tableHeader = setPropsByExcelWindow.TabelHeader; Dictionary <string, int> columnHeaderLookup = new Dictionary <string, int>(); foreach (KeyValuePair <int, Common.ExcelInterop.CellValue> kvp in tableHeader) { string columnName = kvp.Value.DisplayString; try { columnHeaderLookup.Add(columnName, kvp.Key); } catch (ArgumentException) { Win.MessageBox.Show( "Строка с названиями столбцов содрежит одинаковые названия. Повторяется \"" + columnName + "\".", "Одинаковые названия столбцов"); return(0); } } //get state object of COM API ComApi.InwOpState3 oState = ComApiBridge.ComApiBridge.State; //Поиск всех объектов, у которых есть указанное свойство //http://adndevblog.typepad.com/aec/2012/05/navisworks-net-api-find-item.html Search search = new Search(); search.Selection.SelectAll(); search.PruneBelowMatch = true;//В наборе не будет вложенных элементов search.SearchConditions .Add(SearchCondition.HasPropertyByDisplayName/*.HasPropertyByCombinedName*/ (keyCatName, keyPropName)); ModelItemCollection items = search.FindAll(doc, false); matchCount = 0; SearchForExcelTableMatches(doc, items, ignoreNonVisible, keyColumn, //keyValues, keyCatName, keyPropName, oState, worksheet, tableHeader, tabName ); //System.Runtime.InteropServices.Marshal.ReleaseComObject(columns); //System.Runtime.InteropServices.Marshal.ReleaseComObject(keyColumn); Win.MessageBox.Show(timer.TimeOutput("Общее время") + "\nНайдено совпадений - " + matchCount, "Готово", Win.MessageBoxButton.OK, Win.MessageBoxImage.Information); } } catch (Exception ex) { CommonException(ex, "Ошибка при заполнении атрибутов в Navis из таблицы Excel"); } finally { //Закрыть Excel if (setPropsByExcelWindow != null) { setPropsByExcelWindow.CloseUsingExcel(); } } return(0); }
private void SearchForExcelTableMatches (Document doc, IEnumerable <ModelItem> items, bool ignoreNonVisible, Excel.Range keyColumn, //Dictionary<string, int> keyValues, /*NamedConstant*/ string keyCatName, /*NamedConstant*/ string keyPropName, ComApi.InwOpState3 oState, Excel._Worksheet worksheet, SortedDictionary <int, Common.ExcelInterop.CellValue> tableHeader, string tabName ) { foreach (ModelItem item in items) { if (ignoreNonVisible && item.IsHidden) { continue;//Пропустить скрытый элемент } DataProperty property = item.PropertyCategories.FindPropertyByDisplayName/*.FindPropertyByCombinedName*/ (keyCatName, keyPropName); //object searchValue = Utils.GetUserPropValue(property.Value); string searchValue = Utils.GetDisplayValue(property.Value); //Найти в выбранном столбце Excel ячейку с таким же значением Excel.Range row = keyColumn.Find(searchValue, LookIn: Excel.XlFindLookIn.xlValues, LookAt: Excel.XlLookAt.xlWhole, SearchOrder: Excel.XlSearchOrder.xlByColumns, MatchByte: false); //int rowNum = 0; //keyValues.TryGetValue(searchValue, out rowNum); if (/*rowNum != 0*/ row != null) { matchCount++; int rowNum = row.Row; //Получить данные из этой строки таблицы SortedDictionary <int, Common.ExcelInterop.CellValue> rowValues = Common.ExcelInterop.Utils.GetRowValues(worksheet, rowNum); //Привязать пользовательские атрибуты как в строке таблицы. Если такие атрибуты уже были созданы, то переписать их значение //Набор свойств для задания для этого элемента модели ComApi.InwOaPropertyVec propsToSet = oState.ObjectFactory(ComApi.nwEObjectType.eObjectType_nwOaPropertyVec); //Заполнить данными из строки Excel foreach (KeyValuePair <int, Common.ExcelInterop.CellValue> kvp in tableHeader) { int colIndex = kvp.Key; string propName = kvp.Value.DisplayString; Common.ExcelInterop.CellValue cellValue = null; rowValues.TryGetValue(colIndex, out cellValue); object propValue = null; if (cellValue != null) { propValue = Utils.ConvertValueByString(cellValue.DisplayString);//.Value2; } // create new property ComApi.InwOaProperty newP = Utils.CreateNewUserProp(oState, propName, propValue); // add the new property to the new property category propsToSet.Properties().Add(newP); } foreach (ModelItem dItem in item.DescendantsAndSelf) { //convert the .NET collection to COM object ComApi.InwOaPath oPath = ComApiBridge.ComApiBridge.ToInwOaPath(dItem); //Получить текущие свойства элемента ComApi.InwGUIPropertyNode2 propertyNode = (ComApi.InwGUIPropertyNode2)oState.GetGUIPropertyNode(oPath, true); //Проверить есть ли у элемента панель данных пользователя с точно таким же названием //Получить ее индекс int indexToSet = 0; int i = 1; foreach (ComApi.InwGUIAttribute2 attr in propertyNode.GUIAttributes()) { if (attr.UserDefined) { if (attr.ClassUserName.Equals(tabName)) { indexToSet = i; break; } else { i++; } } } //Перезаписать панель данными из Excel propertyNode.SetUserDefined( indexToSet, tabName, "S1NF0", propsToSet); } //System.Runtime.InteropServices.Marshal.ReleaseComObject(row); } else { //Если неправильно указать ключевое свойство и столбец, возникает зависание из-за многократного поиска Search во вложенных элементах //Search search = new Search(); //search.Selection.CopyFrom(item.Descendants); //search.PruneBelowMatch = true;//объекты без вложенных //search.SearchConditions // .Add(SearchCondition.HasPropertyByCombinedName(keyCatCombName, keyPropCombName)); //ModelItemCollection dItems = search.FindAll(doc, false); //IEnumerable<ModelItem> dItems // = item.Descendants.Where(SearchCondition.HasPropertyByCombinedName(keyCatCombName, keyPropCombName));//Не обрезает вложенные объекты //TODO: Это чревато огромными задержками на большой модели если неправильно задано ключевое поле!!! //Вместо Search API Линейный поиск по дереву до нахождения соответствия List <ModelItem> dItems = new List <ModelItem>(); SearchHasPropertyByCombinedName(item.Children, keyCatName, keyPropName, dItems); SearchForExcelTableMatches(doc, dItems, ignoreNonVisible, keyColumn, //keyValues, keyCatName, keyPropName, oState, worksheet, tableHeader, tabName ); } } }