How to set bounds for 3d map in vtk by c++? - c++

I have a lot of lines and planes which are around, for example, (0.5, 0.5, 0.5) point. Also I have area where they have importance, it's a cube. And lines, planes have possibility to intersect this area, and be outside of it. Can I hide part of all elements, and parts of elements, which are not included in my area? Does Vtk have opportunity to do it very simple? Or I need to do it by myself? I want to write, for example SetBounds(bounds), and after that all what isn't included in cube dissapear.

Try using vtkClipDataSet with the clip-function set to vtkBox. Finally, render the output from the vtkClipDataSet filter.
vtkNew<vtkBox> box;
box->SetBounds(.....); // set the bounds of interest.
vtkNew<vtkClipDataSet> clipper;
clipper->SetInputConnection(....); // set to your data producer
clipper->SetClipFunction(box.GetPointer());
// since clipper will produce an unstructured grid, apply the following to
// extract a polydata from it.
vtkNew<vtkGeometryFilter> geomFilter;
geomFilter->SetInputConnection(clipper->GetOutputPort());
// now, this can be connected to the mapper.
vtkNew<vtkPolyDataMapper> mapper;
mapper->SetInputConnection(geomFilter->GetOutputPort());

Related

How to get bounding rectangle of an ArcGIS TextSymbol?

I'm using the Qt C++ ArcGIS Runtime SDK v100.9 and I have various shapes and labels being drawn on a map.
I want to be able to find out the area (bounding rectangle) of Graphic (which is a text label (TextSymbol) at a given point (SpatialReference::wgs84) on the map) so I can determine if the width of the label is more or less than another Graphic (lets say it has a Polygon for its Geometry which is being used to draw a circle) in order to decide if the label should be set to visible or not.
Within a class derived from Esri::ArcGISRuntime::MapGraphicsView the circle and the text label are created along the lines of:
Point centerWgs84(0.0, 0.0, SpatialReference::wgs84());
Graphic* circleGraphic_p = new Graphic(GeometryEngine::bufferGeodetic(centerWgs84, 1000.0, LinearUnit::meters(), 0.5, GeodeticCurveType::Geodesic));
this->graphicsOverlays()->at(0)->graphics()->append(circleGraphic_p);
circleGraphic_p->setSymbol(new SimpleLineSymbol(SimpleLineSymbolStyle::Solid, QColor(Qt::blue), 1.0));
circleGraphic_p->setVisible(true);
TextSymbol* textMarker_p = new TextSymbol("Some Label", Qt::black, 12.0, HorizontalAlignment::Center, VerticalAlignment::Bottom);
Graphic* labelGraphic_p = new Graphic(centerWgs84, textMarker_p);
this->graphicsOverlays()->at(0)->graphics()->append(labelGraphic_p);
labelGraphic_p->setVisible(true);
Rather than always setting the label visibility to true, I thought I would be able to take the Geometry of each Graphic and use it to construct an Envelope which would allow me to then get the width of each envelope that could then be compared:
Envelope circleEnvelope(circleGraphic_p->geometry());
Envelope labelEnvelope(labelGraphic_p->geometry());
labelGraphic_p->setVisible(circleEnvelope.width() >= labelEnvelope.width());
but when I try and do this, the width of each envelope is always a very small negative value (such as -2.25017... e-98)
Any suggestions on what I am doing wrong or if there is a better way to get the size on the map (or in device independent units) of the text label and a Graphic described by the Geometry of a Polyline or Polygon?
EDIT: I've discovered that the Geometry object has an extent() method from which I can get the width of the circle but the Geometry of the Graphic being used for the text label results in a width of zero from its extent() method. I expect this is because the Geometry is just a Point which has no width or height. So the question still stands of how to get the bounding rectangle of a TextSymbol?
You are correct, the extent is being returned of the underlying geometry, not the TextSymbol. I don't think you will be able to achieve what you are wanting in the way you are going about it, as there isn't a way to get the bounding box or screen coordinates of the symbol itself. Instead, have you considered using LabelDefinitions and setting the various deconfliction options? This sample shows labels on layers, but can be applied to graphics as well. There are many labeling options you can apply, and this would allow the internal labeling engine to deconflict for you.

