/// <summary> /// Create line element /// </summary> /// <param name="app">revit application</param> /// <param name="ptA">start point</param> /// <param name="ptB">end point</param> /// <returns></returns> public static ModelCurve MakeLine(UIApplication app, Autodesk.Revit.DB.XYZ ptA, Autodesk.Revit.DB.XYZ ptB) { Document doc = app.ActiveUIDocument.Document; // Create plane by the points Line line = Line.CreateBound(ptA, ptB); Autodesk.Revit.DB.XYZ norm = ptA.CrossProduct(ptB); if (norm.GetLength() == 0) { norm = Autodesk.Revit.DB.XYZ.BasisZ; } Plane plane = app.Application.Create.NewPlane(norm, ptB); SketchPlane skplane = SketchPlane.Create(doc, plane); // Create line here ModelCurve modelcurve = doc.FamilyCreate.NewModelCurve(line, skplane); return(modelcurve); }
/// <summary> /// Project a point on a face /// </summary> /// <param name="xyzArray">the face points, them fix a face </param> /// <param name="point">the point</param> /// <returns>the projected point on this face</returns> static private Autodesk.Revit.DB.XYZ Project(List <XYZ> xyzArray, Autodesk.Revit.DB.XYZ point) { Autodesk.Revit.DB.XYZ a = xyzArray[0] - xyzArray[1]; Autodesk.Revit.DB.XYZ b = xyzArray[0] - xyzArray[2]; Autodesk.Revit.DB.XYZ c = point - xyzArray[0]; Autodesk.Revit.DB.XYZ normal = (a.CrossProduct(b)); try { normal = normal.Normalize(); } catch (Exception) { normal = Autodesk.Revit.DB.XYZ.Zero; } Autodesk.Revit.DB.XYZ retProjectedPoint = point - (normal.DotProduct(c)) * normal; return(retProjectedPoint); }
/// <summary> /// Get triangles in a solid with transform. /// </summary> /// <param name="solid">The solid contains triangulars</param> /// <param name="transform">The transformation.</param> private void GetTriangular(Document document, Solid solid, Transform transform) { // a solid has many faces FaceArray faces = solid.Faces; bool hasTransform = (null != transform); if (0 == faces.Size) { return; } foreach (Face face in faces) { if (face.Visibility != Visibility.Visible) { continue; } Mesh mesh; if (null != m_Settings.Detail) { mesh = face.Triangulate((double)m_Settings.Detail); } else { mesh = face.Triangulate(); } if (null == mesh) { continue; } m_TriangularNumber += mesh.NumTriangles; PlanarFace planarFace = face as PlanarFace; // write face to stl file // a face has a mesh, all meshes are made of triangles for (int ii = 0; ii < mesh.NumTriangles; ii++) { MeshTriangle triangular = mesh.get_Triangle(ii); double[] xyz = new double[9]; Autodesk.Revit.DB.XYZ normal = new Autodesk.Revit.DB.XYZ(); try { Autodesk.Revit.DB.XYZ[] triPnts = new Autodesk.Revit.DB.XYZ[3]; for (int n = 0; n < 3; ++n) { double x, y, z; Autodesk.Revit.DB.XYZ point = triangular.get_Vertex(n); if (hasTransform) { point = transform.OfPoint(point); } if (m_Settings.ExportSharedCoordinates) { ProjectPosition ps = document.ActiveProjectLocation.GetProjectPosition(point); x = ps.EastWest; y = ps.NorthSouth; z = ps.Elevation; } else { x = point.X; y = point.Y; z = point.Z; } if (m_Settings.Units != DisplayUnitType.DUT_UNDEFINED) { xyz[3 * n] = UnitUtils.ConvertFromInternalUnits(x, m_Settings.Units); xyz[3 * n + 1] = UnitUtils.ConvertFromInternalUnits(y, m_Settings.Units); xyz[3 * n + 2] = UnitUtils.ConvertFromInternalUnits(z, m_Settings.Units); } else { xyz[3 * n] = x; xyz[3 * n + 1] = y; xyz[3 * n + 2] = z; } var mypoint = new XYZ(xyz[3 * n], xyz[3 * n + 1], xyz[3 * n + 2]); triPnts[n] = mypoint; } Autodesk.Revit.DB.XYZ pnt1 = triPnts[1] - triPnts[0]; normal = pnt1.CrossProduct(triPnts[2] - triPnts[1]); } catch (Exception ex) { m_TriangularNumber--; STLDialogManager.ShowDebug(ex.Message); continue; } if (m_Writer is SaveDataAsBinary && m_Settings.ExportColor) { Material material = document.GetElement(face.MaterialElementId) as Material; if (material != null) { ((SaveDataAsBinary)m_Writer).Color = material.Color; } } m_Writer.WriteSection(normal, xyz); } } }
/// <summary> /// This method will find out a route to avoid the obstruction. /// </summary> /// <param name="pipe">Pipe to resolve</param> /// <param name="section">Pipe's one obstruction</param> /// <returns>A route which can avoid the obstruction</returns> private Line FindRoute(Pipe pipe, Section section) { // Perpendicular direction minimal length. double minLength = pipe.Diameter * 2; // Parallel direction jump step. double jumpStep = pipe.Diameter; // Calculate the directions in which to find the solution. List <Autodesk.Revit.DB.XYZ> dirs = new List <Autodesk.Revit.DB.XYZ>(); Autodesk.Revit.DB.XYZ crossDir = null; foreach (ReferenceWithContext gref in section.Refs) { Element elem = m_rvtDoc.GetElement(gref.GetReference()); Line locationLine = (elem.Location as LocationCurve).Curve as Line; Autodesk.Revit.DB.XYZ refDir = locationLine.GetEndPoint(1) - locationLine.GetEndPoint(0); refDir = refDir.Normalize(); if (refDir.IsAlmostEqualTo(section.PipeCenterLineDirection) || refDir.IsAlmostEqualTo(-section.PipeCenterLineDirection)) { continue; } crossDir = refDir.CrossProduct(section.PipeCenterLineDirection); dirs.Add(crossDir.Normalize()); break; } // When all the obstruction are parallel with the centerline of the pipe, // We can't calculate the direction from the vector.Cross method. if (dirs.Count == 0) { // Calculate perpendicular directions with dir in four directions. List <Autodesk.Revit.DB.XYZ> perDirs = PerpendicularDirs(section.PipeCenterLineDirection, 4); dirs.Add(perDirs[0]); dirs.Add(perDirs[1]); } Line foundLine = null; while (null == foundLine) { // Extend the section interval by jumpStep. section.Inflate(0, jumpStep); section.Inflate(1, jumpStep); // Find solution in the given directions. for (int i = 0; null == foundLine && i < dirs.Count; i++) { // Calculate the intersections. List <ReferenceWithContext> obs1 = m_detector.Obstructions(section.Start, dirs[i]); List <ReferenceWithContext> obs2 = m_detector.Obstructions(section.End, dirs[i]); // Filter out the intersection result. Filter(pipe, obs1); Filter(pipe, obs2); // Find out the minimal intersections in two opposite direction. ReferenceWithContext[] mins1 = GetClosestSectionsToOrigin(obs1); ReferenceWithContext[] mins2 = GetClosestSectionsToOrigin(obs2); // Find solution in the given direction and its opposite direction. for (int j = 0; null == foundLine && j < 2; j++) { if (mins1[j] != null && Math.Abs(mins1[j].Proximity) < minLength || mins2[j] != null && Math.Abs(mins2[j].Proximity) < minLength) { continue; } // Calculate the maximal height that the parallel line can be reached. double maxHight = 1000 * pipe.Diameter; if (mins1[j] != null && mins2[j] != null) { maxHight = Math.Min(Math.Abs(mins1[j].Proximity), Math.Abs(mins2[j].Proximity)); } else if (mins1[j] != null) { maxHight = Math.Abs(mins1[j].Proximity); } else if (mins2[j] != null) { maxHight = Math.Abs(mins2[j].Proximity); } Autodesk.Revit.DB.XYZ dir = (j == 1) ? dirs[i] : -dirs[i]; // Calculate the parallel line which can avoid obstructions. foundLine = FindParallelLine(pipe, section, dir, maxHight); } } } return(foundLine); }