static XbimMatrix3D()
 {
     _identity = new XbimMatrix3D(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0)
     {
         _isNotDefaultInitialised = true
     };
 }
Exemple #2
0
        /// <summary>
        /// Warning: This function assumes no rotation is used for the tranform.
        /// </summary>
        /// <param name="composed">The NON-ROTATING transform to apply</param>
        /// <returns>the transformed bounding box.</returns>
        public XbimRect3D Transform(XbimMatrix3D composed)
        {
            var min = this.Min * composed;
            var max = this.Max * composed;

            return(new XbimRect3D(min, max));
        }
 /// <summary>
 /// Creates a new instance of a mat4
 /// </summary>
 /// <param name="m">Single[16] containing values to initialize with</param>
 /// <returns>New mat4New mat4</returns>
 public static XbimMatrix3D Copy(XbimMatrix3D m)
 {
     return(new XbimMatrix3D(m.M11, m.M12, m.M13, m.M14,
                             m.M21, m.M22, m.M23, m.M24,
                             m.M31, m.M32, m.M33, m.M34,
                             m.OffsetX, m.OffsetY, m.OffsetZ, m.M44));
 }
        public XbimModelFactors(double angToRads, double lenToMeter, double? precision = null, XbimMatrix3D? wcs= null)
        {
            WorldCoordinateSystem = wcs;
            AngleToRadiansConversionFactor = angToRads;
            LengthToMetresConversionFactor = lenToMeter;
           
            OneMeter = OneMetre = 1/lenToMeter;
            OneMilliMeter = OneMilliMetre = OneMeter / 1000.0;
            OneKilometer = OneMeter * 1000.0;
            OneFoot = OneMeter / 3.2808;
            OneInch = OneMeter / 39.37;
            OneMile = OneMeter * 1609.344;


            DeflectionTolerance = OneMilliMetre*5; //5mm chord deflection
            DeflectionAngle = 0.5; 
            VertexPointDiameter = OneMilliMetre * 10; //1 cm
            //if (precision.HasValue)
            //    Precision = Math.Min(precision.Value,OneMilliMetre / 1000);
            //else
            //    Precision = Math.Max(1e-5, OneMilliMetre / 1000);
            if (precision.HasValue)
                Precision = precision.Value;
            else
                Precision = 1e-5;
            PrecisionMax = OneMilliMetre / 10;
            MaxBRepSewFaceCount = 0;
            PrecisionBoolean =  Math.Max(Precision,OneMilliMetre/10); //might need to make it courser than point precision if precision is very fine
            PrecisionBooleanMax = OneMilliMetre *100;
            Rounding = Math.Abs((int)Math.Log10(Precision*100)); //default round all points to 100 times  precision, this is used in the hash functions

            var exp = Math.Floor(Math.Log10(Math.Abs(OneMilliMetre / 10d))); //get exponent of first significant digit
            _significantOrder = exp > 0 ? 0 : (int)Math.Abs(exp);
            ShortestEdgeLength = 10 * OneMilliMetre;
        }
 public static void AddElements(this MeshGeometry3D m, EntitySelection selection, XbimMatrix3D wcsTransform)
 {
     foreach (var item in selection)
     {
         m.AddElements(item, wcsTransform);
     }
 }
Exemple #6
0
 /// <summary>
 /// Performs a matrix multiplication
 /// </summary>
 /// <param name="mat">mat First operand</param>
 /// <param name="mat2">mat2 Second operand</param>
 /// <returns>dest if specified, mat otherwise</returns>
 public static XbimMatrix3D Multiply(XbimMatrix3D mat1, XbimMatrix3D mat2)
 {
     if (mat1.IsIdentity)
     {
         return(mat2);
     }
     else if (mat2.IsIdentity)
     {
         return(mat1);
     }
     else
     {
         return(new XbimMatrix3D((((mat1._m11 * mat2._m11) + (mat1._m12 * mat2._m21)) + (mat1._m13 * mat2._m31)) + (mat1._m14 * mat2._offsetX),
                                 (((mat1._m11 * mat2._m12) + (mat1._m12 * mat2._m22)) + (mat1._m13 * mat2._m32)) + (mat1._m14 * mat2._offsetY),
                                 (((mat1._m11 * mat2._m13) + (mat1._m12 * mat2._m23)) + (mat1._m13 * mat2._m33)) + (mat1._m14 * mat2._offsetZ),
                                 (((mat1._m11 * mat2._m14) + (mat1._m12 * mat2._m24)) + (mat1._m13 * mat2._m34)) + (mat1._m14 * mat2._m44),
                                 (((mat1._m21 * mat2._m11) + (mat1._m22 * mat2._m21)) + (mat1._m23 * mat2._m31)) + (mat1._m24 * mat2._offsetX),
                                 (((mat1._m21 * mat2._m12) + (mat1._m22 * mat2._m22)) + (mat1._m23 * mat2._m32)) + (mat1._m24 * mat2._offsetY),
                                 (((mat1._m21 * mat2._m13) + (mat1._m22 * mat2._m23)) + (mat1._m23 * mat2._m33)) + (mat1._m24 * mat2._offsetZ),
                                 (((mat1._m21 * mat2._m14) + (mat1._m22 * mat2._m24)) + (mat1._m23 * mat2._m34)) + (mat1._m24 * mat2._m44),
                                 (((mat1._m31 * mat2._m11) + (mat1._m32 * mat2._m21)) + (mat1._m33 * mat2._m31)) + (mat1._m34 * mat2._offsetX),
                                 (((mat1._m31 * mat2._m12) + (mat1._m32 * mat2._m22)) + (mat1._m33 * mat2._m32)) + (mat1._m34 * mat2._offsetY),
                                 (((mat1._m31 * mat2._m13) + (mat1._m32 * mat2._m23)) + (mat1._m33 * mat2._m33)) + (mat1._m34 * mat2._offsetZ),
                                 (((mat1._m31 * mat2._m14) + (mat1._m32 * mat2._m24)) + (mat1._m33 * mat2._m34)) + (mat1._m34 * mat2._m44),
                                 (((mat1._offsetX * mat2._m11) + (mat1._offsetY * mat2._m21)) + (mat1._offsetZ * mat2._m31)) + (mat1._m44 * mat2._offsetX),
                                 (((mat1._offsetX * mat2._m12) + (mat1._offsetY * mat2._m22)) + (mat1._offsetZ * mat2._m32)) + (mat1._m44 * mat2._offsetY),
                                 (((mat1._offsetX * mat2._m13) + (mat1._offsetY * mat2._m23)) + (mat1._offsetZ * mat2._m33)) + (mat1._m44 * mat2._offsetZ),
                                 (((mat1._offsetX * mat2._m14) + (mat1._offsetY * mat2._m24)) + (mat1._offsetZ * mat2._m34)) + (mat1._m44 * mat2._m44)));
     }
 }
 /// <summary>
 /// Performs a matrix multiplication
 /// </summary>
 /// <param name="mat1">mat First operand</param>
 /// <param name="mat2">mat2 Second operand</param>
 /// <returns>dest if specified, mat otherwise</returns>
 public static XbimMatrix3D Multiply(XbimMatrix3D mat1, XbimMatrix3D mat2)
 {
     if (mat1.IsIdentity)
     {
         return(mat2);
     }
     else if (mat2.IsIdentity)
     {
         return(mat1);
     }
     else
     {
         return(new XbimMatrix3D(mat1._m11 * mat2._m11 + mat1._m12 * mat2._m21 + mat1._m13 * mat2._m31 + mat1._m14 * mat2._offsetX,
                                 mat1._m11 * mat2._m12 + mat1._m12 * mat2._m22 + mat1._m13 * mat2._m32 + mat1._m14 * mat2._offsetY,
                                 mat1._m11 * mat2._m13 + mat1._m12 * mat2._m23 + mat1._m13 * mat2._m33 + mat1._m14 * mat2._offsetZ,
                                 mat1._m11 * mat2._m14 + mat1._m12 * mat2._m24 + mat1._m13 * mat2._m34 + mat1._m14 * mat2._m44,
                                 mat1._m21 * mat2._m11 + mat1._m22 * mat2._m21 + mat1._m23 * mat2._m31 + mat1._m24 * mat2._offsetX,
                                 mat1._m21 * mat2._m12 + mat1._m22 * mat2._m22 + mat1._m23 * mat2._m32 + mat1._m24 * mat2._offsetY,
                                 mat1._m21 * mat2._m13 + mat1._m22 * mat2._m23 + mat1._m23 * mat2._m33 + mat1._m24 * mat2._offsetZ,
                                 mat1._m21 * mat2._m14 + mat1._m22 * mat2._m24 + mat1._m23 * mat2._m34 + mat1._m24 * mat2._m44,
                                 mat1._m31 * mat2._m11 + mat1._m32 * mat2._m21 + mat1._m33 * mat2._m31 + mat1._m34 * mat2._offsetX,
                                 mat1._m31 * mat2._m12 + mat1._m32 * mat2._m22 + mat1._m33 * mat2._m32 + mat1._m34 * mat2._offsetY,
                                 mat1._m31 * mat2._m13 + mat1._m32 * mat2._m23 + mat1._m33 * mat2._m33 + mat1._m34 * mat2._offsetZ,
                                 mat1._m31 * mat2._m14 + mat1._m32 * mat2._m24 + mat1._m33 * mat2._m34 + mat1._m34 * mat2._m44,
                                 mat1._offsetX * mat2._m11 + mat1._offsetY * mat2._m21 + mat1._offsetZ * mat2._m31 + mat1._m44 * mat2._offsetX,
                                 mat1._offsetX * mat2._m12 + mat1._offsetY * mat2._m22 + mat1._offsetZ * mat2._m32 + mat1._m44 * mat2._offsetY,
                                 mat1._offsetX * mat2._m13 + mat1._offsetY * mat2._m23 + mat1._offsetZ * mat2._m33 + mat1._m44 * mat2._offsetZ,
                                 mat1._offsetX * mat2._m14 + mat1._offsetY * mat2._m24 + mat1._offsetZ * mat2._m34 + mat1._m44 * mat2._m44));
     }
 }
