Starting in December, we will archive content from the community that is 10 years and older. This FAQ provides more information.
Hi!
I've been working on an add-in that will let you pick tin surfaces from an open Civil 3D-model and then create toposurfaces of those in Revit. The problem I have is when I pick two tin surfaces at a time, Revit creates one toposurface of the first tin surface I picked and another toposurface conisting of both tin surfaces. My goal is to create two separate toposurfaces. I can't figure out where I've messed up, can someone help me? I'll attatch a screencast and my code.
public partial class Import_form : System.Windows.Forms.Form { public IAeccSurfaces surfs; public List<List<XYZ>> topos = new List<List<XYZ>>(); private Autodesk.AutoCAD.Interop.IAcadApplication m_oAcadApp = null; private Autodesk.AECC.Interop.UiLand.IAeccApplication m_oAeccApp = null; private Autodesk.AECC.Interop.UiLand.IAeccDocument m_oAeccDoc = null; private IAeccDocuments m_oAeccDocs = null; private Autodesk.AECC.Interop.Land.IAeccDatabase m_oAeccDb = null; string m_sAcadProdID = "AutoCAD.Application"; string m_sAeccAppProgId = "AeccXUiLand.AeccApplication.13.0"; double[] triangles; List<double> nummer = new List<double>(); public Import_form() { InitializeComponent(); m_oAcadApp = (IAcadApplication)Marshal.GetActiveObject(m_sAcadProdID); if (m_oAcadApp != null) { m_oAeccApp = (Autodesk.AECC.Interop.UiLand.IAeccApplication)m_oAcadApp.GetInterfaceObject(m_sAeccAppProgId); m_oAeccDoc = (Autodesk.AECC.Interop.UiLand.IAeccDocument)m_oAeccApp.ActiveDocument; m_oAeccDocs = (Autodesk.AECC.Interop.UiLand.IAeccDocuments)m_oAeccApp.Documents; m_oAeccDb = (Autodesk.AECC.Interop.Land.IAeccDatabase)m_oAeccApp.ActiveDocument.Database; comboBox1.Items.Add(m_oAeccDoc); comboBox1.SelectedIndex = 0; comboBox1.DisplayMember = "Name"; comboBox1.SelectedItem = m_oAeccDoc; surfs = m_oAeccDb.Surfaces; foreach (IAeccTinSurface surf in surfs) { checkedListBox1.Items.Add(surf); } ((ListBox)checkedListBox1).DisplayMember = "Name"; } } private void Import_form_Load(object sender, EventArgs e) { } private void button1_Click_1(object sender, EventArgs e) { /*int antal = tjo.Count(); MessageBox.Show(antal.ToString());*/ } public static List<List<double>> splitlist(List<double> nummer, int antal = 3) { var list = new List<List<double>>(); for (int i = 0; i < nummer.Count; i += antal) { list.Add(nummer.GetRange(i, Math.Min(antal, nummer.Count - i))); } return list; } private void checkedListBox1_Click(object sender, EventArgs e) { } private void button2_Click(object sender, EventArgs e) { foreach (IAeccTinSurface valdsurface in checkedListBox1.CheckedItems) { triangles = valdsurface.OutputTriangles; List<XYZ> punkter = new List<XYZ>(); List<XYZ> utpunkter = new List<XYZ>(); double x = 0, y = 0, z = 0; foreach (double d in triangles) { nummer.Add(d); } List<List<double>> uppdelning = splitlist(nummer, 3); foreach (List<double> uppdelat in uppdelning) { for (int k = 0; k < uppdelat.Count; ++k) { int j = 1; foreach (double d in uppdelat) { switch (j) { case 1: x = d; break; case 2: y = d; break; case 3: z = d; break; default: break; } j++; } punkter.Add(new XYZ(x, y, z)); } } topos.Add(punkter); } } }
public class Civil_import : IExternalCommand { public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; Autodesk.Revit.ApplicationServices.Application app = uiapp.Application; Autodesk.Revit.Creation.Application appcrea = uiapp.Application.Create; Autodesk.Revit.DB.Document doc = uiapp.ActiveUIDocument.Document; Autodesk.Revit.DB.View currentview = uiapp.ActiveUIDocument.ActiveView; List<List<XYZ>> lists_out = new List<List<XYZ>>(); Import_form f = new Import_form(); var result = f.ShowDialog(); if(result==DialogResult.OK) { using (Transaction t = new Transaction(doc)) { t.Start("ett"); foreach (List<XYZ> punkter in f.topos) { List<XYZ> ut = new List<XYZ>(); GetVertices(ut, punkter); lists_out.Add(ut); } foreach(List<XYZ> tops in lists_out) { TopographySurface.Create(doc, tops); } t.Commit(); } } if (result==DialogResult.Cancel) { return Result.Cancelled; } return Result.Succeeded; } const double _eps = 1.0e-9; public static bool IsZero(double a) { return _eps > Math.Abs(a); } public static bool IsEqual(double a, double b) { return IsZero(b - a); } public static int Compare(double a, double b) { return IsEqual(a, b) ? 0 : (a < b ? -1 : 1); } public static int Compare(XYZ p, XYZ q) { int diff = Compare(p.X, q.X); if (0 == diff) { diff = Compare(p.Y, q.Y); if (0 == diff) { diff = Compare(p.Z, q.Z); } } return diff; } static void GetVertices(List<XYZ> listut, List<XYZ> listin) { Dictionary<XYZ, int> a = new Dictionary<XYZ, int>( new XyzComparer()); foreach (XYZ p in listin) { if (!a.ContainsKey(p)) { a.Add(p, 1); } else { ++a[p]; } } List<XYZ> keys = new List<XYZ>(a.Keys); keys.Sort(Compare); foreach (XYZ p in keys) { listut.Add(p); } } } public class XyzComparer : IEqualityComparer<XYZ> { public bool Equals(XYZ p, XYZ q) { return p.IsAlmostEqualTo(q); } public int GetHashCode(XYZ p) { return p.ToString().GetHashCode(); } }
It sounds to me as if your selection process is adding things to a list, and you are not clearing the list after processing it.
Thanks for the quick reply!
I think I have an Idea where to look.
Btw, kudos to your blog, I've learned a lot!
Hi,
please note that there are two methods to create a TopographySurface (Revit 2020 API).
If you have edges that you want to preserve, you better use
TopographySurface Create( Document document, IList<XYZ> points, IList<PolymeshFacet> facets )
instead of
TopographySurface Create( Document document, IList<XYZ> points )
Revitalizer
Can't find what you're looking for? Ask the community or share your knowledge.