public static IfcAxis2Placement3D ToAixs3D_LateralConnectPlate(IfcStore m, IfcLinearPlacement lp)
        {
            var origin = MakeCartesianPoint(m);
            var locZ   = MakeDirection(m, 0, 0, -1);
            var locX   = MakeDirection(m, 1, 0, 0);
            var locY   = MakeDirection(m, 0, 1, 0);
            var curve  = lp.PlacementRelTo;

            if (curve is IIfcOffsetCurveByDistances offsetCurve)
            {
                var    basicCurve     = offsetCurve.BasisCurve;
                double startDist      = offsetCurve.OffsetValues[0].DistanceAlong + lp.Distance.DistanceAlong;
                double offsetLateral  = offsetCurve.OffsetValues[0].OffsetLateral.Value + lp.Distance.OffsetLateral.Value;
                double offsetVertical = offsetCurve.OffsetValues[0].OffsetVertical.Value + lp.Distance.OffsetVertical.Value;
                if (basicCurve is IIfcAlignmentCurve ac)
                {
                    var    vz      = new XbimVector3D(0, 0, 1);
                    double height  = ac.Vertical.Segments[0].StartHeight;
                    var    horSegs = ac.Horizontal.Segments;
                    (var pt, var vy) = Utilities.GeometryEngine.GetPointByDistAlong(horSegs, startDist);
                    var vx       = vz.CrossProduct(vy);
                    var position = pt + vy * offsetLateral + vz * (offsetVertical + height);
                    origin = MakeCartesianPoint(m, position.X, position.Y, position.Z);
                    locY   = MakeDirection(m, vy.X, vy.Y, vy.Z);
                    locX   = MakeDirection(m, vx.X, vx.Y, vx.Z);
                }
            }
            return(MakeAxis2Placement3D(m, origin, locX, locZ));
        }
        /// <summary>
        /// Builds a windows Matrix3D from an ObjectPlacement
        /// Conversion fo c++ function CartesianTransform::ConvertMatrix3D from CartesianTransform.cpp
        /// </summary>
        /// <param name="objPlacement">IfcObjectPlacement object</param>
        /// <returns>Matrix3D</returns>
        protected XbimMatrix3D ConvertMatrix3D(IfcObjectPlacement objPlacement)
        {
            if (objPlacement is IfcLocalPlacement)
            {
                IfcLocalPlacement locPlacement = (IfcLocalPlacement)objPlacement;
                if (locPlacement.RelativePlacement is IfcAxis2Placement3D)
                {
                    IfcAxis2Placement3D axis3D   = (IfcAxis2Placement3D)locPlacement.RelativePlacement;
                    XbimVector3D        ucsXAxis = new XbimVector3D(axis3D.RefDirection.DirectionRatios[0], axis3D.RefDirection.DirectionRatios[1], axis3D.RefDirection.DirectionRatios[2]);
                    XbimVector3D        ucsZAxis = new XbimVector3D(axis3D.Axis.DirectionRatios[0], axis3D.Axis.DirectionRatios[1], axis3D.Axis.DirectionRatios[2]);
                    ucsXAxis = ucsXAxis.Normalized();
                    ucsZAxis = ucsZAxis.Normalized();
                    XbimVector3D ucsYAxis = XbimVector3D.CrossProduct(ucsZAxis, ucsXAxis);
                    ucsYAxis = ucsYAxis.Normalized();
                    XbimPoint3D ucsCentre = axis3D.Location.XbimPoint3D();

                    XbimMatrix3D ucsTowcs = new XbimMatrix3D(ucsXAxis.X, ucsXAxis.Y, ucsXAxis.Z, 0,
                                                             ucsYAxis.X, ucsYAxis.Y, ucsYAxis.Z, 0,
                                                             ucsZAxis.X, ucsZAxis.Y, ucsZAxis.Z, 0,
                                                             ucsCentre.X, ucsCentre.Y, ucsCentre.Z, 1);
                    if (locPlacement.PlacementRelTo != null)
                    {
                        return(XbimMatrix3D.Multiply(ucsTowcs, ConvertMatrix3D(locPlacement.PlacementRelTo)));
                    }
                    return(ucsTowcs);
                }
                throw new NotImplementedException("Support for Placements other than 3D not implemented");
            }
            throw new NotImplementedException("Support for Placements other than Local not implemented");
        }