Exemple #8
0
 public MapRefData(MapData toAdd)
 {
     RepresentationLabel = toAdd.Geometry.RepresentationLabel;
     EntityLabel = toAdd.Product.EntityLabel;
     EntityTypeId = IfcMetaData.IfcTypeId(toAdd.Product);
     SurfaceStyleLabel = toAdd.Geometry.SurfaceStyleLabel;
     Matrix = XbimMatrix3D.Multiply(toAdd.Geometry.Transform, toAdd.Matrix);
 }
Exemple #9
0
 public XbimRegion(string name, XbimRect3D bounds, int population, XbimMatrix3D worldCoordinateSystem)
 {
     Name                  = name;
     Size                  = new XbimVector3D(bounds.SizeX, bounds.SizeY, bounds.SizeZ);
     Centre                = bounds.Centroid();
     Population            = population;
     WorldCoordinateSystem = worldCoordinateSystem;
 }
 public XbimShapeTriangulation Transform(XbimMatrix3D matrix3D)
 {
     var vertices =_vertices.Select(matrix3D.Transform).ToList();
     var faces = new List<XbimFaceTriangulation>(_faces.Count);
     var q = matrix3D.GetRotationQuaternion();
     faces.AddRange(_faces.Select(face => face.Transform(q)));
     return new XbimShapeTriangulation(vertices, faces, _version);
 }
        public XbimShapeTriangulation Transform(XbimMatrix3D matrix3D)
        {
            var vertices = _vertices.Select(matrix3D.Transform).ToList();
            var faces    = new List <XbimFaceTriangulation>(_faces.Count);
            var q        = matrix3D.GetRotationQuaternion();

            faces.AddRange(_faces.Select(face => face.Transform(q)));
            return(new XbimShapeTriangulation(vertices, faces, _version));
        }
        public static XbimMeshGeometry3D GetMesh(this XbimModel xbimModel, IEnumerable<IPersistIfcEntity> items, XbimMatrix3D wcsTransform)
        {
            var m = new XbimMeshGeometry3D();

            if (xbimModel.GeometrySupportLevel == 1)
            {
                // this is what happens for version 1 of the engine
                //
                foreach (var item in items)
                {
                    var fromModel = item.ModelOf as XbimModel;
                    if (fromModel == null)
                        continue;
                    var geomDataSet = fromModel.GetGeometryData(item.EntityLabel, XbimGeometryType.TriangulatedMesh);
                    foreach (var geomData in geomDataSet)
                    {
                        // todo: add guidance to the TransformBy method so that users can understand how to stop using it (it's marked absolete)
                        geomData.TransformBy(wcsTransform);
                        m.Add(geomData); // todo: what is the modelid value to be passed?
                    }
                }
            }
            else
            {
                // this is what happens for version 2 of the engine
                //
                foreach (var item in items)
                {
                    var fromModel = item.ModelOf as XbimModel;
                    if (fromModel == null || !(item is IfcProduct))
                        continue;
                    var context = new Xbim3DModelContext(fromModel);

                    var productShape =
                        context.ShapeInstancesOf((IfcProduct) item)
                            .Where(
                                s => s.RepresentationType != XbimGeometryRepresentationType.OpeningsAndAdditionsExcluded)
                            .ToList();
                    foreach (var shapeInstance in productShape)
                    {
                        IXbimShapeGeometryData shapeGeom = context.ShapeGeometry(shapeInstance.ShapeGeometryLabel);
                        switch ((XbimGeometryType) shapeGeom.Format)
                        {
                            case XbimGeometryType.PolyhedronBinary:
                                m.Read(shapeGeom.ShapeData,
                                    XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform));
                                break;
                            case XbimGeometryType.Polyhedron:
                                m.Read(((XbimShapeGeometry) shapeGeom).ShapeData,
                                    XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform));
                                break;
                        }
                    }
                }
            }
            return m;
        }
Exemple #13
0
        public static XbimVector3D Multiply(XbimVector3D vec, XbimMatrix3D m)
        {
            var x = vec.X;
            var y = vec.Y;
            var z = vec.Z;

            return(new XbimVector3D(m.M11 * x + m.M21 * y + m.M31 * z,
                                    m.M12 * x + m.M22 * y + m.M32 * z,
                                    m.M13 * x + m.M23 * y + m.M33 * z
                                    ));
        }
Exemple #14
0
 public override bool Equals(object obj)
 {
     if (obj is XbimMatrix3D)
     {
         return(XbimMatrix3D.Equal(this, (XbimMatrix3D)obj));
     }
     else
     {
         return(false);
     }
 }
Exemple #15
0
 public XbimShapeInstance(int id = -1)
 {
     _instanceLabel         = id;
     _expressTypeId         = 0;
     _ifcProductLabel       = 0;
     _styleLabel            = 0;
     _shapeLabel            = -1;
     _representationContext = 0;
     _representationType    = XbimGeometryRepresentationType.OpeningsAndAdditionsExcluded;
     _transformation        = XbimMatrix3D.Identity;
     _boundingBox           = XbimRect3D.Empty;
 }
        public static void AddElements(this MeshGeometry3D m, IPersistIfcEntity item, XbimMatrix3D wcsTransform)
        {

            var fromModel = item.ModelOf as XbimModel;
            if (fromModel == null || !(item is IfcProduct)) 
                return;
            switch (fromModel.GeometrySupportLevel)
            {
                case 2:
                    var context = new Xbim3DModelContext(fromModel);

                    var productShape = context.ShapeInstancesOf((IfcProduct) item)
                        .Where(s => s.RepresentationType != XbimGeometryRepresentationType.OpeningsAndAdditionsExcluded)
                        .ToList();
                    if (!productShape.Any() && item is IfcFeatureElement)
                    {
                        productShape = context.ShapeInstancesOf((IfcProduct) item)
                            .Where(
                                s => s.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsExcluded)
                            .ToList();
                    }

                    if (!productShape.Any()) 
                        return;
                    foreach (var shapeInstance in productShape)
                    {
                        IXbimShapeGeometryData shapeGeom =
                            context.ShapeGeometry(shapeInstance.ShapeGeometryLabel);
                        switch ((XbimGeometryType) shapeGeom.Format)
                        {
                            case XbimGeometryType.PolyhedronBinary:
                                m.Read(shapeGeom.ShapeData,
                                    XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform));
                                break;
                            case XbimGeometryType.Polyhedron:
                                m.Read(((XbimShapeGeometry) shapeGeom).ShapeData,
                                    XbimMatrix3D.Multiply(shapeInstance.Transformation, wcsTransform));
                                break;
                        }
                    }
                    break;
                case 1:
                    var xm3d = new XbimMeshGeometry3D();
                    var geomDataSet = fromModel.GetGeometryData(item.EntityLabel, XbimGeometryType.TriangulatedMesh);
                    foreach (var geomData in geomDataSet)
                    {
                        var gd = geomData.TransformBy(wcsTransform);
                        xm3d.Add(gd);
                    }
                    m.Add(xm3d);
                    break;
            }
        }
        public void QuaternionTests()
        {
            var q = new XbimQuaternion();
            Assert.AreEqual(true, q.IsIdentity(), "Uninitialised quaternion should be identity.");

            q = new XbimQuaternion(0.0f, 0.0f, 0.0f, 1.0f);
            Assert.AreEqual(true, q.IsIdentity(), "Should be identity when initialised with floats.");

            var mat = new XbimMatrix3D();
            q = mat.GetRotationQuaternion();
            Assert.AreEqual(true, q.IsIdentity(), "Quaternion from identity matrix shold be identity.");
        }