How do I remove self-intersecting triangles from a 3D surface mesh?

I have a CGAL surface_mesh of triangles with some self-intersecting triangles which I'm trying to remove to create a continuous 2-manifold shell, ultimately for printing.
I've attempted to use remove_self_intersection() and autorefine_and_remove_self_intersections() from this answer. The first only removes a few self-intersections while the second completely removes my mesh.
So, I'm trying my own approach - I'm finding the self-intersections and then attempting to delete them. I've tried using the low level remove_face but the borders are not detectable afterwards so I'm unable to fill the resulting holes. This answer refers to using the higher level Euler remove_face but this method, and make_hole seem to discard my mesh entirely.
Here is an extract (I'm using break to see if I can get at least one triangle removed, and I'm just trying with the first of the pair):
vector<pair<face_descriptor, face_descriptor> > intersected_tris;
PMP::self_intersections(mesh, back_inserter(intersected_tris));
for (pair<face_descriptor, face_descriptor> &p : intersected_tris) {
CGAL::Euler::remove_face(mesh.halfedge(get<0>(p)), mesh);
break;
}
My approach to removing self-intersecting triangles is to aggressively delete the intersecting faces, along with nearby faces and fill the resulting holes. Thanks to #sloriot 's comment I realised that the Euler::remove_face function was failing due to duplicate faces in the set returned from both the self_intersections and expand_face_selection functions.
A quick way to remove duplicate faces from the vector result of those two functions is:
std::set<face_descriptor> s(selected_faces.begin(), selected_faces.end());
selected_faces.assign(s.begin(), s.end());
This code converts the vector of faces into a set (sets contain no duplicates) and then converting the set back again.
Once the duplicates were removed, the Euler::remove_face function worked correctly, including updating the borders so that the triangulate_hole function could be used on the result producing a final surface with no self-intersections.

Clip Unstructured grid and keep arrays data

I'm trying to clip a vtkUnstructuredGrid using vtkClipDataSet. The problem is that after I clip, the resulting vtkUnstructuredGrid doesn't have the point/cells data (the arrays).
This is my code:
vtkSmartPointer<vtkUnstructuredGrid> model = reader->GetOutput();
// this shows that model has one point data array called "Displacements" (vectorial of 3 components)
model->Print(std::cout);
// Plane to cut it
vtkSmartPointer<vtkPlane> plane = vtkSmartPointer<vtkPlane>::New();
plane->SetOrigin(0.0,0.0,0.0); plane->SetNormal(1,0,0);
// Clip data
vtkSmartPointer<vtkClipDataSet> clipDataSet = vtkSmartPointer<vtkClipDataSet>::New();
clipDataSet->SetClipFunction(plane);
clipDataSet->SetInputConnection(model->GetProducerPort());
clipDataSet->InsideOutOn();
clipDataSet->GenerateClippedOutputOn();
//PROBLEM HERE. The print shows that there aren't any arrays on the output data
clipDataSet->GetOutput()->Print(std::cout);
I need the output grid to have the arrays, because I would like to display the values on the resulting grid.
For example, if the data are are scalars, I would like to display isovalues on the cutted mesh. If the data is vectorial, I would like to deform the mesh (warp) in the direction of the data vectors.
Here I have an example on ParaView of what I would like to do. The solid is the original mesh and the wireframe mesh is the deformed one.
I'm using VTK 5.10 under C++ (Windows 8.1 64 bits, if that helps).
Thank you!
PS: I tried asking this on the VTKusers list, but I got no answer.
Ok I found the error after the comment of user lib. I was missing the call to update after I set the inputconnection.
Thank you all.
// Clip data
vtkSmartPointer<vtkClipDataSet> clipDataSet = vtkSmartPointer<vtkClipDataSet>::New();
clipDataSet->SetClipFunction(plane);
clipDataSet->SetInputConnection(model->GetProducerPort());
clipDataSet->InsideOutOn();
clipDataSet->GenerateClippedOutputOn();
clipDataSet->Update(); // THIS is the solution