Exemplo n.º 3
0
        /// <summary>
        /// Returns the normal of the triangle that contains the specified edge
        /// </summary>
        /// <param name="edge"></param>
        /// <returns></returns>
        public XbimVector3D TriangleNormal(XbimTriangleEdge edge)
        {
            var p1 = _vertices[edge.StartVertexIndex].Position;
            var p2 = _vertices[edge.NextEdge.StartVertexIndex].Position;
            var p3 = _vertices[edge.NextEdge.NextEdge.StartVertexIndex].Position;
            var a  = new XbimPoint3D(p1.X, p1.Y, p1.Z);
            var b  = new XbimPoint3D(p2.X, p2.Y, p2.Z);
            var c  = new XbimPoint3D(p3.X, p3.Y, p3.Z);
            var cv = XbimVector3D.CrossProduct(b - a, c - a);

            cv.Normalize();
            return(cv);
        }
Exemplo n.º 4
0
        /// <summary>
        /// returns the area of the polyloop
        /// </summary>
        /// <param name="loop"></param>
        /// <returns></returns>
        public static double Area(this IfcPolyLoop loop)
        {
            XbimVector3D sum = new XbimVector3D(0, 0, 0);
            IList <IfcCartesianPoint> pts = loop.Polygon;

            for (int i = 0; i < pts.Count - 1; i++)
            {
                XbimVector3D a = new XbimVector3D(pts[i].X, pts[i].Y, pts[i].Z);
                XbimVector3D b = new XbimVector3D(pts[i + 1].X, pts[i + 1].Y, pts[i + 1].Z);
                sum = sum + a.CrossProduct(b);
            }
            XbimVector3D n = loop.NewellsNormal();

            return(n.DotProduct(sum) / 2);
        }
Exemplo n.º 5
0
        /// <summary>
        /// returns the area of the polyloop
        /// </summary>
        /// <param name="loop"></param>
        /// <returns></returns>
        public static double Area(this IfcPolyLoop loop)
        {
            var sum = new XbimVector3D(0, 0, 0);
            var pts = loop.Polygon;

            for (var i = 0; i < pts.Count - 1; i++)
            {
                var a = new XbimVector3D(pts[i].X, pts[i].Y, pts[i].Z);
                var b = new XbimVector3D(pts[i + 1].X, pts[i + 1].Y, pts[i + 1].Z);
                sum = sum + a.CrossProduct(b);
            }
            var n = loop.NewellsNormal();

            return(n.DotProduct(sum) / 2);
        }
        // 已知直线和其上一点距直线起点的沿线距离
        public static (XbimPoint3D pt, XbimVector3D vec) GetPointOnCurve(IIfcLineSegment2D l, double dist)
        {
            var length = l.SegmentLength;

            if (dist > length + Tolerance)
            {
                throw new ArgumentOutOfRangeException("dist");
            }
            var start    = new XbimPoint3D(l.StartPoint.X, l.StartPoint.Y, 0);
            var startDir = ToVector3D((double)l.StartDirection.Value);
            var zAxis    = new XbimVector3D(0, 0, 1);
            var lateral  = zAxis.CrossProduct(startDir);

            return(start + dist * startDir, lateral);
        }
        public double GetArea()
        {
            // the normal can be taken from the product of two segments on the polyline
            if (Count() < 3)
            {
                return(double.NaN);
            }

            var normal       = Normal() * -1;
            var firstSegment = FirstSegment();
            var up           = XbimVector3D.CrossProduct(normal, firstSegment);

            var campos = new XbimVector3D(
                _geomPoints[0].Point.X,
                _geomPoints[0].Point.Y,
                _geomPoints[0].Point.Z
                );
            var target = campos + normal;
            var m      = XbimMatrix3D.CreateLookAt(campos, target, up);


            var point = new XbimPoint3D[Count()];

            for (var i = 0; i < point.Length; i++)
            {
                var pBefore = new XbimPoint3D(
                    _geomPoints[i].Point.X,
                    _geomPoints[i].Point.Y,
                    _geomPoints[i].Point.Z
                    );
                var pAft = m.Transform(pBefore);
                point[i] = pAft;
            }

            // http://stackoverflow.com/questions/2553149/area-of-a-irregular-shape
            // it assumes that the last point is NOT the same of the first one, but it tolerates the case.
            double area = 0.0f;

            var numVertices = Count();

            for (var i = 0; i < numVertices - 1; ++i)
            {
                area += point[i].X * point[i + 1].Y - point[i + 1].X * point[i].Y;
            }
            area += point[numVertices - 1].X * point[0].Y - point[0].X * point[numVertices - 1].Y;
            area /= 2.0;
            return(area);
        }
