Plane-Cut on segment's labelmap

I need to plane-cut a labelmap of a segment with a vtkplanewidget, but the cutting position is not correct.I think there might be an issue with the conversion from voxel ijk coordinates to RAS coordinates, but I can’t pinpoint the cause.

here is code

std::vector<vtkSmartPointer<vtkOrientedImageData>> PlaneCutImage(vtkOrientedImageData* image, double planeOrigin_World[3], double planeNormal_World[3])
{
	Q_D(qSlicerSurgeryPlanPlaneCutEffect);
	if (!image) {
		return {};
	}

	qDebug() << "planeOrigin:" << planeOrigin_World[0] << " " << planeOrigin_World[1] << " " << planeOrigin_World[2];
	qDebug() << "planeNormal:" << planeNormal_World[0] << " " << planeNormal_World[1] << " " << planeNormal_World[2];


	// ijk 2 ras
	vtkNew<vtkTransform> ijkToWorldTransform;
	vtkNew<vtkMatrix4x4> ijkToWorldMatrix;
	image->GetImageToWorldMatrix(ijkToWorldMatrix);
	ijkToWorldTransform->SetMatrix(ijkToWorldMatrix);

	PrintMatrixFormatted(ijkToWorldMatrix);



	//
	int dims[3];
	double spacing[3], origin[3];
	image->GetDimensions(dims);
	image->GetSpacing(spacing);
	image->GetOrigin(origin);

	// 
	if (dims[0] <= 0 || dims[1] <= 0 || dims[2] <= 0) {
		return {};
	}



	// 
	int extent[6] = { 0, dims[0] - 1, 0, dims[1] - 1, 0, dims[2] - 1 };
	void* wholeInputPtr = image->GetScalarPointerForExtent(extent);
	if (!wholeInputPtr) {
		wholeInputPtr = image->GetScalarPointer();
		if (!wholeInputPtr) {
			return {};
		}
	}

	int scalarType = image->GetScalarType();
	int numComponents = image->GetNumberOfScalarComponents();
	size_t scalarSize = image->GetScalarSize();

	if (scalarSize == 0) {
		return {};
	}

	size_t voxelSize = scalarSize * numComponents;

	std::vector<vtkSmartPointer<vtkOrientedImageData>> ret;

	// 
	vtkNew<vtkOrientedImageData> part1;
	vtkNew<vtkOrientedImageData> part2;
	part1->DeepCopy(image);
	part2->DeepCopy(image);



	// 
	part1->AllocateScalars(scalarType, numComponents);
	part2->AllocateScalars(scalarType, numComponents);

	//
	void* wholePart1Ptr = part1->GetScalarPointerForExtent(extent);
	void* wholePart2Ptr = part2->GetScalarPointerForExtent(extent);

	if (!wholePart1Ptr || !wholePart2Ptr) {
		wholePart1Ptr = part1->GetScalarPointer();
		wholePart2Ptr = part2->GetScalarPointer();

		if (!wholePart1Ptr || !wholePart2Ptr) {
			return {};
		}
	}


	vtkIdType totalBytes = static_cast<vtkIdType>(dims[0]) * dims[1] * dims[2] * voxelSize;
	memset(wholePart1Ptr, 0, totalBytes);
	memset(wholePart2Ptr, 0, totalBytes);

	bool sideWrite[2] = { false, false };

	// handle every voxel
	for (int z = 0; z < dims[2]; ++z) {
		for (int y = 0; y < dims[1]; ++y) {
			for (int x = 0; x < dims[0]; ++x) {

				//
				double ijkCenter[3] = { x + 0.5 ,y + 0.5 , z + 0.5 };
				double rasCenter[3];
				ijkToWorldTransform->TransformPoint(ijkCenter, rasCenter);

				if ((y == 0) && (z == 0) && (x == 0)) {
					qDebug() << "IJK (0,0,0) -> RAS:" << rasCenter[0] << rasCenter[1] << rasCenter[2];
				}



				double vector[3] = {
					rasCenter[0] - planeOrigin_World[0],
					rasCenter[1] - planeOrigin_World[1],
					rasCenter[2] - planeOrigin_World[2]
				};

				double dotProduct =
					vector[0] * planeNormal_World[0] +
					vector[1] * planeNormal_World[1] +
					vector[2] * planeNormal_World[2];


				// 
				size_t offset = (z * dims[1] * dims[0] + y * dims[0] + x) * voxelSize;

				void* inputPtr = static_cast<char*>(wholeInputPtr) + offset;
				void* part1Ptr = static_cast<char*>(wholePart1Ptr) + offset;
				void* part2Ptr = static_cast<char*>(wholePart2Ptr) + offset;

				if (dotProduct >= 0) {
					sideWrite[0] = true;
					memcpy(part1Ptr, inputPtr, voxelSize);
					
				}
				else {
					sideWrite[1] = true;
					memcpy(part2Ptr, inputPtr, voxelSize);
					
				}
			}
		}
	}

	
	part1->SetImageToWorldMatrix(ijkToWorldMatrix);
	part2->SetImageToWorldMatrix(ijkToWorldMatrix);

	//
	if (sideWrite[0]) {
		ret.emplace_back(part1);

		WriteNII("D:/part1.nii.gz", part1);
	}
	if (sideWrite[1]) {
		ret.emplace_back(part2);
		WriteNII("D:/part2.nii.gz", part2);
	}

	return ret;
}