Getting IfcPolyline from ifcSpace - xbim

I am quite new to xBim and I am struggeling to find the information I need. I have been able to iterate through all the IFCSpaces for each storey, and I would like to find each space's IfcPolyline so that I will know its boundaries. But how?
using (IfcStore model = IfcStore.Open(filename, null))
{
List<IfcBuildingStorey> allstories = model.Instances.OfType<IfcBuildingStorey>().ToList();
for (int i=0;i<allstories.Count;i++)
{
IfcBuildingStorey storey = allstories[i];
var spaces = storey.Spaces.ToList();
for (int j=0;j<spaces.Count;j++)
{
var space = spaces[j];
var spaceBoundaries=space.BoundedBy.ToList();
for (int u=0;u<spaceBoundaries.Count;u++)
{
//IfcPolyline from here??
}
}
}
}

This is quite old question, but in case you are still looking for the answer: IfcSpace.BoundedBy is an inverse relation and will give you a list of IfcRelSpaceBoundaries. This has RelatedBuildingElement attribute which will give you bounding building element such as a wall, door etc. It also has ConnectionGeometry, which is essentially an interface as the geometry of this connection might be curve, point, surface or volume. If you drill further down in the object model, you will see that the boundary can be any kind of curve, not just a polyline.
Entirely different approach could be to access the space geometry Space.Representation. This could have a 2D representation which would likely be a polygon, or it might be a 3D extrusion with profile. That would again be what you are looking for. But be aware, that it can be any other kind of geometry representation depending on the authoring software and model author.

Related

Retrieving FbxObject3D from an FbxAnimCurveNode

Maya exports all animations to a single FbxAnimStack and FbxAnimLayer. My scene has several objects with independent animations, grouped by top-level objects:
Object_1
this_is_animated_1
this_is_animated_2
Object_2
this_is_animated_3
this_is_animated_4
I'd like to split the single FbxAnimLayer in several layers, one for each Object. My plan is to walk through all FbxAnimCurveNode, get the targeted property, retrieve the FbxObject3D it belongs to, find the top level FbxObject3D and add those curve to the relevant new FbxAnimLayer.
However, I'm stuck: how do I get the targeted property from an animation curve ? FbxAnimCurveNode::GetChannel is private...
for (int i = 0; i < scene->GetSrcObjectCount<FbxAnimCurveNode>() ; ++i) {
auto curve = scene->GetSrcObject<FbxAnimCurveNode>(i);
// Stuck ! How to retrieve the targeted
}
Or maybe my entire approach is wrong ?

Which pcl filter to use to downsample a point cloud

I am getting a point cloud from a lidar on an autonomous driving robot, but it's too much data to process.
I already implemented a passthrough filter.
I did get a very good result and I was asking myself if there were others filters or methods I could dig into.
Of course I'm not looking for anything specific but rather a direction or advice, because I'm pretty new to the pcl library and it seems pretty huge.
Here is my filter now:
pcl::PointCloud<PointXYZIR>::Ptr cloudInput;
cloudInput.reset(new pcl::PointCloud<PointXYZIR> (cloud_in));
pcl::PointCloud<PointXYZIR>::Ptr cloudFiltered;
cloudFiltered.reset(new pcl::PointCloud<PointXYZIR>);
// Create the filtering object: downsample the dataset using a leaf size
pcl::VoxelGrid<PointXYZIR> avg;
avg.setInputCloud(cloudInput);
avg.setLeafSize(0.25f, 0.25f, 0.25f);
avg.filter(*cloudFiltered);
//Filter object
pcl::PassThrough<PointXYZIR> filter;
filter.setInputCloud(cloudFiltered);
filter.setFilterFieldName("x");
filter.setFilterLimits(-100, 100);
filter.filter(*cloudFiltered);
filter.setFilterFieldName("y");
filter.setFilterLimits(-100, 100);
filter.filter(*cloudFiltered);
cloud_out = *cloudFiltered;
Actually i did find a solution, but there is no general solution. In my case, and i think this problem is very specific to which point cloud you gonna get and what you wanna do with it.
The passtrought filter is a very efficient way to down sample without taking too many risk of losing interesting data.
http://pointclouds.org/documentation/tutorials/passthrough.php
Then i tested StatisticalOutlierRemoval, is efficient but not relevant in my case.
http://pointclouds.org/documentation/tutorials/statistical_outlier.php
Now, i downsample the pointcloud with a leafsize function, then i create a kdtree to filter the point by radius.
It's about the same amount of calculation that the passtrought filter took, but it has more sense in my project to do it this way.
// Create the filtering object: downsample the dataset using a leaf size
pcl::VoxelGrid<PointXYZIR> avg;
avg.setInputCloud(cloudInput);
avg.setLeafSize(0.25f, 0.25f, 0.25f);
avg.filter(*cloudFiltered);
//searchPoint
PointXYZIR searchPoint = cloudFiltered->at(0) ;
//result from radiusSearch()
std::vector<int> pointIdxRadiusSearch;
std::vector<float> pointRadiusSquaredDistance;
//kdTree
pcl::KdTreeFLANN<PointXYZIR> kdtree;
kdtree.setInputCloud (cloudFiltered);
kdtree.setSortedResults(true);
if ( kdtree.radiusSearch (searchPoint, 100, pointIdxRadiusSearch, pointRadiusSquaredDistance) > 0 )
{
//delete every point in target
for (size_t j = 0; j < pointIdxRadiusSearch.size (); ++j)
{
//is this the way to erase correctly???
cloud_out.push_back(cloudFiltered->points[pointIdxRadiusSearch[j]]);
}
}
voxel grid to downsampling should maintain pretty good cloud distribution while reducing the number of points. You can set how small the voxels are in each axis in order to maintain as much or as little resolution as you want. Each voxel will delete all points in it and replace them with a single point which is averaged from those deleted.
http://pointclouds.org/documentation/tutorials/voxel_grid.php#voxelgrid