Exemplo n.º 8
0
 public static XbimMatrix3D ToMatrix3D(this IIfcAxis2Placement3D axis3)
 {
     if (axis3.RefDirection != null && axis3.Axis != null)
     {
         var za = new XbimVector3D(axis3.Axis.X, axis3.Axis.Y, axis3.Axis.Z);
         za = za.Normalized();
         var xa = new XbimVector3D(axis3.RefDirection.X, axis3.RefDirection.Y, axis3.RefDirection.Z);
         xa = xa.Normalized();
         XbimVector3D ya = XbimVector3D.CrossProduct(za, xa);
         ya = ya.Normalized();
         return(new XbimMatrix3D(xa.X, xa.Y, xa.Z, 0, ya.X, ya.Y, ya.Z, 0, za.X, za.Y, za.Z, 0, axis3.Location.X,
                                 axis3.Location.Y, axis3.Location.Z, 1));
     }
     return(new XbimMatrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, axis3.Location.X, axis3.Location.Y,
                             axis3.Location.Z, 1));
 }
 private static XbimMatrix3D ConvertAxis3D(IfcAxis2Placement3D axis3)
 {
     if (axis3.RefDirection != null && axis3.Axis != null)
     {
         XbimVector3D za = axis3.Axis.XbimVector3D();
         za = za.Normalized();
         XbimVector3D xa = axis3.RefDirection.XbimVector3D();
         xa = xa.Normalized();
         XbimVector3D ya = XbimVector3D.CrossProduct(za, xa);
         ya = ya.Normalized();
         return(new XbimMatrix3D(xa.X, xa.Y, xa.Z, 0, ya.X, ya.Y, ya.Z, 0, za.X, za.Y, za.Z, 0, axis3.Location.X,
                                 axis3.Location.Y, axis3.Location.Z, 1));
     }
     else
     {
         return(new XbimMatrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, axis3.Location.X, axis3.Location.Y,
                                 axis3.Location.Z, 1));
     }
 }
Exemplo n.º 10
0
        /// <summary>
        /// Get point on arc by given start point, start direction, arc radius,
        /// is counter-clockwise and distance along.
        /// </summary>
        /// <param name="start"></param>
        /// <param name="dir"></param>
        /// <param name="radius"></param>
        /// <param name="isCCW"></param>
        /// <param name="dist"></param>
        /// <returns></returns>
        public static (XbimPoint3D pt, XbimVector3D vec) GetPointOnCurve(XbimPoint3D start, XbimVector3D dir,
                                                                         double radius, bool isCCW, double dist)
        {
            // Compute the location of arc center.
            var zAxis        = new XbimVector3D(0, 0, 1);
            var start2center = isCCW ? zAxis.CrossProduct(dir) : dir.CrossProduct(zAxis);
            var center       = start + radius * start2center;

            // Compute the location of arc end point
            var theta        = isCCW ? dist / radius : -dist / radius;
            var center2start = start2center.Negated();
            var mat          = new XbimMatrix3D();

            mat.RotateAroundZAxis(theta);
            var center2end = mat.Transform(center2start);
            var lateral    = isCCW ? center2end.Negated() : center2end;

            return(center + radius * center2end, lateral);
        }
