Минимальный размер DirectShape
В Revit 2015 API появилась возможность импортировать геометрию элементов напрямую в проект. В API, класс DirectShape представляет собой геометрическую фигуру.
У одного из пользователей возник вопрос, касающийся использования данного класса
Вопрос: Я создаю фигуры (DirectShape) в Revit 2015 API из имеющегося набора поверхностей при помощи класса TessellatedShapeBuilder.
Проблема в том, что минимально допустимая длина грани, с которой Revit может работать равна 0,0026 фута. Если я пытаюсь использовать грань длиной 0,0025 фута, то Revit падает с ошибкой.
Можно ли изменить этот минимальный допуск?
Или может быть есть какой-то другой способ создания фигуры, где можно задать меньшую длину грани?
Ответ: К сожалению, нет. Никак.
Допуск изменить нельзя, и другого способа создания фигуры не существует.
При создании линии модели существует ограничение в 1/16 дюйма, подобное же ограничение распространяется и на фигуры.
Для тестирования я реализовал небольшую тестовую команду для проверки.
В команде определена статическая переменная Iterate_until_crash.
По умолчанию она равна false. В этом случае просто создается тетраэдр с длиной грани равным 0.5 фута:
 
Соответствующее сообщение выводится в окно Output:
- Создание DirectShape тетраэдр с длиной грани 0.5...
 
Если установить Iterate_until_crash равным true, то в бесконечном цикле будут попытки создания тетраэдра с длиной грани равной половине предыдущей длины.
Довольно быстро возникнет исключение, тем не менее, какие-то фигуры будут созданы и в окне Output мы увидим следующее:
- Создание DirectShape тетраэдр с длиной грани 0.5...
 - Создание DirectShape тетраэдр с длиной грани 0.25...
 - Создание DirectShape тетраэдр с длиной грани 0.125...
 - Создание DirectShape тетраэдр с длиной грани 0.0625...
 - Создание DirectShape тетраэдр с длиной грани 0.03125...
 - Создание DirectShape тетраэдр с длиной грани 0.015625...
 - Создание DirectShape тетраэдр с длиной грани 0. 0078125...
 - Создание DirectShape тетраэдр с длиной грани 0.00390625...
 - Создание DirectShape тетраэдр с длиной грани 0. 001953125...
 
- A first chance exception of type 'Autodesk.Revit.Exceptions.InvalidOperationException' occurred in RevitAPI.dll
 - Создание DirectShape тетраэдр с длиной грани 0.001953125 вызвало исключение 'could not create consistent vertex list'
 
Вот полный код команды:
- #region Namespaces
 - using System;
 - using System.Linq;
 - using System.Collections.Generic;
 - using System.Diagnostics;
 - using Autodesk.Revit.ApplicationServices;
 - using Autodesk.Revit.Attributes;
 - using Autodesk.Revit.DB;
 - using Autodesk.Revit.UI;
 - using Autodesk.Revit.UI.Selection;
 - #endregion
 - namespace DirectShapeMinSize
 - {
 - [Transaction( TransactionMode.Manual )]
 - public class Command : IExternalCommand
 - {
 - /// <summary>
 - /// Установите значение равным true
 - /// чтобы создавать меньшие тетраэдры
 - /// пока не возникнет исключение
 - /// </summary>
 - static bool Iterate_until_crash = false;
 - public Result Execute(
 - ExternalCommandData commandData,
 - ref string message,
 - ElementSet elements )
 - {
 - UIApplication uiapp = commandData.Application;
 - UIDocument uidoc = uiapp.ActiveUIDocument;
 - Application app = uiapp.Application;
 - Document doc = uidoc.Document;
 - FilteredElementCollector collector
 - = new FilteredElementCollector( doc )
 - .OfClass( typeof( GraphicsStyle ) );
 - GraphicsStyle style = collector.Cast<GraphicsStyle>()
 - .FirstOrDefault<GraphicsStyle>( gs => gs.Name.Equals( "<Sketch>" ) );
 - ElementId graphicsStyleId = null;
 - if( style != null )
 - {
 - graphicsStyleId = style.Id;
 - }
 - // не забываем создать транзакцию при изменении документа
 - using( Transaction tx = new Transaction( doc ) )
 - {
 - tx.Start( "Создание фигуры" );
 - double length = 1; // foot
 - try
 - {
 - do
 - {
 - length = 0.5 * length;
 - Debug.Print(
 - "Создание DirectShape тетраэдр с длиной грани {0}...",
 - length );
 - List<XYZ> args = new List<XYZ>( 3 );
 - TessellatedShapeBuilder builder = new TessellatedShapeBuilder();
 - builder.OpenConnectedFaceSet( false );
 - args.Add( XYZ.Zero );
 - args.Add( length * XYZ.BasisX );
 - args.Add( length * XYZ.BasisY );
 - builder.AddFace( new TessellatedFace( args, ElementId.InvalidElementId ) );
 - args.Clear();
 - args.Add( XYZ.Zero );
 - args.Add( length * XYZ.BasisX );
 - args.Add( length * XYZ.BasisZ );
 - builder.AddFace( new TessellatedFace( args, ElementId.InvalidElementId ) );
 - args.Clear();
 - args.Add( XYZ.Zero );
 - args.Add( length * XYZ.BasisY );
 - args.Add( length * XYZ.BasisZ );
 - builder.AddFace( new TessellatedFace( args, ElementId.InvalidElementId ) );
 - args.Clear();
 - args.Add( length * XYZ.BasisX );
 - args.Add( length * XYZ.BasisY );
 - args.Add( length * XYZ.BasisZ );
 - builder.AddFace( new TessellatedFace( args, ElementId.InvalidElementId ) );
 - builder.CloseConnectedFaceSet();
 - TessellatedShapeBuilderResult result
 - = builder.Build(
 - TessellatedShapeBuilderTarget.Solid,
 - TessellatedShapeBuilderFallback.Abort,
 - graphicsStyleId );
 - ElementId categoryId = new ElementId(
 - BuiltInCategory.OST_GenericModel );
 - DirectShape ds = DirectShape.CreateElement(
 - doc, categoryId, "A", "B" );
 - ds.SetShape( result.GetGeometricalObjects() );
 - ds.Name = "Тест";
 - }
 - while( Iterate_until_crash && 0 < length );
 - }
 - catch( Exception e )
 - {
 - Debug.Print(
 - " Создание DirectShape тетраэдр с длиной грани {0} "
 - + "вызвало исключение '{1}'",
 - length, e.Message );
 - message = e.Message;
 - return Result.Failed;
 - }
 - tx.Commit();
 - }
 - return Result.Succeeded;
 - }
 - }
 - }
 
Полный код для Visual Studio можно скачать по ссылке DirectShapeMinSize.zip
Источник: http://thebuildingcoder.typepad.com/blog/2014/05/directshape-performance-and-minimum-size.html
Обсуждение: http://adn-cis.org/forum/index.php?topic=799
Опубликовано 12.06.2014