private double GetAngleFromBasicVec(Element element, XYZ basicVec)
        {
            if (element is Opening)
            {
                Opening    opening              = element as Opening;
                CurveArray curveArray           = opening.BoundaryCurves;
                Curve      lengthCurve          = Common.getLongestCurve(curveArray, out Curve shorterCurve);
                XYZ        lengthCurveDirection = GetDirectionCurve(lengthCurve);
                double     angleFromBasicX      = 0;
                if (lengthCurveDirection != null)
                {
                    angleFromBasicX = lengthCurveDirection.AngleOnPlaneTo(basicVec, XYZ.BasisZ.Negate());
                }

                if (angleFromBasicX >= Math.PI)
                {
                    angleFromBasicX = angleFromBasicX - Math.PI;
                }
                return(angleFromBasicX);
            }
            else
            {
                return(double.NaN);
            }
        }
Beispiel #2
0
        //verify which orientation the specify Beam is
        private BeamOrientation verifyBeamOrientation(Element targetBeam)
        {
            Curve  beamCurve = (targetBeam.Location as LocationCurve).Curve;
            XYZ    direction = ((beamCurve.GetEndPoint(1) - beamCurve.GetEndPoint(0)).Normalize());
            double angle     = Utils.ConvertM.radiansToDegrees(direction.AngleOnPlaneTo(XYZ.BasisX, XYZ.BasisZ));

            if ((angle >= 315) && (angle <= 360.01))
            {
                return(BeamOrientation.Horizontal);
            }
            if ((angle >= 0) && (angle <= 45.01))
            {
                return(BeamOrientation.Horizontal);
            }
            if ((angle >= 135) && (angle <= 225.01))
            {
                return(BeamOrientation.Horizontal);
            }

            if ((angle > 45.01) && (angle < 135))
            {
                return(BeamOrientation.Vertical);
            }

            if ((angle > 225.01) && (angle < 315))
            {
                return(BeamOrientation.Vertical);
            }
            return(BeamOrientation.Vertical);
        }
        public Arc ArcToSpeckle(DB.Arc arc)
        {
            // see https://forums.autodesk.com/t5/revit-api-forum/how-to-retrieve-startangle-and-endangle-of-arc-object/td-p/7637128
            var arcPlane = DB.Plane.CreateByNormalAndOrigin(arc.Normal, arc.Center);

            XYZ center = arc.Center;


            XYZ dir0 = (arc.GetEndPoint(0) - center).Normalize();
            XYZ dir1 = (arc.GetEndPoint(1) - center).Normalize();

            XYZ start = arc.Evaluate(0, true);
            XYZ end   = arc.Evaluate(1, true);
            XYZ mid   = arc.Evaluate(0.5, true);

            double startAngle = dir0.AngleOnPlaneTo(arc.XDirection, arc.Normal);
            double endAngle   = dir1.AngleOnPlaneTo(arc.XDirection, arc.Normal);

            var a = new Arc(PlaneToSpeckle(arcPlane), ScaleToSpeckle(arc.Radius), startAngle, endAngle, endAngle - startAngle, ModelUnits);

            a.endPoint   = PointToSpeckle(end);
            a.startPoint = PointToSpeckle(start);
            a.midPoint   = PointToSpeckle(mid);
            return(a);
        }
Beispiel #4
0
        public static void API_rotate(Document doc)
        {
            XYZ pos2  = (tempFi1.Location as LocationPoint).Point;
            XYZ face2 = tempFi1.FacingOrientation;

            using (Transaction trans = new Transaction(doc))
            {
                trans.Start("rotate");
                doc.Delete(tempFi1.Id);
                trans.Commit();
            }
            if (pos1.IsAlmostEqualTo(pos2))
            {
                return;
            }
            else
            {
                //求旋转中心
                XYZ rotateCenter = GetRotateCenter(pos1, face1, pos2, face2);

                double angle = face1.AngleOnPlaneTo(face2, new XYZ(0, 0, 1));

                using (Transaction trans = new Transaction(doc))
                {
                    trans.Start("rotate");
                    //执行模块打的旋转操作
                    //ModuleRotate.RotateOperation(doc, Rotate_CMD.allFi, rotateCenter, angle);
                    trans.Commit();
                }
            }
        }
