public PlanarFace PlanarFaceDistanceToMin(List <PlanarFace> listPlanarFaces, XYZ point) { PlanarFace face = null; double min = 100; foreach (PlanarFace planar in listPlanarFaces) { var fg = planar.Project(point); if (fg == null) { continue; } else { XYZ Tert = fg.XYZPoint; if (Tert != null) { double spa = point.DistanceTo(planar.Project(point).XYZPoint); if (spa < min) { min = spa; face = planar; } } } } return(face); }
public void DimAddAnnotation(Dimension dim, XYZ globalPoint, string above, string prefix, string suffix, string below) { DimensionSegment dimensionSegment = null; double num = double.MaxValue; foreach (object obj in dim.Segments) { DimensionSegment dimensionSegment2 = (DimensionSegment)obj; XYZ origin = dimensionSegment2.Origin; double num2 = origin.DistanceTo(globalPoint); bool flag = num > num2; if (flag) { dimensionSegment = dimensionSegment2; num = num2; } } bool flag2 = dimensionSegment != null; if (flag2) { dimensionSegment.Above = above; dimensionSegment.Prefix = prefix; dimensionSegment.Suffix = suffix; dimensionSegment.Below = below; } }
internal static Plane GetPlaneForCurve(Curve curve) { if (typeof(Line).IsAssignableFrom(curve.GetType())) { return(GetPlaneForLine((Line)curve)); } else { XYZ startPt = curve.GetEndPoint(0); XYZ intPt = curve.Evaluate(0.5, true); XYZ endPt = curve.GetEndPoint(1); if (startPt.DistanceTo(endPt) == 0) { endPt = curve.Evaluate(0.1, true); } XYZ v1 = endPt.Subtract(startPt); XYZ v2 = intPt.Subtract(startPt); XYZ normal = v1.CrossProduct(v2); Random rand = new Random(); while (normal.IsZeroLength()) { intPt = curve.Evaluate(rand.NextDouble(), true); v1 = endPt.Subtract(startPt); v2 = intPt.Subtract(startPt); normal = v1.CrossProduct(v2); } return(Plane.CreateByNormalAndOrigin(normal, startPt)); } }
public static void DrawLine(XYZ p1, XYZ p2) { Transaction t = null; if (_doc.IsModifiable == false) { t = new Transaction(_doc, "Draw Line"); t.Start(); } Line ln = Line.CreateBound(p1, p2); if (p1.DistanceTo(p2) < 1.0 / 32.0) { return; // too small! } XYZ v1 = p2.Subtract(p1).Normalize(); XYZ other = XYZ.BasisX; double ang = (v1.AngleTo(other)); if ((ang > 0.9 * Math.PI) || (ang < 0.1)) { other = XYZ.BasisY; } XYZ norm = v1.CrossProduct(other).Normalize(); Plane p = Plane.CreateByNormalAndOrigin(norm, p1); SketchPlane sp = SketchPlane.Create(_doc, p); _doc.Create.NewModelCurve(ln, sp); if (t != null) { t.Commit(); } }
/// <summary> /// Gets all of the physicals (excluding the given) in the given spherical area. If any part of a physical clips the area, it will be returned. /// </summary> /// <param name="center">The center of the sphere to check.</param> /// <param name="radius">The radius of the sphere to check.</param> /// <param name="physicalsToIgnore">The physicals to exclude from this check.</param> /// <returns>The physicals in this area.</returns> /// <exception cref="System.ArgumentException">When the center is out of bounds or the radius is <= 0.</exception> public IEnumerable <IPhysical> GetPhysicalsInAreaExcluding_Nice(XYZ center, double radius, IEnumerable <IPhysical> physicalsToIgnore) { if (OutOfBounds(center)) { //throw new ArgumentException("The center is out of bounds.", "center"); } if (radius <= 0) { throw new ArgumentException("The radius must be a positive non-zero number.", "radius"); } LinkedList <IPhysical> found = new LinkedList <IPhysical>(); foreach (IPhysical physical in physicals) { if (physicalsToIgnore.Contains(physical)) { continue; } if (center.DistanceTo(physical.GetPosition()) <= (radius + physical.GetSize())) { found.AddLast(physical); } } return(found); }
/// <summary> /// Create a Revit Curve from a vertical column /// </summary> /// <param name="inst">The vertical column instance</param> /// <returns>The created Revit Line</returns> public Line CreateVerticalColumnCurve(FamilyInstance inst) { var lp = inst.Location != null ? (LocationPoint)inst.Location : null; var pt = lp != null ? lp.Point : null; var baseLevelParam = inst.get_Parameter(BuiltInParameter.FAMILY_BASE_LEVEL_PARAM); var baseLevel = baseLevelParam != null?a_doc.GetElement(baseLevelParam.AsElementId()) as Level : null; var topLevelParam = inst.get_Parameter(BuiltInParameter.FAMILY_TOP_LEVEL_PARAM); var topLevel = topLevelParam != null?a_doc.GetElement(topLevelParam.AsElementId()) as Level : null; Line retLine = null; if (pt != null && baseLevel != null && topLevel != null) { var baseOffset = inst.GetParameters("Base Offset"); var baseOffsetVal = baseOffset != null && baseOffset.Count > 0 ? UnitUtils.ConvertFromInternalUnits(baseOffset[0].AsDouble(), DisplayUnitType.DUT_DECIMAL_FEET) : 0.0; var topOffset = inst.GetParameters("Top Offset"); var topOffsetVal = topOffset != null && topOffset.Count > 0 ? UnitUtils.ConvertFromInternalUnits(topOffset[0].AsDouble(), DisplayUnitType.DUT_DECIMAL_FEET) : 0.0; var strPt = new XYZ(pt.X, pt.Y, baseLevel.Elevation + baseOffsetVal); var endPt = new XYZ(pt.X, pt.Y, topLevel.Elevation + topOffsetVal); double length = strPt.DistanceTo(endPt); if (length >= a_doc.Application.ShortCurveTolerance) { retLine = Line.CreateBound(strPt, endPt); } } return(retLine); }
internal static bool IsBoxTooSmall(Autodesk.Revit.ApplicationServices.Application app, BoundingBoxXYZ box) { // we need to determine if any of the lines are less than the curve tolerance. XYZ A1 = box.Min; XYZ A2 = new XYZ(box.Max.X, box.Min.Y, box.Min.Z); XYZ A3 = new XYZ(box.Max.X, box.Max.Y, box.Min.Z); XYZ A4 = new XYZ(box.Min.X, box.Max.Y, box.Min.Z); if (A1.DistanceTo(A2) < app.ShortCurveTolerance) { return(true); } if (A2.DistanceTo(A3) < app.ShortCurveTolerance) { return(true); } if (A3.DistanceTo(A4) < app.ShortCurveTolerance) { return(true); } if (A4.DistanceTo(A1) < app.ShortCurveTolerance) { return(true); } if (Math.Abs(box.Max.Z - box.Min.Z) < app.ShortCurveTolerance) { return(true); } // if we got here, we're in the clear. return(false); }
/// <summary> /// Calculate the signal attenuation between the /// given source and target points using ray tracing. /// Walls and distance through air cause losses. /// </summary> public double Attenuation(XYZ psource, XYZ ptarget) { #if DEBUG_GRAPHICAL Debug.Print(string.Format("{0} -> {1}", Util.PointString(psource), Util.PointString(ptarget))); if (null == _sketch || 0.0001 < _sketch.GetPlane().Origin.Z - psource.Z) { Plane plane = Plane.CreateByNormalAndOrigin( XYZ.BasisZ, psource); _sketch = SketchPlane.Create(_doc, plane); } Line line = Line.CreateBound(psource, ptarget); _sketch.Document.Create.NewModelCurve(line, _sketch); #endif // DEBUG_GRAPHICAL double d = ptarget.DistanceTo(psource); double a = Util.FootToMetre(d) * _settings.AttenuationAirPerMetreInDb; int wallCount = GetWallCount(psource, ptarget); a += wallCount * _settings.AttenuationWallInDb; return(a); }
/// <summary> /// Compute values at point for face /// </summary> /// <param name="face">Give face</param> /// <param name="uvPts">UV points</param> /// <param name="valList">Values at point</param> /// <param name="measurementNo"></param> private void ComputeValueAtPointForFace(Face face, out IList <UV> uvPts, out IList <ValueAtPoint> valList, int measurementNo) { List <double> doubleList = new List <double>(); uvPts = new List <UV>(); valList = new List <ValueAtPoint>(); BoundingBoxUV bb = face.GetBoundingBox(); for (double u = bb.Min.U; u < bb.Max.U + 0.0000001; u = u + (bb.Max.U - bb.Min.U) / 1) { for (double v = bb.Min.V; v < bb.Max.V + 0.0000001; v = v + (bb.Max.V - bb.Min.V) / 1) { UV uvPnt = new UV(u, v); uvPts.Add(uvPnt); XYZ faceXYZ = face.Evaluate(uvPnt); // Specify three values for each point for (int ii = 1; ii <= measurementNo; ii++) { doubleList.Add(faceXYZ.DistanceTo(XYZ.Zero) * ii); } valList.Add(new ValueAtPoint(doubleList)); doubleList.Clear(); } } }
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 static XYZ CalculateTagPointAndLinePointFromLine(Curve beamCurve, XYZ vecticalVector, ref XYZ currentPoint0, ref XYZ currentPoint1) { var standardLength = BeamAnnotationConstaints.standardLength; var midPoint = (beamCurve.GetEndPoint(0) + beamCurve.GetEndPoint(1)) / 2; beamCurve.MakeUnbound(); var project = beamCurve.Project(currentPoint0); var lengthPoint1 = currentPoint1.DistanceTo(project.XYZPoint); var lengthPoint0 = currentPoint0.DistanceTo(project.XYZPoint); if (lengthPoint0 > lengthPoint1)//在梁上方 { currentPoint1 = project.XYZPoint; if (lengthPoint0 < standardLength) { currentPoint0 = currentPoint1 - standardLength * vecticalVector; } return(currentPoint0); } else { currentPoint0 = project.XYZPoint; if (lengthPoint1 < standardLength) { currentPoint1 = currentPoint0 + standardLength * vecticalVector; } return(currentPoint1 - standardLength * vecticalVector); } }
private void UpdateLeaderPosition() { //Update elbow position XYZ AB = _leaderEnd - _tagCenter; double mult = AB.X * AB.Y; mult = mult / Math.Abs(mult); XYZ delta = new XYZ(AB.X - AB.Y * Math.Tan(mult * Math.PI / 4), 0, 0); _elbowPosition = _tagCenter + delta; //Update lines if (_leaderEnd.DistanceTo(_elbowPosition) > _doc.Application.ShortCurveTolerance) { _endLine = Line.CreateBound(_leaderEnd, _elbowPosition); } else { _endLine = Line.CreateBound(new XYZ(0, 0, 0), new XYZ(0, 0, 1)); } if (_elbowPosition.DistanceTo(_tagCenter) > _doc.Application.ShortCurveTolerance) { _baseLine = Line.CreateBound(_elbowPosition, _tagCenter); } else { _baseLine = Line.CreateBound(new XYZ(0, 0, 0), new XYZ(0, 0, 1)); } }
private static XYZ CalculateTagPointAndLinePointFromTag(Curve beamCurve, XYZ tagPoint, XYZ parallelVector, XYZ vecticalVector, out XYZ currentPoint0, out XYZ currentPoint1) { var standardLength = BeamAnnotationConstaints.standardLength; var parallelLength = BeamAnnotationConstaints.parallelLength; var vecticalLength = BeamAnnotationConstaints.vecticalLength; var tagDiagonalXYZ = parallelLength * parallelVector + vecticalLength * vecticalVector; currentPoint0 = tagPoint - tagDiagonalXYZ; var z = currentPoint0.Z; //梁的Z轴为0与Curve绘制的轴不一致,调整为以Curve为准 var midPoint = (beamCurve.GetEndPoint(0) + beamCurve.GetEndPoint(1)) / 2; var orientPoint0 = new XYZ(midPoint.X, midPoint.Y, currentPoint0.Z); //梁的Z轴为0与Curve绘制的轴不一致,调整为以Curve为准 currentPoint1 = currentPoint0 + standardLength * vecticalVector; beamCurve.MakeUnbound(); var project = beamCurve.Project(currentPoint0); if (currentPoint0.DistanceTo(project.XYZPoint) > currentPoint1.DistanceTo(project.XYZPoint)) { currentPoint1 = project.XYZPoint; currentPoint1 = new XYZ(currentPoint1.X, currentPoint1.Y, z); if (currentPoint0.DistanceTo(project.XYZPoint) < standardLength) { currentPoint0 = currentPoint1 - standardLength * vecticalVector; currentPoint0 = new XYZ(currentPoint0.X, currentPoint0.Y, z); return(currentPoint0); } else { return(null); } } else { currentPoint0 = project.XYZPoint; currentPoint0 = new XYZ(currentPoint0.X, currentPoint0.Y, z); if (currentPoint1.DistanceTo(project.XYZPoint) < standardLength) { currentPoint1 = currentPoint0 + standardLength * vecticalVector; currentPoint1 = new XYZ(currentPoint1.X, currentPoint1.Y, z); return(currentPoint1 - standardLength * vecticalVector); } else { return(null); } } }
private double ProjectedDistance(Plane plane, XYZ pointA, XYZ pointB) { //To be tested XYZ UVA = ProjectionOnPlane(pointA, plane); XYZ UVB = ProjectionOnPlane(pointB, plane); return(UVA.DistanceTo(UVB)); }
public static Line TryCreateLine(XYZ firstPoint, XYZ secondPoint) { if (firstPoint.DistanceTo(secondPoint) < 1.MmToFt()) { return(null); } return(Line.CreateBound(firstPoint, secondPoint)); }
/// <summary> /// 求点到某点直线的距离 /// </summary> /// <param name="p1"></param> /// <param name="xLine"></param> /// <returns></returns> public static double DistanceTo(this XYZ p1, Line xLine) { double result = double.NegativeInfinity; XYZ p1_onLine = p1.ProjectToXLine(xLine); result = p1.DistanceTo(p1_onLine); return(result); }
internal static double DistancePointToLevel(XYZ point, Level level) { double elevation = level.Elevation; XYZ location = new XYZ(0, 0, elevation); double distance = point.DistanceTo(location); return(distance); }
public static Line TryCreateBound(XYZ pt1, XYZ pt2) { if (pt1.DistanceTo(pt2) < 1.MmToFt()) { return(null); } return(Line.CreateBound(pt1, pt2)); }
private XYZ FindNearestPoint(List <XYZ> points, XYZ basePoint) { XYZ nearestPoint = points.FirstOrDefault(); double nearestDistance = basePoint.DistanceTo(nearestPoint); double currentDistance = basePoint.DistanceTo(nearestPoint); foreach (XYZ point in points) { currentDistance = basePoint.DistanceTo(point); if (currentDistance < nearestDistance) { nearestPoint = point; nearestDistance = basePoint.DistanceTo(point); } } return(nearestPoint); }
public override Value Evaluate(FSharpList <Value> args) { //Grab our inputs and turn them into XYZs. XYZ ptA = this.getXYZ(((Value.Container)args[0]).Item); XYZ ptB = this.getXYZ(((Value.Container)args[1]).Item); //Return the calculated distance. return(Value.NewNumber(ptA.DistanceTo(ptB))); }
private static ElementId SectionFromTwoPoints(Document doc, XYZ p1, XYZ p2, double height, double elevation, double view_depth) { //Convert all numeric values to internal units height = UnitUtils.ConvertToInternalUnits(height, DisplayUnitType.DUT_METERS); elevation = UnitUtils.ConvertToInternalUnits(elevation, DisplayUnitType.DUT_METERS); view_depth = UnitUtils.ConvertToInternalUnits(view_depth, DisplayUnitType.DUT_MILLIMETERS); //Filtered the document and get the view section, get its ID FilteredElementCollector filter = new FilteredElementCollector(doc); Element view1 = filter.OfClass(typeof(ViewFamilyType)) .WhereElementIsElementType() .Cast <ViewFamilyType>() .First(x => x.ViewFamily == ViewFamily.Section); ElementId viewId = view1.Id; //Create a bounding box on the origin BoundingBoxXYZ bBox = new BoundingBoxXYZ(); bBox.Min = new XYZ(0, 0, 0); bBox.Max = new XYZ(p1.DistanceTo(p2), height, view_depth); //Cartesian transform for the BBox, from 0,0,0 to line initial point Transform t = new Transform(Transform.Identity); XYZ bb_x = (p2 - p1).Normalize(); XYZ bb_y = XYZ.BasisZ; XYZ bb_z = bb_x.CrossProduct(bb_y); t.Origin = new XYZ(p1.X, p1.Y, elevation); t.BasisX = bb_x; t.BasisY = bb_y; t.BasisZ = bb_z; bBox.Transform = t; //try //{ using (Transaction trans = new Transaction(doc, "Create cross section")) { trans.Start(); ViewSection sec = ViewSection.CreateSection(doc, viewId, bBox); trans.Commit(); return(sec.Id); } //} // catch // { // return null; // } }
private double DistancePointToLevel(XYZ point, Level level) { double elevation = level.Elevation; XYZ location = new XYZ(0, 0, elevation); XYZ prolectPoint = new XYZ(0, 0, point.Z); double distance = prolectPoint.DistanceTo(location); return(distance); }
public override Value Evaluate(FSharpList <Value> args) { //Grab our inputs and turn them into XYZs. XYZ ptA = this.getXYZ(((Value.Container)args[0]).Item); XYZ ptB = this.getXYZ(((Value.Container)args[1]).Item); //Return the calculated distance. return(Value.NewContainer(Units.Length.FromFeet(ptA.DistanceTo(ptB), dynSettings.Controller.UnitsManager))); }
/// <summary> /// Extend the line to a boundary line. If the line has already surpassed it, trim the line instead. /// </summary> /// <param name="line"></param> /// <param name="terminal"></param> /// <returns></returns> public static Curve ExtendLine(Curve line, Curve terminal) { Line line_unbound = line.Clone() as Line; Line terminal_unbound = terminal.Clone() as Line; line_unbound.MakeUnbound(); terminal_unbound.MakeUnbound(); SetComparisonResult result = line_unbound.Intersect(terminal_unbound, out IntersectionResultArray results); if (result == SetComparisonResult.Overlap) { XYZ sectPt = results.get_Item(0).XYZPoint; XYZ extensionVec = (sectPt - line.GetEndPoint(0)).Normalize(); if (Algorithm.IsPtOnLine(sectPt, line as Line)) { double distance1 = sectPt.DistanceTo(line.GetEndPoint(0)); double distance2 = sectPt.DistanceTo(line.GetEndPoint(1)); if (distance1 > distance2) { return(Line.CreateBound(line.GetEndPoint(0), sectPt)); } else { return(Line.CreateBound(line.GetEndPoint(1), sectPt)); } } else { if (extensionVec.IsAlmostEqualTo(line_unbound.Direction)) { return(Line.CreateBound(line.GetEndPoint(0), sectPt)); } else { return(Line.CreateBound(sectPt, line.GetEndPoint(1))); } } } else { Debug.Print("Cannot locate the intersection point."); return(null); } }
/// <summary> /// Create a model line between the two given points. /// Internally, it creates an arbitrary sketch /// plane given the model line end points. /// </summary> public static ModelLine CreateModelLine( Document doc, XYZ p, XYZ q) { if (p.DistanceTo(q) < Util.MinLineLength) { return(null); } // Create sketch plane; for non-vertical lines, // use Z-axis to span the plane, otherwise Y-axis: XYZ v = q - p; double dxy = Math.Abs(v.X) + Math.Abs(v.Y); XYZ w = (dxy > Util.TolPointOnPlane) ? XYZ.BasisZ : XYZ.BasisY; XYZ norm = v.CrossProduct(w).Normalize(); //Autodesk.Revit.Creation.Application creApp // = doc.Application.Create; //Plane plane = creApp.NewPlane( norm, p ); // 2014 //Plane plane = new Plane( norm, p ); // 2015, 2016 Plane plane = Plane.CreateByNormalAndOrigin(norm, p); // 2017 //SketchPlane sketchPlane = creDoc.NewSketchPlane( plane ); // 2013 SketchPlane sketchPlane = SketchPlane.Create(doc, plane); // 2014 //Line line = creApp.NewLine( p, q, true ); // 2013 Line line = Line.CreateBound(p, q); // 2014 // The following line is only valid in a project // document. In a family, it will throw an exception // saying "Document.Create can only be used with // project documents. Use Document.FamilyCreate // in the Family Editor." //Autodesk.Revit.Creation.Document creDoc // = doc.Create; //return creDoc.NewModelCurve( // //creApp.NewLine( p, q, true ), // 2013 // Line.CreateBound( p, q ), // 2014 // sketchPlane ) as ModelLine; ModelCurve curve = doc.IsFamilyDocument ? doc.FamilyCreate.NewModelCurve(line, sketchPlane) : doc.Create.NewModelCurve(line, sketchPlane); return(curve as ModelLine); }
public List <Line> TwoLineOneOrigin(Line line1, Line line2) { List <Line> lines = new List <Line>(); XYZ intersection = GetIntersection(line1, line2); if (intersection == null) { return(null); } XYZ xyz_start1 = line1.GetEndPoint(0); XYZ xyz_end1 = line1.GetEndPoint(1); XYZ xyz_start2 = line2.GetEndPoint(0); XYZ xyz_end2 = line2.GetEndPoint(1); Line newline1 = null; Line newline2 = null; if (intersection.DistanceTo(xyz_start1) > intersection.DistanceTo(xyz_end1)) { newline1 = Line.CreateBound(intersection, xyz_start1); } else { newline1 = Line.CreateBound(intersection, xyz_end1); } if (intersection.DistanceTo(xyz_start2) > intersection.DistanceTo(xyz_end2)) { newline2 = Line.CreateBound(intersection, xyz_start2); } else { newline2 = Line.CreateBound(intersection, xyz_end2); } lines.Add(newline1); lines.Add(newline2); return(lines); }
public static MEPCurve BreakCurve(this MEPCurve mep, XYZ point) { var locationline = mep.LocationLine(); var start = locationline.StartPoint(); var end = locationline.EndPoint(); var executeflag = point.IsOnLine(locationline) && point.DistanceTo(start) > 1d.MetricToFeet() && point.DistanceTo(end) > 1d.MetricToFeet(); if (!executeflag) { throw new Exception("点不在线上"); } var doc = mep.Document; #if Revit2016 return(null); #endif #if Revit2019 ElementId result = null; if (mep is Duct) { result = MechanicalUtils.BreakCurve(doc, mep.Id, point); } else if (mep is Pipe) { result = PlumbingUtils.BreakCurve(doc, mep.Id, point); } else if (mep is CableTray) { var newline1 = Line.CreateBound(start, point); var newline2 = Line.CreateBound(point, end); (mep.Location as LocationCurve).Curve = newline1; var newcabletray = CableTray.Create(doc, mep.GetTypeId(), point, end, mep.ReferenceLevel.Id); var para_w = newcabletray.get_Parameter(BuiltInParameter.RBS_CABLETRAY_WIDTH_PARAM); var para_H = newcabletray.get_Parameter(BuiltInParameter.RBS_CABLETRAY_HEIGHT_PARAM); para_w.Set(mep.Width); para_H.Set(mep.Height); result = newcabletray.Id; } return(result.GetElement(doc) as MEPCurve); #endif }
private XYZ FindNearestPoint(List <XYZ> points, XYZ basePoint) { XYZ xyz = ((IEnumerable <XYZ>)points).FirstOrDefault <XYZ>(); double num = basePoint.DistanceTo(xyz); basePoint.DistanceTo(xyz); using (List <XYZ> .Enumerator enumerator = points.GetEnumerator()) { while (enumerator.MoveNext()) { XYZ current = enumerator.Current; if (basePoint.DistanceTo(current) < num) { xyz = current; num = basePoint.DistanceTo(current); } } } return(xyz); }
public double CalculateFamilyInstanceBBRadius() { BoundingBoxXYZ familySolidBB = null; using (Transaction tx = new Transaction(m_doc)) { tx.Start("Transaction Temp"); // Get a bottom face from room solid SpatialElementGeometryCalculator calculator = new SpatialElementGeometryCalculator(m_doc); SpatialElementGeometryResults results = calculator.CalculateSpatialElementGeometry(m_room); Solid roomSolid = results.GetGeometry(); PlanarFace roomFace = GetBottomPlanarFaceFromSolid(roomSolid); // Create family instance temporarily FamilyInstance tempInstance = m_doc.Create.NewFamilyInstance(roomFace.Origin, m_familySymbol, m_level, Autodesk.Revit.DB.Structure.StructuralType.NonStructural); // Get a boudingbox of family instance Options getometryOptions = new Options(); getometryOptions.IncludeNonVisibleObjects = false; getometryOptions.View = m_view; GeometryElement geoElem = tempInstance.get_Geometry(getometryOptions); foreach (GeometryObject geoObject in geoElem) { GeometryInstance geoInst = geoObject as GeometryInstance; foreach (GeometryObject instanceGeoObject in geoInst.GetInstanceGeometry()) { if (instanceGeoObject is Solid) { Solid solid = (Solid)instanceGeoObject; familySolidBB = solid.GetBoundingBox(); } } } tx.RollBack(); } // Calculate perimeter of family instance XYZ familySolidBBMaxPt = familySolidBB.Max; XYZ familySolidBBMinPt = familySolidBB.Min; XYZ minPt = new XYZ(familySolidBBMinPt.X, familySolidBBMinPt.Y, 0.0); XYZ maxPt = new XYZ(familySolidBBMaxPt.X, familySolidBBMaxPt.Y, 0.0); double familySolidBBRadius = (minPt.DistanceTo(maxPt)) / 2; familySolidBBRadius = Math.Round(familySolidBBRadius, 4, MidpointRounding.AwayFromZero); return(familySolidBBRadius); }
/// <summary> /// 判断点是否在直线上 /// </summary> /// <param name="p"></param> /// <param name="l"></param> /// <returns></returns> public static bool IsOnLine(this XYZ p, Line l) { XYZ end1 = l.GetEndPoint(0); XYZ end2 = l.GetEndPoint(1); XYZ vec_pToEnd1 = end1 - p; XYZ vec_pToEnd2 = end2 - p; if (p.DistanceTo(end1) < precision || p.DistanceTo(end2) < precision) { return(true); } if (vec_pToEnd1.IsOppositeDirection(vec_pToEnd2)) { return(true); } return(false); }
/// <summary> /// Create a model line between the two given points. /// Internally, it creates an arbitrary sketch /// plane given the model line end points. /// </summary> public static ModelLine CreateModelLine( Document doc, XYZ p, XYZ q) { if( p.DistanceTo( q ) < Util.MinLineLength ) return null; // Create sketch plane; for non-vertical lines, // use Z-axis to span the plane, otherwise Y-axis: XYZ v = q - p; double dxy = Math.Abs( v.X ) + Math.Abs( v.Y ); XYZ w = ( dxy > Util.TolPointOnPlane ) ? XYZ.BasisZ : XYZ.BasisY; XYZ norm = v.CrossProduct( w ).Normalize(); //Autodesk.Revit.Creation.Application creApp // = doc.Application.Create; //Plane plane = creApp.NewPlane( norm, p ); // 2014 //Plane plane = new Plane( norm, p ); // 2015, 2016 Plane plane = Plane.CreateByNormalAndOrigin( norm, p ); // 2017 //SketchPlane sketchPlane = creDoc.NewSketchPlane( plane ); // 2013 SketchPlane sketchPlane = SketchPlane.Create( doc, plane ); // 2014 //Line line = creApp.NewLine( p, q, true ); // 2013 Line line = Line.CreateBound( p, q ); // 2014 // The following line is only valid in a project // document. In a family, it will throw an exception // saying "Document.Create can only be used with // project documents. Use Document.FamilyCreate // in the Family Editor." //Autodesk.Revit.Creation.Document creDoc // = doc.Create; //return creDoc.NewModelCurve( // //creApp.NewLine( p, q, true ), // 2013 // Line.CreateBound( p, q ), // 2014 // sketchPlane ) as ModelLine; ModelCurve curve = doc.IsFamilyDocument ? doc.FamilyCreate.NewModelCurve( line, sketchPlane ) : doc.Create.NewModelCurve( line, sketchPlane ); return curve as ModelLine; }
/// <summary> /// Miroslav Schonauer's model line creation method. /// A utility function to create an arbitrary sketch /// plane given the model line end points. /// </summary> /// <param name="app">Revit application</param> /// <param name="p">Model line start point</param> /// <param name="q">Model line end point</param> /// <returns></returns> public static ModelLine CreateModelLine( Document doc, XYZ p, XYZ q) { if( p.DistanceTo( q ) < Util.MinLineLength ) return null; // Create sketch plane; for non-vertical lines, // use Z-axis to span the plane, otherwise Y-axis: XYZ v = q - p; double dxy = Math.Abs( v.X ) + Math.Abs( v.Y ); XYZ w = ( dxy > Util.TolPointOnPlane ) ? XYZ.BasisZ : XYZ.BasisY; XYZ norm = v.CrossProduct( w ).Normalize(); Autodesk.Revit.Creation.Application creApp = doc.Application.Create; Plane plane = creApp.NewPlane( norm, p ); Autodesk.Revit.Creation.Document creDoc = doc.Create; //SketchPlane sketchPlane = creDoc.NewSketchPlane( plane ); // 2013 SketchPlane sketchPlane = SketchPlane.Create( doc, plane ); // 2014 return creDoc.NewModelCurve( //creApp.NewLine( p, q, true ), // 2013 Line.CreateBound( p, q ), // 2014 sketchPlane ) as ModelLine; }
private Face FindFace(XYZ location, XYZ vector, Document doc) { Face face = null; FilteredElementCollector elementCollector = new FilteredElementCollector(doc); elementCollector.WhereElementIsNotElementType(); Options opt = new Options { ComputeReferences = true }; foreach (Element e in elementCollector) { try { GeometryElement ge = e.get_Geometry(opt); foreach (GeometryObject go in ge) { try { XYZ endPt = location + vector; Line l = Line.CreateBound(location - vector, endPt); Curve c = l as Curve; double dist = 1000000; GeometryInstance geoInst = go as GeometryInstance; if (geoInst != null) { // Family instance GeometryElement instGeometry = geoInst.GetInstanceGeometry(); foreach (GeometryObject o in instGeometry) { Solid s = o as Solid; if (s != null) foreach (Face f in s.Faces) { IntersectionResultArray results; SetComparisonResult result = f.Intersect(c, out results); if (results != null) { foreach (IntersectionResult res in results) { XYZ intersect = res.XYZPoint; double tempDist = location.DistanceTo(intersect); if (tempDist < dist) { dist = tempDist; face = f; if (dist < 0.05) { return f; } } } } } } } else { // Assume something like a wall. Solid solid = go as Solid; if (solid != null) foreach (Face f in solid.Faces) { IntersectionResultArray results; SetComparisonResult result = f.Intersect(c, out results); if (results != null) { foreach (IntersectionResult res in results) { XYZ intersect = res.XYZPoint; double tempDist = location.DistanceTo(intersect); if (tempDist < dist) { dist = tempDist; face = f; if (dist < 0.05) { return f; } } } } } } } catch (Exception ex) { //errors++; Debug.WriteLine(ex.Message); } } } catch (Exception ex) { //errors++; Debug.WriteLine(ex.Message); } } if (face == null) { TaskDialog.Show("error", "no face found"); } return face; }
/// <summary> /// Returns true if the line segment from pt1 to pt2 is less than the short curve tolerance. /// </summary> /// <param name="pt1">The first point of the line segment.</param> /// <param name="pt2">The final point of the line segment.</param> /// <returns>True if it is too short, false otherwise.</returns> public static bool LineSegmentIsTooShort(XYZ pt1, XYZ pt2) { double dist = pt1.DistanceTo(pt2); return (dist < IFCImportFile.TheFile.Document.Application.ShortCurveTolerance + MathUtil.Eps()); }
/// <summary> /// Main implementation to export walls. /// </summary> /// <param name="exporterIFC">The ExporterIFC object.</param> /// <param name="element">The element.</param> /// <param name="connectedWalls">Information about walls joined to this wall.</param> /// <param name="geometryElement">The geometry element.</param> /// <param name="origWrapper">The ProductWrapper.</param> /// <param name="overrideLevelId">The level id.</param> /// <param name="range">The range to be exported for the element.</param> /// <returns>The exported wall handle.</returns> public static IFCAnyHandle ExportWallBase(ExporterIFC exporterIFC, Element element, IList<IList<IFCConnectedWallData>> connectedWalls, GeometryElement geometryElement, ProductWrapper origWrapper, ElementId overrideLevelId, IFCRange range) { // Check cases where we choose not to export early. ElementId catId = CategoryUtil.GetSafeCategoryId(element); Wall wallElement = element as Wall; FamilyInstance famInstWallElem = element as FamilyInstance; FaceWall faceWall = element as FaceWall; bool exportingWallElement = (wallElement != null); bool exportingFamilyInstance = (famInstWallElem != null); bool exportingFaceWall = (faceWall != null); if (!exportingWallElement && !exportingFamilyInstance && !exportingFaceWall) return null; if (exportingWallElement && IsWallCompletelyClipped(wallElement, exporterIFC, range)) return null; IFCRange zSpan = null; double depth = 0.0; bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End)); bool exportParts = PartExporter.CanExportParts(element); if (exportParts && !PartExporter.CanExportElementInPartExport(element, validRange ? overrideLevelId : element.LevelId, validRange)) return null; IList<Solid> solids = new List<Solid>(); IList<Mesh> meshes = new List<Mesh>(); bool exportingInplaceOpenings = false; if (!exportParts) { if (exportingWallElement || exportingFaceWall) { GetSolidsAndMeshes(geometryElement, range, ref solids, ref meshes); if (solids.Count == 0 && meshes.Count == 0) return null; } else { GeometryElement geomElemToUse = GetGeometryFromInplaceWall(famInstWallElem); if (geomElemToUse != null) { exportingInplaceOpenings = true; } else { exportingInplaceOpenings = false; geomElemToUse = geometryElement; } Transform trf = Transform.Identity; if (geomElemToUse != geometryElement) trf = famInstWallElem.GetTransform(); SolidMeshGeometryInfo solidMeshCapsule = GeometryUtil.GetSplitSolidMeshGeometry(geomElemToUse, trf); solids = solidMeshCapsule.GetSolids(); meshes = solidMeshCapsule.GetMeshes(); } } IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (ProductWrapper localWrapper = ProductWrapper.Create(origWrapper)) { // get bounding box height so that we can subtract out pieces properly. // only for Wall, not FamilyInstance. if (exportingWallElement && geometryElement != null) { // There is a problem in the API where some walls with vertical structures are overreporting their height, // making it appear as if there are clipping problems on export. We will work around this by getting the // height directly from the solid(s). if (solids.Count > 0 && meshes.Count == 0) { zSpan = GetBoundingBoxOfSolids(solids); } else { BoundingBoxXYZ boundingBox = wallElement.get_BoundingBox(null); if (boundingBox != null) zSpan = GetBoundingBoxZRange(boundingBox); } if (zSpan == null) return null; // if we have a top clipping plane, modify depth accordingly. double bottomHeight = validRange ? Math.Max(zSpan.Start, range.Start) : zSpan.Start; double topHeight = validRange ? Math.Min(zSpan.End, range.End) : zSpan.End; depth = topHeight - bottomHeight; if (MathUtil.IsAlmostZero(depth)) return null; depth = UnitUtil.ScaleLength(depth); } else { zSpan = new IFCRange(); } Document doc = element.Document; double baseWallElevation = 0.0; ElementId baseLevelId = PlacementSetter.GetBaseLevelIdForElement(element); if (baseLevelId != ElementId.InvalidElementId) { Element baseLevel = doc.GetElement(baseLevelId); if (baseLevel is Level) baseWallElevation = (baseLevel as Level).Elevation; } IFCAnyHandle axisRep = null; IFCAnyHandle bodyRep = null; bool exportingAxis = false; Curve trimmedCurve = null; bool exportedAsWallWithAxis = false; bool exportedBodyDirectly = false; Curve centerCurve = GetWallAxis(wallElement); XYZ localXDir = new XYZ(1, 0, 0); XYZ localYDir = new XYZ(0, 1, 0); XYZ localZDir = new XYZ(0, 0, 1); XYZ localOrig = new XYZ(0, 0, 0); double eps = MathUtil.Eps(); if (centerCurve != null) { Curve baseCurve = GetWallAxisAtBaseHeight(wallElement); trimmedCurve = GetWallTrimmedCurve(wallElement, baseCurve); IFCRange curveBounds; XYZ oldOrig; GeometryUtil.GetAxisAndRangeFromCurve(trimmedCurve, out curveBounds, out localXDir, out oldOrig); // Move the curve to the bottom of the geometry or the bottom of the range, which is higher. if (baseCurve != null) localOrig = new XYZ(oldOrig.X, oldOrig.Y, validRange ? Math.Max(range.Start, zSpan.Start) : zSpan.Start); else localOrig = oldOrig; double dist = localOrig[2] - oldOrig[2]; if (!MathUtil.IsAlmostZero(dist)) { XYZ moveVec = new XYZ(0, 0, dist); trimmedCurve = GeometryUtil.MoveCurve(trimmedCurve, moveVec); } localYDir = localZDir.CrossProduct(localXDir); // ensure that X and Z axes are orthogonal. double xzDot = localZDir.DotProduct(localXDir); if (!MathUtil.IsAlmostZero(xzDot)) localXDir = localYDir.CrossProduct(localZDir); } else { BoundingBoxXYZ boundingBox = element.get_BoundingBox(null); if (boundingBox != null) { XYZ bBoxMin = boundingBox.Min; XYZ bBoxMax = boundingBox.Max; if (validRange) localOrig = new XYZ(bBoxMin.X, bBoxMin.Y, range.Start); else localOrig = boundingBox.Min; XYZ localXDirMax = null; Transform bTrf = boundingBox.Transform; XYZ localXDirMax1 = new XYZ(bBoxMax.X, localOrig.Y, localOrig.Z); localXDirMax1 = bTrf.OfPoint(localXDirMax1); XYZ localXDirMax2 = new XYZ(localOrig.X, bBoxMax.Y, localOrig.Z); localXDirMax2 = bTrf.OfPoint(localXDirMax2); if (localXDirMax1.DistanceTo(localOrig) >= localXDirMax2.DistanceTo(localOrig)) localXDirMax = localXDirMax1; else localXDirMax = localXDirMax2; localXDir = localXDirMax.Subtract(localOrig); localXDir = localXDir.Normalize(); localYDir = localZDir.CrossProduct(localXDir); // ensure that X and Z axes are orthogonal. double xzDot = localZDir.DotProduct(localXDir); if (!MathUtil.IsAlmostZero(xzDot)) localXDir = localYDir.CrossProduct(localZDir); } } IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); Transform orientationTrf = Transform.Identity; orientationTrf.BasisX = localXDir; orientationTrf.BasisY = localYDir; orientationTrf.BasisZ = localZDir; orientationTrf.Origin = localOrig; double scaledFootprintArea = 0; double scaledLength = 0; using (PlacementSetter setter = PlacementSetter.Create(exporterIFC, element, null, orientationTrf, overrideLevelId)) { IFCAnyHandle localPlacement = setter.LocalPlacement; // The local coordinate system of the wall as defined by IFC for IfcWallStandardCase. Plane wallLCS = new Plane(localXDir, localYDir, localOrig); // project curve to XY plane. XYZ projDir = XYZ.BasisZ; // two representations: axis, body. { if (!exportParts && (centerCurve != null) && (GeometryUtil.CurveIsLineOrArc(centerCurve))) { exportingAxis = true; string identifierOpt = "Axis"; // IFC2x2 convention string representationTypeOpt = "Curve2D"; // IFC2x2 convention IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, wallLCS, projDir, false); ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, trimmedCurve, XYZ.Zero, true); IList<IFCAnyHandle> axisItems = info.GetCurves(); if (axisItems.Count == 0) { exportingAxis = false; } else { HashSet<IFCAnyHandle> axisItemSet = new HashSet<IFCAnyHandle>(); foreach (IFCAnyHandle axisItem in axisItems) axisItemSet.Add(axisItem); IFCAnyHandle contextOfItemsAxis = exporterIFC.Get3DContextHandle("Axis"); axisRep = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, contextOfItemsAxis, identifierOpt, representationTypeOpt, axisItemSet); } } } IList<IFCExtrusionData> cutPairOpenings = new List<IFCExtrusionData>(); if (!exportParts && exportingWallElement && exportingAxis && trimmedCurve != null) { bool isCompletelyClipped; bodyRep = TryToCreateAsExtrusion(exporterIFC, wallElement, connectedWalls, solids, meshes, baseWallElevation, catId, centerCurve, trimmedCurve, wallLCS, depth, zSpan, range, setter, out cutPairOpenings, out isCompletelyClipped, out scaledFootprintArea, out scaledLength); if (isCompletelyClipped) return null; if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) exportedAsWallWithAxis = true; } using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData()) { BodyData bodyData = null; if (!exportedAsWallWithAxis) { extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ; // only allow vertical extrusions! extraParams.AreInnerRegionsOpenings = true; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); // Swept solids are not natively exported as part of CV2.0. // We have removed the UI toggle for this, so that it is by default false, but keep for possible future use. if (ExporterCacheManager.ExportOptionsCache.ExportAdvancedSweptSolids) bodyExporterOptions.TryToExportAsSweptSolid = true; ElementId overrideMaterialId = ElementId.InvalidElementId; if (exportingWallElement) overrideMaterialId = HostObjectExporter.GetFirstLayerMaterialId(wallElement); if (!exportParts) { if ((solids.Count > 0) || (meshes.Count > 0)) { bodyRep = BodyExporter.ExportBody(exporterIFC, element, catId, overrideMaterialId, solids, meshes, bodyExporterOptions, extraParams).RepresentationHnd; } else { IList<GeometryObject> geomElemList = new List<GeometryObject>(); geomElemList.Add(geometryElement); bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, overrideMaterialId, geomElemList, bodyExporterOptions, extraParams); bodyRep = bodyData.RepresentationHnd; } if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { extraParams.ClearOpenings(); return null; } } // We will be able to export as a IfcWallStandardCase as long as we have an axis curve. XYZ extrDirUsed = XYZ.Zero; if (extraParams.HasExtrusionDirection) { extrDirUsed = extraParams.ExtrusionDirection; if (MathUtil.IsAlmostEqual(Math.Abs(extrDirUsed[2]), 1.0)) { if ((solids.Count == 1) && (meshes.Count == 0)) exportedAsWallWithAxis = exportingAxis; exportedBodyDirectly = true; } } } IFCAnyHandle prodRep = null; if (!exportParts) { IList<IFCAnyHandle> representations = new List<IFCAnyHandle>(); if (exportingAxis) representations.Add(axisRep); representations.Add(bodyRep); IFCAnyHandle boundingBoxRep = null; if ((solids.Count > 0) || (meshes.Count > 0)) boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, solids, meshes, Transform.Identity); else boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity); if (boundingBoxRep != null) representations.Add(boundingBoxRep); prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); } ElementId matId = ElementId.InvalidElementId; string objectType = NamingUtil.CreateIFCObjectName(exporterIFC, element); IFCAnyHandle wallHnd = null; string elemGUID = null; int subElementIndex = ExporterStateManager.GetCurrentRangeIndex(); if (subElementIndex == 0) elemGUID = GUIDUtil.CreateGUID(element); else if (subElementIndex <= ExporterStateManager.RangeIndexSetter.GetMaxStableGUIDs()) elemGUID = GUIDUtil.CreateSubElementGUID(element, subElementIndex + (int)IFCGenericSubElements.SplitInstanceStart - 1); else elemGUID = GUIDUtil.CreateGUID(); string elemName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string elemDesc = NamingUtil.GetDescriptionOverride(element, null); string elemObjectType = NamingUtil.GetObjectTypeOverride(element, objectType); string elemTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); string ifcType = IFCValidateEntry.GetValidIFCType(element, null); // For Foundation and Retaining walls, allow exporting as IfcFooting instead. bool exportAsFooting = false; if (exportingWallElement) { WallType wallType = wallElement.WallType; if (wallType != null) { int wallFunction; if (ParameterUtil.GetIntValueFromElement(wallType, BuiltInParameter.FUNCTION_PARAM, out wallFunction) != null) { if (wallFunction == (int)WallFunction.Retaining || wallFunction == (int)WallFunction.Foundation) { // In this case, allow potential to export foundation and retaining walls as footing. string enumTypeValue = null; IFCExportType exportType = ExporterUtil.GetExportType(exporterIFC, wallElement, out enumTypeValue); if (exportType == IFCExportType.IfcFooting) exportAsFooting = true; } } } } if (exportedAsWallWithAxis) { if (exportAsFooting) { wallHnd = IFCInstanceExporter.CreateFooting(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType, localPlacement, exportParts ? null : prodRep, elemTag, ifcType); } else { bool exportAsWall = exportParts; if (!exportAsWall) { // (For Reference View export) If the representation returned earlier is of type Tessellation, create IfcWall instead. foreach (IFCAnyHandle pRep in IFCAnyHandleUtil.GetRepresentations(prodRep)) { if (String.Compare(IFCAnyHandleUtil.GetRepresentationType(pRep), "Tessellation") == 0) { exportAsWall = true; break; } } } if (exportAsWall) { wallHnd = IFCInstanceExporter.CreateWall(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType, localPlacement, null, elemTag, ifcType); } else { wallHnd = IFCInstanceExporter.CreateWallStandardCase(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType, localPlacement, prodRep, elemTag, ifcType); } } if (exportParts) PartExporter.ExportHostPart(exporterIFC, element, wallHnd, localWrapper, setter, localPlacement, overrideLevelId); localWrapper.AddElement(element, wallHnd, setter, extraParams, true); if (!exportParts) { OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, cutPairOpenings, null, exporterIFC, localPlacement, setter, localWrapper); if (exportedBodyDirectly) { Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity; OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, extraParams, offsetTransform, exporterIFC, localPlacement, setter, localWrapper); } else { double scaledWidth = UnitUtil.ScaleLength(wallElement.Width); OpeningUtil.AddOpeningsToElement(exporterIFC, wallHnd, wallElement, null, scaledWidth, range, setter, localPlacement, localWrapper); } } // export Base Quantities if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities) { scaledFootprintArea = MathUtil.AreaIsAlmostZero(scaledFootprintArea) ? extraParams.ScaledArea : scaledFootprintArea; scaledLength = MathUtil.IsAlmostZero(scaledLength) ? extraParams.ScaledLength : scaledLength; PropertyUtil.CreateWallBaseQuantities(exporterIFC, wallElement, solids, meshes, wallHnd, scaledLength, depth, scaledFootprintArea); } } else { if (exportAsFooting) { wallHnd = IFCInstanceExporter.CreateFooting(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType, localPlacement, exportParts ? null : prodRep, elemTag, ifcType); } else { wallHnd = IFCInstanceExporter.CreateWall(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType, localPlacement, exportParts ? null : prodRep, elemTag, ifcType); } if (exportParts) PartExporter.ExportHostPart(exporterIFC, element, wallHnd, localWrapper, setter, localPlacement, overrideLevelId); localWrapper.AddElement(element, wallHnd, setter, extraParams, true); if (!exportParts) { // Only export one material for 2x2; for future versions, export the whole list. if (ExporterCacheManager.ExportOptionsCache.ExportAs2x2 || exportingFamilyInstance) { matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(solids, meshes, element); if (matId != ElementId.InvalidElementId) CategoryUtil.CreateMaterialAssociation(exporterIFC, wallHnd, matId); } if (exportingInplaceOpenings) { OpeningUtil.AddOpeningsToElement(exporterIFC, wallHnd, famInstWallElem, null, 0.0, range, setter, localPlacement, localWrapper); } if (exportedBodyDirectly) { Transform offsetTransform = (bodyData != null) ? bodyData.OffsetTransform : Transform.Identity; OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, extraParams, offsetTransform, exporterIFC, localPlacement, setter, localWrapper); } } } ElementId wallLevelId = (validRange) ? setter.LevelId : ElementId.InvalidElementId; if ((exportingWallElement || exportingFaceWall) && !exportParts) { HostObject hostObject = null; if (exportingWallElement) hostObject = wallElement; else hostObject = faceWall; if (!ExporterCacheManager.ExportOptionsCache.ExportAs2x2 || exportedAsWallWithAxis) HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, localWrapper.GetAnElement(), geometryElement, localWrapper, wallLevelId, Toolkit.IFCLayerSetDirection.Axis2, !exportedAsWallWithAxis); } ExportWallType(exporterIFC, localWrapper, wallHnd, element, matId, exportedAsWallWithAxis, exportAsFooting); SpaceBoundingElementUtil.RegisterSpaceBoundingElementHandle(exporterIFC, wallHnd, element.Id, wallLevelId); tr.Commit(); return wallHnd; } } } } }
/// <summary> /// Main implementation to export walls. /// </summary> /// <param name="exporterIFC"> /// The ExporterIFC object. /// </param> /// <param name="element"> /// The element. /// </param> /// <param name="geometryElement"> /// The geometry element. /// </param> /// <param name="origWrapper"> /// The ProductWrapper. /// </param> /// <param name="overrideLevelId"> /// The level id. /// </param> /// <param name="range"> /// The range to be exported for the element. /// </param> /// <returns> /// The exported wall handle. /// </returns> public static IFCAnyHandle ExportWallBase(ExporterIFC exporterIFC, Element element, GeometryElement geometryElement, ProductWrapper origWrapper, ElementId overrideLevelId, IFCRange range) { IFCFile file = exporterIFC.GetFile(); using (IFCTransaction tr = new IFCTransaction(file)) { using (ProductWrapper localWrapper = ProductWrapper.Create(origWrapper)) { ElementId catId = CategoryUtil.GetSafeCategoryId(element); Wall wallElement = element as Wall; FamilyInstance famInstWallElem = element as FamilyInstance; FaceWall faceWall = element as FaceWall; if (wallElement == null && famInstWallElem == null && faceWall == null) return null; if (wallElement != null && IsWallCompletelyClipped(wallElement, exporterIFC, range)) return null; // get global values. Document doc = element.Document; double scale = exporterIFC.LinearScale; IFCAnyHandle ownerHistory = exporterIFC.GetOwnerHistoryHandle(); IFCAnyHandle contextOfItemsAxis = exporterIFC.Get3DContextHandle("Axis"); IFCAnyHandle contextOfItemsBody = exporterIFC.Get3DContextHandle("Body"); IFCRange zSpan = new IFCRange(); double depth = 0.0; bool validRange = (range != null && !MathUtil.IsAlmostZero(range.Start - range.End)); bool exportParts = PartExporter.CanExportParts(element); if (exportParts && !PartExporter.CanExportElementInPartExport(element, validRange ? overrideLevelId : element.Level.Id, validRange)) return null; // get bounding box height so that we can subtract out pieces properly. // only for Wall, not FamilyInstance. if (wallElement != null && geometryElement != null) { BoundingBoxXYZ boundingBox = element.get_BoundingBox(null); if (boundingBox == null) return null; zSpan = new IFCRange(boundingBox.Min.Z, boundingBox.Max.Z); // if we have a top clipping plane, modify depth accordingly. double bottomHeight = validRange ? Math.Max(zSpan.Start, range.Start) : zSpan.Start; double topHeight = validRange ? Math.Min(zSpan.End, range.End) : zSpan.End; depth = topHeight - bottomHeight; if (MathUtil.IsAlmostZero(depth)) return null; depth *= scale; } IFCAnyHandle axisRep = null; IFCAnyHandle bodyRep = null; bool exportingAxis = false; Curve curve = null; bool exportedAsWallWithAxis = false; bool exportedBodyDirectly = false; bool exportingInplaceOpenings = false; Curve centerCurve = GetWallAxis(wallElement); XYZ localXDir = new XYZ(1, 0, 0); XYZ localYDir = new XYZ(0, 1, 0); XYZ localZDir = new XYZ(0, 0, 1); XYZ localOrig = new XYZ(0, 0, 0); double eps = MathUtil.Eps(); if (centerCurve != null) { Curve baseCurve = GetWallAxisAtBaseHeight(wallElement); curve = GetWallTrimmedCurve(wallElement, baseCurve); IFCRange curveBounds; XYZ oldOrig; GeometryUtil.GetAxisAndRangeFromCurve(curve, out curveBounds, out localXDir, out oldOrig); localOrig = oldOrig; if (baseCurve != null) { if (!validRange || (MathUtil.IsAlmostEqual(range.Start, zSpan.Start))) { XYZ newOrig = baseCurve.Evaluate(curveBounds.Start, false); if (!validRange && (zSpan.Start < newOrig[2] - eps)) localOrig = new XYZ(localOrig.X, localOrig.Y, zSpan.Start); else localOrig = new XYZ(localOrig.X, localOrig.Y, newOrig[2]); } else { localOrig = new XYZ(localOrig.X, localOrig.Y, range.Start); } } double dist = localOrig[2] - oldOrig[2]; if (!MathUtil.IsAlmostZero(dist)) { XYZ moveVec = new XYZ(0, 0, dist); curve = GeometryUtil.MoveCurve(curve, moveVec); } localYDir = localZDir.CrossProduct(localXDir); // ensure that X and Z axes are orthogonal. double xzDot = localZDir.DotProduct(localXDir); if (!MathUtil.IsAlmostZero(xzDot)) localXDir = localYDir.CrossProduct(localZDir); } else { BoundingBoxXYZ boundingBox = element.get_BoundingBox(null); if (boundingBox != null) { XYZ bBoxMin = boundingBox.Min; XYZ bBoxMax = boundingBox.Max; if (validRange) localOrig = new XYZ(bBoxMin.X, bBoxMin.Y, range.Start); else localOrig = boundingBox.Min; XYZ localXDirMax = null; Transform bTrf = boundingBox.Transform; XYZ localXDirMax1 = new XYZ(bBoxMax.X, localOrig.Y, localOrig.Z); localXDirMax1 = bTrf.OfPoint(localXDirMax1); XYZ localXDirMax2 = new XYZ(localOrig.X, bBoxMax.Y, localOrig.Z); localXDirMax2 = bTrf.OfPoint(localXDirMax2); if (localXDirMax1.DistanceTo(localOrig) >= localXDirMax2.DistanceTo(localOrig)) localXDirMax = localXDirMax1; else localXDirMax = localXDirMax2; localXDir = localXDirMax.Subtract(localOrig); localXDir = localXDir.Normalize(); localYDir = localZDir.CrossProduct(localXDir); // ensure that X and Z axes are orthogonal. double xzDot = localZDir.DotProduct(localXDir); if (!MathUtil.IsAlmostZero(xzDot)) localXDir = localYDir.CrossProduct(localZDir); } } Transform orientationTrf = Transform.Identity; orientationTrf.BasisX = localXDir; orientationTrf.BasisY = localYDir; orientationTrf.BasisZ = localZDir; orientationTrf.Origin = localOrig; using (IFCPlacementSetter setter = IFCPlacementSetter.Create(exporterIFC, element, null, orientationTrf, overrideLevelId)) { IFCAnyHandle localPlacement = setter.GetPlacement(); Plane plane = new Plane(localXDir, localYDir, localOrig); // project curve to XY plane. XYZ projDir = XYZ.BasisZ; // two representations: axis, body. { if (!exportParts && (centerCurve != null) && (GeometryUtil.CurveIsLineOrArc(centerCurve))) { exportingAxis = true; string identifierOpt = "Axis"; // IFC2x2 convention string representationTypeOpt = "Curve2D"; // IFC2x2 convention IFCGeometryInfo info = IFCGeometryInfo.CreateCurveGeometryInfo(exporterIFC, plane, projDir, false); ExporterIFCUtils.CollectGeometryInfo(exporterIFC, info, curve, XYZ.Zero, true); IList<IFCAnyHandle> axisItems = info.GetCurves(); if (axisItems.Count == 0) { exportingAxis = false; } else { HashSet<IFCAnyHandle> axisItemSet = new HashSet<IFCAnyHandle>(); foreach (IFCAnyHandle axisItem in axisItems) axisItemSet.Add(axisItem); axisRep = RepresentationUtil.CreateShapeRepresentation(exporterIFC, element, catId, contextOfItemsAxis, identifierOpt, representationTypeOpt, axisItemSet); } } } IList<IFCExtrusionData> cutPairOpenings = new List<IFCExtrusionData>(); Document document = element.Document; IList<Solid> solids = new List<Solid>(); IList<Mesh> meshes = new List<Mesh>(); if (!exportParts && wallElement != null && exportingAxis && curve != null) { SolidMeshGeometryInfo solidMeshInfo = (range == null) ? GeometryUtil.GetSplitSolidMeshGeometry(geometryElement) : GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range); solids = solidMeshInfo.GetSolids(); meshes = solidMeshInfo.GetMeshes(); if (solids.Count == 0 && meshes.Count == 0) return null; bool useNewCode = false; if (useNewCode && solids.Count == 1 && meshes.Count == 0) { bool completelyClipped; bodyRep = ExtrusionExporter.CreateExtrusionWithClipping(exporterIFC, wallElement, catId, solids[0], plane, projDir, range, out completelyClipped); if (completelyClipped) return null; if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { exportedAsWallWithAxis = true; exportedBodyDirectly = true; } else { exportedAsWallWithAxis = false; exportedBodyDirectly = false; } } if (!exportedAsWallWithAxis) { // Fallback - use native routines to try to export wall. bool isCompletelyClipped; bodyRep = FallbackTryToCreateAsExtrusion(exporterIFC, wallElement, solidMeshInfo, catId, curve, plane, depth, zSpan, range, setter, out cutPairOpenings, out isCompletelyClipped); if (isCompletelyClipped) return null; if (!IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) exportedAsWallWithAxis = true; } } using (IFCExtrusionCreationData extraParams = new IFCExtrusionCreationData()) { if (!exportedAsWallWithAxis) { SolidMeshGeometryInfo solidMeshCapsule = null; if (wallElement != null || faceWall != null) { if (validRange) { solidMeshCapsule = GeometryUtil.GetSplitClippedSolidMeshGeometry(geometryElement, range); } else { solidMeshCapsule = GeometryUtil.GetSplitSolidMeshGeometry(geometryElement); } if (solidMeshCapsule.SolidsCount() == 0 && solidMeshCapsule.MeshesCount() == 0) { return null; } } else { GeometryElement geomElemToUse = GetGeometryFromInplaceWall(famInstWallElem); if (geomElemToUse != null) { exportingInplaceOpenings = true; } else { exportingInplaceOpenings = false; geomElemToUse = geometryElement; } Transform trf = Transform.Identity; if (geomElemToUse != geometryElement) trf = famInstWallElem.GetTransform(); solidMeshCapsule = GeometryUtil.GetSplitSolidMeshGeometry(geomElemToUse, trf); } solids = solidMeshCapsule.GetSolids(); meshes = solidMeshCapsule.GetMeshes(); extraParams.PossibleExtrusionAxes = IFCExtrusionAxes.TryZ; // only allow vertical extrusions! extraParams.AreInnerRegionsOpenings = true; BodyExporterOptions bodyExporterOptions = new BodyExporterOptions(true); // Swept solids are not natively exported as part of CV2.0. However, we will add UI to allow a user // to switch of advanced swept solid support. if (ExporterCacheManager.ExportOptionsCache.ExportAdvancedSweptSolids) bodyExporterOptions.TryToExportAsSweptSolid = true; ElementId overrideMaterialId = ElementId.InvalidElementId; if (wallElement != null) overrideMaterialId = HostObjectExporter.GetFirstLayerMaterialId(wallElement); if (!exportParts) { if ((solids.Count > 0) || (meshes.Count > 0)) { bodyRep = BodyExporter.ExportBody(exporterIFC, element, catId, overrideMaterialId, solids, meshes, bodyExporterOptions, extraParams).RepresentationHnd; } else { IList<GeometryObject> geomElemList = new List<GeometryObject>(); geomElemList.Add(geometryElement); BodyData bodyData = BodyExporter.ExportBody(exporterIFC, element, catId, overrideMaterialId, geomElemList, bodyExporterOptions, extraParams); bodyRep = bodyData.RepresentationHnd; } if (IFCAnyHandleUtil.IsNullOrHasNoValue(bodyRep)) { extraParams.ClearOpenings(); return null; } } // We will be able to export as a IfcWallStandardCase as long as we have an axis curve. XYZ extrDirUsed = XYZ.Zero; if (extraParams.HasExtrusionDirection) { extrDirUsed = extraParams.ExtrusionDirection; if (MathUtil.IsAlmostEqual(Math.Abs(extrDirUsed[2]), 1.0)) { if ((solids.Count == 1) && (meshes.Count == 0)) exportedAsWallWithAxis = exportingAxis; exportedBodyDirectly = true; } } } IFCAnyHandle prodRep = null; if (!exportParts) { IList<IFCAnyHandle> representations = new List<IFCAnyHandle>(); if (exportingAxis) representations.Add(axisRep); representations.Add(bodyRep); IFCAnyHandle boundingBoxRep = null; if ((solids.Count > 0) || (meshes.Count > 0)) boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, solids, meshes, Transform.Identity); else boundingBoxRep = BoundingBoxExporter.ExportBoundingBox(exporterIFC, geometryElement, Transform.Identity); if (boundingBoxRep != null) representations.Add(boundingBoxRep); prodRep = IFCInstanceExporter.CreateProductDefinitionShape(file, null, null, representations); } ElementId matId = ElementId.InvalidElementId; string objectType = NamingUtil.CreateIFCObjectName(exporterIFC, element); IFCAnyHandle wallHnd = null; string elemGUID = (validRange) ? GUIDUtil.CreateGUID() : GUIDUtil.CreateGUID(element); string elemName = NamingUtil.GetNameOverride(element, NamingUtil.GetIFCName(element)); string elemDesc = NamingUtil.GetDescriptionOverride(element, null); string elemObjectType = NamingUtil.GetObjectTypeOverride(element, objectType); string elemTag = NamingUtil.GetTagOverride(element, NamingUtil.CreateIFCElementId(element)); if (exportedAsWallWithAxis) { if (exportParts) wallHnd = IFCInstanceExporter.CreateWall(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType, localPlacement, null, elemTag); else wallHnd = IFCInstanceExporter.CreateWallStandardCase(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType, localPlacement, prodRep, elemTag); if (exportParts) PartExporter.ExportHostPart(exporterIFC, element, wallHnd, localWrapper, setter, localPlacement, overrideLevelId); localWrapper.AddElement(wallHnd, setter, extraParams, true); if (!exportParts) { OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, cutPairOpenings, exporterIFC, localPlacement, setter, localWrapper); if (exportedBodyDirectly) { OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, extraParams, exporterIFC, localPlacement, setter, localWrapper); } else { ICollection<IFCAnyHandle> beforeOpenings = localWrapper.GetAllObjects(); double scaledWidth = wallElement.Width * scale; ExporterIFCUtils.AddOpeningsToElement(exporterIFC, wallHnd, wallElement, scaledWidth, range, setter, localPlacement, localWrapper.ToNative()); ICollection<IFCAnyHandle> afterOpenings = localWrapper.GetAllObjects(); if (beforeOpenings.Count != afterOpenings.Count) { foreach (IFCAnyHandle before in beforeOpenings) afterOpenings.Remove(before); foreach (IFCAnyHandle potentiallyBadOpening in afterOpenings) { PotentiallyCorrectOpeningOrientationAndOpeningType(potentiallyBadOpening, localPlacement, scaledWidth); } } } } // export Base Quantities if (ExporterCacheManager.ExportOptionsCache.ExportBaseQuantities) { CreateWallBaseQuantities(exporterIFC, wallElement, wallHnd, depth); } } else { wallHnd = IFCInstanceExporter.CreateWall(file, elemGUID, ownerHistory, elemName, elemDesc, elemObjectType, localPlacement, exportParts ? null : prodRep, elemTag); if (exportParts) PartExporter.ExportHostPart(exporterIFC, element, wallHnd, localWrapper, setter, localPlacement, overrideLevelId); localWrapper.AddElement(wallHnd, setter, extraParams, true); // Only export one material for 2x2; for future versions, export the whole list. if ((exporterIFC.ExportAs2x2 || famInstWallElem != null) && !exportParts) { matId = BodyExporter.GetBestMaterialIdFromGeometryOrParameter(solids, meshes, element); if (matId != ElementId.InvalidElementId) CategoryUtil.CreateMaterialAssociation(doc, exporterIFC, wallHnd, matId); } if (!exportParts) { if (exportingInplaceOpenings) { ExporterIFCUtils.AddOpeningsToElement(exporterIFC, wallHnd, famInstWallElem, 0.0, range, setter, localPlacement, localWrapper.ToNative()); } if (exportedBodyDirectly) OpeningUtil.CreateOpeningsIfNecessary(wallHnd, element, extraParams, exporterIFC, localPlacement, setter, localWrapper); } } PropertyUtil.CreateInternalRevitPropertySets(exporterIFC, element, localWrapper); ElementId wallLevelId = (validRange) ? setter.LevelId : ElementId.InvalidElementId; if ((wallElement != null || faceWall != null) && !exportParts) { HostObject hostObject = null; if (wallElement != null) hostObject = wallElement; else hostObject = faceWall; if (!exporterIFC.ExportAs2x2 || exportedAsWallWithAxis) //will move this check into ExportHostObject HostObjectExporter.ExportHostObjectMaterials(exporterIFC, hostObject, localWrapper.GetAnElement(), geometryElement, localWrapper, wallLevelId, Toolkit.IFCLayerSetDirection.Axis2); } ExportWallType(exporterIFC, wallHnd, element, matId,exportedAsWallWithAxis); exporterIFC.RegisterSpaceBoundingElementHandle(wallHnd, element.Id, wallLevelId); tr.Commit(); return wallHnd; } } } } }
public override Value Evaluate(FSharpList<Value> args) { var curves = ((Value.List)args[0]).Item.Select( x => ((Curve)((Value.Container)x).Item)).ToList(); List<Curve> curvesWithFlip = new List<Curve>(); bool bStart = true; XYZ prevEnd = new XYZ(); double tolMax = 0.0001; double tolMin = 0.00001; foreach (Curve c in curves) { if (!bStart) { XYZ thisEnd = c.Evaluate(1.0, true); XYZ thisStart = c.Evaluate(0.0, true); double thisDist = thisStart.DistanceTo(prevEnd); if (thisDist > tolMax && thisEnd.DistanceTo(prevEnd) < tolMin && (c is Line)) { prevEnd = thisStart; Curve flippedCurve = /* Line.CreateBound */ dynRevitSettings.Revit.Application.Create.NewLineBound(thisEnd, thisStart); curvesWithFlip.Add(flippedCurve); continue; } } else { bStart = false; prevEnd = c.Evaluate(1.0, true); if (curves.Count > 1) { XYZ nextStart = curves[1].Evaluate(0.0, true); double thisDist = prevEnd.DistanceTo(nextStart); if (thisDist > tolMax) { XYZ nextEnd = curves[1].Evaluate(1.0, true); if (nextEnd.DistanceTo(prevEnd) > tolMax) { XYZ thisStart = c.Evaluate(0.0, true); if (thisStart.DistanceTo(nextEnd) < tolMin || thisStart.DistanceTo(nextStart) < tolMin) { if (c is Line) { Curve flippedCurve = /* Line.CreateBound */ dynRevitSettings.Revit.Application.Create.NewLineBound(prevEnd, thisStart); prevEnd = thisStart; curvesWithFlip.Add(flippedCurve); continue; } } } } } } prevEnd = c.Evaluate(1.0, true); curvesWithFlip.Add(c); } Autodesk.Revit.DB.CurveLoop result = Autodesk.Revit.DB.CurveLoop.Create(curvesWithFlip); return Value.NewContainer(result); }
public static Line CreateLineSafe(this Document doc, XYZ p1, XYZ p2) { if (p1.DistanceTo(p2) > doc.Application.ShortCurveTolerance) { return Line.CreateBound(p1, p2); } return null; }