Closed RoyTimmers1980 closed 1 year ago
What are you hoping to with the points of a slab (at the highest level)? i.e. Are you trying to get dimensions/ of the slab? Or visualise the slab? Or edit a slab? or something else?
The screenshot shows you have a Slab's representation which is an IfcExtrudedAreaSolid describing a shape derived from sweeping an a Area profile 200 (mm) along the Z plane. The Swept area profile is defined by a PolyLine with 7 points (so presumably we're not describing a rectangular profile).
If you want to get the absolute world coordinates of the Slab after placement you'll likely want to use Xbim.Geometry repo's Geometry Engine to do the heavy lifting.
Andyward, i'm trying to get the points(7) off the slab so i can draw it in Autocad via code
Those points can just be enumerated from the IfcPolyline Points
property. So something like
For Each point As IIfcCartesianPoint In Solid.SweptArea.OuterCurve.Points
Debug.Write(point .X, point .Y)
Next
But they are probably not going to to give you want you expect: you'll find they will typically give you a set of X/Y Cartesian points that define a closed Polyline defining the 'elevation view' of your slab (i.e. a side view).
I'd expect you want a plan view of your slab in AutoCAD? Even if you did want the side-view, these points may need transforming to the world coords to be appropriate.
It sounds like you'll need the Geometry Engine which handles most of this complexity to build a scene, and project to a 2D plan view
Andy,
i'm getting this error:
Error BC30456 'outercurve' is not a member of 'IfcProfileDef'. I
this de code so far:
'***** IFC plattegrond
<CommandMethod("IFC2PG")>
Public Sub IFC2PG()
'Eerst even opslaan
'Draw.SaveActiveDrawing()
'Draw.AllLayerOn()
'Maak een nieuwe instantie van de IfcStore-klasse en open het IFC-bestand
'Dim model As IfcStore = IfcStore.Open("C:\IFC\AllplanIFC.ifc") '"1. Obergeschoss"
' Open het IFC-bestand
Dim model As IfcStore = IfcStore.Open("C:\IFC\AllplanIFC.ifc")
' Haal de eerste verdieping op
Dim level As IIfcBuildingStorey = model.Instances.OfType(Of IIfcBuildingStorey)().FirstOrDefault(Function(x) x.Name = "1. Obergeschoss")
' Haal alle vloeren op die zich op het niveau bevinden
Dim slabs As IEnumerable(Of IIfcSlab) = model.Instances.OfType(Of IIfcSlab)().Where(Function(x) x.ContainedInStructure.FirstOrDefault(Function(y) y.RelatingStructure Is level) IsNot Nothing)
MsgBox(slabs.Count)
For Each slab In slabs
'MsgBox(slab.HasOpenings.Count) 'werkt
'MsgBox(slab.GetType.ToString)
Dim Solid As IfcExtrudedAreaSolid = slab.Representation.Representations(0).Items(0)
Dim CoordsString As String = ""
'depth is vloerdikte
'MsgBox(Solid.Depth.Value.ToString)
If Solid IsNot Nothing Then
For Each point As IIfcCartesianPoint In Solid.SweptArea.outercurve.points
MsgBox(point.X)
MsgBox(point.Y)
Next
End If
Next
End Sub
It should be Solid.SweptArea.OuterCurve.Points
- note the case
Case does not make a difference, see image. OuterCurve is not avaiable in the list so i think im missing something see second image
It's because you would need to cast to the appropriate implementation of the abstract Ifc type. Very naively this would do the job:
If Solid IsNot Nothing Then
Dim Area As IIfcArbitraryClosedProfileDef = Solid.SweptArea
Dim Curve As IIfcPolyline = Area.OuterCurve
For Each point As IIfcCartesianPoint In Curve.Points
MsgBox(point.X)
MsgBox(point.Y)
Next
End If
But as I've said, I don't believe it will answer your problem.
You want to be using the Geometry engine in some form like:
using Xbim.Ifc;
using Xbim.Ifc4.Interfaces;
using Xbim.ModelGeometry.Scene;
var fileName = @"C:\IFC\AllplanIFC.ifc";
using (var model = IfcStore.Open(fileName))
{
// get the item that you need
var slab = model.Instances.OfType<IIfcSlab>().First();
var geometryContext = new Xbim3DModelContext(model);
// Use the Geometry engine to generate the 3D geometry
geometryContext.CreateContext();
// Get the (first) Shape Instance of this item
Xbim.Common.Geometry.XbimShapeInstance shapeInstance = geometryContext.ShapeInstancesOf(slab).FirstOrDefault();
// Get the geometry of the instance. Vertices, Normals, Faces etc in WCS - plus styling
Xbim.Common.Geometry.XbimShapeGeometry shapeGeom = geometryContext.ShapeGeometry(shapeInstance);
// World placement should you need it
Xbim.Common.Geometry.XbimVector3D? globalPos = shapeInstance?.Transformation.Translation;
}
The VB version will be similar
Thanks Andy!
this worked:
If Solid IsNot Nothing Then
Dim Area As IIfcArbitraryClosedProfileDef = Solid.SweptArea
Dim Curve As IIfcPolyline = Area.OuterCurve
For Each point As IIfcCartesianPoint In Curve.Points
MsgBox(point.X)
MsgBox(point.Y)
Next
End If
Andy, i stranded on an error when the sweptarea is an IfcRectangleProfileDef then de points are not available just X and Y dimensions?? how can i extract de points off the wall like the previous example?
And the location seems to be in the center off the slab from a point of the slab??? how can i get the points from the originpoint off the model?
this is the code for the rectangle :
ElseIf AreaType = "IfcRectangleProfileDef" Then
'solid is een rechthoek
Dim Area As IIfcRectangleProfileDef = Solid.SweptArea
Dim Xdim As Double = Area.XDim
Dim Ydim As Double = Area.YDim
I think this is why you should leave this to the Geometry Engine. There's dozens of different ways of representing geometry and placement in IFC, and you'll never sensibly cover them all. The xbim Geometry Engine has 15 years of work behind it, and that's building on the decades of work in OpenCascade behind the scenes.
Take a look at my example in https://github.com/xBimTeam/XbimGeometry/issues/421#issuecomment-1490329208
I cant seem to get the points of a selected slab using vb.net in the data i see in visual studio the data is there.....
see sreenshot for code i have sofar