Beispiel #5
0
        private static SvgPath ConvertArc(Arc arc)
        {
            SvgPath svgPath = new SvgPath();

            SvgPathSegmentList svgPathSegmentList = new SvgPathSegmentList();

            svgPathSegmentList.Add(new SvgMoveToSegment(arc.GetEndPoint(0).ConvertToPointF()));

            XYZ a = arc.GetEndPoint(0) - arc.Center;
            XYZ b = arc.GetEndPoint(1) - arc.Center;

            double angleAboutAxis = a.AngleOnPlaneTo(b, arc.Normal);


            SvgArcSweep svgArcSweep = SvgArcSweep.Positive;

            if (angleAboutAxis >= 180)
            {
                svgArcSweep = SvgArcSweep.Negative;
            }

            SvgArcSize svgArcSize = SvgArcSize.Small;

            SvgArcSegment svgArcSegment = new SvgArcSegment(svgPathSegmentList.Last.End, (float)arc.Radius, (float)arc.Radius, (float)angleAboutAxis, svgArcSize, svgArcSweep, arc.GetEndPoint(1).ConvertToPointF());

            svgPathSegmentList.Add(svgArcSegment);
            svgPath.PathData = svgPathSegmentList;

            return(svgPath);
        }
        private void UpdateDirection(ElementId id, OpeningModel openningModel)
        {
            XYZ    basicZ    = XYZ.BasisZ;
            XYZ    direction = ConvertOpenningStringToObjectReVit.getDirection(openningModel.Geometry.Direction);
            XYZ    axisVec   = basicZ.CrossProduct(direction);
            Line   axis      = Line.CreateBound(axisVec, axisVec * 2);
            double angle     = basicZ.AngleOnPlaneTo(direction, axisVec);

            ElementTransformUtils.RotateElement(_doc, id, axis, angle);
        }
Beispiel #7
0
        /// <summary>
        /// Return true if vectorToCheck is on plan created by right and front vector
        /// </summary>
        /// <param name="vectorToCheck"></param>
        /// <param name="right"></param>
        /// <param name="front"></param>
        /// <returns></returns>
        internal static bool IsParallelVectorPlan(XYZ vectorToCheck, XYZ right, XYZ front)
        {
            double angle = vectorToCheck.AngleOnPlaneTo(right, front);

            if (IsEqual(angle, 0))
            {
                return(true);
            }
            else
            {
                return(false);
            }
        }
Beispiel #8
0
        private static SvgPath ConverPolyCurve(List <Curve> curves)
        {
            SvgPath svgPath = new SvgPath();

            SvgPathSegmentList svgPathSegmentList = new SvgPathSegmentList();

            svgPathSegmentList.Add(new SvgMoveToSegment(curves[0].GetEndPoint(0).ConvertToPointF()));

            foreach (Curve curve in curves)
            {
                if (curve is Arc)
                {
                    Arc arc = (Arc)curve;

                    XYZ a = arc.GetEndPoint(0) - arc.Center;
                    XYZ b = arc.GetEndPoint(1) - arc.Center;

                    double angleAboutAxis = a.AngleOnPlaneTo(b, arc.Normal);

                    SvgArcSweep svgArcSweep = SvgArcSweep.Positive;

                    if (angleAboutAxis >= 180)
                    {
                        svgArcSweep = SvgArcSweep.Negative;
                    }

                    SvgArcSize svgArcSize = SvgArcSize.Small;

                    SvgArcSegment svgArcSegment = new SvgArcSegment(svgPathSegmentList.Last.End, (float)arc.Radius, (float)arc.Radius, (float)angleAboutAxis, svgArcSize, svgArcSweep, arc.GetEndPoint(1).ConvertToPointF());

                    svgPathSegmentList.Add(svgArcSegment);
                }
                else if (curve is Line)
                {
                    SvgLineSegment svgLineSegment = new SvgLineSegment(svgPathSegmentList.Last.End, ((Line)curve).GetEndPoint(1).ConvertToPointF());

                    svgPathSegmentList.Add(svgLineSegment);
                }
            }


            svgPath.PathData = svgPathSegmentList;

            return(svgPath);
        }
Beispiel #9
0
        public VectorBucket GetBucket(XYZ vector)
        {
            var nv = vector.Normalize();

            nv = GetZeroClamppedPoint(nv);

            var hAngle  = _zeroHVector.AngleOnPlaneTo(nv, _zeroWVector);
            var hbucket = (int)(hAngle % _height);

            var wAngle  = _zeroWVector.AngleOnPlaneTo(nv, _zeroHVector);
            var wbucket = (int)(wAngle % _width);

            if (Buckets.GetLength(0) > hbucket && Buckets.GetLength(1) > wbucket)
            {
                var av = Buckets[hbucket, wbucket];
                return(av);
            }

            return(null);
        }
        private XYZ DirectionPointToLevel(XYZ point, Level level)
        {
            double elevaton = level.Elevation;
            XYZ    location = new XYZ(0, 0, elevaton);
            XYZ    direcVec = location - point;
            double angle    = direcVec.AngleOnPlaneTo(XYZ.BasisX, XYZ.BasisY);

            if (angle < Math.PI)
            {
                return(XYZ.BasisZ);
            }
            else if (angle >= Math.PI)
            {
                return(XYZ.BasisZ.Negate());
            }
            else
            {
                return(new XYZ(0, 0, 0));
            }
        }