Exemple #18
0
        /// <summary>
        /// Decomposes a matrix into a scale, rotation, and translation.
        /// </summary>
        /// <param name="scale">When the method completes, contains the scaling component of the decomposed matrix.</param>
        /// <param name="rotation">When the method completes, contains the rtoation component of the decomposed matrix.</param>
        /// <param name="translation">When the method completes, contains the translation component of the decomposed matrix.</param>
        /// <remarks>
        /// This method is designed to decompose an SRT transformation matrix only.
        /// </remarks>
        public bool Decompose(out XbimVector3D scale, out XbimQuaternion rotation, out XbimVector3D translation)
        {
            //Source: Unknown
            // References: http://www.gamedev.net/community/forums/topic.asp?topic_id=441695
            // via https://code.google.com/p/sharpdx/source/browse/Source/SharpDX/Matrix.cs?r=9f9e209b1be04f06f294bc6d72b06055ad6abdcc

            //Get the translation.
            translation   = new XbimVector3D();
            translation.X = this._offsetX;
            translation.Y = this._offsetY;
            translation.Z = this._offsetZ;

            //Scaling is the length of the rows.
            scale   = new XbimVector3D();
            scale.X = Math.Sqrt((M11 * M11) + (M12 * M12) + (M13 * M13));
            scale.Y = Math.Sqrt((M21 * M21) + (M22 * M22) + (M23 * M23));
            scale.Z = Math.Sqrt((M31 * M31) + (M32 * M32) + (M33 * M33));

            //If any of the scaling factors are zero, than the rotation matrix can not exist.
            //

            double ZeroTolerance = 0.000003;

            if (Math.Abs(scale.X) < ZeroTolerance ||
                Math.Abs(scale.Y) < ZeroTolerance ||
                Math.Abs(scale.Z) < ZeroTolerance)
            {
                rotation = new XbimQuaternion(); // defaults to identity
                return(false);
            }

            //The rotation is the left over matrix after dividing out the scaling.
            XbimMatrix3D rotationmatrix = new XbimMatrix3D();

            rotationmatrix.M11 = M11 / scale.X;
            rotationmatrix.M12 = M12 / scale.X;
            rotationmatrix.M13 = M13 / scale.X;

            rotationmatrix.M21 = M21 / scale.Y;
            rotationmatrix.M22 = M22 / scale.Y;
            rotationmatrix.M23 = M23 / scale.Y;

            rotationmatrix.M31 = M31 / scale.Z;
            rotationmatrix.M32 = M32 / scale.Z;
            rotationmatrix.M33 = M33 / scale.Z;

            rotationmatrix.M44 = 1;

            XbimQuaternion.RotationMatrix(ref rotationmatrix, out rotation);
            return(true);
        }
Exemple #19
0
        public static XbimRegionCollection FromArray(byte[] bytes)
        {
            var coll = new XbimRegionCollection();
            var ms   = new MemoryStream(bytes);
            var br   = new BinaryReader(ms);

            bool oldVersion = true;
            int  version    = br.ReadInt32();//if version is a negative number, we have a new version model, and therefore have coord data to retrieve. Otherwise version is actually the count
            int  count      = 0;

            if (version < 0)
            {
                count      = br.ReadInt32();
                oldVersion = false;
            }
            else
            {
                count = version;
            }

            for (var i = 0; i < count; i++)
            {
                var region = new XbimRegion
                {
                    Name       = br.ReadString(),
                    Population = br.ReadInt32()
                };
                float x = br.ReadSingle();
                float y = br.ReadSingle();
                float z = br.ReadSingle();
                region.Centre = new XbimPoint3D(x, y, z);
                x             = br.ReadSingle();
                y             = br.ReadSingle();
                z             = br.ReadSingle();
                region.Size   = new XbimVector3D(x, y, z);
                if (!oldVersion)
                {
                    region.WorldCoordinateSystem = XbimMatrix3D.FromArray(br.ReadBytes(CoordSize));
#pragma warning disable CS0618 // Type or member is obsolete
                    region.version = version;
                }
                else
                {
                    region.version = 0;
#pragma warning restore CS0618 // Type or member is obsolete
                }
                coll.Add(region);
            }
            return(coll);
        }
        /// <summary>
        /// Creates a quaternion given a rotation matrix.
        /// </summary>
        /// <param name="matrix">The rotation matrix.</param>
        /// <param name="result">When the method completes, contains the newly created quaternion.</param>
        public static void RotationMatrix(ref XbimMatrix3D matrix, out XbimQuaternion result)
        {
            double sqrt;
            double half;
            double scale = matrix.M11 + matrix.M22 + matrix.M33;

            result = new XbimQuaternion();

            if (scale > 0.0f)
            {
                sqrt     = Math.Sqrt(scale + 1.0f);
                result.W = sqrt * 0.5f;
                sqrt     = 0.5f / sqrt;

                result.X = (matrix.M23 - matrix.M32) * sqrt;
                result.Y = (matrix.M31 - matrix.M13) * sqrt;
                result.Z = (matrix.M12 - matrix.M21) * sqrt;
            }
            else if ((matrix.M11 >= matrix.M22) && (matrix.M11 >= matrix.M33))
            {
                sqrt = Math.Sqrt(1.0f + matrix.M11 - matrix.M22 - matrix.M33);
                half = 0.5f / sqrt;

                result.X = 0.5f * sqrt;
                result.Y = (matrix.M12 + matrix.M21) * half;
                result.Z = (matrix.M13 + matrix.M31) * half;
                result.W = (matrix.M23 - matrix.M32) * half;
            }
            else if (matrix.M22 > matrix.M33)
            {
                sqrt = Math.Sqrt(1.0f + matrix.M22 - matrix.M11 - matrix.M33);
                half = 0.5f / sqrt;

                result.X = (matrix.M21 + matrix.M12) * half;
                result.Y = 0.5f * sqrt;
                result.Z = (matrix.M32 + matrix.M23) * half;
                result.W = (matrix.M31 - matrix.M13) * half;
            }
            else
            {
                sqrt = Math.Sqrt(1.0f + matrix.M33 - matrix.M11 - matrix.M22);
                half = 0.5f / sqrt;

                result.X = (matrix.M31 + matrix.M13) * half;
                result.Y = (matrix.M32 + matrix.M23) * half;
                result.Z = 0.5f * sqrt;
                result.W = (matrix.M12 - matrix.M21) * half;
            }
        }
 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.Normalize();
         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;
 }
Exemple #22
0
 /// <summary>
 /// Compares two matrices for equality within a certain margin of error
 /// </summary>
 /// <param name="a">a First matrix</param>
 /// <param name="b">b Second matrix</param>
 /// <returns>True if a is equivalent to b</returns>
 public static bool Equal(XbimMatrix3D a, XbimMatrix3D b)
 {
     return(Math.Abs(a.M11 - b.M11) < FloatEpsilon &&
            Math.Abs(a.M12 - b.M12) < FloatEpsilon &&
            Math.Abs(a.M13 - b.M13) < FloatEpsilon &&
            Math.Abs(a.M14 - b.M14) < FloatEpsilon &&
            Math.Abs(a.M21 - b.M21) < FloatEpsilon &&
            Math.Abs(a.M22 - b.M22) < FloatEpsilon &&
            Math.Abs(a.M23 - b.M23) < FloatEpsilon &&
            Math.Abs(a.M24 - b.M34) < FloatEpsilon &&
            Math.Abs(a.M31 - b.M31) < FloatEpsilon &&
            Math.Abs(a.M32 - b.M32) < FloatEpsilon &&
            Math.Abs(a.M33 - b.M33) < FloatEpsilon &&
            Math.Abs(a.M34 - b.M34) < FloatEpsilon &&
            Math.Abs(a.OffsetX - b.OffsetX) < FloatEpsilon &&
            Math.Abs(a.OffsetY - b.OffsetY) < FloatEpsilon &&
            Math.Abs(a.OffsetZ - b.OffsetZ) < FloatEpsilon &&
            Math.Abs(a.M44 - b.M44) < FloatEpsilon);
 }
        public static XbimPoint3D Multiply(XbimPoint3D p, XbimMatrix3D m)
        {
            var x = p.X;
            var y = p.Y; 
            var z = p.Z;
            

            
            XbimPoint3D pRet = new XbimPoint3D(m.M11 * x + m.M21 * y + m.M31 * z + m.OffsetX,
                                   m.M12 * x + m.M22 * y + m.M32 * z + m.OffsetY,
                                   m.M13 * x + m.M23 * y + m.M33 * z + m.OffsetZ
                                  );
            if (m.IsAffine) return pRet;
            double affineRatio = x * m.M14 + y * m.M24 + z * m.M34 + m.M44;
            x = pRet.X / affineRatio;
            y = pRet.Y / affineRatio;
            z = pRet.Z / affineRatio;
            return new XbimPoint3D(x, y, z);
        }
Exemple #24
0
        public static XbimMatrix3D CreateWorld(XbimVector3D position, XbimVector3D forward, XbimVector3D up)
        {
            // prepare vectors
            forward.Normalized();
            XbimVector3D vector  = forward * -1;
            XbimVector3D vector2 = XbimVector3D.CrossProduct(up, vector);

            vector2.Normalized();
            XbimVector3D vector3 = XbimVector3D.CrossProduct(vector, vector2);

            // prepare matrix
            XbimMatrix3D result = new XbimMatrix3D(
                vector2.X, vector2.Y, vector2.Z, 0.0,
                vector3.X, vector3.Y, vector3.Z, 0.0,
                vector.X, vector.Y, vector.Z, 0.0,
                position.X, position.Y, position.Z, 0.0);

            return(result);
        }