Sorting objects to the front or back depending on their position

I am trying to sort my renderables/actors correctly and noticed that I have some troubles with walls since they get sorted by their centerpoint. So I am sorting all my actors before I draw them depending on their distance to the camera with an insertion sort. After that, I am trying to determine if the wall should be drawn behind or in front of the gamefield. To explain this, the game takes place inside of a cube which is out of 6 planes. Since I can rotate the camera around that cube I need a sorting which would put the planes in front/back depending on that. So here is a picture so you know what we are talking about:
You can clearly see the rendermisstake whats happening at the front of those kind of snake.
Okay here is my current sorting:
//list of Actors the abstract class which Wall and cube and so on extend
void Group::insertionSort(vector<Actor *> &actors)
{
int j;
for (int i = 1; i < actors.size(); i++)
{
Actor *val = actors[i];
j = i - 1;
while (j >= 0 && distanceToCamera(*actors[j]) < distanceToCamera(*val))
{
actors[j + 1] = actors[j];
j = j - 1;
}
actors[j + 1] = val;
}
}
float Group::distanceToCamera(Actor &a)
{
float result = 0;
XMVECTOR posActor = XMLoadFloat3(&a.getPosition()); //here i get the centerpoint of the object
XMVECTOR posCamera = XMLoadFloat3(&m_camera->getPosition());
XMVECTOR length = XMVector3Length(posCamera - posActor);
XMStoreFloat(&result, length);
return result;
}
To determine if it's a Wall I used kind like this dynamic_cast<Wall*>(val) but I don't get them in front/back of the vector depending on that. To remember the objects return their centerpoint. Can anyone lead me to the right way?
It's difficult to answer your question because it is a complex system which you haven't fully explained here and which you should also reduce to something simpler before posting. Chances are that you would find a fix yourself on the way. Anyway, I'll do some guessing...
Now, the first thing I'd fix is the sorting algorithm. Without analysing it in depth whether it works correctly in all cases or not, I'd throw it out and use std::sort(), which is both efficient and very unlikely to contain errors.
While replacing it, you need to think about the ordering between two rendered objects carefully: The question is when exactly does one object need to be drawn before the other? You are using the distance of the center point to the camera. I'm not sure if you are sorting 2D objects or 3D objects, but in both cases it's easy to come up with examples where this doesn't work! For example, a large square that doesn't directly face the camera could cover up a smaller one, even if the smaller square's center is closer. Another problem is when two objects intersect. Similarly for 3D objects, if they have different sizes or intersect then your algorithm doesn't work. If your objects all have the same size and they can't intersect, you should be fine though.
Still, and here I suspect one problem, it could be that a surface of an object and a surface of the cube grid have exactly the same position. One approach is that you shrink the objects slightly or enlarge the outside grid, so that the order is always clear. This would also work around an issue that you suffer from floating point rounding errors. Due to these, two objects that don't have an order mathematically could end up in different positions depending on the circumstances. This can manifest as them flickering between visible to covered depending on the camera angle.
One last thing: I'm assuming you want to solve this yourself for educational reasons, right? Otherwise, it would be a plain waste of time with existing rendering toolkits in place that would even offload all the computations to the graphics hardware.

Sets in raphaeljs not real groups? Transform order