Beispiel #11
0
        private static double FindRotationAngle(Room room, out Line axis)
        {
            double angle = 0;

            axis = null;
            try
            {
                Face bottomFace = GetBottomFace(room);
                if (null == bottomFace)
                {
                    return(angle);
                }
                Curve longestCurve = FindLongestCurve(bottomFace);
                if (null == longestCurve)
                {
                    return(angle);
                }

                XYZ firstPt  = longestCurve.GetEndPoint(0);
                XYZ secondPt = longestCurve.GetEndPoint(1);

                if (firstPt.X > secondPt.X)
                {
                    //switch
                    XYZ tempPt = firstPt;
                    firstPt  = secondPt;
                    secondPt = tempPt;
                }

                XYZ vector = secondPt.Subtract(firstPt);
                angle = vector.AngleOnPlaneTo(XYZ.BasisX, XYZ.BasisZ);
                axis  = Line.CreateBound(firstPt, new XYZ(firstPt.X, firstPt.Y, firstPt.Z + 10));
            }
            catch (Exception ex)
            {
                string message = ex.Message;
            }
            return(angle);
        }
        public static double GetUpAndDownWidth(AvoidElement avoidElement, ConflictElement conflictElement, out double height, out double widthUp, out double widthDown)
        {
            XYZ    verticalDirection    = avoidElement.GetVerticalVector();
            double angleToTurn          = avoidElement.AngleToTurn;
            double miniConnectHeight    = avoidElement.ConnectHeight;
            double miniConnectWidth     = avoidElement.ConnectWidth;
            double offsetWidth          = avoidElement.OffsetWidth;
            var    curve                = (avoidElement.MEPCurve.Location as LocationCurve).Curve;
            XYZ    parallelDirection    = avoidElement.GetParallelVector();
            var    elementToAvoid       = conflictElement.ConflictEle;
            var    elementToAvoidHeight = conflictElement.AvoidHeight;
            var    elementToAvoidWidth  = conflictElement.AvoidWidth;
            XYZ    direction1           = (curve as Line).Direction;
            double faceAngle            = 0;
            XYZ    direction2           = ((elementToAvoid.MEPCurve.Location as LocationCurve).Curve as Line).Direction;//TODO 连接件的ElementToAvoid依旧需要填上 作为溯源数据源

            faceAngle = direction1.AngleOnPlaneTo(direction2, new XYZ(0, 0, 1));
            //对象信息反填到基础模型中
            //点位计算
            //max(垂直最短留白距离,最小斜边长度,最短切割距离)
            height = avoidElement.Height / 2 + elementToAvoidHeight / 2 + MiniSpace;
            height = Math.Max(height, MiniMepLength + miniConnectHeight * 2);//考虑构件的最小高度需求
            //TODO 考虑矩形的最佳方案
            //if (avoidElement.Width!= avoidElement.Height|| elementToAvoidWidth!= elementToAvoidHeight)
            //{
            //}
            widthUp = MiniMepLength / 2 + offsetWidth;
            var diameterAvoid   = Math.Max(avoidElement.Width, avoidElement.Height);
            var diameterToAvoid = Math.Max(elementToAvoidWidth, elementToAvoidHeight);
            var widthOffset     = (angleToTurn - Math.PI / 2).IsMiniValue() ? 0 : height / Math.Tan(angleToTurn);

            widthUp   = (angleToTurn - Math.PI / 2).IsMiniValue() ? widthUp : Math.Max(widthUp, (diameterAvoid / 2 + diameterToAvoid / 2 + MiniSpace) / Math.Sin(angleToTurn) - height * Math.Tan(angleToTurn)); //斜边最短需求
            widthUp   = Math.Max(widthUp, avoidElement.Width / 2 + elementToAvoidWidth / 2 + MiniSpace);                                                                                                         //直径最短需求
            widthDown = widthUp + widthOffset;
            widthUp   = GetFixedJumpLength(widthUp, faceAngle);
            widthDown = GetFixedJumpLength(widthDown, faceAngle);
            return(height);
        }