Exemple #25
0
        // Microsoft.Xna.Framework.Matrix
        public static XbimMatrix3D CreateLookAt(XbimVector3D cameraPosition, XbimVector3D cameraTarget, XbimVector3D cameraUpVector)
        {
            // prepare vectors
            XbimVector3D vector = cameraPosition - cameraTarget;

            vector.Normalized();
            XbimVector3D vector2 = XbimVector3D.CrossProduct(cameraUpVector, vector);

            vector2.Normalized();
            XbimVector3D vector3 = XbimVector3D.CrossProduct(vector, vector2);

            // prepare matrix
            XbimMatrix3D result = new XbimMatrix3D(
                vector2.X, vector3.X, vector.X, 0.0,
                vector2.Y, vector3.Y, vector.Y, 0.0,
                vector2.Z, vector3.Z, vector.Z, 0.0,
                -XbimVector3D.DotProduct(vector2, cameraPosition), -XbimVector3D.DotProduct(vector3, cameraPosition), -XbimVector3D.DotProduct(vector, cameraPosition), 1.0);

            return(result);
        }
Exemple #26
0
 /// <summary>
 /// Compares two matrices for equality within a certain margin of error
 /// </summary>
 /// <param name="a">a First matrix</param>
 /// <param name="b">b Second matrix</param>
 /// <returns>True if a is equivalent to b</returns>
 public static bool Equal(XbimMatrix3D a, XbimMatrix3D b)
 {
     return(System.Object.ReferenceEquals(a, b) || (
                Math.Abs(a.M11 - b.M11) < FLOAT_EPSILON &&
                Math.Abs(a.M12 - b.M12) < FLOAT_EPSILON &&
                Math.Abs(a.M13 - b.M13) < FLOAT_EPSILON &&
                Math.Abs(a.M14 - b.M14) < FLOAT_EPSILON &&
                Math.Abs(a.M21 - b.M21) < FLOAT_EPSILON &&
                Math.Abs(a.M22 - b.M22) < FLOAT_EPSILON &&
                Math.Abs(a.M23 - b.M23) < FLOAT_EPSILON &&
                Math.Abs(a.M24 - b.M34) < FLOAT_EPSILON &&
                Math.Abs(a.M31 - b.M31) < FLOAT_EPSILON &&
                Math.Abs(a.M32 - b.M32) < FLOAT_EPSILON &&
                Math.Abs(a.M33 - b.M33) < FLOAT_EPSILON &&
                Math.Abs(a.M34 - b.M34) < FLOAT_EPSILON &&
                Math.Abs(a.OffsetX - b.OffsetX) < FLOAT_EPSILON &&
                Math.Abs(a.OffsetY - b.OffsetY) < FLOAT_EPSILON &&
                Math.Abs(a.OffsetZ - b.OffsetZ) < FLOAT_EPSILON &&
                Math.Abs(a.M44 - b.M44) < FLOAT_EPSILON
                ));
 }
Exemple #27
0
        /// <summary>
        /// Transforms a bounding rect so that it is still axis aligned
        /// </summary>
        /// <param name="rect3d"></param>
        /// <param name="m"></param>
        /// <returns></returns>
        static public XbimRect3D TransformBy(XbimRect3D rect3d, XbimMatrix3D m)
        {
            XbimPoint3D  min      = rect3d.Min;
            XbimPoint3D  max      = rect3d.Max;
            XbimVector3D up       = m.Up;
            XbimVector3D right    = m.Right;
            XbimVector3D backward = m.Backward;
            var          xa       = right * min.X;
            var          xb       = right * max.X;

            var ya = up * min.Y;
            var yb = up * max.Y;

            var za = backward * min.Z;
            var zb = backward * max.Z;

            return(new XbimRect3D(
                       XbimVector3D.Min(xa, xb) + XbimVector3D.Min(ya, yb) + XbimVector3D.Min(za, zb) + m.Translation,
                       XbimVector3D.Max(xa, xb) + XbimVector3D.Max(ya, yb) + XbimVector3D.Max(za, zb) + m.Translation
                       ));
        }
        public void TransformSolidRectangularProfileDef()
        {
            using (var m = XbimModel.CreateTemporaryModel())
            {
                using (var txn = m.BeginTransaction())
                {

                    var profile = IfcModelBuilder.MakeRectangleHollowProfileDef(m, 20, 10, 1);
                    var extrude = IfcModelBuilder.MakeExtrudedAreaSolid(m, profile, 40);
                    var solid = _xbimGeometryCreator.CreateSolid(extrude);
                    var transform = new XbimMatrix3D(); //test first with identity
                    var solid2 = (IXbimSolid)solid.Transform(transform);
                    var s1Verts = solid.Vertices.ToList();
                    var s2Verts = solid2.Vertices.ToList();
                    for (int i = 0; i < s1Verts.Count; i++)
                    {
                        XbimVector3D v = s1Verts[i].VertexGeometry - s2Verts[i].VertexGeometry;
                        Assert.IsTrue(v.Length < m.ModelFactors.Precision, "vertices not the same");
                    }
                    transform.RotateAroundXAxis(Math.PI/2);
                    transform.RotateAroundYAxis(Math.PI/4);
                    transform.RotateAroundZAxis(Math.PI);
                    transform.OffsetX += 100;
                    transform.OffsetY += 200;
                    transform.OffsetZ += 300;
                    solid2 = (IXbimSolid)solid.Transform(transform);
                    Assert.IsTrue(Math.Abs(solid.Volume - solid2.Volume) < 0.001, "Volume differs");
                    transform.Invert();
                    solid2 = (IXbimSolid)solid2.Transform(transform);
                    s1Verts = solid.Vertices.ToList();
                    s2Verts = solid2.Vertices.ToList();
                    for (int i = 0; i < s1Verts.Count; i++)
                    {
                        XbimVector3D v = s1Verts[i].VertexGeometry-s2Verts[i].VertexGeometry;
                        Assert.IsTrue(v.Length < m.ModelFactors.Precision, "vertices not the same");
                    }
                }
            }
        }
Exemple #29
0
        public static XbimPoint3D Multiply(XbimPoint3D p, XbimMatrix3D m)
        {
            var x = p.X;
            var y = p.Y;
            var z = p.Z;



            XbimPoint3D pRet = new XbimPoint3D(m.M11 * x + m.M21 * y + m.M31 * z + m.OffsetX,
                                               m.M12 * x + m.M22 * y + m.M32 * z + m.OffsetY,
                                               m.M13 * x + m.M23 * y + m.M33 * z + m.OffsetZ
                                               );

            if (!m.IsAffine)
            {
                double AffineRatio = x * m.M14 + y * m.M24 + z * m.M34 + m.M44;
                pRet.X /= AffineRatio;
                pRet.Y /= AffineRatio;
                pRet.Z /= AffineRatio;
            }
            return(pRet);
        }
        public static XbimPoint3D Multiply(XbimPoint3D p, XbimMatrix3D m)
        {
            var x = p.X;
            var y = p.Y; 
            var z = p.Z;
            

            
            XbimPoint3D pRet = new XbimPoint3D(m.M11 * x + m.M21 * y + m.M31 * z + m.OffsetX,
                                   m.M12 * x + m.M22 * y + m.M32 * z + m.OffsetY,
                                   m.M13 * x + m.M23 * y + m.M33 * z + m.OffsetZ
                                  );

            if (!m.IsAffine)
            {
                double AffineRatio = x * m.M14 + y * m.M24 + z * m.M34 + m.M44;
                pRet.X /= AffineRatio;
                pRet.Y /= AffineRatio;
                pRet.Z /= AffineRatio;
            }
            return pRet;

        }
