public static XbimMatrix3D ToMatrix3D(this IfcAxis2Placement2D axis2, ConcurrentDictionary <int, Object> maps = null)
        {
            object transform;

            if (maps != null && maps.TryGetValue(axis2.EntityLabel, out transform)) //already converted it just return cached
            {
                return((XbimMatrix3D)transform);
            }
            if (axis2.RefDirection != null)
            {
                XbimVector3D v = axis2.RefDirection.XbimVector3D();
                v         = v.Normalized();
                transform = new XbimMatrix3D(v.X, v.Y, 0, 0, v.Y, v.X, 0, 0, 0, 0, 1, 0, axis2.Location.X, axis2.Location.Y, 0, 1);
            }
            else
            {
                transform = new XbimMatrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, axis2.Location.X, axis2.Location.Y,
                                             axis2.Location.Z, 1);
            }
            if (maps != null)
            {
                maps.TryAdd(axis2.EntityLabel, transform);
            }
            return((XbimMatrix3D)transform);
        }
Example #2
0
        public static XbimMatrix3D ToMatrix3D(this IIfcAxis2Placement2D axis2)
        {
            if (axis2.RefDirection != null)
            {
                var v = new XbimVector3D(axis2.RefDirection.X, axis2.RefDirection.Y, axis2.RefDirection.Z);
                v = v.Normalized();
                return(new XbimMatrix3D(
                           v.X, v.Y, 0, 0,
                           v.Y, v.X, 0, 0,
                           0, 0, 1, 0,
                           axis2.Location.X, axis2.Location.Y, 0, 1));
            }
            double LocationZ = axis2.Location.Z;

            if (double.IsNaN(LocationZ))
            {
                LocationZ = 0;
            }

            return(new XbimMatrix3D(
                       1, 0, 0, 0,
                       0, 1, 0, 0,
                       0, 0, 1, 0,
                       axis2.Location.X, axis2.Location.Y, LocationZ, 1
                       ));
        }
Example #3
0
        /// <summary>
        /// Calculates the Newell's Normal of the polygon of the loop
        /// </summary>
        /// <param name="loop"></param>
        /// <returns></returns>
        public static XbimVector3D NewellsNormal(this IfcPolyLoop loop)
        {
            double            x = 0, y = 0, z = 0;
            IfcCartesianPoint previous = null;
            var count = 0;
            var total = loop.Polygon.Count;

            for (var i = 0; i <= total; i++)
            {
                var current = i < total ? loop.Polygon[i] : loop.Polygon[0];
                if (count > 0)
                {
                    // ReSharper disable once PossibleNullReferenceException
                    var xn  = previous.X;
                    var yn  = previous.Y;
                    var zn  = previous.Z;
                    var xn1 = current.X;
                    var yn1 = current.Y;
                    var zn1 = current.Z;
                    x += (yn - yn1) * (zn + zn1);
                    y += (xn + xn1) * (zn - zn1);
                    z += (xn - xn1) * (yn + yn1);
                }
                previous = current;
                count++;
            }
            var v = new XbimVector3D(x, y, z);

            return(v.Normalized());
        }
        /// <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");
        }
Example #5
0
        public XbimMatrix3D ToMatrix3D(ConcurrentDictionary <int, object> maps = null)
        {
            object transform;

            if (maps != null && maps.TryGetValue(EntityLabel, out transform)) //already converted it just return cached
            {
                return((XbimMatrix3D)transform);
            }
            if (RefDirection != null)
            {
                XbimVector3D v = RefDirection.XbimVector3D();
                v.Normalized();
                transform = new XbimMatrix3D(v.X, v.Y, 0, 0, v.Y, v.X, 0, 0, 0, 0, 1, 0, Location.X, Location.Y, 0, 1);
            }
            else
            {
                transform = new XbimMatrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, Location.X, Location.Y,
                                             Location.Z, 1);
            }
            if (maps != null)
            {
                maps.TryAdd(EntityLabel, transform);
            }
            return((XbimMatrix3D)transform);
        }