Draw Ring with shapeRenderer in LibGDX

I want to draw a ring (circle with big border) with the shaperenderer.
I tried two different solutions:
Solution: draw n-circles, each with 1 pixel width and 1 pixel bigger than the one before. Problem with that: it produces a graphic glitch. (also with different Multisample Anti-Aliasing values)
Solution: draw one big filled circle and then draw a smaller one with the backgroundcolor. Problem: I can't realize overlapping ring shapes. Everything else works fine.
I can't use a ring texture, because I have to increase/decrease the ring radius dynamic. The border-width should always have the same value.
How can I draw smooth rings with the shaperenderer?
EDIT:
Increasing the line-width doesn't help:
MeshBuilder has the option to create a ring using the ellipse method. It allows you to specify the inner and outer size of the ring. Normally this would result in a Mesh, which you would need to render yourself. But because of a recent change it is also possible to use in conjunction with PolygonSpriteBatch (an implementation of Batch that allows more flexible shapes, while SpriteBatch only allows quads). You can use PolygonSpriteBatch instead of where you normally would use a SpriteBatch (e.g. for your Stage or Sprite class).
Here is an example how to use it: https://gist.github.com/xoppa/2978633678fa1c19cc47, but keep in mind that you do need the latest nightly (or at least release 1.6.4) for this.
Maybe you can try making a ring some other way, such as using triangles. I'm not familiar with LibGDX, so here's some
pseudocode.
// number of sectors in the ring, you may need
// to adapt this value based on the desired size of
// the ring
int sectors=32;
float outer=0.8; // distance to outer edge
float inner=1.2; // distance to inner edge
glBegin(GL_TRIANGLES)
glNormal3f(0,0,1)
for(int i=0;i<sectors;i++){
// define each section of the ring
float angle=(i/sectors)*Math.PI*2
float nextangle=((i+1)/sectors)*Math.PI*2
float s=Math.sin(angle)
float c=Math.cos(angle)
float sn=Math.sin(nextangle)
float cn=Math.cos(nextangle)
glVertex3f(inner*c,inner*s,0)
glVertex3f(outer*cn,outer*sn,0)
glVertex3f(outer*c,outer*s,0)
glVertex3f(inner*c,inner*s,0)
glVertex3f(inner*cn,inner*sn,0)
glVertex3f(outer*cn,outer*sn,0)
}
glEnd()
Alternatively, divide the ring into four polygons, each of which consists of one quarter of the whole ring. Then use ShapeRenderer to fill each of these polygons.
Here's an illustration of how you would divide the ring:
if I understand your question,
maybe, using glLineWidth(); help you.
example pseudo code:
size = 5;
Gdx.gl.glLineWidth(size);
mShapeRenderer.begin(....);
..//
mShapeRenderer.end();

Disconnect first and last point with QwtPlotCurve

I have a problem when I draw a curve in Qt thanks to the Qwt library.
The curve drawing is fine, excepted for the fact that the last point and the first point are connected, the QwtPlot actually draws a polygon with the data I provide...
I've looked into the QwtPlotCurve settings and parameters, but couldn't find anything relevant that could fix that.
The other hint I have thanks to this thread (which sadly is unanswered) is that it has to do with the data I provide.
Currently, I'm using a circular fixed-size buffer (an std::array) to store values I poll continuously. Then, I use the member function
setRawSamples(const double* xData, const double* yData, int size);
to set my curve's data (with the pointers I get with std::array::data()). It means that the list of points to draw isn't ordered (i.e. the point which has the smallest abscissa isn't the first point in the double*).
Could it be the source of the problem ? How can I fix that and just draw a curve and not a polygon ?
A curve draws as a non-closed polygon by default. Each sample point is connected to the previous sample point in provided array (but the first sample isn't connected to the last sample). Qwt doesn't care about ordering of your points by abscissa values. For example, if you provide samples (0, 0), (0, 1), (1, 1), (1, 0), (0, 0), it will draw a rectangle. If you want to avoid self-intersections in curve, you need to provide samples ordered by abscissa.