static public XbimRect3D Inflate(XbimRect3D original, double x, double y, double z) { XbimPoint3D p = new XbimPoint3D(original.X - x, original.Y - y, original.Z - z); XbimVector3D v = new XbimVector3D(original.SizeX + (x * 2), original.SizeY + (y * 2), original.SizeZ + (z * 2)); return(new XbimRect3D(p, v)); }
static public XbimVector3D Min(XbimVector3D a, XbimVector3D b) { return(new XbimVector3D( (a.X < b.X) ? a.X : b.X, (a.Y < b.Y) ? a.Y : b.Y, (a.Z < b.Z) ? a.Z : b.Z)); }
static public XbimVector3D Min(XbimVector3D a, XbimVector3D b) { return new XbimVector3D( (a.X < b.X) ? a.X : b.X, (a.Y < b.Y) ? a.Y : b.Y, (a.Z < b.Z) ? a.Z : b.Z); }
/// <summary> /// Adds a XbimPoint3D structure to a XbimVector3D and returns the result as a XbimPoint3D structure. /// </summary> /// <param name="p"></param> /// <param name="v"></param> /// <returns></returns> public static XbimPoint3D Add(XbimPoint3D p, XbimVector3D v) { return(new XbimPoint3D(p.X + v.X, p.Y + v.Y, p.Z + v.Z )); }
static public XbimVector3D Max(XbimVector3D a, XbimVector3D b) { return new XbimVector3D( (a.X > b.X) ? a.X : b.X, (a.Y > b.Y) ? a.Y : b.Y, (a.Z > b.Z) ? a.Z : b.Z); }
/// <summary> /// Adds a XbimPoint3D structure to a XbimVector3D and returns the result as a XbimPoint3D structure. /// </summary> /// <param name="p"></param> /// <param name="v"></param> /// <returns></returns> public static XbimPoint3D Add(XbimPoint3D p, XbimVector3D v) { return new XbimPoint3D (p.X + v.X, p.Y + v.Y, p.Z + v.Z ); }
static public XbimRect3D Inflate(XbimRect3D original, double inflate) { XbimPoint3D p = new XbimPoint3D(original.X - inflate, original.Y - inflate, original.Z - inflate); XbimVector3D v = new XbimVector3D(original.SizeX + (inflate * 2), original.SizeY + (inflate * 2), original.SizeZ + (inflate * 2)); return(new XbimRect3D(p, v)); }
public XbimRegion(string name, XbimRect3D bounds, int population) { this.Name = name; this.Size = new XbimVector3D(bounds.SizeX,bounds.SizeY,bounds.SizeZ); this.Centre = bounds.Centroid(); this.Population = population; }
static public XbimVector3D Max(XbimVector3D a, XbimVector3D b) { return(new XbimVector3D( (a.X > b.X) ? a.X : b.X, (a.Y > b.Y) ? a.Y : b.Y, (a.Z > b.Z) ? a.Z : b.Z)); }
public XbimPackedNormal Transform(XbimQuaternion q) { XbimVector3D v1 = Normal; XbimVector3D v2; XbimQuaternion.Transform(ref v1, ref q, out v2); return(new XbimPackedNormal(v2)); }
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 XbimRect3D(XbimVector3D vMin, XbimVector3D vMax) { this._x = Math.Min(vMin.X, vMax.X); this._y = Math.Min(vMin.Y, vMax.Y); this._z = Math.Min(vMin.Z, vMax.Z); this._sizeX = Math.Max(vMin.X, vMax.X) - this._x; this._sizeY = Math.Max(vMin.Y, vMax.Y) - this._y; this._sizeZ = Math.Max(vMin.Z, vMax.Z) - this._z; }
public XbimRect3D(XbimPoint3D Position, XbimVector3D Size) { this._x = Position.X; this._y = Position.Y; this._z = Position.Z; this._sizeX = Size.X; this._sizeY = Size.Y; this._sizeZ = Size.Z; }
public override bool Equals(object ob) { if (ob is XbimVector3D) { XbimVector3D v = (XbimVector3D)ob; return(Math.Abs(X - v.X) < Tolerance && Math.Abs(Y - v.Y) < Tolerance && Math.Abs(Z - v.Z) < Tolerance); } return(false); }
public double Angle(XbimVector3D other) { var cosinus = DotProduct(other); if (cosinus > -0.70710678118655 && cosinus < 0.70710678118655) return Math.Acos(cosinus); var sinus = CrossProduct(other).Length; if (cosinus < 0.0) return Math.PI - Math.Asin(sinus); return Math.Asin(sinus); }
/// <summary> /// Returns true if the vectors are normal /// </summary> /// <param name="other">other vector</param> /// <param name="angularTolerance">Tolerance in radians</param> /// <returns></returns> public bool IsNormal(XbimVector3D other, double angularTolerance) { var ang = Math.PI / 2.0 - Angle(other); if (ang < 0) { ang = -ang; } return(ang <= angularTolerance); }
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 )); }
public override bool Equals(object ob) { if (ob is XbimVector3D) { XbimVector3D v = (XbimVector3D)ob; return(X == v.X && Y == v.Y && Z == v.Z); } else { return(false); } }
public static XbimVector3D CrossProduct(XbimVector3D v1, XbimVector3D v2) { var x = v1.X; var y = v1.Y; var z = v1.Z; var x2 = v2.X; var y2 = v2.Y; var z2 = v2.Z; return(new XbimVector3D(y * z2 - z * y2, z * x2 - x * z2, x * y2 - y * x2)); }
/// <summary> /// returns the area of the polyloop /// </summary> /// <param name="loop"></param> /// <returns></returns> public static double Area(this IfcPolyLoop loop) { XbimVector3D sum = new XbimVector3D(0, 0, 0); IList<IfcCartesianPoint> pts = loop.Polygon; for (int i = 0; i < pts.Count - 1; i++) { XbimVector3D a = new XbimVector3D(pts[i].X,pts[i].Y,pts[i].Z); XbimVector3D b = new XbimVector3D(pts[i + 1].X, pts[i + 1].Y, pts[i + 1].Z); sum = sum + a.CrossProduct(b); } XbimVector3D n = loop.NewellsNormal(); return n.DotProduct(sum) / 2; }
/// <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); }
/// <summary> /// Returns the radius of the sphere that contains this bounding box rectangle 3D /// </summary> /// <returns></returns> public double Radius() { XbimVector3D max = new XbimVector3D(SizeX, SizeY, SizeZ); double len = max.Length; if (len != 0) { return(len / 2); } else { return(0); } }
IEnumerable<XbimVector3D> UniformPointsOnSphere(float n) { var points = new List<XbimVector3D>(); var i = Math.PI * (3 - Math.Sqrt(5)); var o = 2 / n; for (var k = 0; k < n; k++) { var y = k * o - 1 + (o / 2); var r = Math.Sqrt(1 - y * y); var phi = k * i; var v = new XbimVector3D(Math.Cos(phi)*r, y, Math.Sin(phi)*r); points.Add(v); } return points; }
public double Angle(XbimVector3D other) { var cosinus = DotProduct(other) / (Length * other.Length); if (cosinus > -0.70710678118655 && cosinus < 0.70710678118655) { return(Math.Acos(cosinus)); } var sinus = CrossProduct(other).Length / (Length * other.Length); if (cosinus < 0.0) { return(Math.PI - Math.Asin(sinus)); } return(Math.Asin(sinus)); }
// Two CreateRotation functions below are adapted from the implementation of getRotation in // the VisualizationLibrary SDK (sources at http://visualizationlibrary.org/ ) /// <summary> /// Creates a rotation matrix converting from a starting direction to a desired direction. /// </summary> /// <param name="fromDirection">Starting direction</param> /// <param name="toDirection">Desired direction</param> /// <returns>the matrix that applied to <see paramref="fromDirection"/> results in <see paramref="toDirection"/></returns> public static XbimMatrix3D CreateRotation(XbimPoint3D fromDirection, XbimPoint3D toDirection) { var a = new XbimVector3D(toDirection.X, toDirection.Y, toDirection.Z); var b = new XbimVector3D(fromDirection.X, fromDirection.Y, fromDirection.Z); a = a.Normalized(); b = b.Normalized(); double cosa = a.DotProduct(b); cosa = clamp(cosa, -1, +1); var axis = XbimVector3D.CrossProduct(a, b).Normalized(); double alpha = Math.Acos(cosa); return(CreateRotation(alpha, axis)); }
public void Scale(XbimVector3D xbimVector3D) { var x = xbimVector3D.X; var y = xbimVector3D.Y; var z = xbimVector3D.Z; M11 *= x; M12 *= x; M13 *= x; M14 *= x; M21 *= y; M22 *= y; M23 *= y; M24 *= y; M31 *= z; M32 *= z; M33 *= z; M34 *= z; }
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); }
public XbimMatrix3D(XbimVector3D offset) { _m11 = Identity.M11; _m12 = Identity.M12; _m13 = Identity.M13; _m14 = Identity.M14; _m21 = Identity.M21; _m22 = Identity.M22; _m23 = Identity.M23; _m24 = Identity.M24; _m31 = Identity.M31; _m32 = Identity.M32; _m33 = Identity.M33; _m34 = Identity.M34; _offsetX = offset.X; _offsetY = offset.Y; _offsetZ = offset.Z; _m44 = Identity.M44; _isNotDefaultInitialised = true; }
// 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); }
/// <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 )); }
/// <summary> /// Transforms a 3D vector by the given <see cref="SharpDX.Quaternion"/> rotation. /// </summary> /// <param name="vector">The vector to rotate.</param> /// <param name="rotation">The <see cref="SharpDX.Quaternion"/> rotation to apply.</param> /// <param name="result">When the method completes, contains the transformed <see cref="SharpDX.Vector4"/>.</param> public static void Transform(ref XbimVector3D vector, ref XbimQuaternion rotation, out XbimVector3D result) { double x = rotation.X + rotation.X; double y = rotation.Y + rotation.Y; double z = rotation.Z + rotation.Z; double wx = rotation.W * x; double wy = rotation.W * y; double wz = rotation.W * z; double xx = rotation.X * x; double xy = rotation.X * y; double xz = rotation.X * z; double yy = rotation.Y * y; double yz = rotation.Y * z; double zz = rotation.Z * z; result = new XbimVector3D( ((vector.X * ((1.0f - yy) - zz)) + (vector.Y * (xy - wz))) + (vector.Z * (xz + wy)), ((vector.X * (xy + wz)) + (vector.Y * ((1.0f - xx) - zz))) + (vector.Z * (yz - wx)), ((vector.X * (xz - wy)) + (vector.Y * (yz + wx))) + (vector.Z * ((1.0f - xx) - yy)) ); }
private void OnOpenView(object sender, ExecutedRoutedEventArgs e) { if (Bcfier.SelectedBcf() == null) return; var view = e?.Parameter as ViewPoint; if (view == null) return; var v = view.VisInfo; var position = new XbimPoint3D(); var direction = new XbimPoint3D(); var upDirection = new XbimPoint3D(); if (v.PerspectiveCamera != null) { // todo: this works internally, but we must ensure it's compatible with other bcf viewers var pc = v.PerspectiveCamera; position = new XbimPoint3D(pc.CameraViewPoint.X, pc.CameraViewPoint.Y, pc.CameraViewPoint.Z); direction = new XbimPoint3D(pc.CameraDirection.X, pc.CameraDirection.Y, pc.CameraDirection.Z); upDirection = new XbimPoint3D(pc.CameraUpVector.X, pc.CameraUpVector.Y, pc.CameraUpVector.Z); _xpWindow.DrawingControl.Viewport.Orthographic = false; var pCam = _xpWindow.DrawingControl.Viewport.Camera as System.Windows.Media.Media3D.PerspectiveCamera; if (pCam != null) pCam.FieldOfView = pc.FieldOfView; } else if (v.OrthogonalCamera != null) { // todo: this works internally, but we must ensure it's compatible with other bcf viewers var pc = v.OrthogonalCamera; _xpWindow.DrawingControl.Viewport.Orthographic = true; position = new XbimPoint3D(pc.CameraViewPoint.X, pc.CameraViewPoint.Y, pc.CameraViewPoint.Z); direction = new XbimPoint3D(pc.CameraDirection.X, pc.CameraDirection.Y, pc.CameraDirection.Z); upDirection = new XbimPoint3D(pc.CameraUpVector.X, pc.CameraUpVector.Y, pc.CameraUpVector.Z); var pCam = _xpWindow.DrawingControl.Viewport.Camera as OrthographicCamera; if (pCam != null) pCam.Width = pc.ViewToWorldScale; } var directionV = new XbimVector3D(direction.X, direction.Y, direction.Z); var upDirectionV = new XbimVector3D(upDirection.X, upDirection.Y, upDirection.Z); var pos = new Point3D(position.X, position.Y, position.Z); var dir = new Vector3D(directionV.X, directionV.Y, directionV.Z); var upDir = new Vector3D(upDirectionV.X, upDirectionV.Y, upDirectionV.Z); _xpWindow.DrawingControl.Viewport.SetView(pos, dir, upDir, 500); if (v.ClippingPlanes != null && v.ClippingPlanes.Any()) { var curP = v.ClippingPlanes[0]; _xpWindow.DrawingControl.SetCutPlane( curP.Location.X, curP.Location.Y, curP.Location.Z, curP.Direction.X, curP.Direction.Y, curP.Direction.Z ); } else { _xpWindow.DrawingControl.ClearCutPlane(); } // todo: components list to be implemented }
internal void SetCenterInMeters(XbimVector3D modelTranslation) { var translation = XbimMatrix3D.CreateTranslation(modelTranslation * OneMeter); var scaling = XbimMatrix3D.CreateScale(1/OneMeter); Transfrom = translation * scaling; }
public XbimPackedNormal(XbimVector3D vec) : this(vec.X, vec.Y, vec.Z) { }
/// <summary> /// Converts an Ifc 3D vector to an Xbim Vector3D /// </summary> /// <returns></returns> public XbimVector3D XbimVector3D() { XbimVector3D vec; if (Orientation.Dim > 2) vec = new XbimVector3D(Orientation.X, Orientation.Y, Orientation.Z); else if (Orientation.Dim == 2) vec = new XbimVector3D(Orientation.X, Orientation.Y, 0); else vec = new XbimVector3D(); vec.Normalize(); //orientation is not normalized vec *= Magnitude; return vec; }
/// <summary> /// Returns the radius of the sphere that contains this bounding box rectangle 3D /// </summary> /// <returns></returns> public double Radius() { XbimVector3D max = new XbimVector3D(SizeX, SizeY, SizeZ); double len = max.Length; if (len != 0) return len / 2; else return 0; }
void IXbimTriangulatesToPositionsNormalsIndices.AddNormal(XbimVector3D normal) { Normals.Add(normal); }
public bool IsEqual(XbimVector3D b, double precision = 1e-9) { double p = this.DotProduct(b); return Math.Abs(p - 1) <= precision; }
/// <summary> /// Returns true if the angle is less than tolerance /// </summary> /// <param name="other">other vector</param> /// <param name="angularTolerance">Tolerance in radians</param> /// <returns></returns> public bool IsOpposite(XbimVector3D other, double angularTolerance) { return Math.PI - Angle (other) <= angularTolerance; }
public static double DotProduct(XbimVector3D v1, XbimVector3D v2) { return v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z; }
public void ExecuteCamera(object sender, ExecutedRoutedEventArgs e) { if (SelFile.T == null) return; var inst = SelFile.T.SelectedItem as BcfInstance; if (inst == null) return; var v = inst.VisualizationInfo; if (v == null) return; var position = new XbimPoint3D(); var direction = new XbimPoint3D(); var upDirection = new XbimPoint3D(); XbimVector3D directionV; XbimVector3D upDirectionV; if (v.PerspectiveCamera != null) { var pc = v.PerspectiveCamera; position = new XbimPoint3D(pc.CameraViewPoint.X, pc.CameraViewPoint.Y, pc.CameraViewPoint.Z); direction = new XbimPoint3D(pc.CameraDirection.X, pc.CameraDirection.Y, pc.CameraDirection.Z); upDirection = new XbimPoint3D(pc.CameraUpVector.X, pc.CameraUpVector.Y, pc.CameraUpVector.Z); _xpWindow.DrawingControl.Viewport.Orthographic = false; var pCam = _xpWindow.DrawingControl.Viewport.Camera as System.Windows.Media.Media3D.PerspectiveCamera; if (pCam != null) pCam.FieldOfView = pc.FieldOfView; } else if (v.OrthogonalCamera != null) { var pc = v.OrthogonalCamera; _xpWindow.DrawingControl.Viewport.Orthographic = true; position = new XbimPoint3D(pc.CameraViewPoint.X, pc.CameraViewPoint.Y, pc.CameraViewPoint.Z); direction = new XbimPoint3D(pc.CameraDirection.X, pc.CameraDirection.Y, pc.CameraDirection.Z); upDirection = new XbimPoint3D(pc.CameraUpVector.X, pc.CameraUpVector.Y, pc.CameraUpVector.Z); var pCam = _xpWindow.DrawingControl.Viewport.Camera as OrthographicCamera; if (pCam != null) pCam.Width = pc.ViewToWorldScale; } directionV = new XbimVector3D(direction.X, direction.Y, direction.Z); upDirectionV = new XbimVector3D(upDirection.X, upDirection.Y, upDirection.Z); var pos = new Point3D(position.X, position.Y, position.Z); var dir = new Vector3D(directionV.X, directionV.Y, directionV.Z); var upDir = new Vector3D(upDirectionV.X, upDirectionV.Y, upDirectionV.Z); _xpWindow.DrawingControl.Viewport.SetView(pos, dir, upDir, 500); if (v.ClippingPlanes.Any()) { var curP = v.ClippingPlanes[0]; _xpWindow.DrawingControl.SetCutPlane( curP.Location.X, curP.Location.Y, curP.Location.Z, curP.Direction.X, curP.Direction.Y, curP.Direction.Z ); } else { _xpWindow.DrawingControl.ClearCutPlane(); } // xpWindow.DrawingControl.Viewport.FieldOfViewText }
public double GetArea() { // the normal can be taken from the product of two segments on the polyline if (Count() < 3) return double.NaN; XbimVector3D normal = Normal() * -1; XbimVector3D firstSegment = this.FirstSegment(); XbimVector3D up = XbimVector3D.CrossProduct(normal, firstSegment); XbimVector3D campos = new XbimVector3D( _geomPoints[0].Point.X, _geomPoints[0].Point.Y, _geomPoints[0].Point.Z ); XbimVector3D target = campos + normal; XbimMatrix3D m = XbimMatrix3D.CreateLookAt(campos, target, up); XbimPoint3D[] point = new XbimPoint3D[Count()]; for (int i = 0; i < point.Length; i++) { XbimPoint3D pBefore = new XbimPoint3D( _geomPoints[i].Point.X, _geomPoints[i].Point.Y, _geomPoints[i].Point.Z ); XbimPoint3D pAft = m.Transform(pBefore); point[i] = pAft; } // http://stackoverflow.com/questions/2553149/area-of-a-irregular-shape // it assumes that the last point is NOT the same of the first one, but it tolerates the case. double area = 0.0f; int numVertices = Count(); for (int i = 0; i < numVertices - 1; ++i) { area += point[i].X * point[i + 1].Y - point[i + 1].X * point[i].Y; } area += point[numVertices - 1].X * point[0].Y - point[0].X * point[numVertices - 1].Y; area /= 2.0; return area; }
/// <summary> /// Clears the current graphics and initiates the cascade of events that result in viewing the scene. /// </summary> /// <param name="EntityLabels">If null loads the whole model, otherwise only elements listed in the enumerable</param> public void LoadGeometry(XbimModel model, bool recalcView = true) { // AddLayerToDrawingControl is the function that actually populates the geometry in the viewer. // AddLayerToDrawingControl is triggered by BuildRefModelScene and BuildScene below here when layers get ready. //reset all the visuals ClearGraphics(recalcView); short userDefinedId = 0; if (model == null) return; //nothing to show model.UserDefinedId = userDefinedId; Xbim3DModelContext context = new Xbim3DModelContext(model); XbimRegion largest = context.GetLargestRegion(); XbimPoint3D c = new XbimPoint3D(0, 0, 0); XbimRect3D bb = XbimRect3D.Empty; if (largest != null) bb = new XbimRect3D(largest.Centre, largest.Centre); foreach (var refModel in model.ReferencedModels) { XbimRegion r; refModel.Model.UserDefinedId = ++userDefinedId; Xbim3DModelContext refContext = new Xbim3DModelContext(refModel.Model); r = refContext.GetLargestRegion(); if (r != null) { if (bb.IsEmpty) bb = new XbimRect3D(r.Centre, r.Centre); else bb.Union(r.Centre); } } XbimPoint3D p = bb.Centroid(); _modelTranslation = new XbimVector3D(-p.X, -p.Y, -p.Z); model.ReferencedModels.CollectionChanged += RefencedModels_CollectionChanged; //build the geometric scene and render as we go BuildScene(context); foreach (var refModel in model.ReferencedModels) { Xbim3DModelContext refContext = new Xbim3DModelContext(refModel.Model); BuildScene(refContext); } if (recalcView) RecalculateView(model); }
/// <summary> /// Returns true if the vectors are parallel /// </summary> /// <param name="other">other vector</param> /// <param name="angularTolerance">Tolerance in radians</param> /// <returns></returns> public bool IsParallel(XbimVector3D other, double angularTolerance) { var ang = Angle(other); return(ang <= angularTolerance || Math.PI - ang <= angularTolerance); }
public XbimRect3D(XbimPoint3D Position, XbimVector3D Size) { this._x = Position.X; this._y = Position.Y; this._z = Position.Z; this._sizeX = Size.X; this._sizeY = Size.Y; this._sizeZ = Size.Z; }
/// <summary> /// Returns true if the vectors are normal /// </summary> /// <param name="other">other vector</param> /// <param name="angularTolerance">Tolerance in radians</param> /// <returns></returns> public bool IsNormal(XbimVector3D other, double angularTolerance) { var ang = Math.PI / 2.0 - Angle(other); if (ang < 0) ang = -ang; return ang <= angularTolerance; }
public XbimRect3D(XbimVector3D vMin, XbimVector3D vMax) { this._x = Math.Min(vMin.X, vMax.X); this._y = Math.Min(vMin.Y, vMax.Y); this._z = Math.Min(vMin.Z, vMax.Z); this._sizeX = Math.Max(vMin.X, vMax.X) - this._x; this._sizeY = Math.Max(vMin.Y, vMax.Y) - this._y; this._sizeZ = Math.Max(vMin.Z, vMax.Z) - this._z; }
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> /// Indicative size of the Box along all axis. /// </summary> /// <returns>Returns the length of the diagonal</returns> public double Length() { XbimVector3D max = new XbimVector3D(SizeX, SizeY, SizeZ); return max.Length; }
/// <summary> /// Returns true if the vectors are parallel /// </summary> /// <param name="other">other vector</param> /// <param name="angularTolerance">Tolerance in radians</param> /// <returns></returns> public bool IsParallel(XbimVector3D other, double angularTolerance) { var ang = Angle(other); return ang <= angularTolerance || Math.PI - ang <= angularTolerance; }
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(); } } }
/// <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 static XbimVector3D CrossProduct(XbimVector3D v1, XbimVector3D v2) { var x = v1.X; var y = v1.Y; var z = v1.Z; var x2 = v2.X; var y2 = v2.Y; var z2 = v2.Z; return new XbimVector3D(y * z2 - z * y2, z * x2 - x * z2, x * y2 - y * x2); }
/// <summary> /// Creates a 3D translation matrix. /// </summary> public static XbimMatrix3D CreateTranslation(XbimVector3D translationVector) { return(CreateTranslation(translationVector.X, translationVector.Y, translationVector.Z)); }
public XbimVector3D CrossProduct(XbimVector3D v2) { return XbimVector3D.CrossProduct(this, v2); }
public XbimVector3D Transform(XbimVector3D xbimVector3D) { return(XbimVector3D.Multiply(xbimVector3D, this)); }
/// <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 double DotProduct(XbimVector3D v2) { return XbimVector3D.DotProduct(this, v2); }
/// <summary> /// Indicative size of the Box along all axis. /// </summary> /// <returns>Returns the length of the diagonal</returns> public double Length() { XbimVector3D max = new XbimVector3D(SizeX, SizeY, SizeZ); return(max.Length); }
internal void SetCenterInMeters(XbimVector3D ModelTranslation) { foreach (var model in _collection.Values) { model.SetCenterInMeters(ModelTranslation); } }