Example #6
0
        private static XbimMatrix3D ConvertCartesianTransform3D(IIfcCartesianTransformationOperator3D ct3D)
        {
            XbimVector3D u3; //Z Axis Direction
            XbimVector3D u2; //X Axis Direction
            XbimVector3D u1; //Y axis direction

            if (ct3D.Axis3 != null)
            {
                var dir = ct3D.Axis3;
                u3 = new XbimVector3D(dir.X, dir.Y, dir.Z);
                u3 = u3.Normalized();
            }
            else
            {
                u3 = new XbimVector3D(0, 0, 1);
            }
            if (ct3D.Axis1 != null)
            {
                var dir = ct3D.Axis1;
                u1 = new XbimVector3D(dir.X, dir.Y, dir.Z);
                u1 = u1.Normalized();
            }
            else
            {
                var defXDir = new XbimVector3D(1, 0, 0);
                u1 = u3 != defXDir ? defXDir : new XbimVector3D(0, 1, 0);
            }
            var xVec  = XbimVector3D.Multiply(XbimVector3D.DotProduct(u1, u3), u3);
            var xAxis = XbimVector3D.Subtract(u1, xVec);

            xAxis = xAxis.Normalized();

            if (ct3D.Axis2 != null)
            {
                var dir = ct3D.Axis2;
                u2 = new XbimVector3D(dir.X, dir.Y, dir.Z);
                u2 = u2.Normalized();
            }
            else
            {
                u2 = new XbimVector3D(0, 1, 0);
            }

            var tmp   = XbimVector3D.Multiply(XbimVector3D.DotProduct(u2, u3), u3);
            var yAxis = XbimVector3D.Subtract(u2, tmp);

            tmp   = XbimVector3D.Multiply(XbimVector3D.DotProduct(u2, xAxis), xAxis);
            yAxis = XbimVector3D.Subtract(yAxis, tmp);
            yAxis = yAxis.Normalized();
            u2    = yAxis;
            u1    = xAxis;

            var lo = new XbimPoint3D(ct3D.LocalOrigin.X, ct3D.LocalOrigin.Y, ct3D.LocalOrigin.Z); //local origin

            return(new XbimMatrix3D(u1.X, u1.Y, u1.Z, 0,
                                    u2.X, u2.Y, u2.Z, 0,
                                    u3.X, u3.Y, u3.Z, 0,
                                    lo.X, lo.Y, lo.Z, 1));
        }
 public static XbimVector3D XAxisDirection(this IfcAxis2Placement3D ax3)
 {
     if (ax3.RefDirection != null && ax3.Axis != null)
     {
         XbimVector3D xa = ax3.RefDirection.XbimVector3D();
         return(xa.Normalized());
     }
     return(new XbimVector3D(1, 0, 0));
 }
Example #8
0
 public XbimVector3D Normalise()
 {
     if (Dim == 3)
     {
         var v3D = new XbimVector3D(X, Y, Z);
         v3D.Normalized();
         return(v3D);
     }
     throw new ArgumentException("Only 3D Directions are supported for normalised at present");
 }
 public static XbimVector3D ZAxisDirection(this IfcAxis2Placement3D ax3)
 {
     if (ax3.RefDirection != null && ax3.Axis != null)
     {
         XbimVector3D za = ax3.Axis.XbimVector3D();
         return(za.Normalized());
     }
     else
     {
         return(new XbimVector3D(0, 0, 1));
     }
 }
