//public void CreateModelLine( XYZ p, XYZ q ) //{ // if( p.IsAlmostEqualTo( q ) ) // { // throw new ArgumentException( // "Expected two different points." ); // } // Line line = Line.CreateBound( p, q ); // if( null == line ) // { // throw new Exception( // "Geometry line creation failed." ); // } // _credoc.NewModelCurve( line, // NewSketchPlanePassLine( line ) ); //} /// <summary> /// Return a new sketch plane containing the given curve. /// Update, later: please note that the Revit API provides /// an overload of the NewPlane method taking a CurveArray /// argument, which could presumably be used instead. /// </summary> SketchPlane NewSketchPlaneContainCurve( Curve curve) { XYZ p = curve.GetEndPoint(0); XYZ normal = GetCurveNormal(curve); //Plane plane = _creapp.NewPlane( normal, p ); // 2016 Plane plane = Plane.CreateByNormalAndOrigin(normal, p); // 2017 #if DEBUG if (!(curve is Line)) { //CurveArray a = _creapp.NewCurveArray(); //a.Append( curve ); //Plane plane2 = _creapp.NewPlane( a ); // 2016 List <Curve> a = new List <Curve>(1); a.Add(curve); CurveLoop b = CurveLoop.Create(a); Plane plane2 = b.GetPlane(); // 2017 Debug.Assert(Util.IsParallel(plane2.Normal, plane.Normal), "expected equal planes"); Debug.Assert(Util.IsZero(plane2.SignedDistanceTo( plane.Origin)), "expected equal planes"); } #endif // DEBUG //return _credoc.NewSketchPlane( plane ); // 2013 return(SketchPlane.Create(_doc, plane)); // 2014 }
/// <summary> /// Identifies if the curve lies entirely in an XY plane (Z = constant) /// </summary> /// <param name="curve">The curve.</param> /// <returns>True if the curve lies in an XY plane, false otherwise.</returns> public static bool IsCurveInXYPlane(Curve curve) { // quick reject - are endpoints at same Z double zDelta = curve.GetEndPoint(1).Z - curve.GetEndPoint(0).Z; if (Math.Abs(zDelta) > 1e-05) { return(false); } if (!(curve is Line) && !curve.IsCyclic) { // Create curve loop from curve and connecting line to get plane List <Curve> curves = new List <Curve>(); curves.Add(curve); curves.Add(Line.CreateBound(curve.GetEndPoint(1), curve.GetEndPoint(0))); CurveLoop curveLoop = CurveLoop.Create(curves); XYZ normal = curveLoop.GetPlane().Normal.Normalize(); if (!normal.IsAlmostEqualTo(XYZ.BasisZ) && !normal.IsAlmostEqualTo(XYZ.BasisZ.Negate())) { return(false); } } return(true); }
public static Plane GetPlaneFromCurve(Curve c, bool planarOnly) { //find the plane of the curve and generate a sketch plane double period = c.IsBound ? 0.0 : (c.IsCyclic ? c.Period : 1.0); var p0 = c.IsBound ? c.Evaluate(0.0, true) : c.Evaluate(0.0, false); var p1 = c.IsBound ? c.Evaluate(0.5, true) : c.Evaluate(0.25 * period, false); var p2 = c.IsBound ? c.Evaluate(1.0, true) : c.Evaluate(0.5 * period, false); if (IsLineLike(c)) { XYZ norm = null; //keep old plane computations if (Math.Abs(p0.Z - p2.Z) < Tolerance) { norm = XYZ.BasisZ; } else { var v1 = p1 - p0; var v2 = p2 - p0; var p3 = new XYZ(p2.X, p2.Y, p0.Z); var v3 = p3 - p0; norm = v1.CrossProduct(v3); if (norm.IsZeroLength()) { norm = v2.CrossProduct(XYZ.BasisY); } norm = norm.Normalize(); } return(Plane.CreateByNormalAndOrigin(norm, p0)); } var cLoop = new CurveLoop(); cLoop.Append(c.Clone()); if (cLoop.HasPlane()) { return(cLoop.GetPlane()); } if (planarOnly) { return(null); } // Get best fit plane using tesselation var points = c.Tessellate().Select(x => x.ToPoint(false)); var bestFitPlane = Autodesk.DesignScript.Geometry.Plane.ByBestFitThroughPoints(points); return(bestFitPlane.ToPlane(false)); }
public static Plane GetPlaneFromCurve(Curve c, bool planarOnly) { //find the plane of the curve and generate a sketch plane double period = c.IsBound ? 0.0 : (c.IsCyclic ? c.Period : 1.0); var p0 = c.IsBound ? c.Evaluate(0.0, true) : c.Evaluate(0.0, false); var p1 = c.IsBound ? c.Evaluate(0.5, true) : c.Evaluate(0.25 * period, false); var p2 = c.IsBound ? c.Evaluate(1.0, true) : c.Evaluate(0.5 * period, false); if (IsLineLike(c)) { XYZ norm = null; //keep old plane computations if (System.Math.Abs(p0.Z - p2.Z) < Tolerance) { norm = XYZ.BasisZ; } else { var v1 = p1 - p0; var v2 = p2 - p0; var p3 = new XYZ(p2.X, p2.Y, p0.Z); var v3 = p3 - p0; norm = v1.CrossProduct(v3); if (norm.IsZeroLength()) { norm = v2.CrossProduct(XYZ.BasisY); } norm = norm.Normalize(); } return new Plane(norm, p0); } var cLoop = new CurveLoop(); cLoop.Append(c.Clone()); if (cLoop.HasPlane()) { return cLoop.GetPlane(); } if (planarOnly) return null; // Get best fit plane using tesselation var points = c.Tessellate().Select(x => x.ToPoint(false)); var bestFitPlane = Autodesk.DesignScript.Geometry.Plane.ByBestFitThroughPoints(points); return bestFitPlane.ToPlane(false); }
/***************************************************/ /**** Public methods ****/ /***************************************************/ public static bool IsVerticalNonLinearCurve(this Curve revitCurve, RevitSettings settings) { if (!(revitCurve is Line)) { CurveLoop curveLoop = CurveLoop.Create(new Curve[] { revitCurve }); if (curveLoop.HasPlane()) { Plane curvePlane = curveLoop.GetPlane(); //Orientation angles are handled slightly differently for framing elements that have a curve fits in a plane that contains the z-vector if (Math.Abs(curvePlane.Normal.DotProduct(XYZ.BasisZ)) < settings.AngleTolerance) { return(true); } } } return(false); }
/// <summary> /// 将CurveLoop压平在xoy平面 /// </summary> /// <param name="loop"></param> /// <returns>如果loop不能确定一个平面,则返回空</returns> public static CurveLoop ProjectXoy(this CurveLoop loop) { Plane plane = null; try { plane = loop.GetPlane(); } catch { /*loop没有在平面内*/ } if (plane != null && !plane.Normal.IsVertical()) { return(null); } XYZ vector = XYZ.Zero - new XYZ(0, 0, loop.FirstOrDefault().GetEndPoint(0).Z); Transform transform = Transform.CreateTranslation(vector); return(CurveLoop.CreateViaTransform(loop, transform)); }
/// <summary> /// Create arc element by three points /// </summary> /// <param name="app">revit application</param> /// <param name="ptA">point a</param> /// <param name="ptB">point b</param> /// <param name="ptC">point c</param> /// <returns></returns> public static ModelCurve MakeArc(UIApplication app, Autodesk.Revit.DB.XYZ ptA, Autodesk.Revit.DB.XYZ ptB, Autodesk.Revit.DB.XYZ ptC) { Document doc = app.ActiveUIDocument.Document; Arc arc = Arc.Create(ptA, ptB, ptC); // Create three lines and a plane by the points Line line1 = Line.CreateBound(ptA, ptB); Line line2 = Line.CreateBound(ptB, ptC); Line line3 = Line.CreateBound(ptC, ptA); CurveLoop ca = new CurveLoop(); ca.Append(line1); ca.Append(line2); ca.Append(line3); Plane plane = ca.GetPlane();// app.Application.Create.NewPlane(ca); SketchPlane skplane = SketchPlane.Create(doc, plane); // Create arc here ModelCurve modelcurve = doc.FamilyCreate.NewModelCurve(arc, skplane); return(modelcurve); }
/// <summary> /// Computes height and width of a curve loop with respect to the projection plane. /// </summary> /// <param name="curveLoop">The curve loop.</param> /// <param name="plane">The projection plane.</param> /// <param name="height">The height.</param> /// <param name="width">The width.</param> /// <returns>True if success, false if fail.</returns> public static bool ComputeHeightWidthOfCurveLoop(CurveLoop curveLoop, Plane plane, out double height, out double width) { height = 0.0; width = 0.0; Plane localPlane = plane; if (localPlane == null) { try { localPlane = curveLoop.GetPlane(); } catch { return false; } } if (curveLoop.IsRectangular(localPlane)) { height = curveLoop.GetRectangularHeight(localPlane); width = curveLoop.GetRectangularWidth(localPlane); return true; } else return false; }
private static IFCAnyHandle CreateCircleProfileDefIfPossible(ExporterIFC exporterIFC, string profileName, CurveLoop curveLoop, Plane origPlane, XYZ projDir) { IFCFile file = exporterIFC.GetFile(); if (curveLoop.IsOpen()) return null; XYZ origPlaneNorm = origPlane.Normal; Plane curveLoopPlane = null; try { curveLoopPlane = curveLoop.GetPlane(); } catch { return null; } XYZ curveLoopPlaneNorm = curveLoopPlane.Normal; if (!MathUtil.IsAlmostEqual(Math.Abs(origPlaneNorm.DotProduct(curveLoopPlaneNorm)), 1.0)) return null; IList<Arc> arcs = new List<Arc>(); foreach (Curve curve in curveLoop) { if (!(curve is Arc)) return null; arcs.Add(curve as Arc); } int numArcs = arcs.Count; if (numArcs == 0) return null; double radius = arcs[0].Radius; XYZ ctr = arcs[0].Center; for (int ii = 1; ii < numArcs; ii++) { XYZ newCenter = arcs[ii].Center; if (!newCenter.IsAlmostEqualTo(ctr)) return null; } double scale = exporterIFC.LinearScale; radius *= scale; XYZ xDir = origPlane.XVec; XYZ yDir = origPlane.YVec; XYZ orig = origPlane.Origin; ctr -= orig; IList<double> newCtr = new List<double>(); newCtr.Add(xDir.DotProduct(ctr) * scale); newCtr.Add(yDir.DotProduct(ctr) * scale); IFCAnyHandle location = IFCInstanceExporter.CreateCartesianPoint(file, newCtr); IList<double> refDir = new List<double>(); refDir.Add(1.0); refDir.Add(0.0); IFCAnyHandle refDirectionOpt = ExporterUtil.CreateDirection(file, refDir); IFCAnyHandle defPosition = IFCInstanceExporter.CreateAxis2Placement2D(file, location, null, refDirectionOpt); return IFCInstanceExporter.CreateCircleProfileDef(file, IFCProfileType.Area, profileName, defPosition, radius); }
/***************************************************/ /**** Public methods ****/ /***************************************************/ public static Element ToRevitGrid(this oM.Geometry.SettingOut.Grid grid, Document document, RevitSettings settings = null, Dictionary <Guid, List <int> > refObjects = null) { Element revitGrid = refObjects.GetValue <Grid>(document, grid.BHoM_Guid); if (revitGrid != null) { return(revitGrid); } settings = settings.DefaultIfNull(); if (BH.Engine.Geometry.Query.IIsClosed(grid.Curve)) { BH.Engine.Reflection.Compute.RecordError("Element could not be created: Revit allows only open curve-based grids. BHoM_Guid: " + grid.BHoM_Guid); return(null); } List <BH.oM.Geometry.ICurve> gridCurves = BH.Engine.Geometry.Query.ISubParts(grid.Curve).ToList(); if (gridCurves.Count == 0) { return(null); } else if (gridCurves.Count == 1) { Curve curve = grid.Curve.IToRevit(); if (curve is Line) { revitGrid = Grid.Create(document, (Line)curve); } else if (curve is Arc) { revitGrid = Grid.Create(document, (Arc)curve); } else { BH.Engine.Reflection.Compute.RecordError("Element could not be created: Revit allows only line- and arc-based grids. BHoM_Guid: " + grid.BHoM_Guid); return(null); } } else { CurveLoop loop = new CurveLoop(); foreach (BH.oM.Geometry.ICurve curve in gridCurves) { Curve revitCurve = curve.IToRevit(); if (revitCurve is Line || revitCurve is Arc) { loop.Append(revitCurve); } else { BH.Engine.Reflection.Compute.RecordError("Element could not be created: Revit allows only line- and arc-based grids. BHoM_Guid: " + grid.BHoM_Guid); return(null); } } Plane plane; try { plane = loop.GetPlane(); } catch { BH.Engine.Reflection.Compute.RecordError("Grid curves need to be coplanar. BHoM_Guid: " + grid.BHoM_Guid); return(null); } SketchPlane sketchPlane = SketchPlane.Create(document, plane); ElementId gridTypeId = document.GetDefaultElementTypeId(ElementTypeGroup.GridType); ElementId gridId = MultiSegmentGrid.Create(document, gridTypeId, loop, sketchPlane.Id); revitGrid = document.GetElement(gridId); } revitGrid.CheckIfNullPush(grid); if (revitGrid == null) { return(null); } try { revitGrid.Name = grid.Name; } catch { BH.Engine.Reflection.Compute.RecordWarning(String.Format("Grid name '{0}' was not unique, name '{1}' has been assigned instead. BHoM_Guid: {2}", grid.Name, revitGrid.Name, grid.BHoM_Guid)); } // Copy parameters from BHoM object to Revit element revitGrid.CopyParameters(grid, settings); refObjects.AddOrReplace(grid, revitGrid); return(revitGrid); }