示例#1
0
        /// <summary>
        /// Compute the angle between two edges
        /// </summary>
        /// <param name="edgeA">The 1st edge</param>
        /// <param name="edgeB">The 2nd edge</param>
        /// <returns>The angle of the 2 edges</returns>
        private double AngleBetweenEdges(Edge edgeA, Edge edgeB)
        {
            Autodesk.Revit.DB.XYZ vectorA = null;
            Autodesk.Revit.DB.XYZ vectorB = null;

            // find coincident vertices
            Autodesk.Revit.DB.XYZ A_0 = edgeA.Evaluate(0);
            Autodesk.Revit.DB.XYZ A_1 = edgeA.Evaluate(1);
            Autodesk.Revit.DB.XYZ B_0 = edgeB.Evaluate(0);
            Autodesk.Revit.DB.XYZ B_1 = edgeB.Evaluate(1);
            if (A_0.IsAlmostEqualTo(B_0))
            {
                vectorA = edgeA.ComputeDerivatives(0).BasisX.Normalize();
                vectorB = edgeA.ComputeDerivatives(0).BasisX.Normalize();
            }
            else if (A_0.IsAlmostEqualTo(B_1))
            {
                vectorA = edgeA.ComputeDerivatives(0).BasisX.Normalize();
                vectorB = edgeB.ComputeDerivatives(1).BasisX.Normalize();
            }
            else if (A_1.IsAlmostEqualTo(B_0))
            {
                vectorA = edgeA.ComputeDerivatives(1).BasisX.Normalize();
                vectorB = edgeB.ComputeDerivatives(0).BasisX.Normalize();
            }
            else if (A_1.IsAlmostEqualTo(B_1))
            {
                vectorA = edgeA.ComputeDerivatives(1).BasisX.Normalize();
                vectorB = edgeB.ComputeDerivatives(1).BasisX.Normalize();
            }

            if (A_1.IsAlmostEqualTo(B_0) || A_0.IsAlmostEqualTo(B_1))
            {
                vectorA = vectorA.Negate();
            }

            if (null == vectorA || null == vectorB)
            {
                return(0d);
            }
            double angle = Math.Acos(vectorA.DotProduct(vectorB));

            return(angle);
        }
示例#2
0
        /// <summary>
        /// Project a point on a face
        /// </summary>
        /// <param name="xyzArray">the face points, them fix a face </param>
        /// <param name="point">the point</param>
        /// <returns>the projected point on this face</returns>
        static private Autodesk.Revit.DB.XYZ Project(List <XYZ> xyzArray, Autodesk.Revit.DB.XYZ point)
        {
            Autodesk.Revit.DB.XYZ a = xyzArray[0] - xyzArray[1];
            Autodesk.Revit.DB.XYZ b = xyzArray[0] - xyzArray[2];
            Autodesk.Revit.DB.XYZ c = point - xyzArray[0];

            Autodesk.Revit.DB.XYZ normal = (a.CrossProduct(b));

            try
            {
                normal = normal.Normalize();
            }
            catch (Exception)
            {
                normal = Autodesk.Revit.DB.XYZ.Zero;
            }

            Autodesk.Revit.DB.XYZ retProjectedPoint = point - (normal.DotProduct(c)) * normal;
            return(retProjectedPoint);
        }
