Solid clip for structured grid

I am new to VTK :slight_smile: and I have a meshed cube produced with structured grid like this:


using this code:


struct Mesh
{
	int xMesh;
	int yMesh;
	int zMesh;
};

struct Size
{
	double xSize;
	double ySize;
	double zSize;
};

struct Offset
{
	double xOffset;
	double yOffset;
	double zOffset;
};

vtkSmartPointer<vtkStructuredGrid> AddStrcutredGrid(Mesh mesh, Size size, Offset offset)
{

	double dx = size.xSize / mesh.xMesh;
	double dy = size.ySize / mesh.yMesh;
	double dz = size.zSize / mesh.zMesh;

	auto cellsCount = mesh.xMesh * mesh.yMesh * mesh.zMesh;

	// Create a structured grid
	vtkSmartPointer<vtkStructuredGrid> structuredGrid = vtkSmartPointer<vtkStructuredGrid>::New();

	// Create points
	vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New();

	for (int z = 0; z < mesh.zMesh + 1; z++) {
		for (int y = 0; y < mesh.yMesh + 1; y++) {
			for (int x = 0; x < mesh.xMesh + 1; x++) {
				points->InsertNextPoint(x * dx, y * dy, z * dz);
			}
		}
	}

	// Set the points to the structured grid
	structuredGrid->SetDimensions(mesh.xMesh + 1, mesh.yMesh + 1, mesh.zMesh + 1);
	structuredGrid->SetPoints(points);

	// Create cell colors
	vtkSmartPointer<vtkUnsignedCharArray> colors = vtkSmartPointer<vtkUnsignedCharArray>::New();
	colors->SetName("Colors");
	colors->SetNumberOfComponents(3); // RGB

	for (int i = 0; i < cellsCount; i++) {
		unsigned char color[3] = { static_cast<unsigned char>(rand() % 256),
								  static_cast<unsigned char>(rand() % 256),
								  static_cast<unsigned char>(rand() % 256) };
		colors->InsertNextTypedTuple(color);
	}

	// Set cell colors to the structured grid
	structuredGrid->GetCellData()->SetScalars(colors);



	// Create mapper
	vtkSmartPointer<vtkDataSetMapper> mapper = vtkSmartPointer<vtkDataSetMapper>::New();
	mapper->SetInputData(structuredGrid);

	// Create actor
	vtkSmartPointer<vtkActor> actor = vtkSmartPointer<vtkActor>::New();
	actor->SetMapper(mapper);

	vtkNew<vtkTransform> transform;
	transform->Translate(offset.xOffset, offset.yOffset, offset.zOffset);
	actor->SetUserTransform(transform);


	return structuredGrid;
}

I also have clipper code like this:


#include <vtkSmartPointer.h>
#include <vtkStructuredGrid.h>
#include <vtkPoints.h>
#include <vtkCellArray.h>
#include <vtkUnsignedCharArray.h>
#include <vtkGeometryFilter.h>
#include <vtkDataSetMapper.h>
#include <vtkActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCellData.h>
#include <vtkActor.h>
#include <vtkAxesActor.h>
#include <vtkCamera.h>
#include <vtkCaptionActor2D.h>
#include <vtkNamedColors.h>
#include <vtkNew.h>
#include <vtkPlane.h>
#include <vtkPolyDataMapper.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSphereSource.h>
#include <vtkTextProperty.h>
#include <vtkTransform.h>
#include <vtkOrientationMarkerWidget.h>
#include <vtkImplicitPlaneRepresentation.h>
#include <vtkImplicitPlaneWidget2.h>
#include <vtkClipPolyData.h>
#include <vtkXMLPolyDataReader.h>
#include <vtkProperty.h>
#include <vtkStructuredGridGeometryFilter.h>
#include <vtkDataSetSurfaceFilter.h>
#include <vtkPolyDataNormals.h>
#include <vtkBoxClipDataSet.h>