Exemplo n.º 11
0
        private XbimMatrix3D ConvertAxis3D()
        {
            if (RefDirection == null || Axis == null)
            {
                return(new XbimMatrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, Location.X, Location.Y,
                                        Location.Z, 1));
            }

            var za = Axis.XbimVector3D();

            za.Normalized();
            var xa = RefDirection.XbimVector3D();

            xa.Normalized();
            var ya = XbimVector3D.CrossProduct(za, xa);

            ya.Normalized();
            return(new XbimMatrix3D(xa.X, xa.Y, xa.Z, 0, ya.X, ya.Y, ya.Z, 0, za.X, za.Y, za.Z, 0, Location.X,
                                    Location.Y, Location.Z, 1));
        }
Exemplo n.º 12
0
        internal IVector3D Normal()
        {
            IfcPolyLoop polyLoop = Bound as IfcPolyLoop;

            if (polyLoop != null)
            {
                int numPts = polyLoop.Polygon.Count;
                for (int i = 1; i < polyLoop.Polygon.Count; i++)
                {
                    XbimPoint3D  c     = polyLoop.Polygon[i].XbimPoint3D();
                    XbimPoint3D  p     = polyLoop.Polygon[i - 1].XbimPoint3D();
                    XbimPoint3D  n     = polyLoop.Polygon[(i + 1 == numPts) ? 0 : i + 1].XbimPoint3D();
                    XbimVector3D left  = c - p;
                    XbimVector3D right = n - c;
                    XbimVector3D cp    = XbimVector3D.CrossProduct(left, right);
                    cp.Normalize();
                    if (!double.IsNaN(cp.X)) //happens if the three points are in a straigh line
                    {
                        if (!Orientation)
                        {
                            cp.Negate();
                        }
                        return(new IfcDirection(cp));
                    }
                    else if (i == polyLoop.Polygon.Count - 1)
                    {
                        // if its the last round of for look then just return the last cp
                        return(new IfcDirection(cp));
                    }
                }
                //srl removed the exception to stop invalid faces from causing a crash, an invalid normal is returned which can be checked for
                return(new IfcDirection(0, 0, 0)); //return an invalid normal as the face is either a line or a point
                //throw new Exception("IfcFaceBound:Normal has an Invalid face");
            }
            else
            {
                //srl removed the exception to stop invalid faces from causing a crash, an invalid normal is returned which can be checked for
                return(new IfcDirection(0, 0, 0)); //return an invalid normal as the face is either a line or a point
            }
            // throw new Exception("IfcFaceBound:Normal has an undefined bound");
        }
Exemplo n.º 13
0
        public static XbimPoint3D GetPlacementPoint(IIfcCurveSegment2D c, double dist,
                                                    double verticalOffset, double lateraloffset)
        {
            XbimPoint3D Point3D = new XbimPoint3D();

            if (c is IIfcLineSegment2D line)
            {
                (XbimPoint3D pointOnCurve, XbimVector3D vecOnCurve) = GetPointOnCurve(line, dist);
                var zAxis  = new XbimVector3D(0, 0, 1);
                var vecoff = vecOnCurve.CrossProduct(zAxis);
                Point3D = (pointOnCurve + vecoff * lateraloffset + zAxis * verticalOffset);
                //return Point3D;
            }
            if (c is IIfcCircularArcSegment2D arc)
            {
                (XbimPoint3D pointOnCurve, XbimVector3D vecOnCurve) = GetPointOnCurve(arc, dist);
                var isCCW        = (bool)arc.IsCCW.Value;
                var zAxis        = new XbimVector3D(0, 0, 1);
                var start2center = isCCW ? zAxis.CrossProduct(vecOnCurve) : vecOnCurve.CrossProduct(zAxis);
                Point3D = (pointOnCurve + start2center * lateraloffset + zAxis * verticalOffset);
                //return Point3D;
            }
            return(Point3D);
        }