/// <summary> /// Find out two References, whose ProximityParameter is negative or positive, /// And Get the minimal value from all positive reference, and get the maximal value /// from the negative reference. if there are no such reference, using null instead. /// </summary> /// <param name="refs">References</param> /// <returns>Reference array</returns> private ReferenceWithContext[] GetClosestSectionsToOrigin(List <ReferenceWithContext> refs) { ReferenceWithContext[] mins = new ReferenceWithContext[2]; if (refs.Count == 0) { return(mins); } if (refs[0].Proximity > 0) { mins[1] = refs[0]; return(mins); } for (int i = 0; i < refs.Count - 1; i++) { if (refs[i].Proximity < 0 && refs[i + 1].Proximity > 0) { mins[0] = refs[i]; mins[1] = refs[i + 1]; return(mins); } } mins[0] = refs[refs.Count - 1]; return(mins); }
/// <summary> /// 构造断面 /// 两个 ReferenceWithContext 一进一出 正好对应一个 障碍物 /// </summary> /// <param name="allrefs">与管线碰撞的所有障碍物</param> /// <param name="dir">管线方向</param> /// <returns></returns> public static List <Section> BuildSections(List <ReferenceWithContext> allrefs, XYZ dir) { List <ReferenceWithContext> buildStack = new List <ReferenceWithContext>(); List <Section> sections = new List <Section>(); Section current = null; foreach (ReferenceWithContext geoRef in allrefs) { if (buildStack.Count == 0) { current = new Section(dir); sections.Add(current); } current.Refs.Add(geoRef); //这里为什么要用一个栈呢? //因为之前找和当前管道碰撞的 ReferenceWithContext 的时候,找的是 face //两个 face 对应一个元素,所以当一个 ReferenceWithContext 进去后再出来,正好对应这一个障碍物 ReferenceWithContext tmp = Find(buildStack, geoRef); if (tmp != null) { buildStack.Remove(tmp); } else { buildStack.Add(geoRef); } } return(sections); }
/// <summary> /// Build sections for References, it's a factory method to build sections. /// A section contains several points through which the ray passes the obstruction(s). /// for example, a section may contain 2 points when the obstruction is stand alone, /// or contain 4 points if 2 obstructions are intersects with each other in the direction of the ray. /// </summary> /// <param name="allrefs">References</param> /// <param name="dir">Pipe's direction</param> /// <returns>List of Section</returns> public static List <Section> BuildSections(List <ReferenceWithContext> allrefs, Autodesk.Revit.DB.XYZ dir) { List <ReferenceWithContext> buildStack = new List <ReferenceWithContext>(); List <Section> sections = new List <Section>(); Section current = null; foreach (ReferenceWithContext geoRef in allrefs) { if (buildStack.Count == 0) { current = new Section(dir); sections.Add(current); } current.Refs.Add(geoRef); ReferenceWithContext tmp = Find(buildStack, geoRef); if (tmp != null) { buildStack.Remove(tmp); } else { buildStack.Add(geoRef); } } return(sections); }
// http://thebuildingcoder.typepad.com/blog/2010/01/findreferencesbydirection.html#comment-4055509541 /// <summary> /// Return reference to ceiling face to place /// lighting fixture above a given point. /// </summary> Reference GetCeilingReferenceAbove( View3D view, XYZ p) { ElementClassFilter filter = new ElementClassFilter( typeof(Ceiling)); ReferenceIntersector refIntersector = new ReferenceIntersector(filter, FindReferenceTarget.Face, view); refIntersector.FindReferencesInRevitLinks = true; ReferenceWithContext rwc = refIntersector.FindNearest( p, XYZ.BasisZ); Reference r = (null == rwc) ? null : rwc.GetReference(); if (null == r) { System.Windows.MessageBox.Show("no intersecting geometry"); } return(r); }
public static double Gethsfs(Document doc, Room piece, ElementCategoryFilter filtresol) { double hsfs = 0.00; // on verifie si sol au dessus de piece try { LocationPoint locpiece = piece.Location as LocationPoint; XYZ ptpiece = locpiece.Point; ptpiece = new XYZ(ptpiece.X, ptpiece.Y, ptpiece.Z + 0.05); XYZ vecteurpiece = new XYZ(0, 0, 1); ReferenceIntersector refi = new ReferenceIntersector(filtresol, FindReferenceTarget.Face, (View3D)doc.ActiveView); ReferenceWithContext refc = refi.FindNearest(ptpiece, vecteurpiece); Reference reference = refc.GetReference(); XYZ intpoint = reference.GlobalPoint; hsfs = ptpiece.DistanceTo(intpoint); hsfs = UnitUtils.ConvertFromInternalUnits(hsfs, DisplayUnitType.DUT_METERS); hsfs = Math.Round(hsfs, 2); //MessageBox.Show(string.Format("hauteur sous dalle : {0}", hsfs)); } catch (Exception) { //MessageBox.Show("pas de sol au dessus de la piece","erreur"); hsfs = 0.00; } return(hsfs); }
private void CreateInstancesAndSetLocations(List <XYZ> locations, Room room) { FilteredElementCollector collector = new FilteredElementCollector(Doc); Func <View3D, bool> isNotTemplate = v3 => !(v3.IsTemplate); View3D view3D = collector.OfClass(typeof(View3D)).Cast <View3D>().First <View3D>(isNotTemplate); BoundingBoxXYZ box = room.get_BoundingBox(view3D); XYZ center = box.Min.Add(box.Max).Multiply(0.5); // Project in the negative Z direction down to the floor. XYZ rayDirection = new XYZ(0, 0, 1); ElementClassFilter filter = new ElementClassFilter(typeof(Floor)); ReferenceIntersector refIntersector = new ReferenceIntersector(filter, FindReferenceTarget.Face, view3D); ReferenceWithContext referenceWithContext = refIntersector.FindNearest(center, rayDirection); Reference reference = referenceWithContext.GetReference(); var el = Doc.GetElement(reference); var ids = string.Empty; var vector = new XYZ(1, 0, 0); for (int i = 0; i < locations.Count; i++) { var fi = App.ActiveUIDocument.Document.Create.NewFamilyInstance(reference, locations[i], vector, this.symbol); ids += fi.Id.IntegerValue.ToString() + ";"; } }
private double CenterToBorder(XYZ targetDirection, FamilyInstance targetFamilyInstance) { ReferenceIntersector rayCaster = new ReferenceIntersector(targetFamilyInstance.Id, FindReferenceTarget.Face, doc.ActiveView as View3D); BoundingBoxXYZ familyBB = targetFamilyInstance.get_BoundingBox(null); Location familyLocation = targetFamilyInstance.Location; XYZ objectCenter = Utils.GetPoint.getMidPoint(familyBB.Min, familyBB.Max); if (familyLocation is LocationPoint) { LocationPoint familyPoint = targetFamilyInstance.Location as LocationPoint; objectCenter = new XYZ(familyPoint.Point.X, familyPoint.Point.Y, objectCenter.Z); } else { LocationCurve familyCurve = targetFamilyInstance.Location as LocationCurve; XYZ midPoint = Utils.GetPoint.getMidPoint(familyCurve.Curve.GetEndPoint(1), familyCurve.Curve.GetEndPoint(0)); Line line = (familyCurve.Curve as Line); if (line == null) { return(0); } XYZ direct = line.Direction; XYZ cross = XYZ.BasisZ.CrossProduct(direct); double offset = targetFamilyInstance.get_Parameter(BuiltInParameter.Y_OFFSET_VALUE).AsDouble(); XYZ offsetFromMidle = cross.Multiply(offset); objectCenter = midPoint.Add(offsetFromMidle); } IList <ReferenceWithContext> hitFaces = rayCaster.Find(objectCenter, targetDirection); ReferenceWithContext refFace = null; if (hitFaces != null) { if (hitFaces.Count > 0) { refFace = hitFaces.LastOrDefault(); } } if (refFace != null) { //FamilySymbol pSafe = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_GenericModel) // .WhereElementIsElementType().Where(t => t.Name == "DebugPointSafe").FirstOrDefault() as FamilySymbol; //using (Transaction ta = new Transaction(doc, "hey")) //{ // ta.Start(); // doc.Create.NewFamilyInstance(refFace.GetReference().GlobalPoint, pSafe, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); // doc.Create.NewFamilyInstance(objectCenter, pSafe, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); // ta.Commit(); //} return(refFace.GetReference().GlobalPoint.DistanceTo(objectCenter)); } return(0); }
public override void Evaluate(FSharpList <FScheme.Value> args, Dictionary <PortData, FScheme.Value> outPuts) { var origin = (XYZ)((FScheme.Value.Container)args[0]).Item; var direction = (XYZ)((FScheme.Value.Container)args[1]).Item; var rayLimit = ((FScheme.Value.Number)args[2]).Item; var view = (View3D)((FScheme.Value.Container)args[3]).Item; XYZ startpt = origin; int rayCount = 0; var bouncePts = FSharpList <FScheme.Value> .Empty; var bounceElements = FSharpList <FScheme.Value> .Empty; bouncePts = FSharpList <FScheme.Value> .Cons(FScheme.Value.NewContainer(origin), bouncePts); for (int ctr = 1; ctr <= rayLimit; ctr++) { var referenceIntersector = new ReferenceIntersector(view); IList <ReferenceWithContext> references = referenceIntersector.Find(startpt, direction); ReferenceWithContext rClosest = null; rClosest = FindClosestReference(references); if (rClosest == null) { break; } else { var reference = rClosest.GetReference(); var referenceElement = dynRevitSettings.Doc.Document.GetElement(reference); bounceElements = FSharpList <FScheme.Value> .Cons(FScheme.Value.NewContainer(referenceElement), bounceElements); var referenceObject = referenceElement.GetGeometryObjectFromReference(reference); var endpt = reference.GlobalPoint; if (startpt.IsAlmostEqualTo(endpt)) { break; } else { rayCount = rayCount + 1; currFace = referenceObject as Face; var endptUV = reference.UVPoint; var FaceNormal = currFace.ComputeDerivatives(endptUV).BasisZ; // face normal where ray hits FaceNormal = rClosest.GetInstanceTransform().OfVector(FaceNormal); // transformation to get it in terms of document coordinates instead of the parent symbol var directionMirrored = direction - 2 * direction.DotProduct(FaceNormal) * FaceNormal; //http://www.fvastro.org/presentations/ray_tracing.htm direction = directionMirrored; // get ready to shoot the next ray startpt = endpt; bouncePts = FSharpList <FScheme.Value> .Cons(FScheme.Value.NewContainer(endpt), bouncePts); } } } bouncePts.Reverse(); bounceElements.Reverse(); outPuts[intersections] = FScheme.Value.NewList(bouncePts); outPuts[elements] = FScheme.Value.NewList(bounceElements); }
/// <summary> /// Judge whether a Reference is already in the list of Reference, return the founded value. /// </summary> /// <param name="arr">List of Reference</param> /// <param name="entry">Reference to test</param> /// <returns>One Reference has the same element's Id with entry</returns> private static ReferenceWithContext Find(List <ReferenceWithContext> arr, ReferenceWithContext entry) { foreach (ReferenceWithContext tmp in arr) { if (tmp.GetReference().ElementId == entry.GetReference().ElementId) { return(tmp); } } return(null); }
/// <summary> /// Judge whether a given Reference is in a Reference list. /// Give two References, if their Proximity and Element Id is equal, /// we say the two reference is equal. /// </summary> /// <param name="arr">Reference Array</param> /// <param name="entry">Reference</param> /// <returns>True of false</returns> private bool InArray(List <ReferenceWithContext> arr, ReferenceWithContext entry) { foreach (ReferenceWithContext tmp in arr) { if (Math.Abs(tmp.Proximity - entry.Proximity) < 1e-9 && tmp.GetReference().ElementId == entry.GetReference().ElementId) { return(true); } } return(false); }
public static Dictionary <string, object> ByOriginDirection(Point origin, Vector direction, int maxBounces, Elements.Views.View3D view) { var startpt = origin.ToXyz(); var rayCount = 0; var bouncePts = new List <Point> { origin }; var bounceElements = new List <Elements.Element>(); for (int ctr = 1; ctr <= maxBounces; ctr++) { var referenceIntersector = new ReferenceIntersector((View3D)view.InternalElement); IList <ReferenceWithContext> references = referenceIntersector.Find(startpt, direction.ToXyz()); ReferenceWithContext rClosest = null; rClosest = FindClosestReference(references); if (rClosest == null) { break; } else { var reference = rClosest.GetReference(); var referenceElement = DocumentManager.Instance.CurrentDBDocument.GetElement(reference); var referenceObject = referenceElement.GetGeometryObjectFromReference(reference); bounceElements.Add(referenceElement.ToDSType(true)); var endpt = reference.GlobalPoint; if (startpt.IsAlmostEqualTo(endpt)) { break; } else { rayCount = rayCount + 1; var currFace = referenceObject as Face; var endptUV = reference.UVPoint; var FaceNormal = currFace.ComputeDerivatives(endptUV).BasisZ; // face normal where ray hits FaceNormal = rClosest.GetInstanceTransform().OfVector(FaceNormal); // transformation to get it in terms of document coordinates instead of the parent symbol var directionMirrored = direction.ToXyz() - 2 * direction.ToXyz().DotProduct(FaceNormal) * FaceNormal; //http://www.fvastro.org/presentations/ray_tracing.htm direction = directionMirrored.ToVector(); // get ready to shoot the next ray startpt = endpt; bouncePts.Add(endpt.ToPoint()); } } } return(new Dictionary <string, object> { { "points", bouncePts }, { "elements", bounceElements } }); }
public Result OLET(ElementSymbol elementSymbol) { try { //Get all pipe connectors var allConnectors = ch.GetALLConnectors(pif._doc); //Determine the branch1point of the olet which is the connection to the olet pipe XYZ bp1 = elementSymbol.Branch1Point.Xyz; XYZ cp = elementSymbol.CentrePoint.Xyz; Pipe pipe1 = null; //Pipe pipe2 = null; pipe1 = ch.CreateDummyPipe(bp1, elementSymbol.CentrePoint.Xyz, elementSymbol.Branch1Point, elementSymbol); var c1 = ch.MatchConnector(bp1, pipe1); ////Determine the corresponding pipe connector to bp1 //var c1 = (from Connector c in allConnectors where Util.IsEqual(bp1, c.Origin) select c).FirstOrDefault(); ////Get the owner of the connector //var owner = c1.Owner; //Find the target pipe var filter = new ElementClassFilter(typeof(Pipe)); var view3D = ch.Get3DView(pif._doc); var refIntersect = new ReferenceIntersector(filter, FindReferenceTarget.Element, view3D); ReferenceWithContext rwc = refIntersect.FindNearest(c1.Origin, c1.CoordinateSystem.BasisZ); var refId = rwc.GetReference().ElementId; var pipeToConnectInto = (MEPCurve)pif._doc.GetElement(refId); if (c1 != null) { Element element = PCFImport.doc.Create.NewTakeoffFitting(c1, pipeToConnectInto); if (pipe1 != null) { PCFImport.doc.Delete(pipe1.Id); } //if (pipe2 != null) PCFImport.doc.Delete(pipe2.Id); elementSymbol.CreatedElement = element; PCFImport.doc.Regenerate(); return(Result.Succeeded); } } catch (Exception e) { Console.WriteLine(e); } //If this point is reached, something has failed return(Result.Failed); }
/// <summary> /// Used to compare two references, just compare their ProximityParameter. /// </summary> /// <param name="a">First Reference to compare</param> /// <param name="b">Second Reference to compare</param> /// <returns>-1, 0, or 1</returns> private int CompareReferencesWithContext(ReferenceWithContext a, ReferenceWithContext b) { if (a.Proximity > b.Proximity) { return(1); } if (a.Proximity < b.Proximity) { return(-1); } return(0); }
private XYZ ProjectPoint(Document doc, Reference refFace, XYZ point, XYZ rayDirection) { View3D active3D = doc.ActiveView as View3D; ReferenceIntersector refIntersector = new ReferenceIntersector(refFace.ElementId, FindReferenceTarget.Face, active3D); ReferenceWithContext referenceWithContext = refIntersector.FindNearest(point, rayDirection); Reference reference = referenceWithContext.GetReference(); XYZ intersection = reference.GlobalPoint; return(intersection); }
internal IList <XYZ> ProjectSupportPointsOnRoof(XYZ currentPointOnRidge) { IList <XYZ> supportPoints = GetEavePointsOnSupports(currentPointOnRidge); //if (supportPoints.Count < 1 || supportPoints.Count > 2) // throw new Exception("Invalid number of support points for the truss"); IList <XYZ> resultingPoints = new List <XYZ>(); ReferenceIntersector roofIntersector = new ReferenceIntersector(CurrentRoof.Id, FindReferenceTarget.Element, CurrentRoof.Document.ActiveView as View3D); foreach (XYZ currentSupportPoint in supportPoints) { XYZ originPoint = new XYZ(currentSupportPoint.X, currentSupportPoint.Y, GetCurrentRoofHeight() - 1); ReferenceWithContext roofIntersContext = roofIntersector.FindNearest(originPoint, XYZ.BasisZ); if (roofIntersContext == null) { continue; } XYZ currentHitPoint = roofIntersContext.GetReference().GlobalPoint; resultingPoints.Add(currentHitPoint); } if (resultingPoints.Count == 1) { if (RoofLineType == RoofLineType.Ridge) { if (Support.HasSameSlopes(CurrentRoof)) { XYZ ridgePointFlaten = new XYZ(currentPointOnRidge.X, currentPointOnRidge.Y, resultingPoints[0].Z); Line CrossedRidgeLine = Line.CreateBound(resultingPoints[0], ridgePointFlaten); XYZ crossedDirection = CrossedRidgeLine.Direction; XYZ mirroredPoint = resultingPoints[0].Add(crossedDirection.Multiply(CrossedRidgeLine.ApproximateLength * 2)); resultingPoints.Add(mirroredPoint); } } } return(resultingPoints); }
/// <summary> /// Find the first intersection with a face /// </summary> /// <param name="references"></param> /// <returns></returns> private static ReferenceWithContext FindClosestReference(IEnumerable <ReferenceWithContext> references) { ReferenceWithContext rClosest = null; var face_prox = Double.PositiveInfinity; var edge_prox = Double.PositiveInfinity; foreach (ReferenceWithContext r in references) { var reference = r.GetReference(); var referenceElement = DocumentManager.Instance.CurrentDBDocument.GetElement(reference); var referenceGeometryObject = referenceElement.GetGeometryObjectFromReference(reference); Face currFace = null; currFace = referenceGeometryObject as Autodesk.Revit.DB.Face; Autodesk.Revit.DB.Edge edge = null; edge = referenceGeometryObject as Autodesk.Revit.DB.Edge; if (currFace != null) { if ((r.Proximity < face_prox) && (r.Proximity > Double.Epsilon)) { rClosest = r; face_prox = Math.Abs(r.Proximity); } } else if (edge != null) { if ((r.Proximity < edge_prox) && (r.Proximity > Double.Epsilon)) { edge_prox = Math.Abs(r.Proximity); } } } if (edge_prox <= face_prox) { // stop bouncing if there is an edge at least as close as the nearest face - there is no single angle of reflection for a ray striking a line //m_outputInfo.Add("there is an edge at least as close as the nearest face - there is no single angle of reflection for a ray striking a line"); rClosest = null; } return(rClosest); }
/// <summary> /// 通过查找到的ReferenceWithContext 获取对象 /// </summary> /// <param name="referenceWithContext"></param> /// <param name="currDoc">当前稳点 Document</param> /// <returns></returns> public static Element GetElementByReferenceWithContext(this ReferenceWithContext referenceWithContext, Document currDoc) { if (referenceWithContext == null) { return(null); } Reference reference = referenceWithContext.GetReference(); Element element = null; if (reference.ElementId != ElementId.InvalidElementId) {//LinkedElement的ElementId是RevitLinkInstance element = currDoc.GetElement(reference.ElementId); } if (reference.LinkedElementId != ElementId.InvalidElementId) { element = LinkedElementUtils.GetLinkedDocumnet(currDoc, reference).GetElement(reference.LinkedElementId); } return(element); }
/// <summary> /// Find Elements Intersect By Ray /// </summary> /// <param name="element"></param> /// <param name="categories"></param> /// <param name="direction"></param> /// <returns></returns> public static Autodesk.Revit.DB.XYZ RayIntersect(this Autodesk.Revit.DB.Element element, List <string> categories, XYZ direction) { // Find a 3D view to use for the ReferenceIntersector constructor FilteredElementCollector collector = new FilteredElementCollector(element.Document); Func <View3D, bool> isNotTemplate = v3 => !(v3.IsTemplate); View3D view3D = collector.OfClass(typeof(View3D)).Cast <View3D>().First <View3D>(isNotTemplate); // Use the center of the skylight bounding box as the start point. BoundingBoxXYZ box = element.get_BoundingBox(view3D); XYZ center = box.Min.Add(box.Max).Multiply(0.5); // Project in the negative Z direction down to the ceiling. ElementFilter elementFilter = element.Document.FiltersElementByCategory(categories); ReferenceIntersector refIntersector = new ReferenceIntersector(elementFilter, FindReferenceTarget.Face, view3D); refIntersector.FindReferencesInRevitLinks = true; ReferenceWithContext referenceWithContext = refIntersector.FindNearest(center, direction); Reference reference = referenceWithContext?.GetReference(); return(reference?.GlobalPoint); }
public void RoomCeilingHeight() { Document doc = this.ActiveUIDocument.Document; UIDocument uidoc = new UIDocument(doc); // RevitCommandId commandId = RevitCommandId.LookupPostableCommandId(PostableCommand.Default3DView); // if (this.CanPostCommand(commandId)) // this.PostCommand(commandId); // Prompt user to select a room Room room = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element)) as Room; LocationPoint roomPoint = room.Location as LocationPoint; //GeometryElement roomGeoElem = room.get_Geometry(new Options()); //XYZ roomCent = roomGeoElem.Select(geo => geo as Solid).FirstOrDefault(sld => null != sld).ComputeCentroid(); var view = new FilteredElementCollector(doc) .OfClass(typeof(View3D)).OfType <View3D>() .FirstOrDefault((View3D v) => v.Name.Contains("{3d")); var bic = BuiltInCategory.OST_Floors; ReferenceIntersector intersector = new ReferenceIntersector( new ElementCategoryFilter(bic), FindReferenceTarget.Element, view); // XYZ.BasisZ shoots the ray "up" ReferenceWithContext rwC = intersector.FindNearest(roomPoint.Point, XYZ.BasisZ * -1); // Report the data to the user. This information could also be used to set a "Ceiling Height" instance parameter if (rwC == null) { TaskDialog.Show(string.Format("{0}", view.Name), "no Floors found"); } else { var rwD = "View used to Project the Ray " + doc.GetElement(intersector.ViewId).Name; var rwPro = "Height is " + UnitUtils.ConvertFromInternalUnits(rwC.Proximity, DisplayUnitType.DUT_MILLIMETERS).ToString() + " mm"; var rwEle = bic.ToString() + " id: " + rwC.GetReference().ElementId.ToString(); TaskDialog.Show("Element ID", rwEle + "\n" + rwPro + "\n" + rwD); } }
/// <summary> /// Find the first intersection with a face /// </summary> /// <param name="references"></param> /// <returns></returns> public Autodesk.Revit.DB.ReferenceWithContext FindClosestReference(IList <ReferenceWithContext> references) { ReferenceWithContext rClosest = null; double face_prox = System.Double.PositiveInfinity; double edge_prox = System.Double.PositiveInfinity; foreach (ReferenceWithContext r in references) { Reference reference = r.GetReference(); Element referenceElement = dynRevitSettings.Doc.Document.GetElement(reference); GeometryObject referenceGeometryObject = referenceElement.GetGeometryObjectFromReference(reference); currFace = null; currFace = referenceGeometryObject as Face; Edge edge = null; edge = referenceGeometryObject as Edge; if (currFace != null) { if ((r.Proximity < face_prox) && (r.Proximity > System.Double.Epsilon)) { rClosest = r; face_prox = Math.Abs(r.Proximity); } } else if (edge != null) { if ((r.Proximity < edge_prox) && (r.Proximity > System.Double.Epsilon)) { edge_prox = Math.Abs(r.Proximity); } } } if (edge_prox <= face_prox) { // stop bouncing if there is an edge at least as close as the nearest face - there is no single angle of reflection for a ray striking a line //m_outputInfo.Add("there is an edge at least as close as the nearest face - there is no single angle of reflection for a ray striking a line"); rClosest = null; } return(rClosest); }
// finding building elevation public double FindBuildingElevation(ProcessPolygon polygon) { List <XYZ> heights = new List <XYZ>(); ReferenceIntersector refIntersector = new ReferenceIntersector(this.TopographyID, FindReferenceTarget.Mesh, this.RayTracerView); int counter = 0; double h = 0; foreach (XYZ item in polygon.ProcessedPolygon) { ReferenceWithContext referenceWithContext = refIntersector.FindNearest(item, XYZ.BasisZ); if (referenceWithContext != null) { counter++; h += referenceWithContext.Proximity; } else { return(-1); } } return(h / counter); }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIDocument uidoc = commandData.Application.ActiveUIDocument; Document doc = uidoc.Document; try { // pick object Reference pickedObj = uidoc.Selection.PickObject(Autodesk.Revit.UI.Selection.ObjectType.Element); if (pickedObj != null) { //Retrieve Element ElementId eleId = pickedObj.ElementId; Element ele = doc.GetElement(eleId); //Project Ray LocationPoint locp = ele.Location as LocationPoint; XYZ p1 = locp.Point; // Ray XYZ rayd = new XYZ(0, 0, 1); ElementCategoryFilter filter = new ElementCategoryFilter(BuiltInCategory.OST_Roofs); ReferenceIntersector refi = new ReferenceIntersector(filter, FindReferenceTarget.Face, (View3D)doc.ActiveView); ReferenceWithContext refc = refi.FindNearest(p1, rayd); Reference reference = refc.GetReference(); XYZ intpoing = reference.GlobalPoint; Double dist = p1.DistanceTo(intpoing); TaskDialog.Show("Ray", string.Format("Distance to roof {0}", dist)); } return(Result.Succeeded); } catch (Exception e) { message = e.Message; return(Result.Failed); } }
//this method checks to see if a rectangular region has valid projection on the ground. private bool CanSubregionBeValid(BoundingBoxUV boundingBox) { List <XYZ> corners = new List <XYZ>(); XYZ Min = new XYZ(boundingBox.Min.U, boundingBox.Min.V, 0); XYZ Max = new XYZ(boundingBox.Max.U, boundingBox.Max.V, 0); XYZ p0 = new XYZ(boundingBox.Min.U, boundingBox.Max.V, 0); XYZ p1 = new XYZ(boundingBox.Max.U, boundingBox.Min.V, 0); corners.Add(Min); corners.Add(Max); corners.Add(p0); corners.Add(p1); ReferenceIntersector refIntersector = new ReferenceIntersector(this.TopographySurfaceId, FindReferenceTarget.Mesh, this.RayTracerView); foreach (XYZ item in corners) { ReferenceWithContext referenceWithContext = refIntersector.FindNearest(item, XYZ.BasisZ); if (referenceWithContext == null) { return(false); } } return(true); }
internal XYZ GetTrussTopPoint(XYZ currentPointOnRidge) { if (RoofLineType == RoofLineType.Ridge) { return(currentPointOnRidge); } //If the is not a Ridge this MUST be a SinglePanelRidge if (RoofLineType == RoofLineType.RidgeSinglePanel) { return(currentPointOnRidge); } Line currentRidgeLine = Curve.Clone() as Line; if (currentRidgeLine == null) { throw new Exception("The ridge is not a straight line!"); } ModelCurveArrArray sketchModels = CurrentRoof.GetProfiles(); double minDist = double.MaxValue; ModelCurve targetEave = null; XYZ projectedPoint = null; double currentRoofTotalHeight = GetCurrentRoofHeight(); foreach (ModelCurveArray currentCurveArr in sketchModels) { foreach (ModelCurve currentCurve in currentCurveArr) { Curve targetGeoCurve = currentCurve.GeometryCurve; Line targetGeoLine = targetGeoCurve as Line; if (targetGeoLine == null) { throw new Exception("Eave is not a straight line"); } targetGeoLine = targetGeoLine.Flatten(currentRoofTotalHeight); double currentDist = targetGeoLine.Project(currentPointOnRidge).Distance; if (currentDist < minDist) { minDist = currentDist; targetEave = currentCurve; projectedPoint = targetGeoLine.Project(currentPointOnRidge).XYZPoint; } } } double overHang = 0; try { overHang = CurrentRoof.get_Overhang(targetEave); } catch { } XYZ ridgePointFlatten = new XYZ(currentPointOnRidge.X, currentPointOnRidge.Y, currentRoofTotalHeight); //We just need to get the side that the eave is to move the point to that direction //so we dont need to get a specific eave, lets just project the first one with infinite bounds to get the direction if (RelatedRidgeEaves == null || RelatedRidgeEaves.Count == 0) { RelatedRidgeEaves = GetRelatedEaves(); } if (RelatedRidgeEaves == null || RelatedRidgeEaves.Count == 0) { throw new Exception("Related eave or eaves to current singleRidge was not found"); } Curve eaveCurve = RelatedRidgeEaves[0].AsCurve(); if (eaveCurve as Line == null) { throw new Exception("Related eave is not a straight line!"); } Line eaveLine = eaveCurve as Line; XYZ lineIntersectionPoint = GeometrySupport.GetRoofIntersectionFlattenLines(currentRidgeLine, ridgePointFlatten, eaveLine, currentRoofTotalHeight); if (lineIntersectionPoint == null) { throw new Exception("No Intersection between eave could be estabilished!"); } XYZ overHangdirection = Line.CreateBound(projectedPoint, lineIntersectionPoint).Direction.Normalize(); XYZ pointOnOverhang = projectedPoint.Add(overHangdirection.Multiply(overHang)); //We will get the point on the overhang because if we are working with a single panel ridge it may have overhangs XYZ pointOnSupport = GetSupportPoint(pointOnOverhang, currentRidgeLine.Direction.Normalize()); //Now we will shoot the point up on the Roof XYZ startingPoint = new XYZ(pointOnSupport.X, pointOnSupport.Y, pointOnSupport.Z - 1); ReferenceIntersector currentRefIntersect = new ReferenceIntersector(CurrentRoof.Id, FindReferenceTarget.Element, CurrentRoof.Document.ActiveView as View3D); ReferenceWithContext currenRefContext = currentRefIntersect.FindNearest(startingPoint, XYZ.BasisZ); if (currenRefContext == null) { return(null); } XYZ projectedPointOnRoof = currenRefContext.GetReference().GlobalPoint; return(projectedPointOnRoof); }
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; // Select two walls and the dimension line point: Selection sel = uidoc.Selection; ReferenceArray refs = new ReferenceArray(); try { ISelectionFilter f = new JtElementsOfClassSelectionFilter <Wall>(); refs.Append(sel.PickObject( ObjectType.Element, f, "Please select first wall")); refs.Append(sel.PickObject( ObjectType.Element, f, "Please pick dimension line " + "point on second wall")); //rFace = sel.PickObject( ObjectType.Face, // "Please select face on second wall at dimension line point" ); // //rPoint = sel.PickObject( ObjectType.PointOnElement, // "Please select point on first wall" ); } catch (Autodesk.Revit.Exceptions.OperationCanceledException) { message = "No two walls selected"; return(Result.Failed); } // Ensure the two selected walls are straight and // parallel; determine their mutual normal vector // and a point on each wall for distance // calculations: Wall[] walls = new Wall[2]; List <int> ids = new List <int>(2); XYZ[] pts = new XYZ[2]; Line[] lines = new Line[2]; IntersectionResult ir; XYZ normal = null; int i = 0; foreach (Reference r in refs) { // 'Autodesk.Revit.DB.Reference.Element' is // obsolete: Property will be removed. Use // Document.GetElement(Reference) instead. //Wall wall = r.Element as Wall; // 2011 Wall wall = doc.GetElement(r) as Wall; // 2012 walls[i] = wall; ids.Add(wall.Id.IntegerValue); // Obtain location curve and // check that it is straight: LocationCurve lc = wall.Location as LocationCurve; Curve curve = lc.Curve; lines[i] = curve as Line; if (null == lines[i]) { message = _prompt; return(Result.Failed); } // Obtain normal vectors // and ensure that they are equal, // i.e. walls are parallel: if (null == normal) { normal = Util.Normal(lines[i]); } else { if (!Util.IsParallel(normal, Util.Normal(lines[i]))) { message = _prompt; return(Result.Failed); } } // Obtain pick points and project // onto wall location lines: XYZ p = r.GlobalPoint; ir = lines[i].Project(p); if (null == ir) { message = string.Format( "Unable to project pick point {0} " + "onto wall location line.", i); return(Result.Failed); } pts[i] = ir.XYZPoint; Debug.Print( "Wall {0} id {1} at {2}, {3} --> point {4}", i, wall.Id.IntegerValue, Util.PointString(lines[i].GetEndPoint(0)), Util.PointString(lines[i].GetEndPoint(1)), Util.PointString(pts[i])); if (0 < i) { // Project dimension point selected on second wall // back onto first wall, and ensure that normal // points from second wall to first: ir = lines[0].Project(pts[1]); if (null == ir) { message = string.Format( "Unable to project selected dimension " + "line point {0} on second wall onto " + "first wall's location line.", Util.PointString(pts[1])); return(Result.Failed); } pts[0] = ir.XYZPoint; } ++i; } XYZ v = pts[0] - pts[1]; if (0 > v.DotProduct(normal)) { normal = -normal; } // Shoot a ray back from the second // picked wall towards first: Debug.Print( "Shooting ray from {0} in direction {1}", Util.PointString(pts[1]), Util.PointString(normal)); View3D view = Get3DView(doc); if (null == view) { message = "No 3D view named '{3D}' found; " + "run the View > 3D View command once " + "to generate it."; return(Result.Failed); } //refs = doc.FindReferencesByDirection( // pts[1], normal, view ); // 2011 //IList<ReferenceWithContext> refs2 // = doc.FindReferencesWithContextByDirection( // pts[1], normal, view ); // 2012 // In the Revit 2014 API, the call to // FindReferencesWithContextByDirection causes a // warning saying: // "FindReferencesWithContextByDirection is obsolete: // This method is deprecated in Revit 2014. // Use the ReferenceIntersector class instead." ReferenceIntersector ri = new ReferenceIntersector( walls[0].Id, FindReferenceTarget.Element, view); ReferenceWithContext ref2 = ri.FindNearest(pts[1], normal); if (null == ref2) { message = "ReferenceIntersector.FindNearest" + " returned null!"; return(Result.Failed); } #region Obsolete code to determine the closest reference #if NEED_TO_DETERMINE_CLOSEST_REFERENCE // Store the references to the wall surfaces: Reference[] surfrefs = new Reference[2] { null, null }; // Find the two closest intersection // points on each of the two walls: double[] minDistance = new double[2] { double.MaxValue, double.MaxValue }; //foreach( Reference r in refs ) foreach (ReferenceWithContext rc in refs2) { // 'Autodesk.Revit.DB.Reference.Element' is // obsolete: Property will be removed. Use // Document.GetElement(Reference) instead. //Element e = r.Element; // 2011 Reference r = rc.GetReference(); Element e = doc.GetElement(r); // 2012 if (e is Wall) { i = ids.IndexOf(e.Id.IntegerValue); if (-1 < i && ElementReferenceType.REFERENCE_TYPE_SURFACE == r.ElementReferenceType) { //GeometryObject g = r.GeometryObject; // 2011 GeometryObject g = e.GetGeometryObjectFromReference(r); // 2012 if (g is PlanarFace) { PlanarFace face = g as PlanarFace; Line line = (e.Location as LocationCurve) .Curve as Line; Debug.Print( "Wall {0} at {1}, {2} surface {3} " + "normal {4} proximity {5}", e.Id.IntegerValue, Util.PointString(line.GetEndPoint(0)), Util.PointString(line.GetEndPoint(1)), Util.PointString(face.Origin), Util.PointString(face.Normal), rc.Proximity); // First reference: assert it is a face on this wall // and the distance is half the wall thickness. // Second reference: the first reference on the other // wall; assert the distance between the two references // equals the distance between the wall location lines // minus half of the sum of the two wall thicknesses. if (rc.Proximity < minDistance[i]) { surfrefs[i] = r; minDistance[i] = rc.Proximity; } } } } } if (null == surfrefs[0]) { message = "No suitable face intersection " + "points found on first wall."; return(Result.Failed); } if (null == surfrefs[1]) { message = "No suitable face intersection " + "points found on second wall."; return(Result.Failed); } CmdDimensionWallsIterateFaces .CreateDimensionElement(doc.ActiveView, pts[0], surfrefs[0], pts[1], surfrefs[1]); #endif // NEED_TO_DETERMINE_CLOSEST_REFERENCE #endregion // Obsolete code to determine the closest reference CmdDimensionWallsIterateFaces .CreateDimensionElement(doc.ActiveView, pts[0], ref2.GetReference(), pts[1], refs.get_Item(1)); return(Result.Succeeded); }
/// <summary> /// Judge whether a Reference is already in the list of Reference, return the founded value. /// </summary> /// <param name="arr">List of Reference</param> /// <param name="entry">Reference to test</param> /// <returns>One Reference has the same element's Id with entry</returns> private static ReferenceWithContext Find(List<ReferenceWithContext> arr, ReferenceWithContext entry) { foreach (ReferenceWithContext tmp in arr) { if (tmp.GetReference().ElementId == entry.GetReference().ElementId) { return tmp; } } return null; }
public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements) { UIApplication uiapp = commandData.Application; UIDocument uidoc = commandData.Application.ActiveUIDocument; Document doc = uidoc.Document; Selection sel = uidoc.Selection; //选择一个点 Reference refPoint = sel.PickObject(ObjectType.PointOnElement); XYZ point1 = refPoint.GlobalPoint; //The position on which the reference is hit.??? //射线方向及工作平面法向量 XYZ rayDirection = XYZ.BasisZ; XYZ skVector = XYZ.BasisX; //??????????? //当选择的主体为平面时,射线根据选择的点与此面的法线方向进行放射 if (refPoint.ElementReferenceType == ElementReferenceType.REFERENCE_TYPE_SURFACE) { PlanarFace pFace = null; //主体是链接的图元时,获取平面的方法 if (refPoint.LinkedElementId.IntegerValue != -1) { RevitLinkInstance linkIIns = doc.GetElement(refPoint) as RevitLinkInstance; Document linkDoc = linkIIns.GetLinkDocument(); Element linkElem = linkDoc.GetElement(refPoint.LinkedElementId); Options opt = new Options(); opt.DetailLevel = ViewDetailLevel.Fine; GeometryElement geoElem = linkElem.get_Geometry(opt); pFace = getTarFace(geoElem, point1); //point1是原始点. } else { //判断是否FamilyInstance类型的族,采用不同的获取方法 Element elem = doc.GetElement(refPoint); if (elem is FamilyInstance) { Options opt = new Options(); opt.DetailLevel = ViewDetailLevel.Fine; GeometryElement ge = elem.get_Geometry(opt); pFace = getTarFace(ge, point1); } else { pFace = elem.GetGeometryObjectFromReference(refPoint) as PlanarFace; } } //修正射线方向及工作平面法向量 if (pFace != null) { rayDirection = pFace.FaceNormal; skVector = pFace.XVector; } } //获得视图 View3D view3D = doc.ActiveView as View3D; //创建射线测量出第二点 ExclusionFilter filter = new ExclusionFilter(new List <ElementId>() { refPoint.ElementId, refPoint.LinkedElementId }); ReferenceIntersector refIntersector = new ReferenceIntersector(filter, FindReferenceTarget.All, view3D); refIntersector.FindReferencesInRevitLinks = true; ReferenceWithContext rwc = refIntersector.FindNearest(point1, rayDirection); if (rwc != null) { XYZ point2 = rwc.GetReference().GlobalPoint; //创建模型线 Line line = Line.CreateBound(point1, point2); TaskDialog.Show("距离", line.Length.FeetToMm().ToString("0.00")); using (Transaction ts = new Transaction(doc, "尺寸")) { ts.Start(); SketchPlane sk = SketchPlane.Create(doc, Plane.CreateByNormalAndOrigin(skVector, point1)); ModelCurve modelCurve = doc.Create.NewModelCurve(line, sk); sel.SetElementIds(new List <ElementId>() { modelCurve.Id }); ts.Commit(); } } else { TaskDialog.Show("返回结果", "未检测到图元"); } return(Result.Succeeded); }
/// <summary> /// Find out two References, whose ProximityParameter is negative or positive, /// And Get the minimal value from all positive reference, and get the maximal value /// from the negative reference. if there are no such reference, using null instead. /// </summary> /// <param name="refs">References</param> /// <returns>Reference array</returns> private ReferenceWithContext[] GetClosestSectionsToOrigin(List<ReferenceWithContext> refs) { ReferenceWithContext[] mins = new ReferenceWithContext[2]; if (refs.Count == 0) { return mins; } if (refs[0].Proximity > 0) { mins[1] = refs[0]; return mins; } for (int i = 0; i < refs.Count - 1; i++) { if (refs[i].Proximity < 0 && refs[i + 1].Proximity > 0) { mins[0] = refs[i]; mins[1] = refs[i + 1]; return mins; } } mins[0] = refs[refs.Count - 1]; return mins; }
static internal EdgeInfo GetCurveInformation(Element targetRoof, Curve targetCurve, IList <PlanarFace> targetPlanarFaceList) { if (targetPlanarFaceList != null && targetRoof != null && (targetRoof as FootPrintRoof) != null) { FootPrintRoof currentRoof = targetRoof as FootPrintRoof; foreach (PlanarFace currentPlanarFace in targetPlanarFaceList) { EdgeArrayArray EdgeLoops = currentPlanarFace.EdgeLoops; foreach (EdgeArray currentEdgeArray in EdgeLoops) { foreach (Edge currentEdge in currentEdgeArray) { if (currentEdge != null) { IList <Edge> currentEdges = new List <Edge>(); currentEdges.Add(currentEdge); EdgeInfo currentEdgeInfo = new EdgeInfo(); Curve edgeCurve = currentEdge.AsCurve(); if (edgeCurve.IsAlmostEqualTo(targetCurve)) { if (edgeCurve.GetEndPoint(0).Z.IsAlmostEqualTo(currentPlanarFace.Origin.Z) && edgeCurve.GetEndPoint(1).Z.IsAlmostEqualTo(currentPlanarFace.Origin.Z)) { currentEdgeInfo = new EdgeInfo { Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Eave, CurrentRoof = currentRoof }; currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList); return(currentEdgeInfo); } else if (edgeCurve.GetEndPoint(0).Z.IsAlmostEqualTo(currentPlanarFace.Origin.Z) || edgeCurve.GetEndPoint(1).Z.IsAlmostEqualTo(currentPlanarFace.Origin.Z)) { PlanarFace firstFace = currentEdge.GetFace(0) as PlanarFace; PlanarFace secondFace = currentEdge.GetFace(1) as PlanarFace; if (!targetPlanarFaceList.Contains(firstFace) || !targetPlanarFaceList.Contains(secondFace)) { currentEdgeInfo = new EdgeInfo { Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Gable, CurrentRoof = currentRoof }; currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList); return(currentEdgeInfo); } else { if (GetOuterCurveLoop(firstFace).Count() == 3 || GetOuterCurveLoop(secondFace).Count() == 3) { currentEdgeInfo = new EdgeInfo { Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Hip, CurrentRoof = currentRoof }; currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList); return(currentEdgeInfo); } else { XYZ startingPoint = targetCurve.GetEndPoint(0).Z < targetCurve.GetEndPoint(1).Z ? targetCurve.GetEndPoint(0) : targetCurve.GetEndPoint(1); XYZ extendedPoint = GetExtendedPoint(startingPoint, firstFace); XYZ rayTracePoint = new XYZ(extendedPoint.X, extendedPoint.Y, extendedPoint.Z + 999); ReferenceIntersector ReferenceIntersect = new ReferenceIntersector(targetRoof.Id, FindReferenceTarget.Element, (targetRoof.Document.ActiveView as View3D)); ReferenceWithContext RefContext = ReferenceIntersect.FindNearest(rayTracePoint, XYZ.BasisZ.Negate()); if (RefContext == null) { currentEdgeInfo = new EdgeInfo { Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Hip, CurrentRoof = currentRoof }; currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList); return(currentEdgeInfo); } currentEdgeInfo = new EdgeInfo { Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Valley, CurrentRoof = currentRoof }; currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList); return(currentEdgeInfo); } } } else { if (edgeCurve.GetEndPoint(0).Z.IsAlmostEqualTo(edgeCurve.GetEndPoint(1).Z)) { if (targetPlanarFaceList.Contains(currentEdge.GetFace(0)) && targetPlanarFaceList.Contains(currentEdge.GetFace(1))) { currentEdgeInfo = new EdgeInfo { Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Ridge, CurrentRoof = currentRoof }; currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList); return(currentEdgeInfo); } else { PlanarFace firstFace = currentEdge.GetFace(0) as PlanarFace; PlanarFace secondFace = currentEdge.GetFace(1) as PlanarFace; XYZ startingPoint = edgeCurve.Evaluate(0.5, true); XYZ crossedDirection = Line.CreateBound(edgeCurve.GetEndPoint(0), edgeCurve.GetEndPoint(1)).Direction.CrossProduct(XYZ.BasisZ); XYZ crossedPointStart = startingPoint.Add(crossedDirection.Multiply(0.02)); XYZ crossedPointEnd = startingPoint.Add(crossedDirection.Multiply(0.1)); XYZ rayTracePointStart = new XYZ(crossedPointStart.X, crossedPointStart.Y, crossedPointStart.Z + 999); XYZ rayTracePointEnd = new XYZ(crossedPointEnd.X, crossedPointEnd.Y, crossedPointEnd.Z + 999); ReferenceIntersector ReferenceIntersect = new ReferenceIntersector(targetRoof.Id, FindReferenceTarget.Element, (targetRoof.Document.ActiveView as View3D)); ReferenceWithContext refStart = ReferenceIntersect.FindNearest(rayTracePointStart, XYZ.BasisZ.Negate()); ReferenceWithContext refEnd = ReferenceIntersect.FindNearest(rayTracePointEnd, XYZ.BasisZ.Negate()); bool isEave = true; if (refEnd != null) { if (refStart != null) { //Document doc = currentRoof.Document; //double refPointHeight = refEnd.GetReference().GlobalPoint.Z; //double starPHeight = refStart.GetReference().GlobalPoint.Z; //FamilySymbol fs = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_GenericModel).WhereElementIsElementType().Where(type => type.Name.Contains("DebugPoint2")).FirstOrDefault() as FamilySymbol; //doc.Create.NewFamilyInstance(refEnd.GetReference().GlobalPoint, fs, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); //doc.Create.NewFamilyInstance(refStart.GetReference().GlobalPoint, fs, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); if (refEnd.GetReference().GlobalPoint.Z < refStart.GetReference().GlobalPoint.Z) { isEave = false; } } } else { crossedPointStart = startingPoint.Add(crossedDirection.Multiply(-0.02)); crossedPointEnd = startingPoint.Add(crossedDirection.Multiply(-0.1)); rayTracePointStart = new XYZ(crossedPointStart.X, crossedPointStart.Y, crossedPointStart.Z + 999); rayTracePointEnd = new XYZ(crossedPointEnd.X, crossedPointEnd.Y, crossedPointEnd.Z + 999); refStart = ReferenceIntersect.FindNearest(rayTracePointStart, XYZ.BasisZ.Negate()); refEnd = ReferenceIntersect.FindNearest(rayTracePointEnd, XYZ.BasisZ.Negate()); if (refEnd != null) { if (refStart != null) { //Document doc = currentRoof.Document; //double refPointHeight = refEnd.GetReference().GlobalPoint.Z; //double starPHeight = refStart.GetReference().GlobalPoint.Z; //FamilySymbol fs = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_GenericModel).WhereElementIsElementType().Where(type => type.Name.Contains("DebugPoint2")).FirstOrDefault() as FamilySymbol; //doc.Create.NewFamilyInstance(refEnd.GetReference().GlobalPoint, fs, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); //doc.Create.NewFamilyInstance(refStart.GetReference().GlobalPoint, fs, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); if (refEnd.GetReference().GlobalPoint.Z < refStart.GetReference().GlobalPoint.Z) { isEave = false; } } } } if (isEave) { currentEdgeInfo = new EdgeInfo { Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Eave, CurrentRoof = currentRoof }; currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList); return(currentEdgeInfo); } else { currentEdgeInfo = new EdgeInfo { Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.RidgeSinglePanel, CurrentRoof = currentRoof }; currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList); return(currentEdgeInfo); } } } else { if (targetPlanarFaceList.Contains(currentEdge.GetFace(0)) && targetPlanarFaceList.Contains(currentEdge.GetFace(1))) { currentEdgeInfo = new EdgeInfo { Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Hip, CurrentRoof = currentRoof }; currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList); return(currentEdgeInfo); } else { currentEdgeInfo = new EdgeInfo { Edges = currentEdges, Curve = edgeCurve, RoofLineType = RoofLineType.Gable, CurrentRoof = currentRoof }; currentEdgeInfo.RelatedPanelFaces = GetEdgeRelatedPanels(currentEdge, targetPlanarFaceList); return(currentEdgeInfo); } } } } } } } } } return(new EdgeInfo { Edges = new List <Edge>(), Curve = targetCurve, RoofLineType = RoofLineType.Undefined, CurrentRoof = null }); }
private Result SlopeSelectedBuildingPad(UIDocument targetUIdoc, ref string message, double maxPointDistInFeet, double targetAngleInRadians) { Document doc = targetUIdoc.Document; Selection sel = targetUIdoc.Selection; View3D current3dView = doc.ActiveView as View3D; if (current3dView == null) { message = Properties.Messages.SlopeGradingFromPads_Not3DView; return(Result.Failed); } BuildingPad selectedBuildingPad = doc.GetElement(sel.PickObject(ObjectType.Element, new PadSelectionFilter(), Properties.Messages.SlopeGradingFromPads_SelectPad)) as BuildingPad; //Check if the Pad is associate with a Surface (never seen one doesnt, but anyways) ElementId topoElementID = selectedBuildingPad.HostId; if (topoElementID.Equals(ElementId.InvalidElementId)) { message = Properties.Messages.SlopeGradingFromPads_NoTopoAssociate; return(Result.Failed); } TopographySurface currentTopo = doc.GetElement(topoElementID) as TopographySurface; if (currentTopo == null) { message = Properties.Messages.SlopeGradingFromPads_NoTopoAssociate;; return(Result.Failed); } IList <CurveLoop> PadBoundaryLoops = new List <CurveLoop>(); CurveLoop outerLoop = null; IList <Reference> TopFacesReferences = HostObjectUtils.GetTopFaces(selectedBuildingPad); if (TopFacesReferences.Count > 1) { message = Properties.Messages.SlopeGradingFromPads_PadsWithMoreThanOneUpperFace; return(Result.Failed); } XYZ plannarDirection = XYZ.BasisZ; XYZ plannarOrigin = XYZ.Zero; // interate on the only face foreach (Reference currentFaceRef in TopFacesReferences) { GeometryObject currentFaceObj = selectedBuildingPad.GetGeometryObjectFromReference(currentFaceRef); if (currentFaceObj is PlanarFace) { PlanarFace currentPlanarFace = currentFaceObj as PlanarFace; plannarDirection = currentPlanarFace.FaceNormal; plannarOrigin = currentPlanarFace.Origin; PadBoundaryLoops = currentPlanarFace.GetEdgesAsCurveLoops(); } else { message = Properties.Messages.SlopeGradingFromPads_UpperFaceNotPlanar; return(Result.Failed); } } //Sort the curves so the outer loop comes first IList <IList <CurveLoop> > curveLoopLoop = ExporterIFCUtils.SortCurveLoops(PadBoundaryLoops); if (curveLoopLoop.Count > 0) { IList <CurveLoop> firstList = curveLoopLoop.First(); if (firstList.Count > 0) { outerLoop = firstList.First(); } } if (outerLoop == null) { message = Properties.Messages.SlopeGradingFromPads_OuterLoopIssue; return(Result.Failed); } //This will be the list of elements that the ReferenceIntersector will shoot the rays //If we try to shoot the rays only in the toposurface and the it has subregions, the reference //intersection will not recognize these regions, so its necessary to shoot rays to the surface and its subregions IList <ElementId> currentSubRegionsAndSurface = currentTopo.GetHostedSubRegionIds(); currentSubRegionsAndSurface.Add(topoElementID); //Search for the max distance from the Pad to the topography //Doesnt matter if it is upwards or downwards, but we will check that, since the ray has to go to one direction //This is to estabilish what the distance will be using to create the slope to the right amount ReferenceIntersector topoRefIntersec = new ReferenceIntersector(currentSubRegionsAndSurface, FindReferenceTarget.Mesh, current3dView); double maxDist = double.NegativeInfinity; foreach (Curve currentCurve in outerLoop) { int numberOfInteractions = 0; double increaseAmount = 0; double currentParameter = 0; EstabilishInteractionPoints(currentCurve, maxPointDistInFeet, out numberOfInteractions, out increaseAmount); for (int i = 0; i < numberOfInteractions; i++) { if (i == 0) { currentParameter = 0; } else { currentParameter += increaseAmount; } XYZ currentPointToEvaluate = currentCurve.Evaluate(currentParameter, true); ReferenceWithContext currentRefContext = topoRefIntersec.FindNearest(currentPointToEvaluate, XYZ.BasisZ); if (currentRefContext == null) { currentRefContext = topoRefIntersec.FindNearest(currentPointToEvaluate, XYZ.BasisZ.Negate()); } if (currentRefContext == null) { continue; } double currentDist = currentRefContext.Proximity; if (currentDist > maxDist) { maxDist = currentDist; } } } // if we haven't changed the maxdist yet, something went wrong if (maxDist == double.NegativeInfinity) { message = Properties.Messages.SlopeGradingFromPads_NoTopoAssociate; return(Result.Failed); } //Estabilish the offset from the pad double offsetDist = maxDist / Math.Tan(targetAngleInRadians); using (TopographyEditScope topoEditGroup = new TopographyEditScope(doc, Properties.Messages.SlopeGradingFromPads_Transaction)) { topoEditGroup.Start(topoElementID); using (Transaction t = new Transaction(doc, Properties.Messages.SlopeGradingFromPads_Transaction)) { t.Start(); CurveLoop offsetLoop = null; try { offsetLoop = CurveLoop.CreateViaOffset(outerLoop, offsetDist, plannarDirection); } catch { message += Properties.Messages.SlopeGradingFromPads_OuterOffsetLoopIssue; return(Result.Failed); } #region DebugCurve Loop //Plane p = new Plane(plannarDirection, plannarOrigin); //SketchPlane sktP = SketchPlane.Create(doc, p); //foreach (Curve currentOffsetCurve in offsetLoop) //{ // doc.Create.NewModelCurve(currentOffsetCurve, sktP); //} #endregion foreach (Curve currentOffsetCurve in offsetLoop) { int numberOfInteractions = 0; double increaseAmount = 0; double currentParameter = 0; EstabilishInteractionPoints(currentOffsetCurve, maxPointDistInFeet, out numberOfInteractions, out increaseAmount); for (int i = 0; i < numberOfInteractions; i++) { if (i == 0) { currentParameter = 0; } else { currentParameter += increaseAmount; } XYZ currentPointOffset = currentOffsetCurve.Evaluate(currentParameter, true); ReferenceWithContext currentRefContext = topoRefIntersec.FindNearest(currentPointOffset, XYZ.BasisZ); if (currentRefContext == null) { currentRefContext = topoRefIntersec.FindNearest(currentPointOffset, XYZ.BasisZ.Negate()); } //if we couldn't find points upwards and downwards, the topo is near the border, so we cant add points if (currentRefContext == null) { continue; } Reference currentReference = currentRefContext.GetReference(); XYZ currentPointToAdd = currentReference.GlobalPoint; if (currentTopo.ContainsPoint(currentPointToAdd)) { continue; } IList <XYZ> ListPointToAdd = new List <XYZ>(); ListPointToAdd.Add(currentPointToAdd); currentTopo.AddPoints(ListPointToAdd); } } foreach (Curve currentCurve in outerLoop) { int numberOfInteractions = 0; double increaseAmount = 0; double currentParameter = 0; EstabilishInteractionPoints(currentCurve, maxPointDistInFeet, out numberOfInteractions, out increaseAmount); for (int i = 0; i < numberOfInteractions; i++) { if (i == 0) { currentParameter = 0; } else { currentParameter += increaseAmount; } XYZ currentPointToAdd = currentCurve.Evaluate(currentParameter, true); if (currentTopo.ContainsPoint(currentPointToAdd)) { continue; } IList <XYZ> ListPointToAdd = new List <XYZ>(); ListPointToAdd.Add(currentPointToAdd); currentTopo.AddPoints(ListPointToAdd); } } t.Commit(); } topoEditGroup.Commit(new TopographyFailurePreprocessor()); return(Result.Succeeded); } }
/// <summary> /// Judge whether a given Reference is in a Reference list. /// Give two References, if their Proximity and Element Id is equal, /// we say the two reference is equal. /// </summary> /// <param name="arr">Reference Array</param> /// <param name="entry">Reference</param> /// <returns>True of false</returns> private bool InArray(List<ReferenceWithContext> arr, ReferenceWithContext entry) { foreach (ReferenceWithContext tmp in arr) { if (Math.Abs(tmp.Proximity - entry.Proximity) < 1e-9 && tmp.GetReference().ElementId == entry.GetReference().ElementId) { return true; } } return false; }
/// <summary> /// Return the neighbouring BIM element generating /// the given room boundary curve c, assuming it /// is oriented counter-clockwise around the room /// if part of an interior loop, and vice versa. /// </summary> public Element GetElementByRay( UIApplication app, Document doc, View3D view3d, Curve c) { Element boundaryElement = null; // Tolerances const double minTolerance = 0.00000001; const double maxTolerance = 0.01; // Height of ray above room level: // ray starts from one foot above room level const double elevation = 1; // Ray starts not directly from the room border // but from a point offset slightly into it. const double stepInRoom = 0.1; // We could use Line.Direction if Curve c is a // Line, but since c also might be an Arc, we // calculate direction like this: XYZ lineDirection = (c.GetEndPoint(1) - c.GetEndPoint(0)) .Normalize(); XYZ upDir = elevation * XYZ.BasisZ; // Assume that the room is on the left side of // the room boundary curve and wall on the right. // This is valid for both outer and inner room // boundaries (outer are counter-clockwise, inner // are clockwise). Start point is slightly inside // the room, one foot above room level. XYZ toRoomVec = stepInRoom * GetLeftDirection( lineDirection); XYZ pointBottomInRoom = c.Evaluate(0.5, true) + toRoomVec; XYZ startPoint = pointBottomInRoom + upDir; // We are searching for walls only ElementFilter wallFilter = new ElementCategoryFilter( BuiltInCategory.OST_Walls); ReferenceIntersector intersector = new ReferenceIntersector(wallFilter, FindReferenceTarget.Element, view3d); // We don't want to find elements in linked files intersector.FindReferencesInRevitLinks = false; XYZ toWallDir = GetRightDirection( lineDirection); ReferenceWithContext context = intersector .FindNearest(startPoint, toWallDir); Reference closestReference = null; if (context != null) { if ((context.Proximity > minTolerance) && (context.Proximity < maxTolerance + stepInRoom)) { closestReference = context.GetReference(); if (closestReference != null) { boundaryElement = doc.GetElement( closestReference); } } } return(boundaryElement); }
/// <summary> /// Return a reference to the topmost face of the given element. /// </summary> private Reference FindTopMostReference(Element e) { Reference ret = null; Document doc = e.Document; #region Revit 2012 #if _2012 using (SubTransaction t = new SubTransaction(doc)) { t.Start(); // Create temporary 3D view //View3D view3D = doc.Create.NewView3D( // 2012 // viewDirection ); // 2012 ViewFamilyType vft = new FilteredElementCollector(doc) .OfClass(typeof(ViewFamilyType)) .Cast <ViewFamilyType>() .FirstOrDefault <ViewFamilyType>(x => ViewFamily.ThreeDimensional == x.ViewFamily); Debug.Assert(null != vft, "expected to find a valid 3D view family type"); View3D view = View3D.CreateIsometric(doc, vft.Id); // 2013 XYZ eyePosition = XYZ.BasisZ; XYZ upDirection = XYZ.BasisY; XYZ forwardDirection = -XYZ.BasisZ; view.SetOrientation(new ViewOrientation3D( eyePosition, upDirection, forwardDirection)); XYZ viewDirection = -XYZ.BasisZ; BoundingBoxXYZ bb = e.get_BoundingBox(view); XYZ max = bb.Max; XYZ minAtMaxElevation = Create.NewXYZ( bb.Min.X, bb.Min.Y, max.Z); XYZ centerOfTopOfBox = 0.5 * (minAtMaxElevation + max); centerOfTopOfBox += 10 * XYZ.BasisZ; // Cast a ray through the model // to find the topmost surface #if DEBUG //ReferenceArray references // = doc.FindReferencesByDirection( // centerOfTopOfBox, viewDirection, view3D ); // 2011 IList <ReferenceWithContext> references = doc.FindReferencesWithContextByDirection( centerOfTopOfBox, viewDirection, view); // 2012 double closest = double.PositiveInfinity; //foreach( Reference r in references ) //{ // // 'Autodesk.Revit.DB.Reference.Element' is // // obsolete: Property will be removed. Use // // Document.GetElement(Reference) instead. // //Element re = r.Element; // 2011 // Element re = doc.GetElement( r ); // 2012 // if( re.Id.IntegerValue == e.Id.IntegerValue // && r.ProximityParameter < closest ) // { // ret = r; // closest = r.ProximityParameter; // } //} foreach (ReferenceWithContext r in references) { Element re = doc.GetElement( r.GetReference()); // 2012 if (re.Id.IntegerValue == e.Id.IntegerValue && r.Proximity < closest) { ret = r.GetReference(); closest = r.Proximity; } } string stable_reference = null == ret ? null : ret.ConvertToStableRepresentation(doc); #endif // DEBUG ReferenceIntersector ri = new ReferenceIntersector( e.Id, FindReferenceTarget.Element, view); ReferenceWithContext r2 = ri.FindNearest( centerOfTopOfBox, viewDirection); if (null == r2) { Debug.Print("ReferenceIntersector.FindNearest returned null!"); } else { ret = r2.GetReference(); Debug.Assert(stable_reference.Equals(ret .ConvertToStableRepresentation(doc)), "expected same reference from " + "FindReferencesWithContextByDirection and " + "ReferenceIntersector"); } t.RollBack(); } #endif // _2012 #endregion // Revit 2012 Options opt = doc.Application.Create .NewGeometryOptions(); opt.ComputeReferences = true; GeometryElement geo = e.get_Geometry(opt); foreach (GeometryObject obj in geo) { GeometryInstance inst = obj as GeometryInstance; if (null != inst) { geo = inst.GetSymbolGeometry(); break; } } Solid solid = geo.OfType <Solid>() .First <Solid>(sol => null != sol); double z = double.MinValue; foreach (Face f in solid.Faces) { BoundingBoxUV b = f.GetBoundingBox(); UV p = b.Min; UV q = b.Max; UV midparam = p + 0.5 * (q - p); XYZ midpoint = f.Evaluate(midparam); XYZ normal = f.ComputeNormal(midparam); if (Util.PointsUpwards(normal)) { if (midpoint.Z > z) { z = midpoint.Z; ret = f.Reference; } } } return(ret); }
/// <summary> /// Used to compare two references, just compare their ProximityParameter. /// </summary> /// <param name="a">First Reference to compare</param> /// <param name="b">Second Reference to compare</param> /// <returns>-1, 0, or 1</returns> private int CompareReferencesWithContext(ReferenceWithContext a, ReferenceWithContext b) { if (a.Proximity > b.Proximity) { return 1; } if (a.Proximity < b.Proximity) { return -1; } return 0; }