Метод CopyElements и параметр View
Параметр View при использовании метода CopyElements, нужно использовать только в случае, если вы работает с элементами, зависимыми от конкретного вида, т.е. 2D элементами.
Это отметил Arnošt Löbel на форуме по Revit API в теме ElementTransformUtils.CopyElements из связанного документа.
Вопрос: Я пытаюсь скопировать и вставить связанные элементы в текущий документ.
Эти действия я легко могу проделать вручную в Revit: выделить связанный элемент, нажать Ctrl+C и, затем Ctrl+V.
Но я полагаю есть какой-то подвох при использование API и вот этот код не работает:
- ElementTransformUtils.CopyElements( view3DInLink,
- ids, view3DInHost, null, new CopyPasteOptions() )
Выскакивает ошибка: Заданный вид не может быть использован ни в качестве источника ни в качестве назначения при копировании элементов (The specified view cannot be used as a source or destination for copying elements between two views.). Я так полагаю, это потому что вид из связанного документа.
Оно работает, если вы просто хотите скопировать семейства из связанного документа (без вставки экземпляров семейства), например, вот так:
- ElementTransformUtils.CopyElements( linkedDoc, ids,
- thisDoc, null, new CopyPasteOptions() );
Может есть какой-то другой способ копирования и вставки элементов из связанного файла? Или должен работать и этот?
Если нет, то видимо Create.NewFamilyInstance это единственный способ решения задачи.
Ответ: На сколько мне известно, метод должен работать.
Возможно стоит сделать эти действия в несколько шагов. Например, сначала скопировать некоторые вспомогательные элементы, такие как стили, затем сами экземпляры семейств.
Скорее всего из документации не очень очевидно, что метод Copy, который принимает View в качестве параметра, работает только с видо-зависимыми элементами. А судя по всему вы копируете как раз такие из 3D вида, которые не могут содержать видо-зависимые объекты, а значит и не могут быть применены в этой реализации метода. Собственно, поэтому вы и видите ошибку.
Решить проблему просто. Используйте реализацию метода Copy, которая принимает в качестве параметров два документа, а не виды. Это должно сработать.
Ответ: Спасибо за ответ.
Я наконец то понял, в чем моя ошибка. Где-то я прочитал, что нужно передать идентификаторы типоразмеров FamilySymbolIds. Я это и делал. Т.е. я передавал типоразмеры, а не экземпляры семейств.
В конце концов, я передал идентификаторы элементов, которые являются экземплярами семейств и все заработало.
Для интересующихся, вот код:
- using System;
- using System.Collections.Generic;
- using System.Collections;
- using System.Collections.ObjectModel;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows;
- using Autodesk.Revit.DB;
- using Autodesk.Revit.UI;
- using Autodesk.Revit.ApplicationServices;
- using Autodesk.Revit.Attributes;
- namespace TransferFamilys
- {
- [TransactionAttribute(TransactionMode.Manual)]
- public class CopyPasteFamilys : IExternalCommand
- {
- public class CopyUseDestination
- : IDuplicateTypeNamesHandler
- {
- public DuplicateTypeAction
- OnDuplicateTypeNamesFound(
- DuplicateTypeNamesHandlerArgs args )
- {
- return DuplicateTypeAction.UseDestinationTypes;
- }
- }
- public Result Execute(
- ExternalCommandData commandData,
- ref string message,
- ElementSet elements )
- {
- Document hostDoc = commandData.Application
- .ActiveUIDocument.Document;
- // Получаем ссылки
- FilteredElementCollector links
- = new FilteredElementCollector( hostDoc )
- .OfClass( typeof( RevitLinkInstance ) );
- Document linkedDoc = links.Cast<RevitLinkInstance>()
- .FirstOrDefault().GetLinkDocument();
- // находим семейство в связанном файле.
- FilteredElementCollector linkedFamCollector
- = new FilteredElementCollector( linkedDoc );
- ICollection<ElementId> ids = linkedFamCollector
- .OfClass( typeof( FamilyInstance ) )
- .OfCategory( BuiltInCategory.OST_GenericModel )
- .ToElementIds();
- if( ids.Count == 0 )
- {
- TaskDialog.Show( "Copy Paste",
- "В связанном файле не содержатся элементы данной категории" );
- }
- else
- {
- using( Transaction targetTrans
- = new Transaction( hostDoc ) )
- {
- CopyPasteOptions copyOptions
- = new CopyPasteOptions();
- copyOptions.SetDuplicateTypeNamesHandler(
- new CopyUseDestination() );
- targetTrans.Start(
- "Копирование и вставка элементов" );
- ElementTransformUtils.CopyElements(
- linkedDoc, ids, hostDoc, null,
- copyOptions );
- //hostDoc.Regenerate();
- targetTrans.Commit();
- }
- }
- return Result.Succeeded;
- }
- }
- }
Обсуждение: http://adn-cis.org/forum/index.php?topic=2715
Опубликовано 18.05.2015