Доброго времени суток!
Предлагаю в данной теме вести обсуждение Revit API. Сейчас готовлю статью для новичков, не только в АПИ Revit, но и впрограммировании тоже. Думаю со временем наберется русскоязычный материал для этой темы и обсуждений будет много... Некоторый материал и мои нароботки присутствуют на моем блоге.
Для начала дам общую информацию по дополнениям. Как они регистрируются в Revit.
Для регистрации дополнения используется файл манифест который находится в папке:
Естественно если у вас Windows установлен на другом диске, то ищете папку там. Файл манифест имеет разширение *.addin.
Вот код, написанный в одном из моих файлов:
Это сделано для того чтобы избежать повторения стандартной нуммерации Ревит. Можно название Альбома делать невидимыми символами. Формула составления номера листа ревит Альбом.Номер листа. Можно попробовать вместе найти компромис. Еще как вариант создать марку с произвольным текстом. Чисто как обозначение и все
Артур, в начале темы Вы говорили, что пишите статью для чайников. Готова ли она?
С помощью какого метода создать линию детализации? В справке к SDK не нашёл 2012-я версия)
Что означает надпись "Overloaded" в описании некоторых методов?
Доброго времени суток! Да, статья есть (точнее перевод статьи ))), но в данный момент ждем пока ее разместит Autodesk. Как только это случится я сразу же сообщу на своем блоге и продублирую здесь.
По поводу надписи Overloaded. Она означает что метод перегружен. То есть у него есть несколько вариантов вызова. Например:
Один и тот же метод GetElement в качестве данных может принимать как ElementId так и Reference. То есть у него два варианта написания. Или в классе DialogBox метод Show вообще имеет не только разные типы атрибутов но и разное их количество! Но задача у этих методов одинаковая.
Надеюсь объяснил понятно )))
С уважением, Артур.
Статью жду с нетерпением, очень мало информации на русском языке.
По поводу Overloaded пока ещё не до конца разобрался, наверное с практикой придёт понимание.
С линией детализации разобрался, оказалось всё просто )
Описание тут: http://blog.rodhowarth.com/2011/02/revit-api-how-to-draw-detail-line-on.html
Сделал линию детализации, но работает только в планах. На разрезах не хочет работать, вываливается с ошибкой.
using System;
using System.Collections.Generic;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Structure;
using Autodesk.Revit.UI;
namespace
Draw_Line
{
[Autodesk.Revit.Attributes.Transaction(Autodesk.Revit.Attributes.TransactionMode.Automatic)]
[Autodesk.Revit.Attributes.Regeneration(Autodesk.Revit.Attributes.RegenerationOption.Manual)]
publicclassDraw_Line: IExternalCommand
{
Application app;
Document doc;
public Result Execute(ExternalCommandData commandData, refstringmessage, ElementSet elements)
{
UIApplication rvtUIApp = commandData.Application;
UIDocument uiDoc = rvtUIApp.ActiveUIDocument;
app = rvtUIApp.Application;
doc = uiDoc.Document;
Draw_Annotation_Line();
returnResult.Succeeded;
}
publicvoidDraw_Annotation_Line()
{
doublex1 = 5.0;
doubley1 = 5.0;
doublez = 0.0;
doublex2 = 117.0;
doubley2 = 115.0;
XYZ point1 = app.Create.NewXYZ(x1, y1, z);
XYZ point2 = app.Create.NewXYZ(x2, y2, z);
Line line = app.Create.NewLineBound(point1, point2);
DetailCurve detailCurve = doc.Create.NewDetailCurve(doc.ActiveView, line);stringa = doc.ActiveView.Category.Name;
TaskDialog.Show("Done", "Line Created");
}
}
}
Все опорные точки в АПИ рисуются в 3Д пространстве. В связи с этим на разрезах используется координата z в зависимости от плоскости разреза x или y.
Получилось разместить линию аннотации в плоскостях фасадов/разрезов с помощью задания координат точек, полученных из
doc.ActiveView.RightDirection и doc.ActiveView.UpDirection
Добрый день!
Пробую программировать на visual studio 2010 c# для Revit 2011. Возникла сложность объединения элементов в линейный массив для их последующего копирования (аналог функции ревита). Для начала решил объединить в массив.
Код:
public Autodesk.Revit.UI.Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { try { var uidoc = commandData.Application.ActiveUIDocument; var sel = doc.Selection.Elements; ElementArray e = sel as Element; ElementArray elementList = new ElementArray(); elementList.Append(e); return Result.Succeeded; } catch (Exception ex) { return Result.Failed; } }
Выдает следующие ошибки:
sel as Element - Cannot implicitly convert type 'Autodesk.Revit.DB.Element' to 'Autodesk.Revit.DB.ElementArray'
Cannot convert type 'Autodesk.Revit.UI.Selection.SelElementSet' to 'Autodesk.Revit.DB.Element' via
a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null
type conversion
elementList.Append(e) - The best overloaded method match for
'Autodesk.Revit.DB.ElementArray.Append(Autodesk.Revit.DB.Element)' has some invalid
arguments
Argument '1': cannot convert from 'Autodesk.Revit.DB.ElementArray' to
'Autodesk.Revit.DB.Element'
Помогите разобраться.
Приветствую!
Все очень просто. Вы пытаетесь преобразовать массив элементов SelElementSet в объект одного элемента Element. Естественно это не возможно. То есть переменная sel уже сама по себе является массивом элементов. Если вам нужно получить один элемент то нужно его забрать из массива сначала, даже если он в нем единсвенный.
На скорую руку пока так. Если нужно разжевать то позднее все распишу.
kart1984, спасибо за подсказку, вроде понял как выбрать элемент из массива.
var sel = commandData.Application.ActiveUIDocument.Selection.Elements; string info = "Selected elements:\n"; //Поиск выбранного элемента foreach (Element elem in sel) { //Создаем сообщение с информацией об объекте info += elem.Name + "\n"; } TaskDialog.Show("Revit",info);
Даже попробовал добавить элемент в ElementArray:
ElementArray elementList = new ElementArray();
elementList.Append(elem);
Теперь вот размышляю над тем как его скопировать. Может кто подскажет?
Не пойму почему колонна не перемещается. Ее местоположение определяется, проверял.
И не выдается сообщение TaskDialog.Show("Revit", "OK");. В чем может быть причина?
var sel = commandData.Application.ActiveUIDocument.Selection.Elements; foreach (Autodesk.Revit.DB.FamilyInstance column in sel) { LocationPoint columnPoint = column.Location as LocationPoint; if (null != columnPoint) { //Положение выделенного элемента //String prompt = "The selected column location information:"; //prompt += "\nPoint: (" + columnPoint.Point.X + ", " + columnPoint.Point.Y + ", " + columnPoint.Point.Z + ")"; //TaskDialog.Show("Revit", prompt); XYZ newLocation = new XYZ(10, 20, 0); columnPoint.Point = newLocation; TaskDialog.Show("Revit", "OK"); } }
Для перемещения перепробовал следующий код
1) double tagOffset = 20;
columnPoint.Point = new XYZ(columnPoint.Point.X + tagOffset, columnPoint.Point.Y, columnPoint.Point.Z);
2) XYZ newLocation = new XYZ(10, 20, 0);
columnPoint.Point = newLocation;
3) Autodesk.Revit.DB.Document document;
XYZ newLocation = new XYZ(10, 20, 0);
document.Move(column, newLocation);
Ошибок не выдают, но и не работают...
Могу предположить что изменения вне транзакции сделаны. Так же можно попробовать поменять свойство location которое у колонны возвращает LocationPoint. (сори - выше не прочитал). Еще очень советую в конце всех действий вызывать метод Regenerate документа, чтоб все изменения прошли процесс проверки на взаимодейсвия между собой.
Ну метода ElementTransformUtils.CopyElements в 2011 точно нет. Только что в справке посмотрел.
Вне транзакции - это как? И как вызвать Regenerate? Можно на примере показать?
Когда начинаю набирать, выдает:
RegenerationAttribute и RegenerationOption
Извиняюсь. Забыл что вы разрабатываете под 2011 версию. Чесно говоря под 2011 под рукой сейчас справки нет. В 2011 помоему все транзакции делались автоматом. Регенирация вызывалась в экземпляре класса Document.
Имеете ввиду вот это?
namespace RevitAddin { [Transaction(TransactionMode.Manual)] [Regeneration(RegenerationOption.Manual)] public class Command : IExternalCommand { public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements) { try { //КОД return Result.Succeeded; } catch (Exception ex) { return Result.Failed; } } } }
Есть продвижения)))) Поменял оба manual на automatic и все заработало!!!!!! Объясните для чего тогда manual нужен???
Да - только еще нужно создать экземпляр класса транзакции
Transaction tr = new Transaction(doc); tr.Name = "Копирование"; tr.Start(); // Действия //...... doc.Regenerate(); tr.Commit();
Хотя в справке написано что регенерация делается автоматически после завершения транзакции я всеравно его вызываю - бывали случаи ))))
Не нашли то, что искали? Задайте вопросы в сообществе или поделитесь своими знаниями.