Beispiel #13
0
        //verify which orientation the specify grid is
        private string verifyGridOrientation(Grid targetGrid)
        {
            Curve  gridCurve = targetGrid.Curve;
            XYZ    direction = ((gridCurve.GetEndPoint(1) - gridCurve.GetEndPoint(0)).Normalize());
            double angle     = Utils.ConvertM.radiansToDegrees(direction.AngleOnPlaneTo(XYZ.BasisX, XYZ.BasisZ));

            //Debug.Print(currentGrid.Name + " " + direction.ToString() + " " + angle);

            if ((angle >= 315) && (angle <= 360.01))
            {
                //HorizontalGrids.Add(currentGrid);
                return("isHorizontal");
            }
            if ((angle >= 0) && (angle <= 45.01))
            {
                //HorizontalGrids.Add(currentGrid);
                return("isHorizontal");
            }
            if ((angle >= 135) && (angle <= 225.01))
            {
                //HorizontalGrids.Add(currentGrid);
                return("isHorizontal");
            }

            if ((angle > 45.01) && (angle < 135))
            {
                //VerticalGrids.Add(currentGrid);
                return("isVertical");
            }

            if ((angle > 225.01) && (angle < 315))
            {
                //VerticalGrids.Add(currentGrid);
                return("isVertical");
            }
            return("isVertical");
        }
        public Result Execute(ExternalCommandData commandData, ref string message, ElementSet elements)
        {
            while (true) //restart until user press ESC
            {
                Application app = commandData.Application.Application;
                UIDocument uidoc = commandData.Application.ActiveUIDocument;
                Document doc = uidoc.Document;
                double mmToFeet = 1.0 / 304.8;
                Reference pickedRebarRef = null;
                Reference pickedDimensionRef = null;
                try
                {
                    pickedRebarRef = uidoc.Selection.PickObject(ObjectType.Element, new RebarSelectFilter(), "Pick a Rebar, TAB to cycle, ESC to cancel.");
                    pickedDimensionRef = uidoc.Selection.PickObject(ObjectType.Element, new DimensionSelectFilter(), "Pick a Dimension, TAB to cycle, ESC to cancel.");
                }
                catch (Autodesk.Revit.Exceptions.OperationCanceledException)
                {
                    return Result.Succeeded;
                }

                //Get rebar info
                Rebar rebar = doc.GetElement(pickedRebarRef) as Rebar;
                XYZ pickedPoint = pickedRebarRef.GlobalPoint;
                int barPositionIndex = 0;
                Line rebarSegment = RebarLineNearestPickedPoint(rebar, pickedPoint, out barPositionIndex);

                //Get dimension info
                Dimension dim = doc.GetElement(pickedDimensionRef) as Dimension;

                //Get view info
                View view = doc.ActiveView;
                double viewScale = System.Convert.ToDouble(view.get_Parameter(BuiltInParameter.VIEW_SCALE).AsInteger());
                XYZ viewOrigin = view.Origin;
                XYZ viewUpDir = view.UpDirection;
                XYZ viewRightDir = view.RightDirection;
                XYZ viewDir = view.ViewDirection;
                Plane viewPlane = Plane.CreateByNormalAndOrigin(viewDir, viewOrigin);

                //Project picked point to calculate tag placement
                XYZ picketPtOnView = Utils.ProjectPointToPlane(pickedPoint, viewPlane);
                XYZ pickedPtOnDim = dim.Curve.Project(picketPtOnView).XYZPoint;
                XYZ projectDir = Line.CreateBound(picketPtOnView, pickedPtOnDim).Direction;

                //Set tag orientation
                double angleToUp = projectDir.AngleOnPlaneTo(viewUpDir, viewDir);
                bool tagAlignmentIsVertical = false;
                TagOrientation tagOrientation = TagOrientation.Horizontal;
                if ((angleToUp < 0.25 * Math.PI) || (angleToUp > 0.75 * Math.PI && angleToUp < 1.25 * Math.PI) || (angleToUp > 1.75 * Math.PI))
                {
                    tagOrientation = TagOrientation.Vertical;
                    tagAlignmentIsVertical = true;
                }

                //Set position av tag:
                XYZ tagPoint = pickedPtOnDim;
                double dotProduct = 0.0;
                if (tagAlignmentIsVertical)
                {
                    dotProduct = viewUpDir.DotProduct(projectDir);
                }
                else
                {
                    dotProduct = viewRightDir.DotProduct(projectDir);
                }

                if (dotProduct < -0.01)
                {
                    tagPoint = tagPoint.Add(projectDir.Normalize().Multiply(viewScale * mmToFeet * 50));
                }
                else
                {
                    tagPoint = tagPoint.Add(projectDir.Normalize().Multiply(viewScale * mmToFeet * 3));
                }

                // Get reference of picked rebar, this can be used to attach rebar to dimension line
                Options opt = new Options();
                opt.View = view;
                opt.ComputeReferences = true;
                opt.IncludeNonVisibleObjects = true;
                List<Line> geomLines = new List<Line>();
                GeometryElement rebarGeom = rebar.get_Geometry(opt);
                Reference rebRef = null;
                foreach (GeometryObject geomObj in rebarGeom)
                {
                    Line geomLine = geomObj as Line;
                    if (null != geomLine)
                    {
                        XYZ p = geomLine.Direction;
                        XYZ q = rebarSegment.Direction;
                        bool isParallel = p.CrossProduct(q).IsZeroLength();

                        if (isParallel == false)
                        {
                            continue;
                        }
                        XYZ endPointOfRebar = rebarSegment.GetEndPoint(1);
                        IntersectionResult ir = geomLine.Project(
                          endPointOfRebar);
                        if (ir == null)
                            continue; // end point of rebar segment is not on the reference curve.

                        if (Math.Abs(ir.Distance) != 0)
                            continue; // end point of rebar segment is not on the reference curve.
                        rebRef = geomLine.Reference;
                    }
                }

                using (Transaction t1 = new Transaction(doc, "Isolate and tag Rebar"))
                {
                    t1.Start();
                    for (int i = 0; i < rebar.NumberOfBarPositions; i++)
                    {
                        if (i == barPositionIndex)
                        {
                            rebar.SetBarHiddenStatus(doc.ActiveView, barPositionIndex, false);
                        }
                        else
                        {
                            rebar.SetBarHiddenStatus(doc.ActiveView, i, true);
                        }
                    }
                    ElementId tagId = new FilteredElementCollector(doc).OfCategory(BuiltInCategory.OST_RebarTags).ToElementIds().FirstOrDefault();
                    IndependentTag.Create(doc, tagId, doc.ActiveView.Id, pickedRebarRef, false, tagOrientation, tagPoint);

                    //Recreate dimension with added reference:
                    if (rebRef != null)
                    {
                        ReferenceArray refArray = dim.References;
                        refArray.Append(rebRef);
                        Line dimLine = dim.Curve as Line;
                        DimensionType dimType = doc.GetElement(dim.GetTypeId()) as DimensionType;
                        doc.Create.NewDimension(doc.ActiveView, dimLine, refArray, dimType);
                        doc.Delete(dim.Id);
                    }
                    t1.Commit();
                }
            }
        }