示例#3
0
        /// <summary>
        /// OK button click event
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonOK_Click(object sender, EventArgs e)
        {
            DeleteLines();
            if (!UpdateData(false))
            {
                return;
            }
            m_outputInfo.Clear();
            m_stopWatch.Start();
            Transaction transaction = new Transaction(m_doc, "RayTraceBounce");

            transaction.Start();
            m_LineCount = 0;
            m_RayCount  = 0;
            // Start Find References By Direction
            Autodesk.Revit.DB.XYZ startpt = m_origin;
            m_outputInfo.Add("Start Find References By Direction: ");
            for (int ctr = 1; ctr <= rayLimit; ctr++)
            {
                ReferenceIntersector         referenceIntersector = new ReferenceIntersector(m_view);
                IList <ReferenceWithContext> references           = referenceIntersector.Find(startpt, m_direction);
                m_rClosest = null;
                FindClosestReference(references);
                if (m_rClosest == null)
                {
                    string info = "Ray " + ctr + " aborted. No closest face reference found. ";
                    m_outputInfo.Add(info);
                    if (ctr == 1)
                    {
                        TaskDialog.Show("Revit", info);
                    }
                    break;
                }
                else
                {
                    Reference             reference        = m_rClosest.GetReference();
                    Element               referenceElement = m_doc.GetElement(reference);
                    GeometryObject        referenceObject  = referenceElement.GetGeometryObjectFromReference(reference);
                    Autodesk.Revit.DB.XYZ endpt            = reference.GlobalPoint;
                    if (startpt.IsAlmostEqualTo(endpt))
                    {
                        m_outputInfo.Add("Start and end points are equal. Ray " + ctr + " aborted\n" + startpt.X + ", " + startpt.Y + ", " + startpt.Z);
                        break;
                    }
                    else
                    {
                        MakeLine(startpt, endpt, m_direction, "bounce");
                        m_RayCount = m_RayCount + 1;
                        string info = "Intersected Element Type: [" + referenceElement.GetType().ToString() + "] ElementId: [" + referenceElement.Id.IntegerValue.ToString();
                        m_face = referenceObject as Face;
                        if (m_face.MaterialElementId != ElementId.InvalidElementId)
                        {
                            Material materialElement = m_doc.GetElement(m_face.MaterialElementId) as Material;
                            info += "] Face MaterialElement Name: [" + materialElement.Name + "] Shininess: [" + materialElement.Shininess;
                        }
                        else
                        {
                            info += "] Face.MaterialElement is null [" + referenceElement.Category.Name;
                        }
                        info += "]";
                        m_outputInfo.Add(info);
                        Autodesk.Revit.DB.UV  endptUV    = reference.UVPoint;
                        Autodesk.Revit.DB.XYZ FaceNormal = m_face.ComputeDerivatives(endptUV).BasisZ;                                // face normal where ray hits
                        FaceNormal = m_rClosest.GetInstanceTransform().OfVector(FaceNormal);                                         // transformation to get it in terms of document coordinates instead of the parent symbol
                        Autodesk.Revit.DB.XYZ directionMirrored = m_direction - 2 * m_direction.DotProduct(FaceNormal) * FaceNormal; //http://www.fvastro.org/presentations/ray_tracing.htm
                        m_direction = directionMirrored;                                                                             // get ready to shoot the next ray
                        startpt     = endpt;
                    }
                }
            }
            transaction.Commit();
            m_stopWatch.Stop();
            TimeSpan ts          = m_stopWatch.Elapsed;
            string   elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}", ts.Hours, ts.Minutes, ts.Seconds, ts.Milliseconds / 10);

            m_outputInfo.Add(elapsedTime + "\n" + "Lines = " + m_LineCount + "\n" + "Rays = " + m_RayCount);
            m_stopWatch.Reset();
            OutputInformation();
        }
示例#4
0
        private static void GetPolygonPlane(IReadOnlyList <RVT.XYZ> polygon, out RVT.XYZ normal, out double dist, out double area)
        {
            normal = RVT.XYZ.Zero;
            dist   = area = 0.0;
            var n  = polygon.Count;
            var rc = (2 < n);

            if (3 == n)
            {
                var a = polygon[0];
                var b = polygon[1];
                var c = polygon[2];
                var v = b - a;
                normal = v.CrossProduct(c - a);
                dist   = normal.DotProduct(a);
            }
            else if (4 == n)
            {
                var a = polygon[0];
                var b = polygon[1];
                var c = polygon[2];
                var d = polygon[3];

                var normalX = (c.Y - a.Y) * (d.Z - b.Z) + (c.Z - a.Z) * (b.Y - d.Y);
                var normalY = (c.Z - a.Z) * (d.X - b.X) + (c.X - a.X) * (b.Z - d.Z);
                var normalZ = (c.X - a.X) * (d.Y - b.Y) + (c.Y - a.Y) * (b.X - d.X);
                normal = new RVT.XYZ(normalX, normalY, normalZ);

                dist = 0.25 * (normal.X * (a.X + b.X + c.X + d.X) + normal.Y * (a.Y + b.Y + c.Y + d.Y) + normal.Z * (a.Z + b.Z + c.Z + d.Z));
            }
            else if (4 < n)
            {
                RVT.XYZ a;
                var     b = polygon[n - 2];
                var     c = polygon[n - 1];
                var     s = RVT.XYZ.Zero;

                for (var i = 0; i < n; ++i)
                {
                    a = b;
                    b = c;
                    c = polygon[i];

                    var normalX = normal.X + b.Y * (c.Z - a.Z);
                    var normalY = normal.Y + b.Z * (c.X - a.X);
                    var normalZ = normal.Z + b.X * (c.Y - a.Y);
                    normal = new RVT.XYZ(normalX, normalY, normalZ);

                    s += c;
                }
                dist = s.DotProduct(normal) / n;
            }
            if (rc)
            {
                //
                // the polygon area is half of the length
                // of the non-normalized normal vector of the plane:
                //
                var length = normal.GetLength();
                rc = !IsZero(length);

                if (rc)
                {
                    normal /= length;
                    dist   /= length;
                    area    = 0.5 * length;
                }
            }
        }