//---------------------------------------------------------------------------- void vesKiwiImageWidgetRepresentation::scrollImageSlice(double deltaX, double deltaY) { deltaY *= -1; vesSharedPtr<vesRenderer> ren = this->renderer(); vesVector3f viewFocus = ren->camera()->focalPoint(); vesVector3f viewFocusDisplay = ren->computeWorldToDisplay(viewFocus); float focalDepth = viewFocusDisplay[2]; this->Internal->LastTouchPosition += vesVector2f(deltaX, deltaY); vesVector3f worldTouchPosition = ren->computeDisplayToWorld(vesVector3f(this->Internal->LastTouchPosition[0], this->Internal->LastTouchPosition[1], focalDepth)); worldTouchPosition -= this->Internal->GrabOffset.cast<float>(); int flatDimension = this->Internal->SelectedImageDimension; vesVector3f planeNormal(0, 0, 0); planeNormal[flatDimension] = 1.0; int extent[6]; vesVector3d spacing; vesVector3d origin; this->imageData()->GetOrigin(origin.data()); this->imageData()->GetSpacing(spacing.data()); this->imageData()->GetExtent(extent); double distanceAlongInteractionAxis = worldTouchPosition.dot(planeNormal); double distanceFromOriginAlongAxis = distanceAlongInteractionAxis - origin[flatDimension]; int slicesFromOrigin = distanceFromOriginAlongAxis / spacing[flatDimension] - extent[flatDimension*2]*spacing[flatDimension]; this->scheduleSetSliceIndex(flatDimension, slicesFromOrigin); }
//---------------------------------------------------------------------------- bool vesKiwiAnimationRepresentation::handleSingleTouchTap(int displayX, int displayY) { vesVector2f textSize = this->Internal->PlayRep->textureSize(); double margin = 30; textSize += vesVector2f(margin, margin); if (displayX <= textSize[0] && displayY <= textSize[1]) { this->Internal->PlayMode = !this->Internal->PlayMode; if (this->Internal->PlayMode) { this->Internal->AnimationT0 = vtkTimerLog::GetUniversalTime(); this->Internal->AnimationFrameStart = this->Internal->CurrentFrame; } std::string playText = this->Internal->PlayMode ? "[Pause]" : "[Play]"; this->Internal->PlayRep->setText(playText); return true; } else if (displayX > this->renderer()->width() - 50 && displayY < 50) { vesShaderProgram::Ptr newShader = this->Internal->GeometryShader; if (this->Internal->FrameReps[0]->shaderProgram() == newShader) { newShader = this->Internal->TextureShader; } for (size_t i = 0; i < this->Internal->FrameReps.size(); ++i) { this->Internal->FrameReps[i]->setShaderProgram(newShader); } } return false; }
//---------------------------------------------------------------------------- vesSourceDataT2f::Ptr vesKiwiDataConversionTools::ConvertTCoords(vtkDataArray* tcoords) { if (!tcoords || tcoords->GetNumberOfComponents() != 2) { return vesSourceDataT2f::Ptr(); } const size_t nTuples = tcoords->GetNumberOfTuples(); vesSourceDataT2f::Ptr texCoordSourceData(new vesSourceDataT2f()); for (size_t i = 0; i < nTuples; ++i) { double* values = tcoords->GetTuple(i); vesVertexDataT2f textureCoordinate; textureCoordinate.m_textureCoordinate = vesVector2f(values[0], values[1]); texCoordSourceData->pushBack(textureCoordinate); } return texCoordSourceData; }
//---------------------------------------------------------------------------- void vesKiwiAnimationRepresentation::initializeWithShader( vesSharedPtr<vesShaderProgram> geometryShader, vesSharedPtr<vesShaderProgram> textureShader, vesSharedPtr<vesShaderProgram> gouraudTextureShader) { this->Internal->GeometryShader = geometryShader; this->Internal->TextureShader = gouraudTextureShader; this->Internal->TextRep = new vesKiwiText2DRepresentation(); this->Internal->TextRep->initializeWithShader(textureShader); this->Internal->TextRep->setDisplayPosition(vesVector2f(10, 10)); this->Internal->TextRep->setText("Time: 0.000 s"); this->Internal->AllReps.push_back(this->Internal->TextRep); this->Internal->PlayRep = new vesKiwiText2DRepresentation(); this->Internal->PlayRep->initializeWithShader(textureShader); this->Internal->PlayRep->setText("[Play]"); this->Internal->AllReps.push_back(this->Internal->PlayRep); }
//---------------------------------------------------------------------------- void vesKiwiDataConversionTools::SetTextureCoordinates(vtkDataArray* tcoords, vesSharedPtr<vesGeometryData> geometryData) { assert(tcoords); assert(tcoords->GetNumberOfComponents() == 2); assert(geometryData); const size_t nTuples = tcoords->GetNumberOfTuples(); vesSourceDataT2f::Ptr texCoordSourceData (new vesSourceDataT2f()); for (size_t i = 0; i < nTuples; ++i) { double* values = tcoords->GetTuple(i); vesVertexDataT2f textureCoordinate; textureCoordinate.m_textureCoordinate = vesVector2f(values[0], values[1]); texCoordSourceData->pushBack(textureCoordinate); } geometryData->addSource(texCoordSourceData); }
//---------------------------------------------------------------------------- void vesKiwiAnimationRepresentation::willRender(vesSharedPtr<vesRenderer> renderer) { vesNotUsed(renderer); if (this->Internal->PlayMode) { double currentTime = vtkTimerLog::GetUniversalTime(); double elapsedTime = currentTime - this->Internal->AnimationT0; double animationFramesPerSecond = this->Internal->AnimationFramesPerSecond; int elapsedFrames = static_cast<int>(elapsedTime * animationFramesPerSecond); if (elapsedFrames != 0) { this->Internal->CurrentFrame += elapsedFrames; this->Internal->CurrentFrame = this->Internal->CurrentFrame % this->Internal->NumberOfFrames; this->Internal->AnimationT0 = currentTime; } } int screenHeight = this->renderer()->height(); double margin = 10; vesVector2f textSize = this->Internal->PlayRep->textureSize(); this->Internal->PlayRep->setDisplayPosition(vesVector2f(margin, screenHeight - (margin + textSize[1]))); if (this->Internal->LastFrame != this->Internal->CurrentFrame) { std::stringstream str; str.precision(4); str << "Time: " << std::fixed << 0.0001*this->Internal->CurrentFrame << " s"; this->Internal->TextRep->setText(str.str()); this->Internal->FrameReps[this->Internal->LastFrame]->removeSelfFromRenderer(this->renderer()); this->Internal->FrameReps[this->Internal->CurrentFrame]->addSelfToRenderer(this->renderer()); this->Internal->LastFrame = this->Internal->CurrentFrame; } }
//---------------------------------------------------------------------------- bool vesKiwiImageWidgetRepresentation::handleSingleTouchDown(int displayX, int displayY) { if (!this->Internal->InteractionEnabled) { return false; } // calculate the focal depth so we'll know how far to move vesSharedPtr<vesRenderer> ren = this->renderer(); // flip Y coordinate displayY = ren->height() - displayY; this->Internal->LastTouchPosition = vesVector2f(displayX, displayY); std::tr1::shared_ptr<vesCamera> camera = ren->camera(); vesVector3f cameraFocalPoint = camera->focalPoint(); vesVector3f cameraPosition = camera->position(); vesVector3f displayFocus = ren->computeWorldToDisplay(cameraFocalPoint); float focalDepth = displayFocus[2]; vesVector3f rayPoint0 = cameraPosition; vesVector3f rayPoint1 = ren->computeDisplayToWorld(vesVector3f(displayX, displayY, focalDepth)); vesVector3f touchWorldPosition = rayPoint1; vesVector3f rayDirection = rayPoint1 - rayPoint0; rayDirection.normalize(); rayPoint1 += rayDirection*1e6; vtkNew<vtkAppendPolyData> appendFilter; std::vector<int> cellIdToPlaneId; for (int i = 0; i < 3; ++i) { if (this->planeVisibility(i)) { appendFilter->AddInputData(this->Internal->SliceReps[i]->imagePlanePolyData()); cellIdToPlaneId.push_back(i); } } appendFilter->Update(); vtkNew<vtkCellLocator> locator; locator->SetDataSet(appendFilter->GetOutput()); locator->BuildLocator(); double p0[3] = {rayPoint0[0], rayPoint0[1], rayPoint0[2]}; double p1[3] = {rayPoint1[0], rayPoint1[1], rayPoint1[2]}; double pickPoint[3]; double t; double paramCoords[3]; vtkIdType cellId = -1; int subId; int result = locator->IntersectWithLine(p0, p1, 0.0, t, pickPoint, paramCoords, subId, cellId); if (result == 1) { this->Internal->SelectedImageDimension = cellIdToPlaneId[cellId]; this->interactionOn(); int currentDimension = this->Internal->SelectedImageDimension; int currentSliceIndex = this->Internal->CurrentSliceIndices[this->Internal->SelectedImageDimension]; int extent[6]; vesVector3d spacing; vesVector3d origin; this->imageData()->GetOrigin(origin.data()); this->imageData()->GetSpacing(spacing.data()); this->imageData()->GetExtent(extent); double sliceDistanceAlongAxis = spacing[currentDimension] * (currentSliceIndex + extent[currentDimension*2]); origin[currentDimension] += sliceDistanceAlongAxis; this->Internal->GrabOffset = touchWorldPosition.cast<double>() - origin; } else { this->Internal->SelectedImageDimension = -1; this->interactionOff(); } return this->interactionIsActive(); }