Exemple #31
0
        private static XbimMatrix3D CreateRotation(double angle, XbimVector3D axis)
        {
            XbimMatrix3D ret = XbimMatrix3D.Identity;

            if (angle == 0 || (axis.X == 0 && axis.Y == 0 && axis.Z == 0))
            {
                return(ret);
            }
            double xx, yy, zz, xy, yz, zx, xs, ys, zs, one_c, s, c;

            s = Math.Sin(angle);
            c = Math.Cos(angle);

            double x = axis.X;
            double y = axis.Y;
            double z = axis.Z;

            // simple cases
            if (x == 0)
            {
                if (y == 0)
                {
                    if (z != 0)
                    {
                        // rotate only around z-axis
                        ret.M11 = c;
                        ret.M22 = c;
                        if (z < 0)
                        {
                            ret.M21 = -s;
                            ret.M12 = s;
                        }
                        else
                        {
                            ret.M21 = s;
                            ret.M12 = -s;
                        }
                        return(ret);
                    }
                }
                else if (z == 0)
                {
                    // rotate only around y-axis
                    ret.M11 = c;
                    ret.M33 = c;
                    if (y < 0)
                    {
                        ret.M31 = s;
                        ret.M13 = -s;
                    }
                    else
                    {
                        ret.M31 = -s;
                        ret.M13 = s;
                    }
                    return(ret);
                }
            }
            else if (y == 0)
            {
                if (z == 0)
                {
                    // rotate only around x-axis
                    ret.M22 = c;
                    ret.M33 = c;
                    if (x < 0)
                    {
                        ret.M32 = -s;
                        ret.M23 = s;
                    }
                    else
                    {
                        ret.M32 = s;
                        ret.M23 = -s;
                    }
                    return(ret);
                }
            }

            // Beginning of general axisa to matrix conversion
            var dot = x * x + y * y + z * z;

            if (dot > 1.0001 || dot < 0.99999)
            {
                var mag = Math.Sqrt(dot);
                x /= mag;
                y /= mag;
                z /= mag;
            }

            xx    = x * x;
            yy    = y * y;
            zz    = z * z;
            xy    = x * y;
            yz    = y * z;
            zx    = z * x;
            xs    = x * s;
            ys    = y * s;
            zs    = z * s;
            one_c = 1 - c;

            ret.M11 = ((one_c * xx) + c); ret.M21 = ((one_c * xy) + zs); ret.M31 = ((one_c * zx) - ys);
            ret.M12 = ((one_c * xy) - zs); ret.M22 = ((one_c * yy) + c); ret.M32 = ((one_c * yz) + xs);
            ret.M13 = ((one_c * zx) + ys); ret.M23 = ((one_c * yz) - xs); ret.M33 = ((one_c * zz) + c);
            return(ret);
        }
 /// <summary>
 /// Creates a new instance of a mat4
 /// </summary>
 /// <param name="mat">Single[16] containing values to initialize with</param>
 /// <returns>New mat4New mat4</returns>
 public static XbimMatrix3D Copy(XbimMatrix3D m)
 {
     return new XbimMatrix3D(m.M11 , m.M12 , m.M13, m.M14 ,
           m.M21 , m.M22 , m.M23, m.M24 ,
           m.M31 , m.M32 , m.M33, m.M34 ,
           m.OffsetX , m.OffsetY , m.OffsetZ , m.M44);
 }
        public static XbimMatrix3D CreateWorld(XbimVector3D position, XbimVector3D forward, XbimVector3D up)
        {
            // prepare vectors
            forward.Normalize();
            XbimVector3D vector = forward * -1;
            XbimVector3D vector2 = XbimVector3D.CrossProduct(up, vector);
            vector2.Normalize();
            XbimVector3D vector3 = XbimVector3D.CrossProduct(vector, vector2);

            // prepare matrix
            XbimMatrix3D result = new XbimMatrix3D(
                vector2.X, vector2.Y, vector2.Z, 0.0,
                vector3.X, vector3.Y, vector3.Z, 0.0,
                vector.X, vector.Y, vector.Z, 0.0,
                position.X, position.Y, position.Z, 0.0);
            return result;
        }
        // Microsoft.Xna.Framework.Matrix
        public static XbimMatrix3D CreateLookAt(XbimVector3D cameraPosition, XbimVector3D cameraTarget, XbimVector3D cameraUpVector)
        {
            // prepare vectors
            XbimVector3D vector = cameraPosition - cameraTarget;
            vector.Normalize();
            XbimVector3D vector2 = XbimVector3D.CrossProduct(cameraUpVector, vector);
            vector2.Normalize();
            XbimVector3D vector3 = XbimVector3D.CrossProduct(vector, vector2);

            // prepare matrix
            XbimMatrix3D result = new XbimMatrix3D(
                vector2.X, vector3.X, vector.X, 0.0,
                vector2.Y, vector3.Y, vector.Y, 0.0,
                vector2.Z, vector3.Z, vector.Z, 0.0,
                -XbimVector3D.DotProduct(vector2, cameraPosition), -XbimVector3D.DotProduct(vector3, cameraPosition), -XbimVector3D.DotProduct(vector, cameraPosition), 1.0);
            return result;
        }
        /// <summary>
        /// Decomposes a matrix into a scale, rotation, and translation.
        /// </summary>
        /// <param name="scale">When the method completes, contains the scaling component of the decomposed matrix.</param>
        /// <param name="rotation">When the method completes, contains the rtoation component of the decomposed matrix.</param>
        /// <param name="translation">When the method completes, contains the translation component of the decomposed matrix.</param>
        /// <remarks>
        /// This method is designed to decompose an SRT transformation matrix only.
        /// </remarks>
        public bool Decompose(out XbimVector3D scale, out XbimQuaternion rotation, out XbimVector3D translation)
        {
            //Source: Unknown
            // References: http://www.gamedev.net/community/forums/topic.asp?topic_id=441695
            // via https://code.google.com/p/sharpdx/source/browse/Source/SharpDX/Matrix.cs?r=9f9e209b1be04f06f294bc6d72b06055ad6abdcc

            //Get the translation.
            translation = new XbimVector3D();
            translation.X = this._offsetX;
            translation.Y = this._offsetY;
            translation.Z = this._offsetZ;

            //Scaling is the length of the rows.
            scale = new XbimVector3D();
            scale.X = Math.Sqrt((M11 * M11) + (M12 * M12) + (M13 * M13));
            scale.Y = Math.Sqrt((M21 * M21) + (M22 * M22) + (M23 * M23));
            scale.Z = Math.Sqrt((M31 * M31) + (M32 * M32) + (M33 * M33));

            //If any of the scaling factors are zero, than the rotation matrix can not exist.
            // 

            double ZeroTolerance = 0.000003;
            if (Math.Abs(scale.X) < ZeroTolerance ||
                Math.Abs(scale.Y) < ZeroTolerance ||
                Math.Abs(scale.Z) < ZeroTolerance)
            {
                rotation = new XbimQuaternion(); // defaults to identity
                return false;
            }

            //The rotation is the left over matrix after dividing out the scaling.
            XbimMatrix3D rotationmatrix = new XbimMatrix3D();
            rotationmatrix.M11 = M11 / scale.X;
            rotationmatrix.M12 = M12 / scale.X;
            rotationmatrix.M13 = M13 / scale.X;

            rotationmatrix.M21 = M21 / scale.Y;
            rotationmatrix.M22 = M22 / scale.Y;
            rotationmatrix.M23 = M23 / scale.Y;

            rotationmatrix.M31 = M31 / scale.Z;
            rotationmatrix.M32 = M32 / scale.Z;
            rotationmatrix.M33 = M33 / scale.Z;

            rotationmatrix.M44 = 1;

            XbimQuaternion.RotationMatrix(ref rotationmatrix, out rotation);
            return true;
        }
 internal void SetCenterInMeters(XbimVector3D modelTranslation)
 {
     var translation = XbimMatrix3D.CreateTranslation(modelTranslation * OneMeter);
     var scaling = XbimMatrix3D.CreateScale(1/OneMeter);
     Transfrom =  translation * scaling;
 }
 public void Add(string mesh, Type productType, int productLabel, int geometryLabel, XbimMatrix3D? transform, short modelId)
 {
     Add(mesh, IfcMetaData.IfcTypeId(productType), productLabel, geometryLabel, transform, modelId);
 }
Exemple #38
0
        /// <summary>
        /// Transforms a bounding rect so that it is still axis aligned
        /// </summary>
        /// <param name="rect3d"></param>
        /// <param name="m"></param>
        /// <returns></returns>
        static public XbimRect3D TransformBy(XbimRect3D rect3d, XbimMatrix3D m)
        {
            XbimPoint3D min = rect3d.Min;
            XbimPoint3D max = rect3d.Max;
            XbimVector3D up = m.Up;
            XbimVector3D right = m.Right;
            XbimVector3D backward = m.Backward;
            var xa = right * min.X;
            var xb = right * max.X;

            var ya = up * min.Y;
            var yb = up * max.Y;

            var za = backward * min.Z;
            var zb = backward * max.Z;

            return new XbimRect3D(
                XbimVector3D.Min(xa, xb) + XbimVector3D.Min(ya, yb) + XbimVector3D.Min(za, zb) + m.Translation,
                XbimVector3D.Max(xa, xb) + XbimVector3D.Max(ya, yb) + XbimVector3D.Max(za, zb) + m.Translation
            );
            
        }
