xBimTeam / XbimGeometry

XbimGeometry contains the CLR interop libraries and the c++ engine used to compute the 3D geometry of models.
https://xbimteam.github.io/
Other
260 stars 131 forks source link

extracting transformed triangulated geometry #51

Closed braunalex closed 7 years ago

braunalex commented 7 years ago

I am trying to extract triangulated geometry from an IFC. this works very nice so far - I documented "my" code (which uses xBIM code) here: http://stackoverflow.com/questions/42798435/cannot-extract-triangulated-geometry-from-ifc-using-xbim/42852848#42852848

However I'm struggling with project based transformations. Could you give me a hint where to introduce the transformation, so that I get the triangles' coordinates on the intended positions?

jdkuhnke commented 7 years ago

Don't know if it helps but I used for a XbimShapeTriangulation:

XbimShapeTriangulation mesh = reader.ReadShapeTriangulation();
mesh = mesh.Transform(product.Transform());

IfcProduct.Transform()returns a transformation which you can apply to a mesh. XbimShapeTriangulation.Transform(XbimMatrix3D transform) - applies transformation to mesh

I used this code to get vertices and faces.

braunalex commented 7 years ago

thanks for your help. I tried this approach, however, I'm still getting the wrong coordinates. I think, I stated my problem a bit unclear: I'm trying to get the geometry according to the corresponding WCS. The correct position is stored in IFCSITE. #79742= IFCSITE('3KY3oN6CHBnwANtfZ8_3Fz',#41,'Default',$,'',#79741,$,$,.ELEMENT.,(52,30,59,759999),(13,23,59,999999),505.799999999998,$,$);

additional question: I'm working with interfaces (IIfcProduct) which don't have the product.Transform() method. It is only available in Ifc2x3.ProductExtension. However I'm getting the same result with XbimShapeInstance.Transformation What is the correct / intended way?

My current approach: foreach (XbimShapeInstance instance in context.ShapeInstancesOf(ifcElement).Where(x => x.RepresentationType == XbimGeometryRepresentationType.OpeningsAndAdditionsIncluded)) { XbimShapeGeometry geometry = context.ShapeGeometry(instance); var data = ((IXbimShapeGeometryData)geometry).ShapeData; using (var stream = new MemoryStream(data)) { using (var reader = new BinaryReader(stream)) { XbimShapeTriangulation mesh = reader.ReadShapeTriangulation(); mesh = mesh.Transform(instance.Transformation);

CBenghi commented 7 years ago

Hello @redscorpion201, This is one of the most complex aspects of the model, and indeed it's poorly documented in our code. The reason for it's complexity is that, in order to cope with the need to have the math work decently in some environments that use single floating point precision (particularly with transformations) we have had to simplify the meshing by performing the transforms around a local coordinate system. It would take quite a bit of time to respond to this as I'd have to study and document it myself, but if you look at the code in XbimXplorer (windowsUI) you might find answers. I'll keep this issue open and in time, spend efforts to try and document this properly. I've got a question for you, though; are you hoping to extract geolocated coordidinates from the representation items, I.E. would you want the representation to be in the form of latitute, longitude, elevation? Because your site uses that type of reference.

braunalex commented 7 years ago

allright. thanks for your answer! I'm hoping to get Gauss–Krüger coordinates. At least, I defined those in Revit :)

CBenghi commented 7 years ago

This is interesting. We use Cartesian coordinates for the local geometry; I suppose that it would be fairly easy to add a function that transforms the Cartesian coordinates of the objects in the context of the geolocated site to provide the coordinates that you need. Is this an area that you are familiar with (in terms of algorithms)?

braunalex commented 7 years ago

ok... after some deeper inspection I found my solution:

IfcObjectPlacement objectPlacement = model.Instances.OfType<Xbim.Ifc2x3.ProductExtension.IfcSite>().First().ObjectPlacement; IfcLocalPlacement relplacement = objectPlacement.ReferencedByPlacements.First(); XbimMatrix3D myTransformation = relplacement.ToMatrix3D();

maybe one final question (not directly related to the WCS topic): when filtering instances with .OfType<> and using interfaces (e.g. IIfcSite), I don't get any results for Ifc2x3 objects. Do you know what I'm doing wrong?

CBenghi commented 7 years ago

The last problem is really weird and unexpected, I'm looking for instance at XbimEssentials\Xbim.Essentials.Tests\CrossAccessTests.cs There's a SettingNamesTest method that uses an interface to search for walls and it works on an ifc2x3.

can you reproduce the issue in a test case? The best repository is probably Xbim.Essentials to notify this.

CBenghi commented 7 years ago

I've added a test case to essentials for your latest problem on IIfcSite querying... which seems to pass. https://github.com/xBimTeam/XbimEssentials/commit/060eefc0829aa1fac7452fb9a321a0bcebe0c7cc Can you reproduce?

braunalex commented 7 years ago

I checked my code again and found an error unrelated to the mentioned problem. Querying works fine. Sorry for the trouble.

CBenghi commented 7 years ago

Ok then I'll close this, but if you find time to document the matter contributions are welcome.