Пример #1
0
        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);
        }
Пример #2
0
        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;
            }
        }
Пример #3
0
        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));
            }
        }
Пример #4
0
        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();
            }
        }
Пример #5
0
        /// <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);
        }
Пример #6
0
        /// <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);
        }
Пример #7
0
        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);
        }
Пример #8
0
        /// <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);
        }
Пример #9
0
        /// <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();
                }
            }
        }
Пример #10
0
        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);
        }
Пример #11
0
        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);
            }
        }
Пример #12
0
        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));
            }
        }
Пример #13
0
        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);
                }
            }
        }
Пример #14
0
        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));
        }
Пример #15
0
 public static Line TryCreateLine(XYZ firstPoint, XYZ secondPoint)
 {
     if (firstPoint.DistanceTo(secondPoint) < 1.MmToFt())
     {
         return(null);
     }
     return(Line.CreateBound(firstPoint, secondPoint));
 }
Пример #16
0
        /// <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);
        }
Пример #17
0
        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);
        }
Пример #18
0
 public static Line TryCreateBound(XYZ pt1, XYZ pt2)
 {
     if (pt1.DistanceTo(pt2) < 1.MmToFt())
     {
         return(null);
     }
     return(Line.CreateBound(pt1, pt2));
 }
Пример #19
0
        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);
        }
Пример #20
0
        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)));
        }
Пример #21
0
        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;
            // }
        }
Пример #22
0
        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);
        }
Пример #23
0
        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)));
        }
Пример #24
0
        /// <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);
            }
        }
Пример #25
0
        /// <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);
        }
Пример #26
0
        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);
        }
Пример #27
0
        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
        }
Пример #28
0
        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);
        }
Пример #29
0
        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);
        }
Пример #30
0
        /// <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;
        }
Пример #32
0
        /// <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;
        }
Пример #33
0
        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;
        }
Пример #34
0
 /// <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());
 }
Пример #35
0
        /// <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;
                        }
                    }
                }
            }
        }
Пример #36
0
        /// <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;
                        }
                    }
                }
            }
        }
Пример #37
0
        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);
        }
Пример #38
0
        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;
        }