ADN Open CIS
Сообщество программистов Autodesk в СНГ

16/12/2014

Поворот на Пи

Вопрос: Я пытаюсь создать приложение, которое переведет модель из SolidWorks в Revit. Идея состоит в том, чтобы перерисовать модель SolidWorks в Revit.

Я столкнулся с очень странным поведением метода ElementTransformUtils.RotateElement, и мне интересно, сталкивались вы с этим или может у вас есть какие мысли по этому поводу. Я использую Revit 2012 и C#. Вот пример моего кода:

Код - C#: [Выделить]
  1.   Autodesk.Revit.Creation.Application creapp
  2.     = fdoc.Application.Create;
  3.  
  4.   XYZ normal = XYZ.BasisZ;
  5.  
  6.   SketchPlane sketchPlane
  7.     = CreateSketchPlane( normal, XYZ.Zero );
  8.  
  9.   XYZ p0 = XYZ.Zero;
  10.   XYZ p1 = new XYZ( 10, 0, 0 );
  11.   XYZ p2 = new XYZ( 10, 10, 0 );
  12.   XYZ p3 = new XYZ( 0, 10, 0 );
  13.   XYZ p4 = new XYZ( 10, 20, 0 );
  14.   Line line1 = creapp.NewLineBound( p0, p1 );
  15.   Line line2 = creapp.NewLineBound( p1, p2 );
  16.   Line line3 = creapp.NewLineBound( p2, p3 );
  17.   Line line4 = creapp.NewLineBound( p3, p0 );
  18.   Line line5 = creapp.NewLineBound( p2, p4 );
  19.   CurveArray curveArray1 = new CurveArray();
  20.   curveArray1.Append( line1 );
  21.   curveArray1.Append( line2 );
  22.   curveArray1.Append( line3 );
  23.   curveArray1.Append( line4 );
  24.   CurveArrArray curveArrArray = new CurveArrArray();
  25.   curveArrArray.Append( curveArray1 );
  26.  
  27.   Revolution aRevolution
  28.     = fdoc.FamilyCreate.NewRevolution( true,
  29.       curveArrArray, sketchPlane, line5,
  30.       Math.PI / -2, 0 );
  31.  
  32.   // Следующий код не работает!
  33.  
  34.   ElementTransformUtils.RotateElement(
  35.     fdoc, aRevolution.Id, line5, Math.PI );

Проблема в значении Math.PI, которое я использую в методе RotateElement. Я застрял в этом месте и такое чувство, что нельзя использовать значение, которое больше или равно значению числа π. В качестве решение я использую не само число π, а Math.PI * 0.995, что означает не совсем точный результат.

Буду рад любым советам.

Ответ: Вот такая  реализация, основанная на вашем коде и адаптированная к Revit 2015 работает без проблем:

Код - C#: [Выделить]
  1. [Transaction( TransactionMode.Manual )]
  2. public class Command : IExternalCommand
  3. {
  4.   public Result Execute(
  5.     ExternalCommandData commandData,
  6.     ref string message,
  7.     ElementSet elements )
  8.   {
  9.     UIApplication uiapp = commandData.Application;
  10.     UIDocument uidoc = uiapp.ActiveUIDocument;
  11.     Application app = uiapp.Application;
  12.     Document doc = uidoc.Document;
  13.  
  14.     XYZ p0 = XYZ.Zero;
  15.     XYZ p1 = new XYZ( 10, 0, 0 );
  16.     XYZ p2 = new XYZ( 10, 10, 0 );
  17.     XYZ p3 = new XYZ( 0, 10, 0 );
  18.     XYZ p4 = new XYZ( 10, 20, 0 );
  19.     Line line1 = Line.CreateBound( p0, p1 );
  20.     Line line2 = Line.CreateBound( p1, p2 );
  21.     Line line3 = Line.CreateBound( p2, p3 );
  22.     Line line4 = Line.CreateBound( p3, p0 );
  23.     Line line5 = Line.CreateBound( p2, p4 );
  24.     CurveArray curveArray1 = new CurveArray();
  25.     curveArray1.Append( line1 );
  26.     curveArray1.Append( line2 );
  27.     curveArray1.Append( line3 );
  28.     curveArray1.Append( line4 );
  29.     CurveArrArray curveArrArray = new CurveArrArray();
  30.     curveArrArray.Append( curveArray1 );
  31.  
  32.     using( Transaction tx = new Transaction( doc ) )
  33.     {
  34.       tx.Start( "Поворот" );
  35.  
  36.       //XYZ normal = XYZ.BasisZ;
  37.       //Plane plane = new Plane( normal, XYZ.Zero );
  38.       //SketchPlane sketchPlane = SketchPlane.Create( doc, plane );
  39.  
  40.       SketchPlane sketchPlane
  41.         = new FilteredElementCollector( doc )
  42.           .OfClass( typeof( SketchPlane ) )
  43.           .Cast<SketchPlane>()
  44.           .Where<SketchPlane>( x
  45.             => x.Name.Equals( "Ref. Level" ) )
  46.           .FirstOrDefault<SketchPlane>();
  47.  
  48.       Revolution aRevolution
  49.         = doc.FamilyCreate.NewRevolution(
  50.           true, curveArrArray, sketchPlane,
  51.           line5, Math.PI / -2, 0 );
  52.  
  53.       doc.Regenerate();
  54.  
  55.       ElementTransformUtils.RotateElement(
  56.         doc, aRevolution.Id, line5, Math.PI ); // Работает без проблем!
  57.  
  58.       tx.Commit();
  59.     }
  60.     return Result.Succeeded;
  61.   }
  62. }

Есть несколько отличий между 2012 и 2015 версией.

Я также поменял создание рабочей поверхности используя FilteredElementCollector.

Наиболее значительное изменение: я вызвал регенерацию документа перед тем как вызвать метод RotateElement.

Обратите внимание, что в качестве аргумента передается ElementId. Это знак того, что элемент должен существовать в базе данных Revit, которые появляется там только после регенерации.

Источник: http://thebuildingcoder.typepad.com/blog/2014/11/rotation-by-and-newsweptblend-using-arcs.html#2

Обсуждение: http://adn-cis.org/forum/index.php?topic=1708

Опубликовано 16.12.2014
Отредактировано 16.12.2014 в 10:55:50