Example #10
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));
     }
 }
        /// <summary>
        /// Computes and returns the normalised vector for the direction.
        /// </summary>
        /// <returns>A 1-length vector if the direction is meaningful or a 0-length vector otherwise</returns>
        public XbimVector3D Normalise()
        {
            if (Dim == 3)
            {
                var v3D = new XbimVector3D(X, Y, Z);
                v3D.Normalized();
                return(v3D);
            }
            // Since the return value is not stored in any field or property
            // and the function return variable is intrinsically 3D it's reasonable do
            // deal with dimensions lower than 3
            //
            var compX = X; // each value is nan if the dimension is not specified
            var compY = Y;
            var compZ = Z;

            // substitite nan for 0
            if (double.IsNaN(compX))
            {
                compX = 0;
            }
            if (double.IsNaN(compY))
            {
                compY = 0;
            }
            if (double.IsNaN(compZ))
            {
                compZ = 0;
            }

            var otherCases = new XbimVector3D(compX, compY, compZ);

            // normalied return a 0-len-vector if no significant direction exists
            otherCases.Normalized();
            return(otherCases);
        }
        /// <summary>
        /// Calculate the ObjectPlacment for an IfcProduct from row data and the parent object
        /// </summary>
        /// <param name="row">COBieCoordinateRow holding the data</param>
        /// <param name="placementRelToIfcProduct">IfcProduct that the ObjectPlacment relates too, i.e. the parent of the ifcProduct ObjectPlacment we are calculating</param>
        /// <returns></returns>
        private IfcLocalPlacement CalcObjectPlacement(COBieCoordinateRow row, IfcProduct placementRelToIfcProduct)
        {
            XbimPoint3D locationPt;
            bool        havePoint = GetPointFromRow(row, out locationPt);

            if (havePoint)
            {
                if ((placementRelToIfcProduct != null) && (placementRelToIfcProduct.ObjectPlacement is IfcLocalPlacement))
                {
                    //TEST, change the building position to see if the same point comes out in Excel sheet, it should be, and in test was.
                    //((IfcAxis2Placement3D)((IfcLocalPlacement)placementRelToIfcProduct.ObjectPlacement).RelativePlacement).SetNewLocation(10.0, 10.0, 0.0);
                    IfcLocalPlacement placementRelTo = (IfcLocalPlacement)placementRelToIfcProduct.ObjectPlacement;
                    XbimMatrix3D      matrix3D       = ConvertMatrix3D(placementRelTo);

                    //we want to take off the translations and rotations caused by IfcLocalPlacement of the parent objects as we will add these to the new IfcLocalPlacement for this floor
                    matrix3D.Invert();                           //so invert matrix to remove the translations to give the origin for the next IfcLocalPlacement
                    locationPt = matrix3D.Transform(locationPt); //get the point with relation to the last IfcLocalPlacement i.e the parent element

                    //Get the WCS matrix values
                    double rotX, rotY, rotZ;
                    if (!(double.TryParse(row.YawRotation, out rotX) && (double.NaN.CompareTo(rotX) != 0)))
                    {
                        rotX = 0.0;
                    }

                    if (!(double.TryParse(row.ElevationalRotation, out rotY) && (double.NaN.CompareTo(rotY) != 0)))
                    {
                        rotY = 0.0;
                    }

                    if (double.TryParse(row.ClockwiseRotation, out rotZ) && (double.NaN.CompareTo(rotZ) != 0))
                    {
                        rotZ = rotZ * -1; //convert back from clockwise to anti clockwise
                    }
                    else
                    {
                        rotZ = 0.0;
                    }

                    //apply the WCS rotation from COBie Coordinates stored values
                    XbimMatrix3D matrixNewRot3D = new XbimMatrix3D();
                    if (rotX != 0.0)
                    {
                        matrixNewRot3D.RotateAroundXAxis(TransformedBoundingBox.DegreesToRadians(rotX));
                    }
                    if (rotY != 0.0)
                    {
                        matrixNewRot3D.RotateAroundYAxis(TransformedBoundingBox.DegreesToRadians(rotY));
                    }
                    if (rotZ != 0.0)
                    {
                        matrixNewRot3D.RotateAroundZAxis(TransformedBoundingBox.DegreesToRadians(rotZ));
                    }

                    //remove any displacement from the matrix which moved/rotated us to the object space
                    matrix3D.OffsetX = 0.0F;
                    matrix3D.OffsetY = 0.0F;
                    matrix3D.OffsetZ = 0.0F;

                    //remove the matrix that got use to the object space from the WCS location of this object
                    XbimMatrix3D matrixRot3D = matrixNewRot3D * matrix3D;

                    //get the rotation vectors to place in the new IfcAxis2Placement3D for the new IfcLocalPlacement for this object
                    XbimVector3D ucsAxisX = matrixRot3D.Transform(new XbimVector3D(1, 0, 0));
                    XbimVector3D ucsAxisZ = matrixRot3D.Transform(new XbimVector3D(0, 0, 1));
                    ucsAxisX = ucsAxisX.Normalized();
                    ucsAxisZ = ucsAxisZ.Normalized();

                    //create the new IfcAxis2Placement3D
                    IfcAxis2Placement3D relativePlacemant = Model.Instances.New <IfcAxis2Placement3D>();
                    relativePlacemant.SetNewDirectionOf_XZ(ucsAxisX.X, ucsAxisX.Y, ucsAxisX.Z, ucsAxisZ.X, ucsAxisZ.Y, ucsAxisZ.Z);
                    relativePlacemant.SetNewLocation(locationPt.X, locationPt.Y, locationPt.Z);

                    //Set up IfcLocalPlacement
                    IfcLocalPlacement objectPlacement = Model.Instances.New <IfcLocalPlacement>();
                    objectPlacement.PlacementRelTo    = placementRelTo;
                    objectPlacement.RelativePlacement = relativePlacemant;

                    return(objectPlacement);
                }
            }
            return(null);
        }