I'm having an issue with sets and how transforms are applied. I'm coming from a graphics background, so I'm familiar with scene graphs as well as the normal SVG group syntax, but Raphael is confusing me. Say I have a circle and a set, on which I want to apply a transform.
circle = paper.circle(0,0.5)
set = paper.set()
If I add the circle first, and then transform, it works.
set.push circle
set.transform("s100,100")
To make a 50 radius circle. If I reverse the order, however,
set.transform("s100,100")
set.push circle
The transform is not applied.
This seems as though it will break many, many rendering and animation type algorithms, where your groups/transforms hold your articulation state, and you add or remove objects to them instead of recreating the entire transform every time. Is there an option somewhere in the documentation that I am not seeing that addresses this, or was this functionality discarded in favor of simplicity? It seems very odd to be missing, given that it is supported directly and easily in the group hierarchy of SVG itself... do I need to manually apply the transform from the set to any children added after the set is transformed?
Sets in Raphael are just simple Arrays.
When you perform some actions on set, Raphael goes through all members via for(...){} loop.
Raphael doesn't support SVG groups <g></g>
UPDATE Raphael's code:
// Set
var Set = function (items) {
this.items = [];
this.length = 0;
this.type = "set";
if (items) {
for (var i = 0, ii = items.length; i < ii; i++) {
if (items[i] && (items[i].constructor == elproto.constructor || items[i].constructor == Set)) {
this[this.items.length] = this.items[this.items.length] = items[i];
this.length++;
}
}
}
},
As you can see, all items are stored in this.items which is array.
Raphaël's sets are merely intended to provide a convenient way of managing groups of shapes as unified sets of objects, by aggregating element related actions and delegating them (by proxying the corresponding methods in the set level) to each shape sequentially.
It seems very odd to be missing, given that it is supported directly
and easily in the group hierarchy of SVG itself...
Well, Raphaël is not an attempt to elevate the SVG specs to a JavaScript based API, but rather to offer an abstraction for vector graphics manipulation regardless of the underlying implementation (be it SVG in modern browsers, or VML in IE<9). Thus, sets are by no means representations of SVG groups.
do I need to manually apply the transform from the set to any
children added after the set is transformed?
Absolutely not, you only need to make sure to add any shapes to the set before applying transformations.

Positioning Circle Shapes within a Body in Box2D Web

I've had to completely revamp this question as I don't think I was explicit enough about my problem.
I'm attempting to learn the ropes of Box2D Web. I started having problems when I wanted to learn how to put multiple shapes in one rigid body (to form responsive concave bodies). One of the assumptions I made was that this kind of feature would only really be useful if I could change the positions of the shapes (so that I can be in control of what the overall rigid body looked like). An example would be creating an 'L' body with two rectangle shapes, one of which was positioned below and to-the-right of the first shape.
I've gotten that far in so-far-as I've found the SetAsOrientedBox method where you can pass the box its position in the 3rd argument (center).
All well and good. But when I tried to create two circle shapes in one rigid body, I found undesirable behaviour. My instinct was to use the SetLocalPosition method (found in the b2CircleShape class). This seems to work to an extent. In the debug draw, the body responds physically as it should do, but visually (within the debug) it doesn't seem to be drawing the shapes in their position. It simply draws the circle shapes at the centre position. I'm aware that this is probably a problem with Box2D's debug draw logic - but it seems strange to me that there is no online-patter regarding this issue. One would think that creating two circle shapes at different positions in the body's coordinate space would be a popular and well-documented phenomina. Clearly not.
Below is the code I'm using to create the bodies. Assume that the world has been passed to this scope effectively:
// first circle shape and def
var fix_def1 = new b2FixtureDef;
fix_def1.density = 1.0;
fix_def1.friction = 0.5;
fix_def1.restitution = .65;
fix_def1.bullet = false;
var shape1 = new b2CircleShape();
fix_def1.shape = shape1;
fix_def1.shape.SetLocalPosition(new b2Vec2(-.5, -.5));
fix_def1.shape.SetRadius(.3);
// second circle def and shape
var fix_def2 = new b2FixtureDef;
fix_def2.density = 1.0;
fix_def2.friction = 0.5;
fix_def2.restitution = .65;
fix_def2.bullet = false;
var shape2 = new b2CircleShape();
fix_def2.shape = shape2;
fix_def2.shape.SetLocalPosition(new b2Vec2(.5, .5));
fix_def2.shape.SetRadius(.3);
// creating the body
var body_def = new b2BodyDef();
body_def.type = b2Body.b2_dynamicBody;
body_def.position.Set(5, 1);
var b = world.CreateBody( body_def );
b.CreateFixture(fix_def1);
b.CreateFixture(fix_def2);
Please note that I'm using Box2D Web ( http://code.google.com/p/box2dweb/ ) with the HTML5 canvas.
It looks like you are not actually using the standard debug draw at all, but a function that you have written yourself - which explains the lack of online-patter about it (pastebin for posterity).
Take a look in the box2dweb source and look at these functions for a working reference:
b2World.prototype.DrawDebugData
b2World.prototype.DrawShape
b2DebugDraw.prototype.DrawSolidCircle
You can use the canvas context 'arc' function to avoid the need for calculating points with sin/cos and then drawing individual lines to make a circle. It also lets the browser use the most efficient way it knows of to render the curve, eg. hardware support on some browsers.
Since it seems like you want to do custom rendering, another pitfall to watch out for is the different call signatures for DrawCircle and DrawSolidCircle. The second of these takes a parameter for the axis direction, so if you mistakenly use the three parameter version Javascript will silently use the color parameter for the axis, leaving you with an undefined color parameter. Hours of fun!
DrawCircle(center, radius, color)
DrawSolidCircle(center, radius, axis, color)