Exemple #39
0
 private bool IncludePoint(XbimPoint3D Point, XbimMatrix3D Matrix)
 {
     XbimPoint3D t = XbimPoint3D.Multiply(Point, Matrix);
     return IncludePoint(t);
 }
        public static void Read(this MeshGeometry3D m3D, string shapeData, XbimMatrix3D? transform = null)
        {
            transform = null;
            RotateTransform3D qrd = new RotateTransform3D();
            Matrix3D? matrix3D = null;
            if (transform.HasValue)
            {
                XbimQuaternion xq = transform.Value.GetRotationQuaternion();
                qrd.Rotation = new QuaternionRotation3D(new Quaternion(xq.X, xq.Y, xq.Z, xq.W));
                matrix3D = transform.Value.ToMatrix3D();
            }
            
            using (StringReader sr = new StringReader(shapeData))
            {
                int version = 1;
                List<Point3D> vertexList = new List<Point3D>(512); //holds the actual unique positions of the vertices in this data set in the mesh
                List<Vector3D> normalList = new List<Vector3D>(512); //holds the actual unique normals of the vertices in this data set in the mesh

                List<Point3D> positions = new List<Point3D>(1024); //holds the actual positions of the vertices in this data set in the mesh
                List<Vector3D> normals = new List<Vector3D>(1024); //holds the actual normals of the vertices in this data set in the mesh
                List<int> triangleIndices = new List<int>(2048);
                String line;
                // Read and display lines from the data until the end of
                // the data is reached.

                while ((line = sr.ReadLine()) != null)
                {

                    string[] tokens = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    if (tokens.Length > 0) //we need a command
                    {
                        string command = tokens[0].Trim().ToUpper();
                        switch (command)
                        {
                            case "P":
                                vertexList = new List<Point3D>(512);
                                normalList = new List<Vector3D>(512);
                                if (tokens.Length > 0)
                                    version = Int32.Parse(tokens[1]);
                                break;
                            case "V": //process vertices
                                for (int i = 1; i < tokens.Length; i++)
                                {
                                    string[] xyz = tokens[i].Split(',');
                                    Point3D p = new Point3D(Convert.ToDouble(xyz[0], CultureInfo.InvariantCulture),
                                                                      Convert.ToDouble(xyz[1], CultureInfo.InvariantCulture),
                                                                      Convert.ToDouble(xyz[2], CultureInfo.InvariantCulture));
                                    if (matrix3D.HasValue)
                                        p = matrix3D.Value.Transform(p);
                                    vertexList.Add(p);
                                }
                                break;
                            case "N": //processes normals
                                for (int i = 1; i < tokens.Length; i++)
                                {
                                    string[] xyz = tokens[i].Split(',');
                                    Vector3D v = new Vector3D(Convert.ToDouble(xyz[0], CultureInfo.InvariantCulture),
                                                                       Convert.ToDouble(xyz[1], CultureInfo.InvariantCulture),
                                                                       Convert.ToDouble(xyz[2], CultureInfo.InvariantCulture));
                                    normalList.Add(v);
                                }
                                break;
                            case "T": //process triangulated meshes
                                Vector3D currentNormal = new Vector3D(0,0,0);
                                //each time we start a new mesh face we have to duplicate the vertices to ensure that we get correct shading of planar and non planar faces
                                var writtenVertices = new Dictionary<int, int>();

                                for (int i = 1; i < tokens.Length; i++)
                                {
                                    string[] indices = tokens[i].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                                    if (indices.Length != 3) throw new Exception("Invalid triangle definition");
                                    for (int t = 0; t < 3; t++)
                                    {
                                        string[] indexNormalPair = indices[t].Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

                                        if (indexNormalPair.Length > 1) //we have a normal defined
                                        {
                                            if (version == 1)
                                            {
                                                string normalStr = indexNormalPair[1].Trim();
                                                switch (normalStr)
                                                {
                                                    case "F": //Front
                                                        currentNormal = new Vector3D(0, -1, 0);
                                                        break;
                                                    case "B": //Back
                                                        currentNormal = new Vector3D(0, 1, 0);
                                                        break;
                                                    case "L": //Left
                                                        currentNormal = new Vector3D(-1, 0, 0);
                                                        break;
                                                    case "R": //Right
                                                        currentNormal = new Vector3D(1, 0, 0);
                                                        break;
                                                    case "U": //Up
                                                        currentNormal = new Vector3D(0, 0, 1);
                                                        break;
                                                    case "D": //Down
                                                        currentNormal = new Vector3D(0, 0, -1);
                                                        break;
                                                    default: //it is an index number
                                                        int normalIndex = int.Parse(indexNormalPair[1]);
                                                        currentNormal = normalList[normalIndex];
                                                        break;
                                                }
                                            }
                                            else //we have support for packed normals
                                            {
                                                var packedNormal = new XbimPackedNormal(ushort.Parse(indexNormalPair[1]));
                                                var n = packedNormal.Normal;
                                                currentNormal = new Vector3D(n.X, n.Y, n.Z);
                                            }
                                            if (matrix3D.HasValue)
                                            { 
                                                currentNormal = qrd.Transform(currentNormal);
                                            }
                                        }

                                        //now add the index
                                        int index = int.Parse(indexNormalPair[0]);

                                        int alreadyWrittenAt; //in case it is the first mesh
                                        if (!writtenVertices.TryGetValue(index, out alreadyWrittenAt)) //if we haven't  written it in this mesh pass, add it again unless it is the first one which we know has been written
                                        {
                                            //all vertices will be unique and have only one normal
                                            writtenVertices.Add(index, positions.Count);
                                            triangleIndices.Add(positions.Count + m3D.TriangleIndices.Count);
                                            positions.Add(vertexList[index]);
                                            normals.Add(currentNormal);
                                        }
                                        else //just add the index reference
                                        {
                                            if(normals[alreadyWrittenAt] == currentNormal)
                                                triangleIndices.Add(alreadyWrittenAt);
                                            else //we need another
                                            {
                                                triangleIndices.Add(positions.Count + m3D.TriangleIndices.Count);
                                                positions.Add(vertexList[index]);
                                                normals.Add(currentNormal);
                                            }
                                        }
                                    }
                                }
                                break;
                            case "F": //skip faces for now, can be used to draw edges
                                break;
                            default:
                                throw new Exception("Invalid Geometry Command");

                        }
                    }
                }
                m3D.Positions = new Point3DCollection(m3D.Positions.Concat(positions)); //we do this for wpf performance issues
                m3D.Normals = new Vector3DCollection(m3D.Normals.Concat(normals)); //we do this for wpf performance issues
                m3D.TriangleIndices = new Int32Collection(m3D.TriangleIndices.Concat(triangleIndices)); //we do this for wpf performance issues
            }
        }