Example #14
0
        /// <summary>
        /// If adding the data to the mesh causes the mesh to exceed the max size of ushort.MaxSize
        /// the data is not added and false is returned.
        /// </summary>
        /// <typeparam name="TGeomType"></typeparam>
        /// <param name="builder"></param>
        /// <param name="br"></param>
        /// <param name="transform"></param>
        /// <returns></returns>
        private bool BuildWithNormals <TGeomType>(TGeomType builder, BinaryReader br, XbimMatrix3D transform) where TGeomType : IXbimTriangulatesToPositionsNormalsIndices
        {
            uint numPositions = br.ReadUInt32();
            //if we the mesh is smaller that 64K then try and add it to this mesh, if it is bigger than 65K we just have to stake what we can
            //if (numPositions < ushort.MaxValue && builder.PositionCount > 0 && (builder.PositionCount + numPositions >= ushort.MaxValue)) //we cannot build meshes bigger than this and pass them through to standard graphics buffers
            //    return false;
            uint numNormals   = br.ReadUInt32();
            uint numUniques   = br.ReadUInt32();
            uint numTriangles = br.ReadUInt32();
            uint numPolygons  = br.ReadUInt32();

            IndexReader PositionReader = new IndexReader(numPositions, br);
            IndexReader NormalsReader  = new IndexReader(numNormals, br);
            IndexReader UniquesReader  = new IndexReader(numUniques, br);

            float[,] pos = new float[numPositions, 3];
            float[,] nrm;
            nrm = new float[numNormals, 3];

            // coordinates of positions
            //
            for (uint i = 0; i < numPositions; i++)
            {
                pos[i, 0] = br.ReadSingle();
                pos[i, 1] = br.ReadSingle();
                pos[i, 2] = br.ReadSingle();
            }
            // dimensions of normals
            //
            for (uint i = 0; i < numNormals; i++)
            {
                nrm[i, 0] = br.ReadSingle();
                nrm[i, 1] = br.ReadSingle();
                nrm[i, 2] = br.ReadSingle();
            }

            // loop twice for how many indices to create the point/normal combinations.
            builder.BeginPoints(numUniques);
            if (transform.IsIdentity)
            {
                for (uint i = 0; i < numUniques; i++)
                {
                    uint readpositionI = PositionReader.ReadIndex();
                    builder.AddPosition(
                        new XbimPoint3D(pos[readpositionI, 0], pos[readpositionI, 1], pos[readpositionI, 2]));
                }
                for (uint i = 0; i < numUniques; i++)
                {
                    uint readnormalI = NormalsReader.ReadIndex();
                    builder.AddNormal(
                        new XbimVector3D(nrm[readnormalI, 0], nrm[readnormalI, 1], nrm[readnormalI, 2])
                        );
                }
            }
            else
            {
                for (uint i = 0; i < numUniques; i++)
                {
                    uint readpositionI = PositionReader.ReadIndex();
                    var  tfdPosition   = transform.Transform(new XbimPoint3D(pos[readpositionI, 0], pos[readpositionI, 1], pos[readpositionI, 2]));
                    builder.AddPosition(tfdPosition);
                }
                for (uint i = 0; i < numUniques; i++)
                {
                    // todo: use a quaternion extracted from the matrix instead
                    //
                    uint         readnormalI = NormalsReader.ReadIndex();
                    var          origNormal  = new XbimVector3D(nrm[readnormalI, 0], nrm[readnormalI, 1], nrm[readnormalI, 2]);
                    XbimVector3D v           = transform.Transform(origNormal);
                    v = v.Normalized();
                    builder.AddNormal(v);
                }
            }

            builder.EndPoints();             //point/normal combinations completed

            builder.BeginPolygons(numTriangles, numPolygons);
            for (uint p = 0; p < numPolygons; p++)
            {
                // set the state
                TriangleType meshType     = (TriangleType)br.ReadByte();
                uint         indicesCount = br.ReadUInt32();
                builder.BeginPolygon(meshType, indicesCount);
                //get the triangles
                for (uint i = 0; i < indicesCount; i++)
                {
                    builder.AddTriangleIndex(UniquesReader.ReadIndex());
                }
                builder.EndPolygon();
            }
            builder.EndPolygons();
            return(true);
        }