///////////////////////////////////////////////////////////////////////////////////////// ////////////////// Fire a reference intersector with filters //////////////////////// public IList <ElementId> Fire(Document doc, LocationPoint pXYZ) { IList <ElementId> returnId = new List <ElementId>(); //limit depth of ray cast double limit = 10; //setup parameters for raycast View3D view = Get3DView(doc); XYZ direction = new XYZ(0, 0, -1); XYZ origin = pXYZ.Point; ElementCategoryFilter roofFilter = new ElementCategoryFilter(BuiltInCategory.OST_Roofs); ElementCategoryFilter floorFilter = new ElementCategoryFilter(BuiltInCategory.OST_Floors); LogicalOrFilter orFilter = new LogicalOrFilter(roofFilter, floorFilter); //cast ray, found elements are stored in array as References with proximity data attached ReferenceIntersector refIntersector = new ReferenceIntersector(orFilter, FindReferenceTarget.Element, view); IList <ReferenceWithContext> referenceWithContext = refIntersector.Find(origin, direction).Where(w => w.Proximity < limit).OrderBy(o => o.Proximity).ToList(); //iterate through array, store Elements with proximity < limit to ElementId array foreach (ReferenceWithContext rC in referenceWithContext) { returnId.Add(doc.GetElement(rC.GetReference()).GetTypeId()); } if (returnId.Count < 1) { return(null); } return(returnId); }
/// <summary> /// 寻找给定线段上的障碍物,并按距离排序 /// 超出线段长度会被忽略 /// </summary> /// <param name="boundLine"></param> /// <returns></returns> public List <ReferenceWithContext> Obstructions(Line boundLine) { List <ReferenceWithContext> result = new List <ReferenceWithContext>(); XYZ start = boundLine.GetEndPoint(0); XYZ end = boundLine.GetEndPoint(1); XYZ direcion = (end - start).Normalize(); ReferenceIntersector referenceIntersector = new ReferenceIntersector(view3d); referenceIntersector.TargetType = FindReferenceTarget.Face; IList <ReferenceWithContext> obstructionsOnUnboundLine = referenceIntersector.Find(start, direcion); foreach (ReferenceWithContext gRefWithContext in obstructionsOnUnboundLine) { Reference gRef = gRefWithContext.GetReference(); //如果点到线段的距离 为0,说明点在直线上 if (boundLine.Distance(gRef.GlobalPoint) < 1e-9) { if (!InArray(result, gRefWithContext)) { result.Add(gRefWithContext); } } } result.Sort(CompareReferencesWithContext); return(result); }
/// <summary> /// Finds columns by projecting rays along a given direction. /// </summary> /// <param name="rayStart">The origin of the ray.</param> /// <param name="rayDirection">The direction of the ray.</param> /// <param name="within">The maximum distance away that columns may be found.</param> /// <param name="wall">The wall that this search is associated with.</param> private void FindColumnsByDirection(XYZ rayStart, XYZ rayDirection, double within, Wall wall) { ReferenceIntersector referenceIntersector = new ReferenceIntersector(m_view3D); IList <ReferenceWithContext> intersectedReferences = referenceIntersector.Find(rayStart, rayDirection); FindColumnsWithin(intersectedReferences, within, wall); }
/// <summary> /// Determines the line segment that connects the skylight to the already obtained floor. /// </summary> /// <returns>The line segment.</returns> private Line CalculateLineAboveFloor() { // Use the center of the skylight bounding box as the start point. BoundingBoxXYZ box = m_skylight.get_BoundingBox(m_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); // Look for references to faces where the element is the floor element id. ReferenceIntersector referenceIntersector = new ReferenceIntersector(m_floor.Id, FindReferenceTarget.Face, m_view3D); IList <ReferenceWithContext> references = referenceIntersector.Find(center, rayDirection); double distance = Double.PositiveInfinity; XYZ intersection = null; foreach (ReferenceWithContext referenceWithContext in references) { Reference reference = referenceWithContext.GetReference(); // Keep the closest matching reference (using the proximity parameter to determine closeness). double proximity = referenceWithContext.Proximity; if (proximity < distance) { distance = proximity; intersection = reference.GlobalPoint; } } // Create line segment from the start point and intersection point. Line result = Line.CreateBound(center, intersection); return(result); }
private List <double> GetDistancesToFloors(Document doc, View3D view3D, Room room) { LocationPoint point = room.Location as LocationPoint; XYZ origin = point.Point; XYZ center = new XYZ(point.Point.X, point.Point.Y, point.Point.Z + 0.01); // Project in the positive Z direction up to the floor. XYZ rayDirection = new XYZ(0, 0, 1); ElementClassFilter filter = new ElementClassFilter(typeof(Floor)); ReferenceIntersector refIntersector = new ReferenceIntersector(filter, FindReferenceTarget.Face, view3D); refIntersector.FindReferencesInRevitLinks = true; IList <ReferenceWithContext> referencesWithContext = refIntersector.Find(center, rayDirection); IList <Reference> intersectRefs = new List <Reference>(); Dictionary <Reference, XYZ> dictProvisionForVoidRefs = new Dictionary <Reference, XYZ>(); List <double> result = new List <double>(); foreach (ReferenceWithContext r in referencesWithContext) { XYZ intersection = r.GetReference().GlobalPoint; Line line = Line.CreateBound(origin, intersection); result.Add(line.Length); } result.Sort(); return(result); }
public List <XYZ> GetWallOpenings(Element wall, double eyeLevel, View3D view) { List <XYZ> somePoints = new List <XYZ>(); Curve c = (wall.Location as LocationCurve).Curve; XYZ wallOrigin = c.GetEndPoint(0); XYZ wallEndPoint = c.GetEndPoint(1); XYZ wallDirection = wallEndPoint - wallOrigin; double wallLength = wallDirection.GetLength(); wallDirection = wallDirection.Normalize(); UV offset = new UV(wallDirection.X, wallDirection.Y); double step_outside = offset.GetLength(); XYZ rayStart = new XYZ(wallOrigin.X - offset.U, wallOrigin.Y - offset.V, eyeLevel); ReferenceIntersector intersector = new ReferenceIntersector(wall.Id, FindReferenceTarget.Face, view); IList <ReferenceWithContext> refs = intersector.Find(rayStart, wallDirection); List <XYZ> pointList = new List <XYZ>(refs.Select <ReferenceWithContext, XYZ>(r => r.GetReference().GlobalPoint)); //TaskDialog.Show("title", pointList.Count.ToString()); if (pointList.Count() >= 4) { pointList.RemoveAt(0); pointList.RemoveAt(0); somePoints.AddRange(pointList); } return(somePoints); }
/// <summary> /// Return all the obstructions which intersect with a bound line. /// </summary> /// <param name="boundLine">Bound line</param> /// <returns>Obstructions intersected with the bound line</returns> public List <ReferenceWithContext> Obstructions(Line boundLine) { List <ReferenceWithContext> result = new List <ReferenceWithContext>(); Autodesk.Revit.DB.XYZ startPt = boundLine.GetEndPoint(0); Autodesk.Revit.DB.XYZ endPt = boundLine.GetEndPoint(1); Autodesk.Revit.DB.XYZ dir = (endPt - startPt).Normalize(); ReferenceIntersector referenceIntersector = new ReferenceIntersector(m_view3d); referenceIntersector.TargetType = FindReferenceTarget.Face; IList <ReferenceWithContext> obstructionsOnUnboundLine = referenceIntersector.Find(startPt, dir); foreach (ReferenceWithContext gRefWithContext in obstructionsOnUnboundLine) { Reference gRef = gRefWithContext.GetReference(); // Judge whether the point is in the bound line or not, if the distance between the point and line // is Zero, then the point is in the bound line. if (boundLine.Distance(gRef.GlobalPoint) < 1e-9) { if (!InArray(result, gRefWithContext)) { result.Add(gRefWithContext); } } } result.Sort(CompareReferencesWithContext); return(result); }
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); }
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> /// Determine walls in linked file intersecting pipe /// </summary> public void GetWalls(UIDocument uidoc) { Document doc = uidoc.Document; Reference pipeRef = uidoc.Selection.PickObject( ObjectType.Element); Element pipeElem = doc.GetElement(pipeRef); LocationCurve lc = pipeElem.Location as LocationCurve; Curve curve = lc.Curve; ReferenceComparer reference1 = new ReferenceComparer(); ElementFilter filter = new ElementCategoryFilter( BuiltInCategory.OST_Walls); FilteredElementCollector collector = new FilteredElementCollector(doc); Func <View3D, bool> isNotTemplate = v3 => !(v3.IsTemplate); View3D view3D = collector .OfClass(typeof(View3D)) .Cast <View3D>() .First <View3D>(isNotTemplate); ReferenceIntersector refIntersector = new ReferenceIntersector( filter, FindReferenceTarget.Element, view3D); refIntersector.FindReferencesInRevitLinks = true; IList <ReferenceWithContext> referenceWithContext = refIntersector.Find( curve.GetEndPoint(0), (curve as Line).Direction); IList <Reference> references = referenceWithContext .Select(p => p.GetReference()) .Distinct(reference1) .Where(p => p.GlobalPoint.DistanceTo( curve.GetEndPoint(0)) < curve.Length) .ToList(); IList <Element> walls = new List <Element>(); foreach (Reference reference in references) { RevitLinkInstance instance = doc.GetElement(reference) as RevitLinkInstance; Document linkDoc = instance.GetLinkDocument(); Element element = linkDoc.GetElement(reference.LinkedElementId); walls.Add(element); } TaskDialog.Show("Count of wall", walls.Count.ToString()); }
//method to find parallel trays/ducts from the list public static List <Element> ParallelElements(XYZ point, Document m_document, ICollection <ElementId> parallels) { try { List <Element> intersected = new List <Element>(); //create an instance of the refernce intersector and make it to intersect in Elements in list ReferenceIntersector intersector = new ReferenceIntersector(parallels, FindReferenceTarget.Element, view3D); intersector.FindReferencesInRevitLinks = false; //find the points of intersection in upward direction IList <ReferenceWithContext> referContUp = intersector.Find(point, XYZ.BasisZ); //find the points of intersection in downward direction IList <ReferenceWithContext> referContDown = intersector.Find(point, -XYZ.BasisZ); for (int i = 0; i < referContUp.Count; i++) { if ((m_document.GetElement(referContUp[i].GetReference()) is CableTray) || (m_document.GetElement(referContUp[i].GetReference()) is Duct)) { intersected.Add(m_document.GetElement(referContUp[i].GetReference())); } } for (int i = 0; i < referContDown.Count; i++) { if ((m_document.GetElement(referContDown[i].GetReference()) is CableTray) || (m_document.GetElement(referContDown[i].GetReference()) is Duct)) { intersected.Add(m_document.GetElement(referContDown[i].GetReference())); } } intersected = intersected.Distinct().ToList(); return(intersected); } catch { throw new Exception(); } }
//method to find parallel trays/ducts from the list public static List <Element> ParallelElements(XYZ point, Document m_document, ICollection <ElementId> parallels, XYZ normal) { try { List <Element> intersected = new List <Element>(); //create an instance of the refernce intersector and make it to intersect in Elements in list ReferenceIntersector intersector = new ReferenceIntersector(parallels, FindReferenceTarget.Element, view3D); intersector.FindReferencesInRevitLinks = false; //find the points of intersection in upward direction IList <ReferenceWithContext> referContLeft = intersector.Find(point, normal); //find the points of intersection in downward direction IList <ReferenceWithContext> referContRight = intersector.Find(point, -normal); for (int i = 0; i < referContLeft.Count; i++) { if ((m_document.GetElement(referContLeft[i].GetReference()) is Pipe) && (referContLeft[i].Proximity < 10)) { intersected.Add(m_document.GetElement(referContLeft[i].GetReference())); } } for (int i = 0; i < referContRight.Count; i++) { if ((m_document.GetElement(referContRight[i].GetReference()) is Pipe) && (referContLeft[i].Proximity < 10)) { intersected.Add(m_document.GetElement(referContRight[i].GetReference())); } } intersected = intersected.Distinct().ToList(); return(intersected); } catch { throw new Exception(); } }
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 } }); }
/// <summary> /// Gets planar face list by ray that room cener point to element center point. /// </summary> /// <typeparam name="T"></typeparam> /// <param name="elm"></param> /// <param name="room"></param> /// <param name="doc"></param> /// <param name="view"></param> /// <returns></returns> public static List <PlanarFace> GetPlanarFaceList <T>(this T elm, SpatialElement room, Document doc, View3D view) where T : Element { if (elm is null) { throw new ArgumentNullException(nameof(elm)); } if (room is null) { throw new ArgumentNullException(nameof(room)); } if (doc is null) { throw new ArgumentNullException(nameof(doc)); } if (view is null) { throw new ArgumentNullException(nameof(view)); } var elmCenter = elm.GetBoundingBox(doc).GetBoxCenter(); var roomCenter = room.GetBoundingBox(doc).GetBoxCenter(); var direction = (elmCenter - roomCenter).Normalize(); var elmFilter = new ElementClassFilter(elm.GetType()); var intersector = new ReferenceIntersector(elmFilter, FindReferenceTarget.Face, view); var contexts = intersector.Find(roomCenter, direction); var results = new List <PlanarFace>(); foreach (var context in contexts) { var reference = context.GetReference(); var refElm = doc.GetElement(reference.ElementId); var face = refElm.GetGeometryObjectFromReference(reference) as Face; if (face is PlanarFace planarFace) { results.Add(planarFace); } } return(results); }
//method to extend the rod height to structure above public static double StructureHeight(XYZ point, Document m_document) { try { double leastProximity = 0; //create an instance of the refernce intersector and make it to intersect in Elements and revit links ReferenceIntersector intersector = new ReferenceIntersector(view3D); intersector.TargetType = FindReferenceTarget.Element; intersector.FindReferencesInRevitLinks = true; //find the points of intersection IList <ReferenceWithContext> referenceWithContext = intersector.Find(point, XYZ.BasisZ); //remove the intersection on the element inside which the point lies for (int i = 0; i < referenceWithContext.Count; i++) { if (m_document.GetElement(referenceWithContext[i].GetReference()).GetType().Name != "RevitLinkInstance") { referenceWithContext.RemoveAt(i); i--; } } if (referenceWithContext.Count != 0) { //find the least proximity leastProximity = referenceWithContext.First().Proximity; for (int i = 0; i < referenceWithContext.Count; i++) { if (leastProximity > referenceWithContext[i].Proximity) { leastProximity = referenceWithContext[i].Proximity; } } } if (leastProximity <= 10) { return(leastProximity); } else { return(0); } } catch { throw new Exception(); } }
public static IEnumerable <XYZ> GetPointProjectedVertically(View3D view, ElementId targetId, XYZ pointOfInterest) { //Move the point WAY down so that it is guaranteed (well almost) to be below target element //Everest is 29000ft so if we use 50000ft should be within typical working range :). var projectionBasePoint = pointOfInterest.Subtract(new XYZ(0, 0, 50000)); //find all points of intersection between the target element and a vertical ray var intersector = new ReferenceIntersector(targetId, FindReferenceTarget.Element, view); var rwcList = intersector.Find(projectionBasePoint, XYZ.BasisZ); return(from r in rwcList select r.GetReference().GlobalPoint); }
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 } }; }
//method to extend the rod height to structure above public static double ExtendRod(XYZ point, Document m_document, View3D view3D) { double leastProximity = -1.0; try { //create an instance of the refernce intersector and make it to intersect in Elements and revit links ReferenceIntersector intersector = new ReferenceIntersector(view3D); intersector.TargetType = FindReferenceTarget.Element; intersector.FindReferencesInRevitLinks = true; //find the points of intersection IList <ReferenceWithContext> referenceWithContext = intersector.Find(point, XYZ.BasisZ); //remove the intersection on the pipe inside which the point lies for (int i = 0; i < referenceWithContext.Count; i++) { if (m_document.GetElement(referenceWithContext[i].GetReference()).GetType().Name != "RevitLinkInstance") { referenceWithContext.RemoveAt(i); i--; } } //if the referncewithcontext is empty return to the calling method if (referenceWithContext.Count == 0) { return(-1); } //find the least proximity leastProximity = referenceWithContext.First().Proximity; for (int i = 0; i < referenceWithContext.Count; i++) { if (leastProximity > referenceWithContext[i].Proximity) { leastProximity = referenceWithContext[i].Proximity; } } } catch { return(-1); } //return least proximity found above return(leastProximity); }
/// <summary> /// 寻找与光线相交的柱子 /// </summary> /// <param name="rayStart"></param> /// <param name="rayDirection"></param> /// <param name="proximity"></param> /// <param name="wall"></param> private void FindColumnsByDirection(XYZ rayStart, XYZ rayDirection, double proximity, Wall wall) { ReferenceIntersector referenceIntersector = new ReferenceIntersector(m_view3D); IList <ReferenceWithContext> intersectedReferences = referenceIntersector.Find(rayStart, rayDirection); //处理找到的柱子,加入集合中 foreach (ReferenceWithContext reference in intersectedReferences) { // Exclude items too far from the start point. if (reference.Proximity < proximity) { Element referenceElement = wall.Document.GetElement(reference.GetReference()); if (referenceElement is FamilyInstance) { FamilyInstance familyInstance = (FamilyInstance)referenceElement; ElementId familyInstanceId = familyInstance.Id; ElementId wallId = wall.Id; int categoryIdValue = referenceElement.Category.Id.IntegerValue; if (categoryIdValue == (int)BuiltInCategory.OST_Columns || categoryIdValue == (int)BuiltInCategory.OST_StructuralColumns) { // Add the column to the map of wall->columns if (m_columnsOnWall.ContainsKey(wallId)) { List <ElementId> columnsOnWall = m_columnsOnWall[wallId]; if (!columnsOnWall.Contains(familyInstanceId)) { columnsOnWall.Add(familyInstanceId); } } else { List <ElementId> columnsOnWall = new List <ElementId>(); columnsOnWall.Add(familyInstanceId); m_columnsOnWall.Add(wallId, columnsOnWall); } // Add the column to the complete list of all embedded columns if (!m_allColumnsOnWalls.Contains(familyInstanceId)) { m_allColumnsOnWalls.Add(familyInstanceId); } } //end if is column } //end if is instance } //end if is in wallLength } //end foreach }
/// <summary> /// Return all the obstructions which intersect with a ray given by an origin and a direction. /// </summary> /// <param name="origin">Ray's origin</param> /// <param name="dir">Ray's direction</param> /// <returns>Obstructions intersected with the given ray</returns> public List <ReferenceWithContext> Obstructions(Autodesk.Revit.DB.XYZ origin, Autodesk.Revit.DB.XYZ dir) { List <ReferenceWithContext> result = new List <ReferenceWithContext>(); ReferenceIntersector referenceIntersector = new ReferenceIntersector(m_view3d); referenceIntersector.TargetType = FindReferenceTarget.Face; IList <ReferenceWithContext> obstructionsOnUnboundLine = referenceIntersector.Find(origin, dir); foreach (ReferenceWithContext gRef in obstructionsOnUnboundLine) { if (!InArray(result, gRef)) { result.Add(gRef); } } result.Sort(CompareReferencesWithContext); return(result); }
/// <summary> /// Return the number of walls encountered /// between the two given points. /// </summary> int GetWallCount(XYZ psource, XYZ ptarget) { double d = ptarget.DistanceTo(psource); ReferenceIntersector intersector = new ReferenceIntersector(_wallFilter, FindReferenceTarget.Face, _view3d); intersector.FindReferencesInRevitLinks = true; IList <ReferenceWithContext> referencesWithContext = intersector.Find(psource, ptarget - psource); List <ElementId> wallIds = new List <ElementId>(); foreach (ReferenceWithContext rc in referencesWithContext) { if (rc.Proximity <= d) { Reference r = rc.GetReference(); Element e = _doc.GetElement(r.ElementId); Debug.Assert(e is Wall, "expected only walls"); Debug.Print(string.Format("wall {0} at {1}", e.Id, d)); if (!wallIds.Contains(e.Id)) { wallIds.Add(e.Id); } } } Debug.Print( string.Format("{0} -> {1}: {2} walls", Util.PointString(psource), Util.PointString(ptarget), wallIds.Count)); return(wallIds.Count); }
//射线法找元素 private List <FamilyInstance> ReferenceIntersectElement(Document doc, View3D view3d, XYZ origin, XYZ normal) { ElementClassFilter filter = new ElementClassFilter(typeof(FamilyInstance)); ReferenceIntersector refInter = new ReferenceIntersector(filter, FindReferenceTarget.Element, view3d); IList <ReferenceWithContext> listContext = refInter.Find(origin, normal); List <FamilyInstance> instances = new List <FamilyInstance>(); foreach (ReferenceWithContext reference in listContext) { Reference refer = reference.GetReference(); ElementId id = refer.ElementId; FamilyInstance instance = doc.GetElement(id) as FamilyInstance; if (instance.Symbol.Family.Name.Contains("chordFamlily")) { instances.Add(instance); } } return(instances); }
List <Reference> GetWallOpenings(Wall wall, View3D view) { Document doc = wall.Document; Level level = doc.GetElement(wall.LevelId) as Level; double elevation = level.Elevation; Curve c = (wall.Location as LocationCurve).Curve; XYZ wallOrigin = c.GetEndPoint(0); XYZ wallEndPoint = c.GetEndPoint(1); XYZ wallDirection = wallEndPoint - wallOrigin; double wallLength = wallDirection.GetLength(); wallDirection = wallDirection.Normalize(); UV offsetOut = _offset * new UV( wallDirection.X, wallDirection.Y); XYZ rayStart = new XYZ( wallOrigin.X - offsetOut.U, wallOrigin.Y - offsetOut.V, elevation + _offset); ReferenceIntersector intersector = new ReferenceIntersector( wall.Id, FindReferenceTarget.Face, view); IList <ReferenceWithContext> refs = intersector.Find(rayStart, wallDirection); List <Reference> faceReferenceList = new List <Reference>(refs .Where <ReferenceWithContext>(r => IsSurface( r.GetReference())) .Where <ReferenceWithContext>(r => r.Proximity < wallLength + _offset + _offset) .Select <ReferenceWithContext, Reference>(r => r.GetReference())); return(faceReferenceList); }
public string FindDoorsInWallWithReferenceIntersector(Document doc, UIDocument uidoc) { Wall wall = doc.GetElement(uidoc.Selection.PickObject(ObjectType.Element)) as Wall; LocationCurve locCurve = wall.Location as LocationCurve; Curve curve = locCurve.Curve; XYZ curveTangent = curve.ComputeDerivatives(0.5, true).BasisX; XYZ wallEnd = curve.GetEndPoint(0); ElementCategoryFilter filter = new ElementCategoryFilter(BuiltInCategory.OST_Doors); ReferenceIntersector intersector = new ReferenceIntersector(filter, FindReferenceTarget.Element, (View3D)doc.ActiveView); string doorDistanceInfo = ""; foreach (ReferenceWithContext refWithContext in intersector.Find(wallEnd, curveTangent)) { double proximity = refWithContext.Proximity; FamilyInstance door = doc.GetElement(refWithContext.GetReference()) as FamilyInstance; doorDistanceInfo += String.Format("{0} - {1} = {2}\n", door.Symbol.Family.Name, door.Name, proximity); } return(doorDistanceInfo); }
private bool CheckVisibilityByMaterial(ReferenceIntersector intersector, XYZ pointOrigin, List <XYZ> viewPoints) { bool visible = false; try { foreach (XYZ vPt in viewPoints) { XYZ direction = vPt - pointOrigin; IList <ReferenceWithContext> contexts = intersector.Find(pointOrigin, direction); if (null != contexts) { var filteredContexts = from context in contexts where context.Proximity > epsilon select context; filteredContexts = filteredContexts.OrderBy(x => x.Proximity).ToList(); if (filteredContexts.Count() > 0) { visible = true; foreach (ReferenceWithContext context in filteredContexts) { Reference reference = context.GetReference(); Element element = null; Transform transform = Transform.Identity; if (reference.LinkedElementId != ElementId.InvalidElementId) { //element from linked models if (linkedInstances.ContainsKey(reference.ElementId.IntegerValue)) { LinkedInstanceData lid = linkedInstances[reference.ElementId.IntegerValue]; element = lid.LinkedDocument.GetElement(reference.LinkedElementId); transform = lid.TransformValue; } } else { //element from host element = m_doc.GetElement(reference.ElementId); } if (null != element) { int categoryId = element.Category.Id.IntegerValue; if (categoryId == (int)BuiltInCategory.OST_Walls) { Wall wall = element as Wall; if (null != wall) { if (wall.WallType.Kind != WallKind.Curtain) { visible = false; break; } else { var exteriorWalls = from exWall in exteriorElementIds where exWall.LinkInstanceId == reference.ElementId && (exWall.HostElementId == reference.LinkedElementId || exWall.LinkedElementId == reference.LinkedElementId) select exWall; if (exteriorWalls.Count() > 0) { break; //exterior curtain walls } } } else { //family instance of wall visible = false; break; } } else if (categoryId == (int)BuiltInCategory.OST_StructuralColumns) { visible = false; break; } else if (categoryId == (int)BuiltInCategory.OST_Windows || categoryId == (int)BuiltInCategory.OST_Doors || categoryId == (int)BuiltInCategory.OST_CurtainWallPanels) { Face face = FindFaceByReference(element, reference, transform); if (null != face) { if (face.MaterialElementId != ElementId.InvalidElementId) { Material material = element.Document.GetElement(face.MaterialElementId) as Material; if (material.Transparency < minTransparency) { visible = false; break; } } } FamilyInstance instance = element as FamilyInstance; if (null != instance) { if (null != instance.Host) { ElementId wallId = instance.Host.Id; var exteriorWalls = from exWall in exteriorElementIds where exWall.LinkInstanceId == reference.ElementId && (exWall.HostElementId == wallId || exWall.LinkedElementId == wallId) select exWall; if (exteriorWalls.Count() > 0) { break; //exterior curtain walls } } } } } } if (visible) { break; //at least one direction should be visible } } } } } catch (Exception ex) { string message = ex.Message; } return(visible); }
private static double FindFloorHeight(Document doc, Room room, View3D view) { double floorHeight = 10; try { LocationPoint locationPoint = room.Location as LocationPoint; XYZ roomPoint = locationPoint.Point; List <ElementFilter> filters = new List <ElementFilter>(); filters.Add(new ElementCategoryFilter(BuiltInCategory.OST_Roofs)); filters.Add(new ElementCategoryFilter(BuiltInCategory.OST_Floors)); filters.Add(new ElementCategoryFilter(BuiltInCategory.OST_RvtLinks)); LogicalOrFilter orFilter = new LogicalOrFilter(filters); ReferenceIntersector intersector = new ReferenceIntersector(orFilter, FindReferenceTarget.Element, view); intersector.FindReferencesInRevitLinks = true; IList <ReferenceWithContext> contexts = intersector.Find(roomPoint, new XYZ(0, 0, 1)); if (null != contexts) { //floorHeight = 8.0; foreach (ReferenceWithContext context in contexts) { if (context.Proximity > 0) { Reference reference = context.GetReference(); Element element = null; if (reference.LinkedElementId != ElementId.InvalidElementId) { RevitLinkInstance instance = doc.GetElement(reference.ElementId) as RevitLinkInstance; if (null != instance) { Document linkedDoc = instance.GetLinkDocument(); if (null != linkedDoc) { element = linkedDoc.GetElement(reference.LinkedElementId); } } } else if (reference.ElementId != ElementId.InvalidElementId) { element = doc.GetElement(reference.ElementId); } if (null != element) { if (null != element.Category) { if (element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Floors || element.Category.Id.IntegerValue == (int)BuiltInCategory.OST_Roofs) { floorHeight = context.Proximity; break; } } } } } } } catch (Exception ex) { MessageBox.Show("Failed to find the floor height.\n" + ex.Message, "Find Floor Height", MessageBoxButton.OK, MessageBoxImage.Warning); } return(floorHeight); }
/// <summary> /// Cast a ray in a direction and return all collisions /// </summary> public static RRay Cast(ModelInfo info, View3D view, List <BuiltInCategory> find_cats, XYZ origin_pt, XYZ ray_dir, double max_distance = -1, List <ElementId> ids_to_ignore = null) { RRay ray = new RRay { direction = ray_dir, start_point = origin_pt }; bool prune_lengths = max_distance >= 0; ReferenceIntersector ref_intersect = new ReferenceIntersector( new ElementMulticategoryFilter(find_cats), FindReferenceTarget.Element, view) { FindReferencesInRevitLinks = true }; List <ReferenceWithContext> rwcs = new List <ReferenceWithContext>(); rwcs = ref_intersect.Find(ray.start_point, ray.direction).ToList(); if (prune_lengths) { foreach (var rwc in rwcs.ToArray()) { if (rwc.Proximity > max_distance) { rwcs.Remove(rwc); } } } List <RRayCollision> temp_collisions_storage = new List <RRayCollision>(); if (ids_to_ignore == null) { ids_to_ignore = new List <ElementId>(); } foreach (var rwc in rwcs) { Reference r = rwc.GetReference(); if (ids_to_ignore.Any(x => x.IntegerValue == r.ElementId.IntegerValue)) { continue; } Element collided_element = info.DOC.GetElement(r.ElementId); if (collided_element == null) { continue; } RRayCollision ray_collision = new RRayCollision(); if (max_distance == -1) { ray_collision.distance = rwc.Proximity; ray_collision.other_id = collided_element.Id; ray_collision.point = r.GlobalPoint; temp_collisions_storage.Add(ray_collision); } else { if (rwc.Proximity <= max_distance) { ray_collision.distance = rwc.Proximity; ray_collision.other_id = collided_element.Id; ray_collision.point = r.GlobalPoint; temp_collisions_storage.Add(ray_collision); } } } ray.collisions = temp_collisions_storage.ToArray(); return(ray); }
/// <summary> /// Retrieve all wall openings, /// including at start and end of wall. /// </summary> List <WallOpening2d> GetWallOpenings( Wall wall, View3D view) { Document doc = wall.Document; Level level = doc.GetElement(wall.LevelId) as Level; double elevation = level.Elevation; Curve c = (wall.Location as LocationCurve).Curve; XYZ wallOrigin = c.GetEndPoint(0); XYZ wallEndPoint = c.GetEndPoint(1); XYZ wallDirection = wallEndPoint - wallOrigin; double wallLength = wallDirection.GetLength(); wallDirection = wallDirection.Normalize(); UV offsetOut = _offset * new UV(wallDirection.X, wallDirection.Y); XYZ rayStart = new XYZ(wallOrigin.X - offsetOut.U, wallOrigin.Y - offsetOut.V, elevation + _offset); ReferenceIntersector intersector = new ReferenceIntersector(wall.Id, FindReferenceTarget.Face, view); IList <ReferenceWithContext> refs = intersector.Find(rayStart, wallDirection); // Extract the intersection points: // - only surfaces // - within wall length plus offset at each end // - sorted by proximity // - eliminating duplicates List <XYZ> pointList = new List <XYZ>(refs .Where <ReferenceWithContext>(r => IsSurface( r.GetReference())) .Where <ReferenceWithContext>(r => r.Proximity < wallLength + _offset + _offset) .OrderBy <ReferenceWithContext, double>( r => r.Proximity) .Select <ReferenceWithContext, XYZ>(r => r.GetReference().GlobalPoint) .Distinct <XYZ>(new XyzEqualityComparer())); // Check if first point is at the wall start. // If so, the wall does not begin with an opening, // so that point can be removed. Else, add it. XYZ q = wallOrigin + _offset * XYZ.BasisZ; bool wallHasFaceAtStart = Util.IsEqual( pointList[0], q); if (wallHasFaceAtStart) { pointList.RemoveAll(p //=> _eps > p.DistanceTo( q ) ); => Util.IsEqual(p, q)); } else { pointList.Insert(0, wallOrigin); } // Check if last point is at the wall end. // If so, the wall does not end with an opening, // so that point can be removed. Else, add it. q = wallEndPoint + _offset * XYZ.BasisZ; bool wallHasFaceAtEnd = Util.IsEqual( pointList.Last(), q); if (wallHasFaceAtEnd) { pointList.RemoveAll(p //=> _eps > p.DistanceTo( q ) ); => Util.IsEqual(p, q)); } else { pointList.Add(wallEndPoint); } int n = pointList.Count; Debug.Assert(IsEven(n), "expected an even number of opening sides"); var wallOpenings = new List <WallOpening2d>( n / 2); for (int i = 0; i < n; i += 2) { wallOpenings.Add(new WallOpening2d { Start = pointList[i], End = pointList[i + 1] }); } return(wallOpenings); }
/// <summary> 射线法:找到与梁相交的所有墙对象 </summary> public Result FindSupporting() { Transaction trans = new Transaction(Doc, "ExComm"); trans.Start(); // 在界面中选择一个梁 Selection sel = UIDoc.Selection; Reference ref1 = sel.PickObject(ObjectType.Element, "Please pick a beam"); FamilyInstance beam = Doc.GetElement(ref1) as FamilyInstance; //Read the beam's location line LocationCurve lc = beam.Location as LocationCurve; Curve curve = lc.Curve; // 将梁的起点和端点作为射线的原点与方向 XYZ ptStart = curve.GetEndPoint(0); XYZ ptEnd = curve.GetEndPoint(1); //move the two point a little bit lower, so the ray can go through the wall // 将这两个点向下移动一点点,来让引射线可以穿过墙 XYZ offset = new XYZ(0, 0, 0.01); ptStart = ptStart - offset; ptEnd = ptEnd - offset; // 将当前3D视图作为ReferenceIntersector的构造参数 View3D view3d = null; view3d = Doc.ActiveView as View3D; if (view3d == null) { TaskDialog.Show("3D view", "current view should be 3D view"); return(Result.Failed); } // 执行射线相交。注意此射线是无限延长的,如果没有指定ReferenceIntersector中的搜索范围,则会在整个项目中的所有Element中进行相交运算。 double beamLen = Convert.ToDouble(curve.Length); ReferenceIntersector ReferenceIntersector1 = new ReferenceIntersector(view3d); IList <ReferenceWithContext> references = ReferenceIntersector1.Find(ptStart, ptEnd - ptStart); // 清除已经选择的对象 sel.SetElementIds(new List <ElementId>()); // 返回已经选择的对象 ICollection <ElementId> Ge = sel.GetElementIds(); // 找到所有相交对象中,与梁相交的墙对象 double tolerate = 0.00001; foreach (ReferenceWithContext reference in references) { Reference ref2 = reference.GetReference(); ElementId id = ref2.ElementId; Element elem = Doc.GetElement(id); // if (elem is Wall) { // 如果与射线相交的对象到射线原点的距离比梁的长度小,说明,此对象是与梁相交的 // 如果相交面与梁的端面重合,则可以设置一个tolerate,这样的话,那个与之重合的面也可以被选中了。 if (reference.Proximity < beamLen + tolerate) { Ge.Add(elem.Id); } } } // 整体选择所有与梁相交的墙 sel.SetElementIds(Ge); trans.Commit(); // Change return(Result.Succeeded); }
/// <summary> /// OK button click event /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonOK_Click(object sender, EventArgs e) { DeleteLines(); if (!UpdateData(false)) { return; } m_outputInfo.Clear(); m_stopWatch.Start(); Transaction transaction = new Transaction(m_doc, "RayTraceBounce"); transaction.Start(); m_LineCount = 0; m_RayCount = 0; // Start Find References By Direction Autodesk.Revit.DB.XYZ startpt = m_origin; m_outputInfo.Add("Start Find References By Direction: "); for (int ctr = 1; ctr <= rayLimit; ctr++) { ReferenceIntersector referenceIntersector = new ReferenceIntersector(m_view); IList <ReferenceWithContext> references = referenceIntersector.Find(startpt, m_direction); m_rClosest = null; FindClosestReference(references); if (m_rClosest == null) { string info = "Ray " + ctr + " aborted. No closest face reference found. "; m_outputInfo.Add(info); if (ctr == 1) { TaskDialog.Show("Revit", info); } break; } else { Reference reference = m_rClosest.GetReference(); Element referenceElement = m_doc.GetElement(reference); GeometryObject referenceObject = referenceElement.GetGeometryObjectFromReference(reference); Autodesk.Revit.DB.XYZ endpt = reference.GlobalPoint; if (startpt.IsAlmostEqualTo(endpt)) { m_outputInfo.Add("Start and end points are equal. Ray " + ctr + " aborted\n" + startpt.X + ", " + startpt.Y + ", " + startpt.Z); break; } else { MakeLine(startpt, endpt, m_direction, "bounce"); m_RayCount = m_RayCount + 1; string info = "Intersected Element Type: [" + referenceElement.GetType().ToString() + "] ElementId: [" + referenceElement.Id.IntegerValue.ToString(); m_face = referenceObject as Face; if (m_face.MaterialElementId != ElementId.InvalidElementId) { Material materialElement = m_doc.GetElement(m_face.MaterialElementId) as Material; info += "] Face MaterialElement Name: [" + materialElement.Name + "] Shininess: [" + materialElement.Shininess; } else { info += "] Face.MaterialElement is null [" + referenceElement.Category.Name; } info += "]"; m_outputInfo.Add(info); Autodesk.Revit.DB.UV endptUV = reference.UVPoint; Autodesk.Revit.DB.XYZ FaceNormal = m_face.ComputeDerivatives(endptUV).BasisZ; // face normal where ray hits FaceNormal = m_rClosest.GetInstanceTransform().OfVector(FaceNormal); // transformation to get it in terms of document coordinates instead of the parent symbol Autodesk.Revit.DB.XYZ directionMirrored = m_direction - 2 * m_direction.DotProduct(FaceNormal) * FaceNormal; //http://www.fvastro.org/presentations/ray_tracing.htm m_direction = directionMirrored; // get ready to shoot the next ray startpt = endpt; } } } transaction.Commit(); m_stopWatch.Stop(); TimeSpan ts = m_stopWatch.Elapsed; string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10); m_outputInfo.Add(elapsedTime + "\n" + "Lines = " + m_LineCount + "\n" + "Rays = " + m_RayCount); m_stopWatch.Reset(); OutputInformation(); }