/// <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> /// Adds a placement to current top scope. /// </summary> /// <param name="modifier">Action to modify placement by given relative coordinates</param> /// <returns>A local placement reference</returns> public IIfcLocalPlacement NewLocalPlacement(XbimVector3D refPosition, bool scaleUp = false) { IIfcLocalPlacement placement = null; Wrap(s => { var product = CurrentScope as IIfcProduct; var relPlacement = CurrentPlacement; if (null != product) { if (null == product.ObjectPlacement) { placement = s.NewLocalPlacement(refPosition, scaleUp); if (relPlacement != product.ObjectPlacement) { // Don't reference former placement while replacing own placement placement.PlacementRelTo = relPlacement; } product.ObjectPlacement = placement; } else { Log.LogWarning($"#{product.EntityLabel} has already a placement #{product.ObjectPlacement.EntityLabel}"); } } else { throw new OperationCanceledException("No IfcProduct as head of current hierarchy"); } }); return(placement); }
public XbimRegion(string name, XbimRect3D bounds, int population) { Name = name; Size = new XbimVector3D(bounds.SizeX, bounds.SizeY, bounds.SizeZ); Centre = bounds.Centroid(); Population = population; }
/// <summary> /// calculates the tansform to convert models to metres and centre on the most populated region, includes reference models /// </summary> /// <returns></returns> private XbimMatrix3D GetGlobalModelTransform() { XbimRegion largest = _context.GetLargestRegion(); XbimRect3D bb = XbimRect3D.Empty; if (largest != null) { bb = new XbimRect3D(largest.Centre, largest.Centre); } foreach (var refModel in _context.Model.ReferencedModels) { XbimRegion r; 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(); var modelTranslation = new XbimVector3D(-p.X, -p.Y, -p.Z); double metreFactor = 1.0 / _context.Model.ModelFactors.OneMetre; return(XbimMatrix3D.CreateTranslation(modelTranslation) * XbimMatrix3D.CreateScale(metreFactor)); }
public static List <MctNode> TranslateNodes(IIfcCurve directrix, List <double> distAlong, int index) { var nodes = new List <MctNode>(); if (directrix is IIfcOffsetCurveByDistances ocbd) { var basicCurve = ocbd.BasisCurve; if (basicCurve is IIfcAlignmentCurve ac) { for (int i = 0; i < distAlong.Count; i++) { double startDist = ocbd.OffsetValues[0].DistanceAlong + distAlong[i]; double offsetLateral = ocbd.OffsetValues[0].OffsetLateral.Value; double offserVertical = ocbd.OffsetValues[0].OffsetVertical.Value; var vz = new XbimVector3D(0, 0, 1); double height = ac.Vertical.Segments[0].StartHeight; var horSegs = ac.Horizontal.Segments; (var pt, var vy) = Utilities.GeometryEngine.GetPointByDistAlong(horSegs, startDist); var position = pt + vy * offsetLateral + vz * (offserVertical + height); nodes.Add(new MctNode(index * distAlong.Count + i + 1, position.X, position.Y, position.Z)); } } } return(nodes); }
internal void SetCenterInMeters(XbimVector3D modelTranslation) { foreach (var model in _collection.Values) { model.SetCenterInMeters(modelTranslation); } }
public static IfcAxis2Placement3D ToAixs3D_LateralConnectPlate(IfcStore m, IfcLinearPlacement lp) { var origin = MakeCartesianPoint(m); var locZ = MakeDirection(m, 0, 0, -1); var locX = MakeDirection(m, 1, 0, 0); var locY = MakeDirection(m, 0, 1, 0); var curve = lp.PlacementRelTo; if (curve is IIfcOffsetCurveByDistances offsetCurve) { var basicCurve = offsetCurve.BasisCurve; double startDist = offsetCurve.OffsetValues[0].DistanceAlong + lp.Distance.DistanceAlong; double offsetLateral = offsetCurve.OffsetValues[0].OffsetLateral.Value + lp.Distance.OffsetLateral.Value; double offsetVertical = offsetCurve.OffsetValues[0].OffsetVertical.Value + lp.Distance.OffsetVertical.Value; if (basicCurve is IIfcAlignmentCurve ac) { var vz = new XbimVector3D(0, 0, 1); double height = ac.Vertical.Segments[0].StartHeight; var horSegs = ac.Horizontal.Segments; (var pt, var vy) = Utilities.GeometryEngine.GetPointByDistAlong(horSegs, startDist); var vx = vz.CrossProduct(vy); var position = pt + vy * offsetLateral + vz * (offsetVertical + height); origin = MakeCartesianPoint(m, position.X, position.Y, position.Z); locY = MakeDirection(m, vy.X, vy.Y, vy.Z); locX = MakeDirection(m, vx.X, vx.Y, vx.Z); } } return(MakeAxis2Placement3D(m, origin, locX, locZ)); }
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); }
/// <summary> /// Creates the transform based on the model dimensional unit (oneMeter) /// </summary> /// <param name="modelTranslation">The translation is expressed in meters.</param> internal void PrepareTransform(XbimVector3D modelTranslation) { var translation = XbimMatrix3D.CreateTranslation(modelTranslation * OneMeter); var scaling = XbimMatrix3D.CreateScale(1 / OneMeter); Transform = translation * scaling; }
internal void ComputeViewBoundsTransform() { var p = ModelSpaceBounds.Centroid(); _viewSpaceTranslation = new XbimVector3D(-p.X, -p.Y, -p.Z); SetCenterInMeters(_viewSpaceTranslation); }
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)); }
/// <summary> /// Creates the partition walls between the units. Not surprisingly uses similar logic to /// creating units /// </summary> /// <param name="story"></param> private void CreatePartitionWalls(XPreviewBuildingStory story) { UnitParameters firstUnit = unitsToCreate.First(); XLine refLine = parameters.ReferenceLine.Transformed(building.InverseGlobalTransform); XbimVector3D cross = refLine.NormalizedVector.CrossProduct(new XbimVector3D(0, 0, 1)); // The reference point on the center line from which the insertion points will be calculated XbimPoint3D referencePoint = new XbimPoint3D(refLine.sp.X + (firstUnit.UnitWidth - parameters.InteriorWallThickness / 2), refLine.sp.Y, refLine.sp.Z); int unitCount = 0; int wallcount = 0; foreach (UnitParameters unit in unitsToCreate) { if (unitCount != unitsToCreate.Count - 1) { // the length of the wall is going to be the minimum of the dwpth of the two units the wall is between double length = Math.Min(unit.UnitDepth, unitsToCreate[unitCount + 1].UnitDepth); if (parameters.CorridorMode != CorridorMode.Left) { // Right of the corridor XbimPoint3D location = cross.GetPoint(referencePoint, parameters.CorridorWidth / 2 + parameters.InteriorWallThickness / 2); XPreviewWall wall = new XPreviewWall { Name = "Wall " + (story.StoryNumber * 100 + wallcount).ToString(), Location = location, Container = story, ProfilePath = CreateWallProfile(length), Height = parameters.CeilingElevation, ReferenceDirection = new XbimVector3D(0, -1, 0) }; wallcount++; } if (parameters.CorridorMode != CorridorMode.Right) { // Left of the corridor XbimPoint3D location = cross.GetPoint(referencePoint, -parameters.CorridorWidth / 2 - parameters.InteriorWallThickness / 2); XPreviewWall wall = new XPreviewWall { Name = "Wall " + (story.StoryNumber * 100 + wallcount).ToString(), Location = location, Container = story, ProfilePath = CreateWallProfile(length), Height = parameters.CeilingElevation, ReferenceDirection = new XbimVector3D(0, 1, 0), }; wallcount++; } // Increment the location. Must use next unit width too as units may be different sizes if (unitCount != unitsToCreate.Count - 1) { UnitParameters nextUnit = unitsToCreate[unitCount + 1]; XbimPoint3D delta = new XbimPoint3D(nextUnit.UnitWidth, 0, 0); referencePoint = XbimPoint3D.Add(referencePoint, delta); } } unitCount++; } }
internal static IEnumerable <double> DirectionRatios(this XbimVector3D vector3D) { yield return(vector3D.X); yield return(vector3D.Y); yield return(vector3D.Z); }
public XPreviewBase() { Location = new XbimPoint3D(0, 0, 0); ReferenceDirection = new XbimVector3D(1, 0, 0); Axis = new XbimVector3D(0, 0, 1); // We don't set a guid, when we create the Ifc objects a guid will be created for us GUID = Guid.NewGuid().ToIfcGuid(); }
public static IfcLocalPlacement NewIfc4LocalPlacement(this IModel s, XbimVector3D refPoint, bool scaleUp = false) { var localPlacement = s.Instances.New <IfcLocalPlacement>(); var placement = s.Instances.New <IfcAxis2Placement3D>(); placement.Location = s.NewIfcPoint <IfcCartesianPoint>(refPoint, scaleUp); localPlacement.RelativePlacement = placement; return(localPlacement); }
/// <summary> /// Creates the units. /// </summary> /// <remarks> /// The units are inserted at their bounding box center, so what we need to do is calculate where that center should be. /// Take a point along the corridor center line, using the cross product vector get a point to the right and to the left /// The units profile is already adjusted for whether we are FullDetail or not. /// </remarks> /// <param name="story"></param> private void CreateUnits(XPreviewBuildingStory story) { UnitParameters firstUnit = unitsToCreate.First(); XLine refLine = parameters.ReferenceLine.Transformed(building.InverseGlobalTransform); XbimVector3D cross = refLine.NormalizedVector.CrossProduct(new XbimVector3D(0, 0, 1)); // The reference point on the center line from which the insertion points will be calculated XbimPoint3D referencePoint = new XbimPoint3D(refLine.sp.X + (firstUnit.UnitWidth - parameters.InteriorWallThickness) / 2, refLine.sp.Y, refLine.sp.Z); int unitNumber = 1; // The sequence number used to generate the unit name (incremented for every unit) int unitCount = 0; // The count of units to create, increment every two units (for both sides) foreach (UnitParameters unit in unitsToCreate) { if (parameters.CorridorMode != CorridorMode.Left) { XbimPoint3D location = cross.GetPoint(referencePoint, (unit.UnitDepth + parameters.CorridorWidth) / 2); // Create units to the right XPreviewSpace space = new XPreviewSpace { Name = "Unit " + (story.StoryNumber * 100 + unitNumber).ToString(), // "101, 102, 103" etc. ProfilePath = unit.Profile.Clone(), LongName = unit.UnitType, Height = parameters.CeilingElevation, Location = location, ReferenceDirection = new XbimVector3D(-1, 0, 0), Container = story, Color = unit.Color, }; unitNumber++; } if (parameters.CorridorMode != CorridorMode.Right) { XbimPoint3D location = cross.GetPoint(referencePoint, -(unit.UnitDepth + parameters.CorridorWidth) / 2); // Create units to the left XPreviewSpace space = new XPreviewSpace { Name = "Unit " + (story.StoryNumber * 100 + unitNumber).ToString(), // "101, 102, 103" etc. ProfilePath = unit.Profile.Clone(), LongName = unit.UnitType, Height = parameters.CeilingElevation, Location = location, Container = story, Color = unit.Color }; unitNumber++; } // Increment the location. Must use next unit width too as units may be different sizes if (unitCount != unitsToCreate.Count - 1) { UnitParameters nextUnit = unitsToCreate[unitCount + 1]; XbimPoint3D delta = new XbimPoint3D(unit.UnitWidth / 2 + nextUnit.UnitWidth / 2, 0, 0); referencePoint = XbimPoint3D.Add(referencePoint, delta); } unitCount++; } }
/// <summary> /// Shofts the points int he polygon relative to the origin. /// </summary> /// <remarks> /// Because XbimPoint3 wont allow us to modify the X,Y,Z values then we have to create new points /// </remarks> /// <param name="origin"></param> public void Normalize(XbimPoint3D origin) { XbimVector3D offset = new XbimVector3D(-origin.X, -origin.Y, -origin.Z); XbimMatrix3D tr = new XbimMatrix3D(offset); List <XbimPoint3D> temp = new List <XbimPoint3D>(this); Clear(); temp.ForEach(pt => Add(tr.Transform(pt))); }
public static IEnumerable <double> ToDoubleModelScale(this XbimVector3D v, IModelFactors f) { return(new double[] { PrecisionClamp(v.X, f.OneMeter, f.Precision), PrecisionClamp(v.Y, f.OneMeter, f.Precision), PrecisionClamp(v.Z, f.OneMeter, f.Precision) }); }
public static XYZ ToXYZ(this XbimVector3D v, double scale = 1.0) { return(new XYZ() { X = (v.X * scale), Y = (v.Y * scale), Z = (v.Z * scale) }); }
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"); }
internal void SetCenterInMeters(XbimVector3D modelTranslation) { _viewSpaceTranslation = modelTranslation; foreach (var model in _collection.Values) { // each item in the collection stores a matrix that depends on the units of measure of the model. // model.PrepareTransform(modelTranslation); } }
public static IfcLine MakeLine(MemoryModel m, XbimPoint3D loc, XbimVector3D dir, double len) { var l = m.Instances.New <IfcLine>(); l.Dir = m.Instances.New <IfcVector>(); l.Dir.Magnitude = len; l.Dir.Orientation = m.Instances.New <IfcDirection>(d => d.SetXYZ(dir.X, dir.Y, dir.Z)); l.Pnt = m.Instances.New <IfcCartesianPoint>(p => p.SetXYZ(loc.X, loc.Y, loc.Z)); return(l); }
/// <summary> /// Compares two objects for geometric equality /// </summary> /// <param name="a"></param> /// <param name="b">object to compare with</param> /// <returns></returns> public static bool GeometricEquals(this IfcDirection a, IfcDirection b) { if (a.Equals(b)) { return(true); } XbimVector3D va = a.XbimVector3D(); XbimVector3D vb = b.XbimVector3D(); return(va.IsEqual(vb, b.ModelOf.ModelFactors.Precision)); }
public static IEnumerable <double> ToDoubleMeter(this XbimVector3D v, IModelFactors f) { var precisionInM = f.Precision * f.LengthToMetresConversionFactor; return(new double[] { PrecisionClamp(v.X, f.LengthToMetresConversionFactor, precisionInM), PrecisionClamp(v.Y, f.LengthToMetresConversionFactor, precisionInM), PrecisionClamp(v.Z, f.LengthToMetresConversionFactor, precisionInM) }); }
public static IfcLocalPlacement NewIfc2x3FullPlacement(this IModel s, XbimVector3D refPoint, XbimVector3D refAxis, bool scaleUp = false) { var localPlacement = s.Instances.New <IfcLocalPlacement>(); var placement = s.Instances.New <IfcAxis2Placement3D>(); placement.Location = s.NewIfcPoint <IfcCartesianPoint>(refPoint, scaleUp); placement.RefDirection = s.NewIfcDirection <IfcDirection>(refAxis); placement.Axis = s.NewIfcDirection <IfcDirection>(new XbimVector3D(0, 0, 1)); localPlacement.RelativePlacement = placement; return(localPlacement); }
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)); } return(new XbimMatrix3D(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, axis2.Location.X, axis2.Location.Y, axis2.Location.Z, 1)); }
public static IfcPlane MakePlane(MemoryModel m, XbimPoint3D loc, XbimVector3D zdir, XbimVector3D xdir) { var plane = m.Instances.New <IfcPlane>(); var p = m.Instances.New <IfcAxis2Placement3D>(); p.Axis = m.Instances.New <IfcDirection>(d => d.SetXYZ(zdir.X, zdir.Y, zdir.Z)); p.Location = m.Instances.New <IfcCartesianPoint>(c => c.SetXYZ(loc.X, loc.Y, loc.Z)); p.RefDirection = m.Instances.New <IfcDirection>(d => d.SetXYZ(xdir.X, xdir.Y, xdir.Z)); plane.Position = p; return(plane); }
public override string WhereRule() { string baseErr = base.WhereRule(); if (_extrudedDirection != null && XbimVector3D.DotProduct(_extrudedDirection.XbimVector3D(), new XbimVector3D(0, 0, 1)) == 0) { baseErr += "WR31 ExtrudedAreaSolid : The ExtrudedDirection shall not be perpendicular to the local z-axis.\n"; } return(baseErr); }
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)); } }