I have a question regarding a VTK class called vtkPoints. The class has the functionality to insert individual points, but doesn't have the functionality to remove individual points. This is inconvenient for the case when the view needs to be updated by calling vtkPoints::Modified() to drive the graphics pipeline again to update/re-render the view. The obvious case of re-initializing vtkPoints, adding all points again and updating/re-rendering the view is too slow and resource intensive.
Is there a possible solution to this problem?
Thanks,
timecatcher
The example http://www.vtk.org/Wiki/VTK/Examples/Cxx/PolyData/DeletePoint has a rather simple solution. Copy points to another temporary vtkPoints by filtering the id to remove, and shallow-copy it to the original one:
void ReallyDeletePoint(vtkSmartPointer<vtkPoints> points, vtkIdType id)
{
vtkSmartPointer<vtkPoints> newPoints =
vtkSmartPointer<vtkPoints>::New();
for(vtkIdType i = 0; i < points->GetNumberOfPoints(); i++)
{
if(i != id)
{
double p[3];
points->GetPoint(i,p);
newPoints->InsertNextPoint(p);
}
}
points->ShallowCopy(newPoints);
}
There is no way to remove individual points from vtkPoints. Depending on what your problem is here are some potential solutions:
Store all the points in a single vtkPoint instance, overwrite points you want to get rid of with a value to replace it. This would be useful to cap the max amount of memory a point cloud could use.
Store all the points in a single vtkPoint instance, overwrite points you want to get rid of with a value a value that is far away from your scene.
Create a vtkPoint, vtkCellArray, and vtkPolyData for each point, join them together using vtkAppendPolyData. This has a RemoveInput(vtkPolyData*) so you could remove individual points.
this is a way to remove a point from vtkPoints in python.
def deletePoint(vtk_points, *args):
if isinstance(args[0], list):
args = args[0]
points = vtk.vtkPoints()
for i in range(vtk_points.GetNumberOfPoints()):
if i in args: continue
p = vtk_points.GetPoint(i)
points.InsertNextPoint(p)
return points
No: it has the same limitations on mutability as a float[] array. The only way to remove a point is to copy and exclude. Note that you will incur the same copy penalty when doing Insert() operations if you exceed pre-allocated storage.
Other related data structure options include vtkCollection and vtkPolyData. Also, it might be informative to look at the source for some of the PolyData clip filters to get an idea of the way these type of operations are implemented internally - those should be about as fast as they can be within the limitations of the data structure.
Allowing a point to be deleted from vtkPoints can cause a data set that uses the point to become corrupted. You would also have to delete all cells that use that point as well as shrink the point data arrays.
I would suggest that if you have a filter that is creating the vtkPoints to modify the vtkPoints object and anything that depends on that in the RequestData() method.
Related
I'm a MEP engineer and I want to add space information on mechanical equipment, duct accessories and pipe accessories above the (room bounding) ceilings.
My first idea was to use BoundingBoxIntersectsFilter with an Outline with a modified ClosedShell.GetBoundingBox().Max.Z from the space and then use a BoundingBoxIntersectsFilter to catch my elements. This method works, but I will have trouble with accuracy above spaces which are note limited to six sides. This is because of the fact than Outline only takes to points. Now, I'm thinking I need to convert my spaces to a solid geometry and modify the Z-value and then use the ElementIntersectsElementFilter, but I am currently stuck figuring out which methods to use to modify my space geometry.
Maybe I need to use the GetGeometryObjectFromReference, but I do not really understand how to use Reference. I've seen get_Geometry has been used here, but I need help how to use it. Specifically, this is the code I do not understand how to implement in python code:
foreach( GeometryObject obj in e.Objects )
{
Solid solid = obj as Solid;
if( null != solid )
{
foreach( Face face in solid.Faces )
{
PlanarFace pf = face as PlanarFace;
if( null != pf )
Any kick in the right direction is much appreciated!
Kyrre
When I've done this before, sometimes I've used an easier approach. Identify the key point on the equipment, then drop down the z-value on that equipment point to a z-value just above the next Level down that has spaces on it, and then test that XYZ to determine which space encloses it.
There are many ways to do this. I think the simplest might be to simply do this in two steps. First, use a bounding box or an outline or whatever quick filter fits your needs to reduce the number of potential candidate objects to a reasonable number within a rectangular area. In a second step, iterate through the candidate objects one by one an call the Space. IsPointInSpace method on each of them to eliminate the ones lying outside an irregular space boundary.
I am fairly new to AE. I am aware of JS expressions. I have a programming background.
I have the following type of data that I want to visualise.....
I have about 10,000 different elements (locations in a city). Each of these elements occur during the last 10 years (I will compress this into 60 seconds).
When each element occurs..I want a small sphere to appear. This sphere will occur somewhere in the X,Y space (depending on its lattitude and longitude).
To provide some context ... the data is a series of house sales. The larger the price of the sale...the larger the sphere....
Becuase of the large number of elements. It is not possible (nor desirable) to manually do this in AE.
So...my question is....how can I programmatically do this in AE...?
Is it possible...?
Or perhaps should I write a program to automatically create some type of SVG that I could then import into AE...?
Or another approach entirely...?
Any ideas ... on a basic approach would be welcome.
Thanks,
Mark
Q1: So...my question is....how can I programmatically do this in AE...?
A1: You can use the ExtendScript API to run a Javascript that creates your elements.
Q2: Is it possible...?
A2: Yes.
Q3: Or perhaps should I write a program to automatically create some type of SVG that I could then import into AE...?
A3: You can't import SVG into AE (as far as I know).
Q4: Or another approach entirely...?
A4: No. You are in the right spot (IMHO).
You could use my two scripts (Warning: shameless self promotion) for creating maps and location markers in an AE comp.
Locations creates the markers for you http://aescripts.com/locations/ from CSV files.
AEMaps creates the Map http://aescripts.com/aemap/ for you from geojson files.
Or checkout GeoLayers by Markus Bergelt http://aescripts.com/geolayers/ which does the same but in a different way.
To add the price/size to your sphere you need to do some additional scripting. I suggest hacking on Locations for that.
The function add_projected_marker in line 1814 should be a good entrypoint to add additional expressions to you newly created layer.
You could add an expression like this to the scale property (where v is the value you read from your csv):
layer.transform.scale.expression = "var v = 50;\n[v,v];"
To get the data into the the locdata object you need to hack on the function win.read_button.onClick in line 1181.
the job of the layout is to place vertexes at given locations. if the layout is iterative, then the layout's job is to iterate through an algo, moving the vertexes with each step, until the final layout configuration is achieved.
I have a multi-level graph - say 100 objects of type A; each A object has 10 objects as children; call the children type B objects.
I would like the layout location placement algos to operate on objects of type A only (let's say) - and ignore the B objects.
The cleanest way to achieve this objective might be to define a transform to expose those elements that should participate in the 'algo' placement operation via the step method.
Currently, the step methods, assuming they respect the lock flag at all, do their calculations including the locked vertexes first - so lock/unlock won't work in this case.
Is it possible to do this somehow without resorting to multiple graph objects?
If you want to ignore the B objects entirely, then the simplest option is to create a graph consisting only of the A objects, lay it out, and use the locations from that layout.
That said, it's not clear how you intend to assign locations to the B objects. And if the A objects aren't connected to each other at all, then this approach won't make much sense. (OTOH, if they aren't connected to each other then you're really just laying out a bunch of trees.)
I've been trying to implement a Compute Shader based particle system.
I have a compute shader which builds a structured buffer of particles, using a UAV with the D3D11_BUFFER_UAV_FLAG_COUNTER flag.
When I add to this buffer, I check if this particle has any complex behaviours, which I want to filter out and perform in a separate compute shader. As an example, if the particle wants to perform collision detection, I add its index to another structured buffer, also with the D3D11_BUFFER_UAV_FLAG_COUNTER flag.
I then run a second compute shader, which processes all the indices, and applies collision detection to those particles.
However, in the second compute shader, I'd estimate that about 5% of the indices are wrong - they belong to other particles, which don't support collision detection.
Here's the compute shader code that perfroms the list building:
// append to destination buffer
uint dstIndex = g_dstParticles.IncrementCounter();
g_dstParticles[ dstIndex ] = particle;
// add to behaviour lists
if ( params.flags & EMITTER_FLAG_COLLISION )
{
uint behaviourIndex = g_behaviourCollisionIndices.IncrementCounter();
g_behaviourCollisionIndices[ behaviourIndex ] = dstIndex;
}
If I split out the "add to behaviour lists" bit into a separate compute shader, and run it after the particle lists are built, everything works perfectly. However I think I shouldn't need to do this - it's a waste of bandwidth going through all the particles again.
I suspect that IncrementCounter is actually not guaranteed to return a unique index into the UAV, and that there is some clever optimisation going on that means the index is only valid inside the compute shader it is used in. And thus my attempt to pass it to the second compute shader is not valid.
Can anyone give any concrete answers to what's going on here? And if there's a way for me to keep the filtering inside the same compute shader as my core update?
Thanks!
IncrementCounter is an atomic operation and so will (driver/hardware bugs notwithstanding) return a unique value to each thread that calls it.
Have you thought about using Append/Consume buffers for this, as it's what they were designed for? The first pass simply appends the complex collision particles to an AppendStructuredBuffer and the second pass consumes from the same buffer but using a ConsumeStructuredBuffer view instead. The second run of compute will need to use DispatchIndirect so you only run as many thread groups as necessary for the number in the list (something the CPU won't know).
The usual recommendations apply though, have you tried the D3D11 Debug Layer and running it on the reference device to be sure it isn't a driver issue?
Suppose I have a list of numbers and I've computed the q-quantile (using Quantile).
Now a new datapoint comes along and I want to update my q-quantile, without having stored the whole list of previous datapoints.
What would you recommend?
Perhaps it can't be done exactly without, in the worst case, storing all previous datapoints.
In that case, can you think of something that would work well enough?
One idea I had, if you can assume normality, is to use the inverse CDF instead of the q-quantile.
Keep track of the sample variance as you go and then you can compute InverseCDF[NormalDistribution[sampleMean,sampleVariance], q] which should be the value such that a fraction q of the values are smaller, which is what the q-quantile is.
(I see belisarius was thinking along the same lines.
Here's the link he pointed to: http://en.wikipedia.org/wiki/Algorithms_for_calculating_variance#On-line_algorithm )
Unless you know that your underlying data comes from some distribution, it is not possible to update arbitrary quantiles without retaining the original data. You can, as others suggested, assume that the data has some sort of distribution and store the quantiles this way, but this is a rather restrictive approach.
Alternately, have you thought of programming this somewhere besides Mathematica? For example, you could create a class for your datapoints that contains (1) the Double value and (2) some timestamp for when the data came in. In a SortedList of these datapoints classes (which compares based on value), you could get the quantile very fast by simply referencing the index of the datapoints. Want to get a historical quantile? Simply filter on the timestamps in your sorted list.