Exemple #41
0
 public BoundingBox TransformBy(XbimMatrix3D m)
 {
     return new BoundingBox(m.Transform(PointMin), m.Transform(PointMax));
 }
        /// <summary>
        /// Reads an ascii string of Xbim mesh geometry data
        /// </summary>
        /// <param name="data"></param>
        /// <returns></returns>
        public bool Read(String data, XbimMatrix3D? trans = null)
        {
            var version = 2; //we are at at least verson 2 now
            var q = new XbimQuaternion();
            if (trans.HasValue)
                q = trans.Value.GetRotationQuaternion();
            using (var sr = new StringReader(data))
            {

                var vertexList = new List<XbimPoint3D>(); //holds the actual positions of the vertices in this data set in the mesh
                var normalList = new List<XbimVector3D>(); //holds the actual normals of the vertices in this data set in the mesh
                String line;
                // Read and display lines from the data until the end of
                // the data is reached.

                while ((line = sr.ReadLine()) != null)
                {

                    var tokens = line.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                    if (tokens.Length > 1) //we need a command and some data
                    {
                        var command = tokens[0].Trim().ToUpper();
                        switch (command)
                        {
                            case "P":
                                version = Int32.Parse(tokens[1]);
                                var pointCount = 512;
                                //var faceCount = 128;
                                //var triangleCount = 256;
                                var normalCount = 512;
                                if (tokens.Length > 1) pointCount = Int32.Parse(tokens[2]);
                               // if (tokens.Length > 2) faceCount = Int32.Parse(tokens[3]);
                               // if (tokens.Length > 3) triangleCount = Int32.Parse(tokens[4]);
                                //version 2 of the string format uses packed normals
                                if (version < 2 && tokens.Length > 4) normalCount = Int32.Parse(tokens[5]);
                                vertexList = new List<XbimPoint3D>(pointCount);
                                normalList = new List<XbimVector3D>(normalCount);
                                break;
                            case "V": //process vertices
                                for (var i = 1; i < tokens.Length; i++)
                                {
                                    var xyz = tokens[i].Split(',');
                                    var p = new XbimPoint3D(Convert.ToDouble(xyz[0], CultureInfo.InvariantCulture),
                                                                      Convert.ToDouble(xyz[1], CultureInfo.InvariantCulture),
                                                                      Convert.ToDouble(xyz[2], CultureInfo.InvariantCulture));
                                    if (trans.HasValue)
                                        p = trans.Value.Transform(p);
                                    vertexList.Add(p);
                                }
                                break;
                            case "N": //processes normals
                                for (var i = 1; i < tokens.Length; i++)
                                {
                                    var xyz = tokens[i].Split(',');
                                    var v = new XbimVector3D(Convert.ToDouble(xyz[0], CultureInfo.InvariantCulture),
                                                                       Convert.ToDouble(xyz[1], CultureInfo.InvariantCulture),
                                                                       Convert.ToDouble(xyz[2], CultureInfo.InvariantCulture));
                                    normalList.Add(v);
                                }
                                break;
                            case "T": //process triangulated meshes
                                var currentNormal = XbimVector3D.Zero;
                                //each time we start a new mesh face we have to duplicate the vertices to ensure that we get correct shading of planar and non planar faces
                                var writtenVertices = new Dictionary<int, int>();

                                for (var i = 1; i < tokens.Length; i++)
                                {
                                    var triangleIndices = tokens[i].Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
                                    if (triangleIndices.Length != 3) throw new Exception("Invalid triangle definition");
                                    for (var t = 0; t < 3; t++)
                                    {
                                        var indexNormalPair = triangleIndices[t].Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);

                                        if (indexNormalPair.Length > 1) //we have a normal defined
                                        {
                                            var normalStr = indexNormalPair[1].Trim();
                                            if (version < 2)
                                            {
                                                switch (normalStr)
                                                {
                                                    case "F": //Front
                                                        currentNormal = new XbimVector3D(0, -1, 0);
                                                        break;
                                                    case "B": //Back
                                                        currentNormal = new XbimVector3D(0, 1, 0);
                                                        break;
                                                    case "L": //Left
                                                        currentNormal = new XbimVector3D(-1, 0, 0);
                                                        break;
                                                    case "R": //Right
                                                        currentNormal = new XbimVector3D(1, 0, 0);
                                                        break;
                                                    case "U": //Up
                                                        currentNormal = new XbimVector3D(0, 0, 1);
                                                        break;
                                                    case "D": //Down
                                                        currentNormal = new XbimVector3D(0, 0, -1);
                                                        break;
                                                    default: //it is an index number
                                                        var normalIndex = int.Parse(indexNormalPair[1]);
                                                        currentNormal = normalList[normalIndex];
                                                        break;
                                                }
                                            }
                                            else
                                            {
                                                var normalIndex = ushort.Parse(indexNormalPair[1]);
                                                var packedNormal = new XbimPackedNormal(normalIndex);
                                                currentNormal = packedNormal.Normal;
                                            }
                                            if (trans.HasValue)
                                            {
                                                XbimVector3D v;
                                                XbimQuaternion.Transform(ref currentNormal, ref q, out v);
                                                currentNormal = v;

                                            }
                                        }

                                        //now add the index
                                        var index = int.Parse(indexNormalPair[0]);

                                        int alreadyWrittenAt;
                                        if (!writtenVertices.TryGetValue(index, out alreadyWrittenAt)) //if we haven't  written it in this mesh pass, add it again unless it is the first one which we know has been written
                                        {
                                            //all vertices will be unique and have only one normal
                                            writtenVertices.Add(index, PositionCount);
                                            TriangleIndices.Add(PositionCount);
                                            Positions.Add(vertexList[index]);
                                            Normals.Add(currentNormal);
                                        }
                                        else //just add the index reference
                                        {
                                            TriangleIndices.Add(alreadyWrittenAt);
                                        }
                                    }
                                }

                                break;
                            case "F":
                                break;
                            default:
                                throw new Exception("Invalid Geometry Command");

                        }
                    }
                }
            }
            return true;
        }
 public void Add(string mesh, short productTypeId, int productLabel, int geometryLabel, XbimMatrix3D? transform, short modelId)
 {
     lock (meshLock)
     {
         var frag = new XbimMeshFragment(PositionCount, TriangleIndexCount, productTypeId, productLabel, geometryLabel, modelId);
         Read(mesh, transform);
         frag.EndPosition = PositionCount - 1;
         frag.EndTriangleIndex = TriangleIndexCount - 1;
         _meshes.Add(frag);
     }
 }
        public static XbimMeshGeometry3D MakeBoundingBox(XbimRect3D r3D, XbimMatrix3D transform)
        {
            XbimMeshGeometry3D mesh = new XbimMeshGeometry3D(8);
            XbimPoint3D p0 = transform.Transform(r3D.Location);
            XbimPoint3D p1 = p0;
            p1.X += r3D.SizeX;
            XbimPoint3D p2 = p1;
            p2.Z += r3D.SizeZ;
            XbimPoint3D p3 = p2;
            p3.X -= r3D.SizeX;
            XbimPoint3D p4 = p3;
            p4.Y += r3D.SizeY;
            XbimPoint3D p5 = p4;
            p5.Z -= r3D.SizeZ;
            XbimPoint3D p6 = p5;
            p6.X += r3D.SizeX;
            XbimPoint3D p7 = p6;
            p7.Z += r3D.SizeZ;

            mesh.Positions.Add(p0);
            mesh.Positions.Add(p1);
            mesh.Positions.Add(p2);
            mesh.Positions.Add(p3);
            mesh.Positions.Add(p4);
            mesh.Positions.Add(p5);
            mesh.Positions.Add(p6);
            mesh.Positions.Add(p7);

            mesh.TriangleIndices.Add(3);
            mesh.TriangleIndices.Add(0);
            mesh.TriangleIndices.Add(2);

            mesh.TriangleIndices.Add(0);
            mesh.TriangleIndices.Add(1);
            mesh.TriangleIndices.Add(2);

            mesh.TriangleIndices.Add(4);
            mesh.TriangleIndices.Add(5);
            mesh.TriangleIndices.Add(3);

            mesh.TriangleIndices.Add(5);
            mesh.TriangleIndices.Add(0);
            mesh.TriangleIndices.Add(3);

            mesh.TriangleIndices.Add(7);
            mesh.TriangleIndices.Add(6);
            mesh.TriangleIndices.Add(4);

            mesh.TriangleIndices.Add(6);
            mesh.TriangleIndices.Add(5);
            mesh.TriangleIndices.Add(4);

            mesh.TriangleIndices.Add(2);
            mesh.TriangleIndices.Add(1);
            mesh.TriangleIndices.Add(7);

            mesh.TriangleIndices.Add(1);
            mesh.TriangleIndices.Add(6);
            mesh.TriangleIndices.Add(7);

            mesh.TriangleIndices.Add(4);
            mesh.TriangleIndices.Add(3);
            mesh.TriangleIndices.Add(7);

            mesh.TriangleIndices.Add(3);
            mesh.TriangleIndices.Add(2);
            mesh.TriangleIndices.Add(7);

            mesh.TriangleIndices.Add(6);
            mesh.TriangleIndices.Add(1);
            mesh.TriangleIndices.Add(5);

            mesh.TriangleIndices.Add(1);
            mesh.TriangleIndices.Add(0);
            mesh.TriangleIndices.Add(5);

            return mesh;
        }
        /// <summary>
        /// Reads a triangulated model from an array of bytes and adds the mesh to the current state
        ///  </summary>
        /// <param name="m3D"></param>
        /// <param name="mesh">byte array of XbimGeometryType.PolyhedronBinary  Data</param>
        /// <param name="transform">Transforms the mesh to the new position if not null</param>
        public static void Read(this MeshGeometry3D m3D, byte[] mesh, XbimMatrix3D? transform = null)
        {
            int indexBase = m3D.Positions.Count;
            var qrd = new RotateTransform3D();
            Matrix3D? matrix3D = null;
            if (transform.HasValue)
            {
                var xq = transform.Value.GetRotationQuaternion();
                var quaternion = new Quaternion(xq.X, xq.Y, xq.Z, xq.W);
                if (!quaternion.IsIdentity)
                    qrd.Rotation = new QuaternionRotation3D(quaternion);
                else
                    qrd = null;
                matrix3D = transform.Value.ToMatrix3D();
            }
            using (var ms = new MemoryStream(mesh))
            {
                using (var br = new BinaryReader(ms))
                {
// ReSharper disable once UnusedVariable
                    var version = br.ReadByte(); //stream format version
                    var numVertices = br.ReadInt32();
                    var numTriangles = br.ReadInt32();
                   
                    var uniqueVertices = new List<Point3D>(numVertices);
                    var vertices = new List<Point3D>(numVertices * 4); //approx the size
                    var triangleIndices = new List<Int32>(numTriangles*3);
                    var normals = new List<Vector3D>(numVertices * 4);
                    for (var i = 0; i < numVertices; i++)
                    {
                        double x = br.ReadSingle();
                        double y = br.ReadSingle();
                        double z = br.ReadSingle();
                        var p = new Point3D(x, y, z);
                        if (matrix3D.HasValue)
                            p = matrix3D.Value.Transform(p);
                        uniqueVertices.Add(p);
                    }
                    var numFaces = br.ReadInt32();
                   
                    for (var i = 0; i < numFaces; i++)
                    {
                        var numTrianglesInFace = br.ReadInt32();
                        if (numTrianglesInFace == 0) continue;
                        var isPlanar = numTrianglesInFace > 0;
                        numTrianglesInFace = Math.Abs(numTrianglesInFace);
                        if (isPlanar)
                        {
                            var normal = br.ReadPackedNormal().Normal;
                            var wpfNormal = new Vector3D(normal.X, normal.Y, normal.Z);
                            if (qrd!=null) //transform the normal if we have to
                                wpfNormal = qrd.Transform(wpfNormal);
                            var uniqueIndices = new Dictionary<int, int>();
                            for (var j = 0; j < numTrianglesInFace; j++)
                            {
                                for (int k = 0; k < 3; k++)
                                {
                                    int idx = ReadIndex(br, numVertices);
                                    int writtenIdx;
                                    if (!uniqueIndices.TryGetValue(idx, out writtenIdx)) //we haven't got it, so add it
                                    {
                                        writtenIdx = vertices.Count;
                                        vertices.Add(uniqueVertices[idx]);
                                        uniqueIndices.Add(idx, writtenIdx);
                                        //add a matching normal
                                        normals.Add(wpfNormal);
                                    }
                                    triangleIndices.Add(indexBase + writtenIdx);
                                }
                            }
                        }
                        else
                        {
                            var uniqueIndices = new Dictionary<int, int>();
                            for (var j = 0; j < numTrianglesInFace; j++)
                            {
                                for (int k = 0; k < 3; k++)
                                {
                                    int idx = ReadIndex(br, numVertices);
                                    var normal = br.ReadPackedNormal().Normal;
                                    int writtenIdx;
                                    var wpfNormal = new Vector3D(normal.X, normal.Y, normal.Z);
                                    if (qrd != null) //transform the normal if we have to
                                        wpfNormal = qrd.Transform(wpfNormal);
                                    if (!uniqueIndices.TryGetValue(idx, out writtenIdx)) //we haven't got it, so add it
                                    {
                                        writtenIdx = vertices.Count;
                                        vertices.Add(uniqueVertices[idx]);
                                        uniqueIndices.Add(idx, writtenIdx);
                                        normals.Add(wpfNormal);
                                    }
                                    else
                                    {
                                        if (normals[writtenIdx] != wpfNormal) //deal with normals that vary at a node
                                        {
                                            writtenIdx = vertices.Count;
                                            vertices.Add(uniqueVertices[idx]);
                                            normals.Add(wpfNormal);
                                        }
                                    }

                                    triangleIndices.Add(indexBase + writtenIdx);
                                }
                            }
                        }
                    }

                    m3D.Positions = new Point3DCollection(m3D.Positions.Concat(vertices));
                    m3D.TriangleIndices = new Int32Collection(m3D.TriangleIndices.Concat(triangleIndices));
                    m3D.Normals = new Vector3DCollection(m3D.Normals.Concat(normals));
                }
              // if(m3D.CanFreeze) m3D.Freeze(); //freeze the mesh to improve performance
            }
        }
 /// <summary>
 /// Adds the geometry to the mesh for the given product, returns the mesh fragment details
 /// </summary>
 /// <param name="geometryModel">Geometry to add</param>
 /// <param name="product">The product the geometry represents (this may be a partial representation)</param>
 /// <param name="transform">Transform the geometry to a new location or rotation</param>
 /// <param name="deflection">Deflection for triangulating curves, if null default defelction for the model is used</param>
 public XbimMeshFragment Add(IXbimGeometryModel geometryModel, IfcProduct product, XbimMatrix3D transform, double? deflection = null, short modelId = 0)
 {
     return geometryModel.MeshTo(this, product, transform, deflection ?? product.ModelOf.ModelFactors.DeflectionTolerance);
 }
