static RevSurface FromRevolvedSurface(DB.XYZ origin, DB.XYZ xDir, DB.XYZ yDir, DB.XYZ zDir, DB.Curve curve, DB.BoundingBoxUV bboxUV, double relativeTolerance) { var atol = relativeTolerance * Revit.AngleTolerance; var ctol = relativeTolerance * Revit.ShortCurveTolerance; var uu = new Interval(bboxUV.Min.U - atol, bboxUV.Max.U + atol); var plane = new Plane ( AsPoint3d(origin), AsVector3d(xDir), AsVector3d(yDir) ); var axisDir = AsVector3d(zDir); using (var ECStoWCS = new DB.Transform(DB.Transform.Identity) { Origin = origin, BasisX = xDir.Normalize(), BasisY = yDir.Normalize(), BasisZ = zDir.Normalize() }) { var c = ToRhino(curve.CreateTransformed(ECStoWCS)); c = ctol == 0.0 ? c : c.Extend(CurveEnd.Both, ctol, CurveExtensionStyle.Smooth); var axis = new Line(plane.Origin, plane.Normal); return(RevSurface.Create(c, axis, uu.Min, uu.Max)); } }
static RevSurface FromCylindricalSurface(DB.XYZ origin, DB.XYZ xDir, DB.XYZ yDir, DB.XYZ zDir, double radius, DB.BoundingBoxUV bboxUV) { var ctol = Revit.ShortCurveTolerance; var atol = Revit.AngleTolerance; var uu = new Interval(bboxUV.Min.U - atol, bboxUV.Max.U + atol); var vv = new Interval(bboxUV.Min.V - ctol, bboxUV.Max.V + ctol); var o = origin.ToRhino(); var x = (Vector3d)xDir.Normalize().ToRhino(); var z = (Vector3d)zDir.Normalize().ToRhino(); var axis = new Line(o, o + z); var curve = new LineCurve ( new Line ( o + (x * radius) + (z * vv.Min), o + (x * radius) + (z * vv.Max) ), vv.Min, vv.Max ); return(RevSurface.Create(curve, axis, uu.Min, uu.Max)); }
static RevSurface FromConicalSurface(DB.XYZ origin, DB.XYZ xDir, DB.XYZ yDir, DB.XYZ zDir, double halfAngle, DB.BoundingBoxUV bboxUV) { var ctol = Revit.ShortCurveTolerance; var atol = Revit.AngleTolerance * 10.0; var uu = new Interval(bboxUV.Min.U - atol, bboxUV.Max.U + atol); var vv = new Interval(bboxUV.Min.V - ctol, bboxUV.Max.V + ctol); var o = origin.ToRhino(); var x = (Vector3d)xDir.Normalize().ToRhino(); var z = (Vector3d)zDir.Normalize().ToRhino(); var axis = new Line(o, o + z); var dir = z + x * Math.Tan(halfAngle); dir.Unitize(); var curve = new LineCurve ( new Line ( o + (dir * vv.Min), o + (dir * vv.Max) ), vv.Min, vv.Max ); return(RevSurface.Create(curve, axis, uu.Min, uu.Max)); }
/// <summary> /// Make a line from start point to end point with the direction and style /// </summary> /// <param name="startpt">start point</param> /// <param name="endpt">end point</param> /// <param name="direction">the direction which decide the plane</param> /// <param name="style">line style name</param> public void MakeLine(Autodesk.Revit.DB.XYZ startpt, Autodesk.Revit.DB.XYZ endpt, Autodesk.Revit.DB.XYZ direction, string style) { try { m_LineCount = m_LineCount + 1; Line line = m_app.Application.Create.NewLineBound(startpt, endpt); // Line must lie in the sketch plane. Use the direction of the line to construct a plane that hosts the target line. XYZ rotatedDirection = XYZ.BasisX; // If the direction is not vertical, cross the direction vector with Z to get a vector rotated ninety degrees. That vector, // plus the original vector, form the axes of the sketch plane. if (!direction.IsAlmostEqualTo(XYZ.BasisZ) && !direction.IsAlmostEqualTo(-XYZ.BasisZ)) { rotatedDirection = direction.Normalize().CrossProduct(XYZ.BasisZ); } Plane geometryPlane = m_app.Application.Create.NewPlane(direction, rotatedDirection, startpt); SketchPlane skplane = m_app.ActiveUIDocument.Document.Create.NewSketchPlane(geometryPlane); ModelCurve mcurve = m_app.ActiveUIDocument.Document.Create.NewModelCurve(line, skplane); m_app.ActiveUIDocument.Document.Regenerate(); ElementArray lsArr = mcurve.LineStyles; foreach (Autodesk.Revit.DB.Element e in lsArr) { if (e.Name == style) { mcurve.LineStyle = e; break; } } m_app.ActiveUIDocument.Document.Regenerate(); } catch (System.Exception ex) { m_outputInfo.Add("Failed to create lines: " + ex.ToString()); } }
/// <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); }
static RevSurface FromRevolvedSurface(DB.XYZ origin, DB.XYZ xDir, DB.XYZ yDir, DB.XYZ zDir, DB.Curve curve, DB.BoundingBoxUV bboxUV) { var ctol = Revit.ShortCurveTolerance; var atol = Revit.AngleTolerance; var uu = new Interval(bboxUV.Min.U - atol, bboxUV.Max.U + atol); var o = origin.ToRhino(); var z = (Vector3d)zDir.Normalize().ToRhino(); var axis = new Line(o, o + z); using (var ECStoWCS = new DB.Transform(DB.Transform.Identity) { Origin = origin, BasisX = xDir.Normalize(), BasisY = yDir.Normalize(), BasisZ = zDir.Normalize() }) { var c = curve.CreateTransformed(ECStoWCS).ToRhino().Extend(CurveEnd.Both, ctol, CurveExtensionStyle.Smooth); return(RevSurface.Create(c, axis, uu.Min, uu.Max)); } }
public RevitPipeConverter() { var ptConv = new PointConverter(); AddConverter(ptConv); var planeConv = AddConverter(new PipeConverter <rg.Plane, ppg.Plane>( (rpl) => { return(new ppg.Plane(ptConv.ToPipe <rg.XYZ, ppg.Vec>(rpl.Origin), ptConv.ToPipe <rg.XYZ, ppg.Vec>(rpl.XVec), ptConv.ToPipe <rg.XYZ, ppg.Vec>(rpl.YVec), ptConv.ToPipe <rg.XYZ, ppg.Vec>(rpl.Normal))); }, (ppl) => { return(rg.Plane.CreateByOriginAndBasis(ptConv.FromPipe <rg.XYZ, ppg.Vec>(ppl.Origin), ptConv.FromPipe <rg.XYZ, ppg.Vec>(ppl.X), ptConv.FromPipe <rg.XYZ, ppg.Vec>(ppl.Y))); } )); var geomConv = new GeometryConverter(ptConv, planeConv); AddConverter(geomConv); var polylineListConv = AddConverter(new PipeConverter <rg.Line[], ppc.Polyline>( (rlg) => { List <rg.XYZ> pts = rlg.Select((ln) => ln.GetEndPoint(0)).ToList(); pts.Add(rlg.LastOrDefault().GetEndPoint(1)); return(new ppc.Polyline(pts.Select((pt) => ptConv.ToPipe <rg.XYZ, ppg.Vec>(pt)).ToList())); }, (ppl) => { List <ppc.Line> lines = ppl.ExplodedLines(); return(lines.Select((ln) => (rg.Line)geomConv.FromPipe <rg.GeometryObject, IPipeMemberType>(ln)).ToArray()); } )); //extrusions var extrConv = AddConverter(new PipeConverter <rg.Extrusion, pps.Extrusion>( (rext) => { rg.XYZ norm = rext.Sketch.SketchPlane.GetPlane().Normal.Normalize(); var startNorm = norm.Multiply(rext.StartOffset); var endNorm = norm.Normalize().Multiply(rext.EndOffset); var depthVec = norm.Normalize().Multiply(rext.EndOffset - rext.StartOffset); List <ppc.Curve> curs = new List <ppc.Curve>(); foreach (rg.Curve cur in rext.Sketch.Profile) { curs.Add(geomConv.CurveConverter.ToPipe <rg.Curve, ppc.Curve>(cur.CreateTransformed( rg.Transform.CreateTranslation(startNorm)))); } return(new pps.Extrusion(new ppc.PolyCurve(curs), ptConv.ToPipe <rg.XYZ, ppg.Vec>(depthVec), rext.EndOffset - rext.StartOffset)); }, (pe) => { double tolerance = 1e-3; rg.CurveArrArray profile = new rg.CurveArrArray(); rg.CurveArray curs = new rg.CurveArray(); List <ppc.Curve> pCurs = pe.ProfileCurve.FlattenedCurveList(); rg.Plane plane = null; pCurs.ForEach((cur) => { rg.Curve revitCur = geomConv.CurveConverter.FromPipe <rg.Curve, ppc.Curve>(cur); curs.Append(revitCur); rg.Plane newPl = Utils.SketchPlaneUtil.GetPlaneForCurve(revitCur); if (plane == null) { plane = newPl; } else if (Math.Abs(plane.Normal.Normalize().DotProduct(newPl.Normal.Normalize()) - 1) > tolerance) { //the two planes are not aligned so throw exception throw new InvalidOperationException("Cannot create a Revit Extrusion because the profile " + "curves are not in the same plane"); } }); profile.Append(curs); rg.XYZ dir = ptConv.FromPipe <rg.XYZ, ppg.Vec>(pe.Direction); if (Math.Abs(plane.Normal.Normalize().DotProduct(dir.Normalize()) - 1) > tolerance) { throw new NotImplementedException("Extrusions with direction not perpendicular to curve" + "cannot be imported into revit, try converting it to a mesh before sending through the pipe"); } return(PipeForRevit.ActiveDocument.FamilyCreate.NewExtrusion(false, profile, rg.SketchPlane.Create(PipeForRevit.ActiveDocument, plane), pe.Height)); } )); }
/// <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); }
/// <summary> /// Detect the obstructions of pipe and resolve them. /// </summary> /// <param name="pipe">Pipe to resolve</param> private void Resolve(Pipe pipe) { // Get the centerline of pipe. Line pipeLine = (pipe.Location as LocationCurve).Curve as Line; // Calculate the intersection references with pipe's centerline. List <ReferenceWithContext> obstructionRefArr = m_detector.Obstructions(pipeLine); // Filter out the references, just allow Pipe, Beam, and Duct. Filter(pipe, obstructionRefArr); if (obstructionRefArr.Count == 0) { // There are no intersection found. return; } // Calculate the direction of pipe's centerline. Autodesk.Revit.DB.XYZ dir = pipeLine.GetEndPoint(1) - pipeLine.GetEndPoint(0); // Build the sections from the intersection references. List <Section> sections = Section.BuildSections(obstructionRefArr, dir.Normalize()); // Merge the neighbor sections if the distance of them is too close. for (int i = sections.Count - 2; i >= 0; i--) { Autodesk.Revit.DB.XYZ detal = sections[i].End - sections[i + 1].Start; if (detal.GetLength() < pipe.Diameter * 3) { sections[i].Refs.AddRange(sections[i + 1].Refs); sections.RemoveAt(i + 1); } } // Resolve the obstructions one by one. foreach (Section sec in sections) { Resolve(pipe, sec); } // Connect the neighbor sections with pipe and elbow fittings. // for (int i = 1; i < sections.Count; i++) { // Get the end point from the previous section. Autodesk.Revit.DB.XYZ start = sections[i - 1].End; // Get the start point from the current section. Autodesk.Revit.DB.XYZ end = sections[i].Start; // Create a pipe between two neighbor section. Pipe tmpPipe = m_rvtDoc.Create.NewPipe(start, end, pipe.PipeType); // Copy pipe's parameters values to tmpPipe. CopyParameters(pipe, tmpPipe); // Create elbow fitting to connect previous section with tmpPipe. Connector conn1 = FindConnector(sections[i - 1].Pipes[2], start); Connector conn2 = FindConnector(tmpPipe, start); FamilyInstance fi = m_rvtDoc.Create.NewElbowFitting(conn1, conn2); // Create elbow fitting to connect current section with tmpPipe. Connector conn3 = FindConnector(sections[i].Pipes[0], end); Connector conn4 = FindConnector(tmpPipe, end); FamilyInstance f2 = m_rvtDoc.Create.NewElbowFitting(conn3, conn4); } // Find two connectors which pipe's two ends connector connected to. Connector startConn = FindConnectedTo(pipe, pipeLine.GetEndPoint(0)); Connector endConn = FindConnectedTo(pipe, pipeLine.GetEndPoint(1)); Pipe startPipe = null; if (null != startConn) { // Create a pipe between pipe's start connector and pipe's start section. startPipe = m_rvtDoc.Create.NewPipe(sections[0].Start, startConn, pipe.PipeType); } else { // Create a pipe between pipe's start point and pipe's start section. startPipe = m_rvtDoc.Create.NewPipe(sections[0].Start, pipeLine.GetEndPoint(0), pipe.PipeType); } // Copy parameters from pipe to startPipe. CopyParameters(pipe, startPipe); // Connect the startPipe and first section with elbow fitting. Connector connStart1 = FindConnector(startPipe, sections[0].Start); Connector connStart2 = FindConnector(sections[0].Pipes[0], sections[0].Start); FamilyInstance fii = m_rvtDoc.Create.NewElbowFitting(connStart1, connStart2); Pipe endPipe = null; int count = sections.Count; if (null != endConn) { // Create a pipe between pipe's end connector and pipe's end section. endPipe = m_rvtDoc.Create.NewPipe(sections[count - 1].End, endConn, pipe.PipeType); } else { // Create a pipe between pipe's end point and pipe's end section. endPipe = m_rvtDoc.Create.NewPipe(sections[count - 1].End, pipeLine.GetEndPoint(1), pipe.PipeType); } // Copy parameters from pipe to endPipe. CopyParameters(pipe, endPipe); // Connect the endPipe and last section with elbow fitting. Connector connEnd1 = FindConnector(endPipe, sections[count - 1].End); Connector connEnd2 = FindConnector(sections[count - 1].Pipes[2], sections[count - 1].End); FamilyInstance fiii = m_rvtDoc.Create.NewElbowFitting(connEnd1, connEnd2); // Delete the pipe after resolved. m_rvtDoc.Delete(pipe.Id); }