Beispiel #15
0
        private static void CalculateLocations(AvoidElement avoidElement, ConflictElement conflictElement, double height = -1)
        {
            int    id = avoidElement.MEPCurve.Id.IntegerValue;
            XYZ    verticalDirection    = avoidElement.GetVerticalVector();
            double angleToTurn          = avoidElement.AngleToTurn;
            double miniConnectHeight    = avoidElement.ConnectHeight;
            double miniConnectWidth     = avoidElement.ConnectWidth;
            double offsetWidth          = avoidElement.OffsetWidth;
            var    curve                = (avoidElement.MEPCurve.Location as LocationCurve).Curve;
            var    pointStart           = avoidElement.StartPoint;
            var    pointEnd             = avoidElement.EndPoint;
            XYZ    parallelDirection    = (pointStart - pointEnd).Normalize();
            var    elementToAvoid       = conflictElement.ConflictEle;
            var    elementToAvoidHeight = conflictElement.AvoidHeight;
            var    elementToAvoidWidth  = conflictElement.AvoidWidth;
            XYZ    direction1           = (curve as Line).Direction;
            double faceAngle            = 0;
            XYZ    direction2           = ((elementToAvoid.MEPCurve.Location as LocationCurve).Curve as Line).Direction;//TODO 连接件的ElementToAvoid依旧需要填上 作为溯源数据源

            faceAngle = direction1.AngleOnPlaneTo(direction2, new XYZ(0, 0, 1));
            if (conflictElement.IsConnector)
            {
                conflictElement.ConnectorLocation = conflictElement.ConflictLocation + height * verticalDirection;
            }
            #region old
            //if (conflictElement.IsConnector)
            //{
            //    faceAngle = Math.PI / 2;//问题出在 如果连接点作为
            //    conflictElement.ConnectorLocation = conflictElement.ConflictLocation + height * verticalDirection;
            //}
            //else
            //{
            //    XYZ direction2 = ((elementToAvoid.MEPCurve.Location as LocationCurve).Curve as Line).Direction;
            //    faceAngle = direction1.AngleOnPlaneTo(direction2, new XYZ(0, 0, 1));
            //}
            #endregion
            //对象信息反填到基础模型中
            //点位计算
            var midPoint = conflictElement.ConflictLocation;
            //max(垂直最短留白距离,最小斜边长度,最短切割距离)
            if (height == -1)
            {
                height = avoidElement.Height / 2 + elementToAvoidHeight / 2 + MiniSpace;
                height = Math.Max(height, MiniMepLength + miniConnectHeight * 2);//考虑构件的最小高度需求
                conflictElement.Height = height;
            }
            //TODO 考虑矩形的最佳方案
            //if (avoidElement.Width!= avoidElement.Height|| elementToAvoidWidth!= elementToAvoidHeight)
            //{
            //}
            var widthUp         = MiniMepLength / 2 + offsetWidth;//构件最短需求
            var diameterAvoid   = Math.Max(avoidElement.Width, avoidElement.Height);
            var diameterToAvoid = Math.Max(elementToAvoidWidth, elementToAvoidHeight);
            widthUp = Math.Max(widthUp, (diameterAvoid / 2 + diameterToAvoid / 2 + MiniSpace) / Math.Sin(angleToTurn) - height * Math.Tan(angleToTurn)); //斜边最短需求
            widthUp = Math.Max(widthUp, avoidElement.Width / 2 + elementToAvoidWidth / 2 + MiniSpace);                                                   //直径最短需求
            var widthDown = widthUp + height / Math.Tan(angleToTurn);                                                                                    //水平最短距离对应的水平偏移
            widthUp   = GetFixedJumpLength(widthUp, faceAngle);
            widthDown = GetFixedJumpLength(widthDown, faceAngle);
            //double co = Math.Abs(Math.Cos(faceAngle));
            //if (!co.IsMiniValue())
            //{
            //    widthUp = widthUp / co;
            //    widthDown = widthDown / co;
            //}
            conflictElement.StartSplit = midPoint + parallelDirection * widthDown;
            conflictElement.EndSplit   = midPoint - parallelDirection * widthDown;
            midPoint += height * verticalDirection;
            conflictElement.MiddleStart = midPoint + parallelDirection * widthUp;
            conflictElement.MiddleEnd   = midPoint - parallelDirection * widthUp;
        }
