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; if (doc.IsFamilyDocument) { TaskDialog.Show("ОТМЕНЕНО", "Данная команда предназначена для запуска в документе проекта"); return(Result.Cancelled); } try { //Выбрать несколько файлов CSV с координатами Transform projectTransform = Utils.GetProjectCoordinatesTransform(doc); string[] filenames = null; WinForms.OpenFileDialog openFileDialog1 = new WinForms.OpenFileDialog(); string curDocPath = doc.PathName; if (!String.IsNullOrEmpty(curDocPath)) { openFileDialog1.InitialDirectory = Path.GetDirectoryName(curDocPath); } openFileDialog1.Filter = "csv files (*.csv)|*.csv"; openFileDialog1.FilterIndex = 1; openFileDialog1.RestoreDirectory = true; openFileDialog1.Multiselect = true; openFileDialog1.Title = "Выберите таблицы CSV с координатами 3d-полилиний"; if (openFileDialog1.ShowDialog() == WinForms.DialogResult.OK) { filenames = openFileDialog1.FileNames; List <List <XYZ> > lines3d = new List <List <XYZ> >(); if (Utils.ReadCoordinatesFromCSV(filenames, projectTransform, lines3d)) { //Загрузить семейство 3d линии если нет Family line3dFamily = Utils.GetFamily(doc, "3d line"); ElementId symId = line3dFamily.GetFamilySymbolIds().First(); FamilySymbol familySymbol = (FamilySymbol)doc.GetElement(symId); //Вывести форму для выбора семейств Categories categories = doc.Settings.Categories; ElementId IdGeneric = categories.get_Item(BuiltInCategory.OST_GenericModel).Id; SelectTypeWindow selectTypeWindow = new SelectTypeWindow(doc, IdGeneric); bool? result = selectTypeWindow.ShowDialog(); if (result != null && result.Value && selectTypeWindow.SelectedFamilySymbols.Count > 0) { familySymbol = selectTypeWindow.SelectedFamilySymbols.First(); } //Расставить линии по координатам using (Transaction tr = new Transaction(doc)) { tr.Start("Draw 3D line"); //активировать типоразмер if (!familySymbol.IsActive) { familySymbol.Activate(); doc.Regenerate(); } foreach (List <XYZ> ptList in lines3d) { for (int i = 0; i < ptList.Count - 1; i++) { FamilyInstance instance = AdaptiveComponentInstanceUtils.CreateAdaptiveComponentInstance(doc, familySymbol); IList <ElementId> placePointIds = AdaptiveComponentInstanceUtils.GetInstancePlacementPointElementRefIds(instance); ReferencePoint point1 = (ReferencePoint)doc.GetElement(placePointIds[0]); point1.Position = ptList[i]; ReferencePoint point2 = (ReferencePoint)doc.GetElement(placePointIds[1]); point2.Position = ptList[i + 1]; } } tr.Commit(); } } } } catch (Autodesk.Revit.Exceptions.OperationCanceledException) { } catch (Exception ex) { CommonException(ex, "Ошибка при вычерчивании 3d линии в Revit"); } return(Result.Succeeded); }
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; if (doc.IsFamilyDocument) { TaskDialog.Show("ОТМЕНЕНО", "Данная команда предназначена для запуска в документе проекта"); return(Result.Cancelled); } try { Transform projectTransform = Utils.GetProjectCoordinatesTransform(doc); string[] filenames = null; WinForms.OpenFileDialog openFileDialog1 = new WinForms.OpenFileDialog(); string curDocPath = doc.PathName; if (!String.IsNullOrEmpty(curDocPath)) { openFileDialog1.InitialDirectory = Path.GetDirectoryName(curDocPath); } openFileDialog1.Filter = "csv files (*.csv)|*.csv"; openFileDialog1.FilterIndex = 1; openFileDialog1.RestoreDirectory = true; openFileDialog1.Multiselect = true; openFileDialog1.Title = "Выберите таблицы CSV с координатами"; if (openFileDialog1.ShowDialog() == WinForms.DialogResult.OK) { filenames = openFileDialog1.FileNames; List <List <XYZ> > lines3d = new List <List <XYZ> >(); if (Utils.ReadCoordinatesFromCSV(filenames, projectTransform, lines3d) && lines3d.Count > 0 && lines3d.First().Count > 0) { Categories categories = doc.Settings.Categories; ElementId IdGeneric = categories.get_Item(BuiltInCategory.OST_GenericModel).Id; SelectTypeWindow selectTypeWindow = new SelectTypeWindow(doc, IdGeneric); bool?result = selectTypeWindow.ShowDialog(); if (result != null && result.Value && selectTypeWindow.SelectedFamilySymbols.Count > 0) { FamilySymbol familySymbol = selectTypeWindow.SelectedFamilySymbols.First(); //Document famDoc = doc.EditFamily(selectedSymbol.Family);//как проверить, что выбранный типоразмер - на основе плоскости??? using (Transaction tr = new Transaction(doc)) { tr.Start("PlaceGenericByCoord"); if (!familySymbol.IsActive) { familySymbol.Activate(); doc.Regenerate(); } foreach (List <XYZ> ptList in lines3d) { for (int i = 0; i < ptList.Count - 1; i++) { XYZ bubbleEnd = ptList[i]; XYZ thirdPnt = ptList[i + 1]; XYZ freeEnd = bubbleEnd + (thirdPnt - bubbleEnd).CrossProduct(XYZ.BasisZ).Normalize(); ReferencePlane refPlane = doc.Create.NewReferencePlane2(bubbleEnd, freeEnd, thirdPnt, doc.ActiveView); Reference reference = refPlane.GetReference(); FamilyInstance fi = doc.Create.NewFamilyInstance(reference, bubbleEnd, thirdPnt /*freeEnd*/, familySymbol); //НЕ РАБОТАЕТ НИКАК!!!!!!!!!! ОБЪЕКТЫ ВСЕГДА ПОВЕРНУТЫ КРИВО!!! //Line axis = Line.CreateBound(bubbleEnd, // bubbleEnd + (freeEnd - bubbleEnd).CrossProduct(thirdPnt - bubbleEnd).Normalize()); //double angle = (thirdPnt - bubbleEnd).AngleOnPlaneTo(XYZ.BasisY, XYZ.BasisZ); //ElementTransformUtils.RotateElement(doc, fi.Id, axis, angle /*- 25.78 * Math.PI / 180*/); } } tr.Commit(); } } } } } catch (Autodesk.Revit.Exceptions.OperationCanceledException) { } catch (Exception ex) { CommonException(ex, "Ошибка при расстановке объектов по координатам в Revit"); } return(Result.Succeeded); }
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; if (doc.IsFamilyDocument) { TaskDialog.Show("ОТМЕНЕНО", "Данная команда предназначена для запуска в документе проекта"); return(Result.Cancelled); } try { //Выбрать несколько файлов CSV с координатами Transform projectTransform = Utils.GetProjectCoordinatesTransform(doc); string[] filenames = null; WinForms.OpenFileDialog openFileDialog1 = new WinForms.OpenFileDialog(); string curDocPath = doc.PathName; if (!String.IsNullOrEmpty(curDocPath)) { openFileDialog1.InitialDirectory = Path.GetDirectoryName(curDocPath); } openFileDialog1.Filter = "csv files (*.csv)|*.csv"; openFileDialog1.FilterIndex = 1; openFileDialog1.RestoreDirectory = true; openFileDialog1.Multiselect = true; openFileDialog1.Title = "Выберите таблицы CSV с координатами 3d-полилиний"; if (openFileDialog1.ShowDialog() == WinForms.DialogResult.OK) { filenames = openFileDialog1.FileNames; List <List <XYZ> > lines3d = new List <List <XYZ> >(); if (Utils.ReadCoordinatesFromCSV(filenames, projectTransform, lines3d) && lines3d.Count > 0 && lines3d.First().Count > 0) { //Выбор семейства из числа загруженных семейств формы //Определить id категории Форма Categories categories = doc.Settings.Categories; ElementId IdForm = categories.get_Item(BuiltInCategory.OST_Mass).Id; SelectTypeWindow selectTypeWindow = new SelectTypeWindow(doc, IdForm); bool? result = selectTypeWindow.ShowDialog(); if (result != null && result.Value && selectTypeWindow.SelectedFamilySymbols.Count > 0) { FamilySymbol selectedSymbol = selectTypeWindow.SelectedFamilySymbols.First(); Document crossSectFamDoc = doc.EditFamily(selectedSymbol.Family); //Создать новое семейство формы string fileName = Path.Combine(Path.GetDirectoryName(App.AssemblyLocation), App.FamilyLibRelativePath + massTemplateName + ".rft"); Document massFamDoc = app.NewFamilyDocument(fileName); if (massFamDoc == null) { throw new Exception("Невозможно создать семейство формы"); } //Пересчет координат относительно координат первой точки List <List <XYZ> > lines3dInFam = new List <List <XYZ> >(); XYZ basePt = lines3d.First().First(); foreach (List <XYZ> ptList in lines3d) { List <XYZ> ptListInFam = new List <XYZ>(); lines3dInFam.Add(ptListInFam); foreach (XYZ pt in ptList) { XYZ convertedPt = pt - basePt; ptListInFam.Add(convertedPt); } } //Полный путь к сохраненному семейству string targetRfaFullPath = null; //Выбрать имя для семейства формы, так чтобы оно не пересекалось с уже загруженными семействами FilteredElementCollector a = new FilteredElementCollector(doc).OfClass(typeof(Family)); string famName = null; int n = 0; do { famName = "Massing" + n; n++; } while (a.Any(e => e.Name.Equals(famName))); { //Расставить формы по координатам внутри формы, считая за ноль первую точку первой линии //Вставить созданное семейство в проект //Загрузить семейство поперечного сечения Family family = crossSectFamDoc.LoadFamily(massFamDoc); using (Transaction tr = new Transaction(massFamDoc)) { RCreation.FamilyItemFactory crDoc = massFamDoc.FamilyCreate; tr.Start("Place cross sections"); //Найти выбранный типоразмер FamilySymbol familySymbol = null; foreach (ElementId id in family.GetFamilySymbolIds()) { FamilySymbol fs = (FamilySymbol)massFamDoc.GetElement(id); if (fs.Name.Equals(selectedSymbol.Name)) { familySymbol = fs; } } //активировать типоразмер Utils.ActivateFamSym(massFamDoc, familySymbol); //Вставить поперечник в каждую точку и повернуть по биссектриссе foreach (List <XYZ> ptList in lines3dInFam) { for (int i = 0; i < ptList.Count; i++) { XYZ pt = ptList[i]; FamilyInstance crossSection = crDoc.NewFamilyInstance(pt, familySymbol, StructuralType.NonStructural); XYZ prevVector = null; double prevHorAngle = 0; XYZ nextVector = null; double nextHorAngle = 0; if (i != 0) { XYZ prevPt = ptList[i - 1]; prevVector = pt - prevPt; prevHorAngle = XYZ.BasisY.AngleOnPlaneTo(prevVector, XYZ.BasisZ); } if (i != ptList.Count - 1) { XYZ nextPt = ptList[i + 1]; nextVector = nextPt - pt; nextHorAngle = XYZ.BasisY.AngleOnPlaneTo(nextVector, XYZ.BasisZ); } //Изначально поперечное сечение ориентировано по оси Y //Расчет угла поворота double horRotationAngle = 0; if (prevVector != null && nextVector != null) { horRotationAngle = (prevHorAngle + nextHorAngle) / 2; } else if (prevVector != null && nextVector == null) { horRotationAngle = prevHorAngle; } else if (prevVector == null && nextVector != null) { horRotationAngle = nextHorAngle; } Line vertAxis = Line.CreateBound(pt, pt + XYZ.BasisZ); ElementTransformUtils.RotateElement(massFamDoc, crossSection.Id, vertAxis, horRotationAngle); #region ЭЛЕМЕНТ НЕ МОЖЕТ БЫТЬ ПОВЕРНУТ В ЭТУ ПОЗИЦИЮ //? Определить угол поворота в плоскости, перпендикулярной сечению //XYZ normal = Transform.CreateRotation(XYZ.BasisZ, horRotationAngle).OfVector(XYZ.BasisX);//Нормаль плоскости //double vertRotationAngle = 0; //double prevVertAngle = 0; //double nextVertAngle = 0; //if (prevVector != null) //{ // prevVertAngle = XYZ.BasisY.AngleOnPlaneTo(prevVector, normal); //} //if (nextVector != null) //{ // nextVertAngle = XYZ.BasisY.AngleOnPlaneTo(nextVector, normal); //} //if (prevVector != null && nextVector != null) //{ // vertRotationAngle = (prevVertAngle + nextVertAngle) / 2; //} //else if (prevVector != null && nextVector == null) //{ // vertRotationAngle = prevVertAngle; //} //else if (prevVector == null && nextVector != null) //{ // vertRotationAngle = nextVertAngle; //} //Line horAxis = Line.CreateBound(pt, pt + normal); //ElementTransformUtils.RotateElement(massFamDoc, crossSection.Id, horAxis, vertRotationAngle); #endregion } } tr.Commit(); } string famSaveDir = doc.PathName; if (!String.IsNullOrEmpty(famSaveDir)) { famSaveDir = Path.GetDirectoryName(famSaveDir); } else { famSaveDir = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); } targetRfaFullPath = Common.Utils.GetNonExistentFileName(famSaveDir, famName, "rfa"); massFamDoc.SaveAs(targetRfaFullPath); } { //Загрузить семейство формы. Family family = massFamDoc.LoadFamily(doc); using (Transaction tr = new Transaction(doc)) { RCreation.Document crDoc = doc.Create; tr.Start("Place mass family"); FamilySymbol familySymbol = (FamilySymbol)doc.GetElement(family.GetFamilySymbolIds().First()); //активировать типоразмер Utils.ActivateFamSym(doc, familySymbol); //Вставить экземпляр семейства crDoc.NewFamilyInstance(basePt, familySymbol, StructuralType.NonStructural); tr.Commit(); } } //Удалить сохраненный файл семейства формы massFamDoc.Close(); if (!String.IsNullOrEmpty(targetRfaFullPath)) { File.Delete(targetRfaFullPath); } //TODO: Открыть загруженное в проект семейство. //Похоже можно открыть только сохраненное семейство по пути //uiapp.OpenAndActivateDocument() } } } } catch (Autodesk.Revit.Exceptions.OperationCanceledException) { } catch (Exception ex) { CommonException(ex, "Ошибка при расстановке поперечных сечений в Revit"); } return(Result.Succeeded); }