public static XbimMatrix3D ToMatrix3D(this IfcAxis2Placement2D axis2, ConcurrentDictionary <int, Object> maps = null) { object transform; if (maps != null && maps.TryGetValue(axis2.EntityLabel, out transform)) //already converted it just return cached { return((XbimMatrix3D)transform); } if (axis2.RefDirection != null) { XbimVector3D v = axis2.RefDirection.XbimVector3D(); v = v.Normalized(); transform = new XbimMatrix3D(v.X, v.Y, 0, 0, v.Y, v.X, 0, 0, 0, 0, 1, 0, axis2.Location.X, axis2.Location.Y, 0, 1); } else { transform = new XbimMatrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, axis2.Location.X, axis2.Location.Y, axis2.Location.Z, 1); } if (maps != null) { maps.TryAdd(axis2.EntityLabel, transform); } return((XbimMatrix3D)transform); }
public static XbimMatrix3D ToMatrix3D(this IIfcAxis2Placement2D axis2) { if (axis2.RefDirection != null) { var v = new XbimVector3D(axis2.RefDirection.X, axis2.RefDirection.Y, axis2.RefDirection.Z); v = v.Normalized(); return(new XbimMatrix3D( v.X, v.Y, 0, 0, v.Y, v.X, 0, 0, 0, 0, 1, 0, axis2.Location.X, axis2.Location.Y, 0, 1)); } double LocationZ = axis2.Location.Z; if (double.IsNaN(LocationZ)) { LocationZ = 0; } return(new XbimMatrix3D( 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, axis2.Location.X, axis2.Location.Y, LocationZ, 1 )); }
/// <summary> /// Calculates the Newell's Normal of the polygon of the loop /// </summary> /// <param name="loop"></param> /// <returns></returns> public static XbimVector3D NewellsNormal(this IfcPolyLoop loop) { double x = 0, y = 0, z = 0; IfcCartesianPoint previous = null; var count = 0; var total = loop.Polygon.Count; for (var i = 0; i <= total; i++) { var current = i < total ? loop.Polygon[i] : loop.Polygon[0]; if (count > 0) { // ReSharper disable once PossibleNullReferenceException var xn = previous.X; var yn = previous.Y; var zn = previous.Z; var xn1 = current.X; var yn1 = current.Y; var zn1 = current.Z; x += (yn - yn1) * (zn + zn1); y += (xn + xn1) * (zn - zn1); z += (xn - xn1) * (yn + yn1); } previous = current; count++; } var v = new XbimVector3D(x, y, z); return(v.Normalized()); }
/// <summary> /// Builds a windows Matrix3D from an ObjectPlacement /// Conversion fo c++ function CartesianTransform::ConvertMatrix3D from CartesianTransform.cpp /// </summary> /// <param name="objPlacement">IfcObjectPlacement object</param> /// <returns>Matrix3D</returns> protected XbimMatrix3D ConvertMatrix3D(IfcObjectPlacement objPlacement) { if (objPlacement is IfcLocalPlacement) { IfcLocalPlacement locPlacement = (IfcLocalPlacement)objPlacement; if (locPlacement.RelativePlacement is IfcAxis2Placement3D) { IfcAxis2Placement3D axis3D = (IfcAxis2Placement3D)locPlacement.RelativePlacement; XbimVector3D ucsXAxis = new XbimVector3D(axis3D.RefDirection.DirectionRatios[0], axis3D.RefDirection.DirectionRatios[1], axis3D.RefDirection.DirectionRatios[2]); XbimVector3D ucsZAxis = new XbimVector3D(axis3D.Axis.DirectionRatios[0], axis3D.Axis.DirectionRatios[1], axis3D.Axis.DirectionRatios[2]); ucsXAxis = ucsXAxis.Normalized(); ucsZAxis = ucsZAxis.Normalized(); XbimVector3D ucsYAxis = XbimVector3D.CrossProduct(ucsZAxis, ucsXAxis); ucsYAxis = ucsYAxis.Normalized(); XbimPoint3D ucsCentre = axis3D.Location.XbimPoint3D(); XbimMatrix3D ucsTowcs = new XbimMatrix3D(ucsXAxis.X, ucsXAxis.Y, ucsXAxis.Z, 0, ucsYAxis.X, ucsYAxis.Y, ucsYAxis.Z, 0, ucsZAxis.X, ucsZAxis.Y, ucsZAxis.Z, 0, ucsCentre.X, ucsCentre.Y, ucsCentre.Z, 1); if (locPlacement.PlacementRelTo != null) { return(XbimMatrix3D.Multiply(ucsTowcs, ConvertMatrix3D(locPlacement.PlacementRelTo))); } return(ucsTowcs); } throw new NotImplementedException("Support for Placements other than 3D not implemented"); } throw new NotImplementedException("Support for Placements other than Local not implemented"); }
public XbimMatrix3D ToMatrix3D(ConcurrentDictionary <int, object> maps = null) { object transform; if (maps != null && maps.TryGetValue(EntityLabel, out transform)) //already converted it just return cached { return((XbimMatrix3D)transform); } if (RefDirection != null) { XbimVector3D v = RefDirection.XbimVector3D(); v.Normalized(); transform = new XbimMatrix3D(v.X, v.Y, 0, 0, v.Y, v.X, 0, 0, 0, 0, 1, 0, Location.X, Location.Y, 0, 1); } else { transform = new XbimMatrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, Location.X, Location.Y, Location.Z, 1); } if (maps != null) { maps.TryAdd(EntityLabel, transform); } return((XbimMatrix3D)transform); }
private static XbimMatrix3D ConvertCartesianTransform3D(IIfcCartesianTransformationOperator3D ct3D) { XbimVector3D u3; //Z Axis Direction XbimVector3D u2; //X Axis Direction XbimVector3D u1; //Y axis direction if (ct3D.Axis3 != null) { var dir = ct3D.Axis3; u3 = new XbimVector3D(dir.X, dir.Y, dir.Z); u3 = u3.Normalized(); } else { u3 = new XbimVector3D(0, 0, 1); } if (ct3D.Axis1 != null) { var dir = ct3D.Axis1; u1 = new XbimVector3D(dir.X, dir.Y, dir.Z); u1 = u1.Normalized(); } else { var defXDir = new XbimVector3D(1, 0, 0); u1 = u3 != defXDir ? defXDir : new XbimVector3D(0, 1, 0); } var xVec = XbimVector3D.Multiply(XbimVector3D.DotProduct(u1, u3), u3); var xAxis = XbimVector3D.Subtract(u1, xVec); xAxis = xAxis.Normalized(); if (ct3D.Axis2 != null) { var dir = ct3D.Axis2; u2 = new XbimVector3D(dir.X, dir.Y, dir.Z); u2 = u2.Normalized(); } else { u2 = new XbimVector3D(0, 1, 0); } var tmp = XbimVector3D.Multiply(XbimVector3D.DotProduct(u2, u3), u3); var yAxis = XbimVector3D.Subtract(u2, tmp); tmp = XbimVector3D.Multiply(XbimVector3D.DotProduct(u2, xAxis), xAxis); yAxis = XbimVector3D.Subtract(yAxis, tmp); yAxis = yAxis.Normalized(); u2 = yAxis; u1 = xAxis; var lo = new XbimPoint3D(ct3D.LocalOrigin.X, ct3D.LocalOrigin.Y, ct3D.LocalOrigin.Z); //local origin return(new XbimMatrix3D(u1.X, u1.Y, u1.Z, 0, u2.X, u2.Y, u2.Z, 0, u3.X, u3.Y, u3.Z, 0, lo.X, lo.Y, lo.Z, 1)); }
public static XbimVector3D XAxisDirection(this IfcAxis2Placement3D ax3) { if (ax3.RefDirection != null && ax3.Axis != null) { XbimVector3D xa = ax3.RefDirection.XbimVector3D(); return(xa.Normalized()); } return(new XbimVector3D(1, 0, 0)); }
public XbimVector3D Normalise() { if (Dim == 3) { var v3D = new XbimVector3D(X, Y, Z); v3D.Normalized(); return(v3D); } throw new ArgumentException("Only 3D Directions are supported for normalised at present"); }
public static XbimVector3D ZAxisDirection(this IfcAxis2Placement3D ax3) { if (ax3.RefDirection != null && ax3.Axis != null) { XbimVector3D za = ax3.Axis.XbimVector3D(); return(za.Normalized()); } else { return(new XbimVector3D(0, 0, 1)); } }
public static XbimMatrix3D ToMatrix3D(this IIfcAxis2Placement3D axis3) { if (axis3.RefDirection != null && axis3.Axis != null) { var za = new XbimVector3D(axis3.Axis.X, axis3.Axis.Y, axis3.Axis.Z); za = za.Normalized(); var xa = new XbimVector3D(axis3.RefDirection.X, axis3.RefDirection.Y, axis3.RefDirection.Z); xa = xa.Normalized(); XbimVector3D ya = XbimVector3D.CrossProduct(za, xa); ya = ya.Normalized(); return(new XbimMatrix3D(xa.X, xa.Y, xa.Z, 0, ya.X, ya.Y, ya.Z, 0, za.X, za.Y, za.Z, 0, axis3.Location.X, axis3.Location.Y, axis3.Location.Z, 1)); } return(new XbimMatrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, axis3.Location.X, axis3.Location.Y, axis3.Location.Z, 1)); }
private static XbimMatrix3D ConvertAxis3D(IfcAxis2Placement3D axis3) { if (axis3.RefDirection != null && axis3.Axis != null) { XbimVector3D za = axis3.Axis.XbimVector3D(); za = za.Normalized(); XbimVector3D xa = axis3.RefDirection.XbimVector3D(); xa = xa.Normalized(); XbimVector3D ya = XbimVector3D.CrossProduct(za, xa); ya = ya.Normalized(); return(new XbimMatrix3D(xa.X, xa.Y, xa.Z, 0, ya.X, ya.Y, ya.Z, 0, za.X, za.Y, za.Z, 0, axis3.Location.X, axis3.Location.Y, axis3.Location.Z, 1)); } else { return(new XbimMatrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, axis3.Location.X, axis3.Location.Y, axis3.Location.Z, 1)); } }
/// <summary> /// Computes and returns the normalised vector for the direction. /// </summary> /// <returns>A 1-length vector if the direction is meaningful or a 0-length vector otherwise</returns> public XbimVector3D Normalise() { if (Dim == 3) { var v3D = new XbimVector3D(X, Y, Z); v3D.Normalized(); return(v3D); } // Since the return value is not stored in any field or property // and the function return variable is intrinsically 3D it's reasonable do // deal with dimensions lower than 3 // var compX = X; // each value is nan if the dimension is not specified var compY = Y; var compZ = Z; // substitite nan for 0 if (double.IsNaN(compX)) { compX = 0; } if (double.IsNaN(compY)) { compY = 0; } if (double.IsNaN(compZ)) { compZ = 0; } var otherCases = new XbimVector3D(compX, compY, compZ); // normalied return a 0-len-vector if no significant direction exists otherCases.Normalized(); return(otherCases); }
/// <summary> /// Calculate the ObjectPlacment for an IfcProduct from row data and the parent object /// </summary> /// <param name="row">COBieCoordinateRow holding the data</param> /// <param name="placementRelToIfcProduct">IfcProduct that the ObjectPlacment relates too, i.e. the parent of the ifcProduct ObjectPlacment we are calculating</param> /// <returns></returns> private IfcLocalPlacement CalcObjectPlacement(COBieCoordinateRow row, IfcProduct placementRelToIfcProduct) { XbimPoint3D locationPt; bool havePoint = GetPointFromRow(row, out locationPt); if (havePoint) { if ((placementRelToIfcProduct != null) && (placementRelToIfcProduct.ObjectPlacement is IfcLocalPlacement)) { //TEST, change the building position to see if the same point comes out in Excel sheet, it should be, and in test was. //((IfcAxis2Placement3D)((IfcLocalPlacement)placementRelToIfcProduct.ObjectPlacement).RelativePlacement).SetNewLocation(10.0, 10.0, 0.0); IfcLocalPlacement placementRelTo = (IfcLocalPlacement)placementRelToIfcProduct.ObjectPlacement; XbimMatrix3D matrix3D = ConvertMatrix3D(placementRelTo); //we want to take off the translations and rotations caused by IfcLocalPlacement of the parent objects as we will add these to the new IfcLocalPlacement for this floor matrix3D.Invert(); //so invert matrix to remove the translations to give the origin for the next IfcLocalPlacement locationPt = matrix3D.Transform(locationPt); //get the point with relation to the last IfcLocalPlacement i.e the parent element //Get the WCS matrix values double rotX, rotY, rotZ; if (!(double.TryParse(row.YawRotation, out rotX) && (double.NaN.CompareTo(rotX) != 0))) { rotX = 0.0; } if (!(double.TryParse(row.ElevationalRotation, out rotY) && (double.NaN.CompareTo(rotY) != 0))) { rotY = 0.0; } if (double.TryParse(row.ClockwiseRotation, out rotZ) && (double.NaN.CompareTo(rotZ) != 0)) { rotZ = rotZ * -1; //convert back from clockwise to anti clockwise } else { rotZ = 0.0; } //apply the WCS rotation from COBie Coordinates stored values XbimMatrix3D matrixNewRot3D = new XbimMatrix3D(); if (rotX != 0.0) { matrixNewRot3D.RotateAroundXAxis(TransformedBoundingBox.DegreesToRadians(rotX)); } if (rotY != 0.0) { matrixNewRot3D.RotateAroundYAxis(TransformedBoundingBox.DegreesToRadians(rotY)); } if (rotZ != 0.0) { matrixNewRot3D.RotateAroundZAxis(TransformedBoundingBox.DegreesToRadians(rotZ)); } //remove any displacement from the matrix which moved/rotated us to the object space matrix3D.OffsetX = 0.0F; matrix3D.OffsetY = 0.0F; matrix3D.OffsetZ = 0.0F; //remove the matrix that got use to the object space from the WCS location of this object XbimMatrix3D matrixRot3D = matrixNewRot3D * matrix3D; //get the rotation vectors to place in the new IfcAxis2Placement3D for the new IfcLocalPlacement for this object XbimVector3D ucsAxisX = matrixRot3D.Transform(new XbimVector3D(1, 0, 0)); XbimVector3D ucsAxisZ = matrixRot3D.Transform(new XbimVector3D(0, 0, 1)); ucsAxisX = ucsAxisX.Normalized(); ucsAxisZ = ucsAxisZ.Normalized(); //create the new IfcAxis2Placement3D IfcAxis2Placement3D relativePlacemant = Model.Instances.New <IfcAxis2Placement3D>(); relativePlacemant.SetNewDirectionOf_XZ(ucsAxisX.X, ucsAxisX.Y, ucsAxisX.Z, ucsAxisZ.X, ucsAxisZ.Y, ucsAxisZ.Z); relativePlacemant.SetNewLocation(locationPt.X, locationPt.Y, locationPt.Z); //Set up IfcLocalPlacement IfcLocalPlacement objectPlacement = Model.Instances.New <IfcLocalPlacement>(); objectPlacement.PlacementRelTo = placementRelTo; objectPlacement.RelativePlacement = relativePlacemant; return(objectPlacement); } } return(null); }
/// <summary> /// If adding the data to the mesh causes the mesh to exceed the max size of ushort.MaxSize /// the data is not added and false is returned. /// </summary> /// <typeparam name="TGeomType"></typeparam> /// <param name="builder"></param> /// <param name="br"></param> /// <param name="transform"></param> /// <returns></returns> private bool BuildWithNormals <TGeomType>(TGeomType builder, BinaryReader br, XbimMatrix3D transform) where TGeomType : IXbimTriangulatesToPositionsNormalsIndices { uint numPositions = br.ReadUInt32(); //if we the mesh is smaller that 64K then try and add it to this mesh, if it is bigger than 65K we just have to stake what we can //if (numPositions < ushort.MaxValue && builder.PositionCount > 0 && (builder.PositionCount + numPositions >= ushort.MaxValue)) //we cannot build meshes bigger than this and pass them through to standard graphics buffers // return false; uint numNormals = br.ReadUInt32(); uint numUniques = br.ReadUInt32(); uint numTriangles = br.ReadUInt32(); uint numPolygons = br.ReadUInt32(); IndexReader PositionReader = new IndexReader(numPositions, br); IndexReader NormalsReader = new IndexReader(numNormals, br); IndexReader UniquesReader = new IndexReader(numUniques, br); float[,] pos = new float[numPositions, 3]; float[,] nrm; nrm = new float[numNormals, 3]; // coordinates of positions // for (uint i = 0; i < numPositions; i++) { pos[i, 0] = br.ReadSingle(); pos[i, 1] = br.ReadSingle(); pos[i, 2] = br.ReadSingle(); } // dimensions of normals // for (uint i = 0; i < numNormals; i++) { nrm[i, 0] = br.ReadSingle(); nrm[i, 1] = br.ReadSingle(); nrm[i, 2] = br.ReadSingle(); } // loop twice for how many indices to create the point/normal combinations. builder.BeginPoints(numUniques); if (transform.IsIdentity) { for (uint i = 0; i < numUniques; i++) { uint readpositionI = PositionReader.ReadIndex(); builder.AddPosition( new XbimPoint3D(pos[readpositionI, 0], pos[readpositionI, 1], pos[readpositionI, 2])); } for (uint i = 0; i < numUniques; i++) { uint readnormalI = NormalsReader.ReadIndex(); builder.AddNormal( new XbimVector3D(nrm[readnormalI, 0], nrm[readnormalI, 1], nrm[readnormalI, 2]) ); } } else { for (uint i = 0; i < numUniques; i++) { uint readpositionI = PositionReader.ReadIndex(); var tfdPosition = transform.Transform(new XbimPoint3D(pos[readpositionI, 0], pos[readpositionI, 1], pos[readpositionI, 2])); builder.AddPosition(tfdPosition); } for (uint i = 0; i < numUniques; i++) { // todo: use a quaternion extracted from the matrix instead // uint readnormalI = NormalsReader.ReadIndex(); var origNormal = new XbimVector3D(nrm[readnormalI, 0], nrm[readnormalI, 1], nrm[readnormalI, 2]); XbimVector3D v = transform.Transform(origNormal); v = v.Normalized(); builder.AddNormal(v); } } builder.EndPoints(); //point/normal combinations completed builder.BeginPolygons(numTriangles, numPolygons); for (uint p = 0; p < numPolygons; p++) { // set the state TriangleType meshType = (TriangleType)br.ReadByte(); uint indicesCount = br.ReadUInt32(); builder.BeginPolygon(meshType, indicesCount); //get the triangles for (uint i = 0; i < indicesCount; i++) { builder.AddTriangleIndex(UniquesReader.ReadIndex()); } builder.EndPolygon(); } builder.EndPolygons(); return(true); }