namespace {
	// Callback for the interaction
	// This does the actual work: updates the vtkPlane implicit function.
	// This in turn causes the pipeline to update and clip the object.
	class vtkIPWCallback : public vtkCommand
	{
	public:
		static vtkIPWCallback* New()
		{
			return new vtkIPWCallback;
		}

		virtual void Execute(vtkObject* caller, unsigned long, void*)
		{
			vtkImplicitPlaneWidget2* planeWidget =
				reinterpret_cast<vtkImplicitPlaneWidget2*>(caller);
			vtkImplicitPlaneRepresentation* rep =
				reinterpret_cast<vtkImplicitPlaneRepresentation*>(
					planeWidget->GetRepresentation());
			rep->GetPlane(this->plane);

		}

		vtkIPWCallback() = default;

		vtkPlane* plane{ nullptr };
	};
}
int main(int argc, char* argv[])
{

#pragma region Initialization

	// Create a renderer
	vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();

	// Create a render window
	vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->AddRenderer(renderer);

	// Create a render window interactor
	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
	renderWindowInteractor->SetRenderWindow(renderWindow);

#pragma endregion



	auto structuredGrid = AddStrcutredGrid(Mesh{ 10, 10, 10 }, Size{ 10, 10, 10 }, Offset{ 10, 10, 10 });
	auto orientationWidget = AddCoordinateAxes(renderWindowInteractor);

	vtkSmartPointer<vtkGeometryFilter> geometryFilter = vtkSmartPointer<vtkGeometryFilter>::New();
	geometryFilter->SetInputData(structuredGrid);

	// Setup a visualization pipeline.
	vtkNew<vtkPlane> plane;
	vtkNew<vtkClipPolyData> clipper;
	clipper->SetClipFunction(plane);
	//clipper->InsideOutOn();
	clipper->SetInputConnection(geometryFilter->GetOutputPort());


	vtkNew<vtkPolyDataMapper> clippedMapper;
	clippedMapper->SetInputConnection(clipper->GetOutputPort());

	vtkNew<vtkActor> clippedActor;
	clippedActor->SetMapper(clippedMapper);

	renderer->AddActor(clippedActor);


	// Create a mapper and actor.
	vtkNew<vtkPolyDataMapper> mapper;
	mapper->SetInputConnection(clipper->GetOutputPort());
	vtkNew<vtkActor> actor;
	actor->SetMapper(mapper);
	//vtkNew<vtkProperty> backFaces;
	//backFaces->SetDiffuseColor(namedColors->GetColor3d("Gold").GetData());

	//actor->SetBackfaceProperty(backFaces);

	// The callback will do the work.
	vtkNew<vtkIPWCallback> myCallback;
	myCallback->plane = plane;

	vtkNew<vtkImplicitPlaneRepresentation> rep;
	rep->SetPlaceFactor(1.25); // This must be set prior to placing the widget.
	rep->PlaceWidget(actor->GetBounds());
	rep->SetNormal(plane->GetNormal());

	vtkNew<vtkImplicitPlaneWidget2> planeWidget;
	planeWidget->SetInteractor(renderWindowInteractor);
	planeWidget->SetRepresentation(rep);
	planeWidget->AddObserver(vtkCommand::InteractionEvent, myCallback);

#pragma region Finalization

	SetupScene(renderer);

	renderWindowInteractor->Initialize();
	// Render the scene
	renderWindow->Render();
	planeWidget->On();

	// Start the interaction
	renderWindowInteractor->Start();

#pragma endregion

	return 0;
}

the clipper is applied to the grid like this:

the problem is i can see inside the cube but i want my clip be like a solid clip that at clip plane i see colors based on the cells the plane goes through them. how can i solve this issue?

It looks like that because you got rid of the interior information by using geometry filter and passed the outer shell to vtkClipPolyData. So, all it did was clip the outer shell.

Can you try to use vtkClipDataSet instead? It should clip the interior cells. You can also get rid of geometry filter in the middle. Try this pipeline insted.

structuredGrid -> vtkClipDataSet -> vtkDataSetMapper -> Actor -> ...

Yes it works and gives the behaviour i was looking :grinning:
wish you the best