Beispiel #16
0
        /// <summary>
        /// Generate the sketch base on the calculated CenterPoint:
        /// Divide the corner into NumSteps evenly.
        /// </summary>
        public override void GenerateSketch(double runWidth,
                                            IList <Curve> outerBoundary, IList <Curve> walkPath,
                                            IList <Curve> innerBoundary, IList <Curve> riserLines)
        {
            // Calculate the bisect direction in the corner.
            XYZ bisectDir         = (Direction2 - Direction1).Normalize();
            XYZ perpendicularDir1 = new XYZ(-Direction1.Y, Direction1.X, 0);
            XYZ perpendicularDir2 = new XYZ(-Direction2.Y, Direction2.X, 0);

            if (bisectDir.DotProduct(perpendicularDir1) < 0)
            {
                perpendicularDir1 = perpendicularDir1.Negate();
                perpendicularDir2 = perpendicularDir2.Negate();
            }

            // Determine the rotation axis and the angle span in the corner.
            double runwidth_2      = runWidth * 0.5;
            XYZ    zDir            = XYZ.BasisZ;
            double winderAngleSpan = perpendicularDir1.AngleOnPlaneTo(perpendicularDir2, zDir);

            if (winderAngleSpan > Math.PI)
            {
                zDir            = zDir.Negate();
                winderAngleSpan = Math.PI * 2.0 - winderAngleSpan;
            }

            // Calculate the corner points
            double diagonalDist    = runwidth_2 / Math.Cos(winderAngleSpan * 0.5);
            XYZ    middleCornerPnt = CornerPoint + bisectDir * diagonalDist;
            XYZ    innerCornerPnt  = middleCornerPnt + bisectDir * diagonalDist;
            XYZ    middleStart     = StartPoint + perpendicularDir1 * runwidth_2;
            XYZ    innerStart      = StartPoint + perpendicularDir1 * runWidth;
            XYZ    middleEnd       = EndPoint + perpendicularDir2 * runwidth_2;
            XYZ    innerEnd        = EndPoint + perpendicularDir2 * runWidth;
            XYZ    middleEnd0      = innerCornerPnt - perpendicularDir1 * runwidth_2;
            XYZ    middleEnd1      = innerCornerPnt - perpendicularDir2 * runwidth_2;

            // Generate the two outer boundary lines
            Line outerLine1 = Line.CreateBound(StartPoint, CornerPoint);

            outerBoundary.Add(outerLine1);
            Line outerLine2 = Line.CreateBound(CornerPoint, EndPoint);

            outerBoundary.Add(outerLine2);

            // Generate the first inner line
            Line innerLine1 = null;

            if (!innerStart.IsAlmostEqualTo(innerCornerPnt))
            {
                innerLine1 = Line.CreateBound(innerStart, innerCornerPnt);
                innerBoundary.Add(innerLine1);
            }

            // Generate the second inner line
            Line innerLine2 = null;

            if (!innerCornerPnt.IsAlmostEqualTo(innerEnd))
            {
                innerLine2 = Line.CreateBound(innerCornerPnt, innerEnd);
                innerBoundary.Add(innerLine2);
            }

            // Generate the first middle line
            Line middleLine1 = null;

            if (!middleStart.IsAlmostEqualTo(middleEnd0))
            {
                middleLine1 = Line.CreateBound(middleStart, middleEnd0);
                walkPath.Add(middleLine1);
            }

            // Generate the middle fillet arc
            XYZ middleCenter = innerCornerPnt - bisectDir * runwidth_2;
            Arc middleArc    = Arc.Create(middleEnd0, middleEnd1, middleCenter);

            walkPath.Add(middleArc);

            // Genera the second middle line
            Line middleLine2 = null;

            if (!middleEnd1.IsAlmostEqualTo(middleEnd))
            {
                middleLine2 = Line.CreateBound(middleEnd1, middleEnd);
                walkPath.Add(middleLine2);
            }

            //
            // Generate the riser lines by dividing the corner into NumSteps evenly.
            //
            double    winderAnglePerStep = winderAngleSpan / NumSteps;
            Transform tsf        = Transform.CreateRotation(zDir, winderAnglePerStep);
            XYZ       currentDir = perpendicularDir1;

            for (int i = 0; i < NumSteps - 1; ++i)
            {
                XYZ  rayDir = tsf.OfVector(currentDir); currentDir = rayDir;
                Line ray    = Line.CreateUnbound(CenterPoint, rayDir);

                IntersectionResultArray xsect;
                if (ray.Intersect(outerLine1, out xsect) == SetComparisonResult.Overlap ||
                    ray.Intersect(outerLine2, out xsect) == SetComparisonResult.Overlap)
                {
                    XYZ xOuter = xsect.get_Item(0).XYZPoint;
                    XYZ xInner = null;
                    if (innerLine1 == null || innerLine2 == null)
                    {
                        if (ray.Distance(innerCornerPnt) < 1.0e-9)
                        {
                            xInner = innerCornerPnt;
                        }
                    }
                    if (xInner == null)
                    {
                        if (innerLine1 != null && ray.Intersect(innerLine1, out xsect) == SetComparisonResult.Overlap)
                        {
                            xInner = xsect.get_Item(0).XYZPoint;
                        }
                        else if (innerLine2 != null && ray.Intersect(innerLine2, out xsect) == SetComparisonResult.Overlap)
                        {
                            xInner = xsect.get_Item(0).XYZPoint;
                        }
                    }

                    if (xInner == null)
                    {
                        throw new ArgumentException("Bad Input.");
                    }
                    riserLines.Add(Line.CreateBound(xOuter, xInner));
                }
                else
                {
                    throw new ArgumentException("Bad Input.");
                }
            }
        }
        public Result Execute(
            ExternalCommandData commandData,
            ref String message,
            ElementSet elements)
        {
            //Util.ListForgeTypeIds();

            UIApplication app   = commandData.Application;
            UIDocument    uidoc = app.ActiveUIDocument;
            Document      doc   = uidoc.Document;

            Element e = Util.SelectSingleElement(
                uidoc, "a line or wall");

            LocationCurve curve = null;

            if (null == e)
            {
                message = "No element selected";
            }
            else
            {
                curve = e.Location as LocationCurve;
            }

            if (null == curve)
            {
                message = "No curve available";
            }
            else
            {
                XYZ p = curve.Curve.GetEndPoint(0);
                XYZ q = curve.Curve.GetEndPoint(1);

                Debug.WriteLine("Start point "
                                + Util.PointString(p));

                Debug.WriteLine("End point "
                                + Util.PointString(q));

                // the angle between the vectors from the project origin
                // to the start and end points of the wall is pretty irrelevant:

                double a = p.AngleTo(q);
                Debug.WriteLine(
                    "Angle between start and end point vectors = "
                    + Util.AngleString(a));

                XYZ v  = q - p;
                XYZ vx = XYZ.BasisX;
                a = vx.AngleTo(v);
                Debug.WriteLine(
                    "Angle between points measured from X axis = "
                    + Util.AngleString(a));

                XYZ z = XYZ.BasisZ;
                a = vx.AngleOnPlaneTo(v, z);
                Debug.WriteLine(
                    "Angle around measured from X axis = "
                    + Util.AngleString(a));

                if (e is Wall)
                {
                    Wall wall = e as Wall;
                    XYZ  w    = z.CrossProduct(v).Normalize();
                    if (wall.Flipped)
                    {
                        w = -w;
                    }
                    a = vx.AngleOnPlaneTo(w, z);
                    Debug.WriteLine(
                        "Angle pointing out of wall = "
                        + Util.AngleString(a));
                }
            }

            foreach (ProjectLocation location
                     in doc.ProjectLocations)
            {
                //ProjectPosition projectPosition
                //  = location.get_ProjectPosition( XYZ.Zero ); // 2017

                ProjectPosition projectPosition
                    = location.GetProjectPosition(XYZ.Zero); // 2018

                double pna = projectPosition.Angle;
                Debug.WriteLine(
                    "Angle between project north and true north "
                    + Util.AngleString(pna));
            }
            return(Result.Failed);
        }