Exemple #47
0
        /// <summary>
        /// Warning: This function assumes no rotation is used for the tranform.
        /// </summary>
        /// <param name="composed">The NON-ROTATING transform to apply</param>
        /// <returns>the transformed bounding box.</returns>
        public XbimRect3D Transform(XbimMatrix3D composed)
        {
            var min = this.Min * composed;
            var max = this.Max * composed;

            return new XbimRect3D(min, max);
        }
        /// <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.Normalize();
					ucsZAxis.Normalize();
                    XbimVector3D ucsYAxis = XbimVector3D.CrossProduct(ucsZAxis, ucsXAxis);
					ucsYAxis.Normalize();
					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));
					}
					else
						return ucsTowcs;

				}
				else //must be 2D
				{
                    throw new NotImplementedException("Support for Placements other than 3D not implemented");
				}

			}
			else //probably a Grid
			{
                throw new NotImplementedException("Support for Placements other than Local not implemented");
			}
        }
        public static void Read(this XbimMeshGeometry3D m3D, byte[] mesh, XbimMatrix3D? transform = null)
        {
            var indexBase = m3D.Positions.Count;
            var qrd = new XbimQuaternion();

            XbimMatrix3D? matrix3D = null;
            if (transform.HasValue)
            {
                qrd = transform.Value.GetRotationQuaternion();
                matrix3D = transform.Value;
            }
            using (var ms = new MemoryStream(mesh))
            {
                using (var br = new BinaryReader(ms))
                {
                    // ReSharper disable once UnusedVariable
                    var version = br.ReadByte(); //stream format version
                    var numVertices = br.ReadInt32();
                    var numTriangles = br.ReadInt32();

                    var uniqueVertices = new List<XbimPoint3D>(numVertices);
                    var vertices = new List<XbimPoint3D>(numVertices * 4); //approx the size
                    var triangleIndices = new List<int>(numTriangles * 3);
                    var normals = new List<XbimVector3D>(numVertices * 4);
                    for (var i = 0; i < numVertices; i++)
                    {
                        double x = br.ReadSingle();
                        double y = br.ReadSingle();
                        double z = br.ReadSingle();
                        var p = new XbimPoint3D(x, y, z);
                        if (matrix3D.HasValue)
                            p = matrix3D.Value.Transform(p);
                        uniqueVertices.Add(p);
                    }
                    var numFaces = br.ReadInt32();

                    for (var i = 0; i < numFaces; i++)
                    {
                        var numTrianglesInFace = br.ReadInt32();
                        if (numTrianglesInFace == 0) continue;
                        var isPlanar = numTrianglesInFace > 0;
                        numTrianglesInFace = Math.Abs(numTrianglesInFace);
                        if (isPlanar)
                        {
                            var normal = br.ReadPackedNormal().Normal;
                            if (!qrd.IsIdentity())
                            {
                                var baseVal = new XbimVector3D(normal.X, normal.Y, normal.Z);
                                XbimQuaternion.Transform(ref baseVal, ref qrd, out normal);
                            }
                            var uniqueIndices = new Dictionary<int, int>();
                            for (var j = 0; j < numTrianglesInFace; j++)
                            {
                                for (var k = 0; k < 3; k++)
                                {
                                    var idx = ReadIndex(br, numVertices);
                                    int writtenIdx;
                                    if (!uniqueIndices.TryGetValue(idx, out writtenIdx)) //we haven't got it, so add it
                                    {
                                        writtenIdx = vertices.Count;
                                        vertices.Add(uniqueVertices[idx]);
                                        uniqueIndices.Add(idx, writtenIdx);
                                        //add a matching normal
                                        normals.Add(normal);
                                    }
                                    triangleIndices.Add(indexBase + writtenIdx);
                                }
                            }
                        }
                        else
                        {
                            var uniqueIndices = new Dictionary<int, int>();
                            for (var j = 0; j < numTrianglesInFace; j++)
                            {
                                for (var k = 0; k < 3; k++)
                                {
                                    var idx = ReadIndex(br, numVertices);
                                    var normal = br.ReadPackedNormal().Normal;
                                    int writtenIdx;
                                    if (!uniqueIndices.TryGetValue(idx, out writtenIdx)) //we haven't got it, so add it
                                    {
                                        writtenIdx = vertices.Count;
                                        vertices.Add(uniqueVertices[idx]);
                                        uniqueIndices.Add(idx, writtenIdx);

                                        if (!qrd.IsIdentity())
                                        {
                                            var baseVal = new XbimVector3D(normal.X, normal.Y, normal.Z);
                                            XbimQuaternion.Transform(ref baseVal, ref qrd, out normal);
                                        }
                                        normals.Add(normal);
                                    }
                                    triangleIndices.Add(indexBase + writtenIdx);
                                }
                            }
                        }
                    }

                    m3D.Positions = m3D.Positions.Concat(vertices).ToList();
                    m3D.TriangleIndices = m3D.TriangleIndices.Concat(triangleIndices).ToList();
                    m3D.Normals = m3D.Normals.Concat(normals).ToList();
                }
            }
        }
 public static XbimVector3D Multiply(XbimVector3D vec, XbimMatrix3D m)
 {
     var x = vec.X;
     var y = vec.Y;
     var z = vec.Z;
     return new XbimVector3D (m.M11 * x + m.M21 * y + m.M31 * z ,
                              m.M12 * x + m.M22 * y + m.M32 * z ,
                              m.M13 * x + m.M23 * y + m.M33 * z 
                             );
 }
        /// <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.Normalize();
                    ucsAxisZ.Normalize();

                    //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;
           
        }
Exemple #52
0
 public static XbimMatrix3D operator *(XbimMatrix3D a, XbimMatrix3D b)
 {
     return(XbimMatrix3D.Multiply(a, b));
 }