Beispiel #18
0
        /// <summary>
        /// 这里形成了源对象上与之碰撞的碰撞元素价值组
        /// 价值组的价值越大,自身则越应避让.
        /// 即 赢退 输不动
        /// </summary>
        /// <param name="startElement">源对象</param>
        /// <param name="conflictElement"></param>
        /// <param name="conflictNodes"></param>
        /// <param name="avoidElements"></param>
        private void SetupGroup(AvoidElement startElement, ConflictElement conflictElement, List <ValuedConflictNode> conflictNodes, List <AvoidElement> avoidElements)
        {
            var currentGroupingDistance = GroupingDistance + startElement.ConnectWidth * 2;
            XYZ direction1 = ((startElement.MEPCurve.Location as LocationCurve).Curve as Line).Direction;
            ConflictLineSection conflictLineSection = new ConflictLineSection(startElement);

            //碰撞点处理
            conflictLineSection.ConflictElements.Add(conflictElement);
            //向后 连续组团处理
            var             startIndex   = startElement.ConflictElements.IndexOf(conflictElement);
            var             currentIndex = startIndex;
            ConflictElement current      = conflictElement;
            ConflictElement next;

            for (int i = currentIndex + 1; i < startElement.ConflictElements.Count(); i++)
            {
                next = startElement.ConflictElements[i];
                if (next.IsConnector)
                {
                    break;
                }
                XYZ direction2 = ((next.ConflictEle.MEPCurve.Location as LocationCurve).Curve as Line).Direction;
                var faceAngle  = direction1.AngleOnPlaneTo(direction2, new XYZ(0, 0, 1));
                if (current.GetDistanceTo(next) > ValuedConflictNode.GetFixedJumpLength(currentGroupingDistance, faceAngle))
                {
                    break;
                }

                conflictLineSection.ConflictElements.Add(next);
                current      = next;
                currentIndex = i;
            }
            //向后 连接件处理 边界连续处理
            if (conflictElement.ConflictLocation != startElement.EndPoint && currentIndex == startElement.ConflictElements.Count() - 1)
            {
                var connector = startElement.ConnectorEnd;
                var point     = startElement.EndPoint;
                if (connector != null && current.GetDistanceTo(point) <= currentGroupingDistance)
                {
                    var continueEle = startElement.AddConflictElement(connector, conflictElement);
                    conflictLineSection.ConflictElements.Add(continueEle);
                    TopoConnector(conflictNodes, avoidElements, connector, conflictElement);
                }
            }
            //重置
            current      = conflictElement;
            currentIndex = startIndex;
            //往前 连续组团处理
            for (int i = currentIndex - 1; i >= 0; i--)
            {
                next = startElement.ConflictElements[i];
                if (next.IsConnector)
                {
                    break;
                }
                XYZ direction2 = ((next.ConflictEle.MEPCurve.Location as LocationCurve).Curve as Line).Direction;
                var faceAngle  = direction1.AngleOnPlaneTo(direction2, new XYZ(0, 0, 1));
                if (current.GetDistanceTo(next) > ValuedConflictNode.GetFixedJumpLength(currentGroupingDistance, faceAngle))
                {
                    break;
                }

                conflictLineSection.ConflictElements.Add(next);
                current      = next;
                currentIndex = i;
            }
            //往前 连接件处理
            if (conflictElement.ConflictLocation != startElement.StartPoint && currentIndex == 0)
            {
                var connector = startElement.ConnectorStart;
                var point     = startElement.StartPoint;
                if (connector != null && current.GetDistanceTo(point) <= currentGroupingDistance)
                {
                    var continueEle = startElement.AddConflictElement(connector, conflictElement);
                    conflictLineSection.ConflictElements.Add(continueEle);
                    TopoConnector(conflictNodes, avoidElements, connector, conflictElement);
                }
            }
            conflictLineSection.ConflictElements = conflictLineSection.ConflictElements.OrderByDescending(c => c.ConflictLocation, new XYZComparer()).ToList();
            ConflictLineSections.Add(conflictLineSection);
        }