From 26f9347874f5d6baafa0a3e7221391fc1075191c Mon Sep 17 00:00:00 2001 From: pkv Date: Thu, 20 Oct 2005 06:22:11 +0000 Subject: [PATCH] fix for Bug GVIEW10293 --- src/PIPELINE/VISU_ImplicitFunctionWidget.cxx | 729 +++++++++++-------- src/PIPELINE/VISU_ImplicitFunctionWidget.h | 88 +-- 2 files changed, 456 insertions(+), 361 deletions(-) diff --git a/src/PIPELINE/VISU_ImplicitFunctionWidget.cxx b/src/PIPELINE/VISU_ImplicitFunctionWidget.cxx index 2ac6af1d..844371c9 100644 --- a/src/PIPELINE/VISU_ImplicitFunctionWidget.cxx +++ b/src/PIPELINE/VISU_ImplicitFunctionWidget.cxx @@ -168,6 +168,14 @@ static float DistanceToPlane(const float x[3], const float n[3], const float p0[3]); +static void GetBndPoints(vtkDataSet *pDataSet, + float aPnts[24]); + +static + bool IsValidPlane2Position(vtkPlane *pPx, + vtkDataSet *pDataSet, + float aTol=0.003); + vtkCxxRevisionMacro(VISU_ImplicitFunctionWidget, "$Revision$"); vtkStandardNewMacro(VISU_ImplicitFunctionWidget); @@ -193,9 +201,9 @@ VISU_ImplicitFunctionWidget::VISU_ImplicitFunctionWidget() // Build the representation of the widget // - Plane = vtkPlane::New(); - Plane->SetNormal(0,0,1); - Plane->SetOrigin(0,0,0); + myPlane1 = vtkPlane::New(); + myPlane1->SetNormal(0,0,1); + myPlane1->SetOrigin(0,0,0); // myDistance = 10.; myPlane2 = vtkPlane::New(); @@ -205,43 +213,53 @@ VISU_ImplicitFunctionWidget::VISU_ImplicitFunctionWidget() myImplicitFunction = vtkImplicitBoolean::New(); myImplicitFunction->SetOperationType(VTK_UNION); // - Box = vtkImageData::New(); - Box->SetDimensions(2,2,2); - Outline = vtkOutlineFilter::New(); - Outline->SetInput(Box); - OutlineMapper = vtkPolyDataMapper::New(); - OutlineMapper->SetInput(Outline->GetOutput()); - OutlineActor = vtkActor::New(); - this->OutlineActor->SetMapper(this->OutlineMapper); - this->OutlineActor->PickableOff(); + myBox = vtkImageData::New(); + myBox->SetDimensions(2,2,2); + myOutline = vtkOutlineFilter::New(); + myOutline->SetInput(myBox); + myOutlineMapper = vtkPolyDataMapper::New(); + myOutlineMapper->SetInput(myOutline->GetOutput()); + myOutlineActor = vtkActor::New(); + this->myOutlineActor->SetMapper(this->myOutlineMapper); + this->myOutlineActor->PickableOff(); this->OutlineTranslation = 0; - this->Cutter = vtkCutter::New(); - this->Cutter->SetInput(this->Box); - this->Cutter->SetCutFunction(this->Plane); - this->CutMapper = vtkPolyDataMapper::New(); - this->CutMapper->SetInput(this->Cutter->GetOutput()); - this->CutActor = vtkActor::New(); - this->CutActor->SetMapper(this->CutMapper); - this->DrawPlane = 1; + this->myCutter1 = vtkCutter::New(); + this->myCutter1->SetInput(myBox); + this->myCutter1->SetCutFunction(myPlane1); + this->myCutMapper1 = vtkPolyDataMapper::New(); + this->myCutMapper1->SetInput(this->myCutter1->GetOutput()); + this->myCutActor1 = vtkActor::New(); + this->myCutActor1->SetMapper(this->myCutMapper1); + this->myDrawPlane = 1; + + this->myEdges1 = vtkFeatureEdges::New(); + myEdges1->SetColoring(0); + this->myEdges1->SetInput(this->myCutter1->GetOutput()); + this->myEdgesMapper1 = vtkPolyDataMapper::New(); + this->myEdgesMapper1->SetInput(this->myEdges1->GetOutput()); + this->myEdgesActor1 = vtkActor::New(); + this->myEdgesActor1->SetMapper(this->myEdgesMapper1); + myEdgesActor1->GetProperty()->SetLineWidth(4.); + myEdgesActor1->GetProperty()->SetColor(0., .5, .7); this->myCutter2 = vtkCutter::New(); - this->myCutter2->SetInput(this->Box); + this->myCutter2->SetInput(myBox); this->myCutter2->SetCutFunction(this->myPlane2); this->myCutMapper2 = vtkPolyDataMapper::New(); this->myCutMapper2->SetInput(this->myCutter2->GetOutput()); this->myCutActor2 = vtkActor::New(); this->myCutActor2->SetMapper(this->myCutMapper2); - this->Edges = vtkFeatureEdges::New(); - Edges->SetColoring(0); - this->Edges->SetInput(this->Cutter->GetOutput()); - this->EdgesMapper = vtkPolyDataMapper::New(); - this->EdgesMapper->SetInput(this->Edges->GetOutput()); - this->EdgesActor = vtkActor::New(); - this->EdgesActor->SetMapper(this->EdgesMapper); - EdgesActor->GetProperty()->SetLineWidth(4.); - EdgesActor->GetProperty()->SetColor(0., .5, .7); + myEdges2 = vtkFeatureEdges::New(); + myEdges2->SetColoring(0); + myEdges2->SetInput(myCutter2->GetOutput()); + myEdgesMapper2 = vtkPolyDataMapper::New(); + myEdgesMapper2->SetInput(myEdges2->GetOutput()); + myEdgesActor2 = vtkActor::New(); + myEdgesActor2->SetMapper(myEdgesMapper2); + myEdgesActor2->GetProperty()->SetLineWidth(4.); + myEdgesActor2->GetProperty()->SetColor(.7, .0, .0); // Create the + plane normal this->LineSource = vtkLineSource::New(); @@ -307,14 +325,14 @@ VISU_ImplicitFunctionWidget::VISU_ImplicitFunctionWidget() //Manage the picking stuff this->Picker = vtkCellPicker::New(); this->Picker->SetTolerance(0.005); - this->Picker->AddPickList(this->CutActor); + this->Picker->AddPickList(this->myCutActor1); this->Picker->AddPickList(this->myCutActor2); this->Picker->AddPickList(this->LineActor); this->Picker->AddPickList(this->ConeActor); this->Picker->AddPickList(this->LineActor2); this->Picker->AddPickList(this->ConeActor2); this->Picker->AddPickList(this->SphereActor); - this->Picker->AddPickList(this->OutlineActor); + this->Picker->AddPickList(this->myOutlineActor); this->Picker->PickFromListOn(); // Set up the initial properties @@ -327,27 +345,31 @@ VISU_ImplicitFunctionWidget::VISU_ImplicitFunctionWidget() //================================================================== VISU_ImplicitFunctionWidget::~VISU_ImplicitFunctionWidget() { - this->Plane->Delete(); + myPlane1->Delete(); this->myPlane2->Delete(); this->myImplicitFunction->Delete(); - this->Box->Delete(); - this->Outline->Delete(); - this->OutlineMapper->Delete(); - this->OutlineActor->Delete(); + myBox->Delete(); + this->myOutline->Delete(); + this->myOutlineMapper->Delete(); + this->myOutlineActor->Delete(); - this->Cutter->Delete(); - this->CutMapper->Delete(); - this->CutActor->Delete(); + this->myCutter1->Delete(); + this->myCutMapper1->Delete(); + this->myCutActor1->Delete(); + this->myEdges1->Delete(); + this->myEdgesMapper1->Delete(); + this->myEdgesActor1->Delete(); + myCutter2->Delete(); myCutMapper2->Delete(); myCutActor2->Delete(); - - this->Edges->Delete(); - this->EdgesMapper->Delete(); - this->EdgesActor->Delete(); + + myEdges2->Delete(); + myEdgesMapper2->Delete(); + myEdgesActor2->Delete(); this->LineSource->Delete(); this->LineMapper->Delete(); @@ -401,8 +423,8 @@ void VISU_ImplicitFunctionWidget::SetDistance(const float theDistance) myDistance=theDistance; // float *origin, *normal, oNew[3], aN2[3]; - origin = Plane->GetOrigin(); - normal = Plane->GetNormal(); + origin = myPlane1->GetOrigin(); + normal = myPlane1->GetNormal(); vtkMath::Normalize(normal); oNew[0] = origin[0] + myDistance*normal[0]; oNew[1] = origin[1] + myDistance*normal[1]; @@ -451,46 +473,51 @@ void VISU_ImplicitFunctionWidget::SetEnabled(int enabling) vtkCamera *pCamera=CurrentRenderer->GetActiveCamera(); pCamera->SetParallelProjection(1); // - this->myImplicitFunction->AddFunction(this->Plane); + this->myImplicitFunction->AddFunction(myPlane1); this->myImplicitFunction->AddFunction(this->myPlane2); this->Enabled = 1; // listen for the following events vtkRenderWindowInteractor *i = this->Interactor; - if( this->HandleMoveEvent ) - { - i->AddObserver(vtkCommand::MouseMoveEvent, this->EventCallbackCommand, + if( this->HandleMoveEvent ) { + i->AddObserver(vtkCommand::MouseMoveEvent, + this->EventCallbackCommand, this->Priority); } - if( this->HandleLeftButtonEvent ) - { + if( this->HandleLeftButtonEvent ) { i->AddObserver(vtkCommand::LeftButtonPressEvent, - this->EventCallbackCommand, this->Priority); + this->EventCallbackCommand, + this->Priority); i->AddObserver(vtkCommand::LeftButtonReleaseEvent, - this->EventCallbackCommand, this->Priority); + this->EventCallbackCommand, + this->Priority); } - if( this->HandleMiddleButtonEvent ) - { + if( this->HandleMiddleButtonEvent ) { i->AddObserver(vtkCommand::MiddleButtonPressEvent, - this->EventCallbackCommand, this->Priority); + this->EventCallbackCommand, + this->Priority); i->AddObserver(vtkCommand::MiddleButtonReleaseEvent, - this->EventCallbackCommand, this->Priority); + this->EventCallbackCommand, + this->Priority); } - if( this->HandleRightButtonEvent ) - { + if( this->HandleRightButtonEvent ) { i->AddObserver(vtkCommand::RightButtonPressEvent, - this->EventCallbackCommand, this->Priority); + this->EventCallbackCommand, + this->Priority); i->AddObserver(vtkCommand::RightButtonReleaseEvent, - this->EventCallbackCommand, this->Priority); + this->EventCallbackCommand, + this->Priority); } // add the outline - this->CurrentRenderer->AddActor(this->OutlineActor); - this->OutlineActor->SetProperty(this->OutlineProperty); + this->CurrentRenderer->AddActor(this->myOutlineActor); + this->myOutlineActor->SetProperty(this->OutlineProperty); // add the edges - this->CurrentRenderer->AddActor(this->EdgesActor); - this->OutlineActor->SetProperty(this->EdgesProperty); + this->CurrentRenderer->AddActor(this->myEdgesActor1); + this->CurrentRenderer->AddActor(myEdgesActor2); + + this->myOutlineActor->SetProperty(this->EdgesProperty); // add the normal vector this->CurrentRenderer->AddActor(this->LineActor); @@ -508,18 +535,17 @@ void VISU_ImplicitFunctionWidget::SetEnabled(int enabling) this->SphereActor->SetProperty(this->NormalProperty); // add the plane (if desired) - if ( this->DrawPlane ) - { - this->CurrentRenderer->AddActor(this->CutActor); + if ( this->myDrawPlane ) { + this->CurrentRenderer->AddActor(this->myCutActor1); this->CurrentRenderer->AddActor(this->myCutActor2); - } - this->CutActor->SetProperty(this->PlaneProperty); + } + this->myCutActor1->SetProperty(this->PlaneProperty); myCutActor2->SetProperty(this->PlaneProperty); - + this->UpdateRepresentation(); this->SizeHandles(); this->InvokeEvent(vtkCommand::EnableEvent,NULL); - } + } else {//disabling---------------------------------------------------------- vtkDebugMacro(<<"Disabling plane widget"); @@ -539,14 +565,15 @@ void VISU_ImplicitFunctionWidget::SetEnabled(int enabling) this->Interactor->RemoveObserver(this->EventCallbackCommand); // turn off the various actors - this->CurrentRenderer->RemoveActor(this->OutlineActor); - this->CurrentRenderer->RemoveActor(this->EdgesActor); + this->CurrentRenderer->RemoveActor(this->myOutlineActor); + this->CurrentRenderer->RemoveActor(this->myEdgesActor1); + this->CurrentRenderer->RemoveActor(myEdgesActor2); this->CurrentRenderer->RemoveActor(this->LineActor); this->CurrentRenderer->RemoveActor(this->ConeActor); this->CurrentRenderer->RemoveActor(this->LineActor2); this->CurrentRenderer->RemoveActor(this->ConeActor2); this->CurrentRenderer->RemoveActor(this->SphereActor); - this->CurrentRenderer->RemoveActor(this->CutActor); + this->CurrentRenderer->RemoveActor(this->myCutActor1); this->CurrentRenderer->RemoveActor(myCutActor2); this->InvokeEvent(vtkCommand::DisableEvent,NULL); @@ -555,15 +582,14 @@ void VISU_ImplicitFunctionWidget::SetEnabled(int enabling) this->Interactor->Render(); } - -int -VISU_ImplicitFunctionWidget -::IsEnabled() +//================================================================== +// function: IsEnabled +// purpose : +//================================================================== +int VISU_ImplicitFunctionWidget::IsEnabled() { return this->Enabled; } - - //================================================================== // function: ProcessEvents // purpose : @@ -600,6 +626,8 @@ void VISU_ImplicitFunctionWidget::ProcessEvents(vtkObject* vtkNotUsed(object), case vtkCommand::MouseMoveEvent: self->OnMouseMove(); break; + default: + break; } } //================================================================== @@ -624,7 +652,6 @@ void VISU_ImplicitFunctionWidget::HighlightNormal(int highlight) this->SphereActor->SetProperty(this->NormalProperty); } } - //================================================================== // function: HighlightPlane // purpose : @@ -632,11 +659,11 @@ void VISU_ImplicitFunctionWidget::HighlightNormal(int highlight) void VISU_ImplicitFunctionWidget::HighlightPlane(int highlight) { if ( highlight ) { - this->CutActor->SetProperty(this->SelectedPlaneProperty); + this->myCutActor1->SetProperty(this->SelectedPlaneProperty); myCutActor2->SetProperty(this->SelectedPlaneProperty); } else { - this->CutActor->SetProperty(this->PlaneProperty); + this->myCutActor1->SetProperty(this->PlaneProperty); myCutActor2->SetProperty(this->PlaneProperty); } } @@ -646,11 +673,11 @@ void VISU_ImplicitFunctionWidget::HighlightPlane(int highlight) //================================================================== void VISU_ImplicitFunctionWidget::HighlightOutline(int highlight) { - if ( highlight ) { - this->OutlineActor->SetProperty(this->SelectedOutlineProperty); + if (highlight) { + this->myOutlineActor->SetProperty(this->SelectedOutlineProperty); } else { - this->OutlineActor->SetProperty(this->OutlineProperty); + this->myOutlineActor->SetProperty(this->OutlineProperty); } } //================================================================== @@ -693,7 +720,7 @@ void VISU_ImplicitFunctionWidget::OnLeftButtonDown() this->HighlightNormal(1); this->State = VISU_ImplicitFunctionWidget::Rotating; } - else if ( prop == this->CutActor) { + else if ( prop == this->myCutActor1) { this->HighlightPlane(1); this->State = VISU_ImplicitFunctionWidget::Pushing; } @@ -896,26 +923,33 @@ void VISU_ImplicitFunctionWidget::OnMouseMove() // Process the motion if ( this->State == VISU_ImplicitFunctionWidget::MovingPlane ) { - this->TranslatePlane(prevPickPoint, pickPoint); + //this->TranslatePlane(prevPickPoint, pickPoint); + //printf(" TranslatePlane\n"); } else if ( this->State == VISU_ImplicitFunctionWidget::MovingOutline ) { - this->TranslateOutline(prevPickPoint, pickPoint); + //this->TranslateOutline(prevPickPoint, pickPoint); + //printf(" TranslateOutline\n"); } else if ( this->State == VISU_ImplicitFunctionWidget::MovingOrigin ) { this->TranslateOrigin(prevPickPoint, pickPoint); + //printf(" TranslateOrigin\n"); } else if ( this->State == VISU_ImplicitFunctionWidget::Pushing ) { this->Push(prevPickPoint, pickPoint); + // printf(" Push\n"); } else if ( this->State == VISU_ImplicitFunctionWidget::Scaling ) { - this->Scale(prevPickPoint, pickPoint, X, Y); + //this->Scale(prevPickPoint, pickPoint, X, Y); + //printf(" Scale\n"); } else if ( this->State == VISU_ImplicitFunctionWidget::Rotating ) { camera->GetViewPlaneNormal(vpn); this->Rotate(X, Y, prevPickPoint, pickPoint, vpn); + //printf(" Rotate\n"); } else if ( this->State == VISU_ImplicitFunctionWidget::ChangeDistance ) { this->PushDistance(prevPickPoint, pickPoint); + //printf(" PushDistance\n"); } // Interact, if desired this->EventCallbackCommand->SetAbortFlag(1); @@ -924,22 +958,121 @@ void VISU_ImplicitFunctionWidget::OnMouseMove() this->Interactor->Render(); } //================================================================== +// function: Push +// purpose : +//================================================================== +void VISU_ImplicitFunctionWidget::Push(double *p1, double *p2) +{ + //Get the motion vector + int i; + float v[3]; + // + for (i=0; i<3; ++i){ + v[i] = p2[i] - p1[i]; + } + // + float aOr1[3], aNr1[3], aNr2[3], aD, z1; + // + myPlane1->GetOrigin(aOr1); + myPlane1->GetNormal(aNr1); + myPlane2->GetNormal(aNr2); + // + aD=vtkMath::Dot(v, aNr2); + z1 = aOr1[2]+aD*aNr2[2]; + if( z1 <= myBox->GetOrigin()[2] ){ + return; + } + // + aD=vtkMath::Dot(v, aNr1); + for (i=0; i < 3; ++i) { + aOr1[i]=aOr1[i]+aD*aNr1[i]; + } + SetOriginInternal(aOr1); + this->UpdateRepresentation(); +} +//================================================================== +// function: TranslateOrigin +// purpose : +//================================================================== +void VISU_ImplicitFunctionWidget::TranslateOrigin(double *p1, double *p2) +{ + //Get the motion vector + int i; + double v[3]; + // + for (i=0; i<3; ++i){ + v[i] = p2[i] - p1[i]; + } + // + //Add to the current point, project back down onto plane + float *o = myPlane1->GetOrigin(); + float *n = myPlane1->GetNormal(); + float newOrigin[3]; + // + for (i=0; i<3; ++i){ + newOrigin[i]=o[i] + v[i]; + } + vtkPlane::ProjectPoint(newOrigin, o, n, newOrigin); + SetOriginInternal(newOrigin); + this->UpdateRepresentation(); +} +//================================================================== +// function: SetOriginInternal +// purpose : Set the origin of the plane.(for Internal calls) +//================================================================== +void VISU_ImplicitFunctionWidget::SetOriginInternal(float x[3]) +{ + float *bounds = this->myOutline->GetOutput()->GetBounds(); + int i, j; + for (i=0; i<3; ++i) { + j=2*i; + if ( x[i] < bounds[j] ) { + x[i] = bounds[j]; + } + else if ( x[i] > bounds[j+1] ) { + x[i] = bounds[j+1]; + } + } + // + bool bFlag; + float aOr2[3], aNr2[3], aNr1[3]; + vtkPlane *pPx; + // + myPlane1->GetNormal(aNr1); + myPlane2->GetNormal(aNr2); + for (i=0; i<3; ++i) { + aOr2[i]=x[i]+myDistance*aNr1[i]; + } + pPx=vtkPlane::New(); + pPx->SetOrigin(aOr2); + pPx->SetNormal(aNr2); + bFlag=IsValidPlane2Position(pPx, myBox); + if (bFlag){ + myPlane1->SetOrigin(x); + myPlane2->SetOrigin(aOr2); + } + pPx->Delete(); +} +//================================================================== // function: Rotate // purpose : //================================================================== -void VISU_ImplicitFunctionWidget::Rotate(int X, int Y, double *p1, double *p2, double *vpn) +void VISU_ImplicitFunctionWidget::Rotate(int X, int Y, + double *p1, double *p2, + double *vpn) { - double v[3]; //vector of motion + double v[3]; //vector of motion double axis[3]; //axis of rotation - double theta; //rotation angle + double theta; //rotation angle + int i; // mouse motion vector in world space - v[0] = p2[0] - p1[0]; - v[1] = p2[1] - p1[1]; - v[2] = p2[2] - p1[2]; - - float *origin = this->Plane->GetOrigin(); - float *normal = this->Plane->GetNormal(); + for (i=0; i<3; ++i){ + v[i] = p2[i] - p1[i]; + } + // + float *origin = myPlane1->GetOrigin(); + float *normal = myPlane1->GetNormal(); // Create axis of rotation and angle of rotation vtkMath::Cross(vpn,v,axis); @@ -961,23 +1094,84 @@ void VISU_ImplicitFunctionWidget::Rotate(int X, int Y, double *p1, double *p2, d this->Transform->Translate(-origin[0],-origin[1],-origin[2]); //Set the new normal - float nNew[3], aN2[3]; + float nNew[3], aN2[3], oNew[3]; this->Transform->TransformNormal(normal,nNew); - this->Plane->SetNormal(nNew); - - aN2[0] = -nNew[0]; - aN2[1] = -nNew[1]; - aN2[2] = -nNew[2]; - this->myPlane2->SetNormal(aN2); - float oNew[3]; + // + for (i=0; i<3; ++i){ + aN2[i] = -nNew[i]; + } vtkMath::Normalize(nNew); - oNew[0] = origin[0] + myDistance*nNew[0]; - oNew[1] = origin[1] + myDistance*nNew[1]; - oNew[2] = origin[2] + myDistance*nNew[2]; - this->myPlane2->SetOrigin(oNew); - + for (i=0; i<3; ++i){ + oNew[i] = origin[i] + myDistance*nNew[i]; + } + // + vtkPlane *pPx=vtkPlane::New(); + pPx->SetNormal(aN2); + pPx->SetOrigin(oNew); + // + bool bFlag=IsValidPlane2Position(pPx, myBox); + if (bFlag) { + myPlane1->SetNormal(nNew); + this->myPlane2->SetNormal(aN2); + this->myPlane2->SetOrigin(oNew); + } + pPx->Delete(); this->UpdateRepresentation(); } +//================================================================== +// function: PushDistance +// purpose : +//================================================================== +void VISU_ImplicitFunctionWidget::PushDistance(double *p1, double *p2) +{ + int i; + float v[3], *anOrigin1, *aN1, *anOrigin2, *aN2, aD; + //Get the motion vector + for (i=0; i<3; ++i){ + v[i] = p2[i] - p1[i]; + } + // + anOrigin1 = myPlane1->GetOrigin(); + aN1 = myPlane1->GetNormal(); + anOrigin2 = myPlane2->GetOrigin(); + aN2 = myPlane2->GetNormal(); + + vtkMath::Normalize(aN1); + + float origin[3]; + double distance = vtkMath::Dot( v, aN2 ); + for(i=0; i<3; ++i) { + origin[i] = anOrigin2[i] + distance * aN2[i]; + } + float d = DistanceToPlane(origin, aN1, anOrigin1); + if( d <= 0.0 ) + return; + // + bool bFlag; + float aOr2[3], aNr2[3]; + vtkPlane *pPx; + // + myPlane2->GetOrigin(aOr2); + myPlane2->GetNormal(aNr2); + pPx=vtkPlane::New(); + pPx->SetNormal(aNr2); + aD=vtkMath::Dot(v, aNr2); + for (i=0; i < 3; ++i) { + aOr2[i]=aOr2[i]+aD*aNr2[i]; + } + pPx->SetOrigin(aOr2); + bFlag=IsValidPlane2Position(pPx, myBox); + if(bFlag) { + myPlane2->SetOrigin(aOr2); + myPlane2->Modified(); + aD=DistanceToPlane(aOr2, aN1, anOrigin1); + // + myDistance=aD; + } + pPx->Delete(); + this->UpdateRepresentation(); +} + //================================================================== // function: TranslatePlane // purpose : Loop through all points and translate them @@ -992,11 +1186,11 @@ void VISU_ImplicitFunctionWidget::TranslatePlane(double *p1, double *p2) //Translate the plane float oNew[3]; - float *origin = this->Plane->GetOrigin(); + float *origin = myPlane1->GetOrigin(); oNew[0] = origin[0] + v[0]; oNew[1] = origin[1] + v[1]; oNew[2] = origin[2] + v[2]; - this->Plane->SetOrigin(oNew); + myPlane1->SetOrigin(oNew); origin = this->myPlane2->GetOrigin(); oNew[0] = origin[0] + v[0]; @@ -1019,19 +1213,19 @@ void VISU_ImplicitFunctionWidget::TranslateOutline(double *p1, double *p2) v[2] = p2[2] - p1[2]; //Translate the bounding box - float *origin = this->Box->GetOrigin(); + float *origin = myBox->GetOrigin(); float oNew[3]; oNew[0] = origin[0] + v[0]; oNew[1] = origin[1] + v[1]; oNew[2] = origin[2] + v[2]; - this->Box->SetOrigin(oNew); + myBox->SetOrigin(oNew); //Translate the plane - origin = this->Plane->GetOrigin(); + origin = myPlane1->GetOrigin(); oNew[0] = origin[0] + v[0]; oNew[1] = origin[1] + v[1]; oNew[2] = origin[2] + v[2]; - this->Plane->SetOrigin(oNew); + myPlane1->SetOrigin(oNew); origin = this->myPlane2->GetOrigin(); oNew[0] = origin[0] + v[0]; @@ -1041,31 +1235,7 @@ void VISU_ImplicitFunctionWidget::TranslateOutline(double *p1, double *p2) this->UpdateRepresentation(); } -//================================================================== -// function: TranslateOrigin -// purpose :Loop through all points and translate them -//================================================================== -void VISU_ImplicitFunctionWidget::TranslateOrigin(double *p1, double *p2) -{ - //Get the motion vector - double v[3]; - v[0] = p2[0] - p1[0]; - v[1] = p2[1] - p1[1]; - v[2] = p2[2] - p1[2]; - - //Add to the current point, project back down onto plane - float *o = this->Plane->GetOrigin(); - float *n = this->Plane->GetNormal(); - float newOrigin[3]; - newOrigin[0] = o[0] + v[0]; - newOrigin[1] = o[1] + v[1]; - newOrigin[2] = o[2] + v[2]; - - vtkPlane::ProjectPoint(newOrigin,o,n,newOrigin); - this->SetOrigin(newOrigin); - this->UpdateRepresentation(); -} //================================================================== // function: Scale // purpose : @@ -1080,10 +1250,10 @@ void VISU_ImplicitFunctionWidget::Scale(double *p1, double *p2, v[2] = p2[2] - p1[2]; //int res = this->PlaneSource->GetXResolution(); - float *o = this->Plane->GetOrigin(); + float *o = myPlane1->GetOrigin(); // Compute the scale factor - float sf = vtkMath::Norm(v) / this->Outline->GetOutput()->GetLength(); + float sf = vtkMath::Norm(v) / this->myOutline->GetOutput()->GetLength(); if ( Y > this->Interactor->GetLastEventPosition()[1] ) { sf = 1.0 + sf; } @@ -1096,8 +1266,8 @@ void VISU_ImplicitFunctionWidget::Scale(double *p1, double *p2, this->Transform->Scale(sf,sf,sf); this->Transform->Translate(-o[0],-o[1],-o[2]); - float *origin = this->Box->GetOrigin(); - float *spacing = this->Box->GetSpacing(); + float *origin = myBox->GetOrigin(); + float *spacing = myBox->GetSpacing(); float oNew[3], p[3], pNew[3]; p[0] = origin[0] + spacing[0]; p[1] = origin[1] + spacing[1]; @@ -1106,71 +1276,13 @@ void VISU_ImplicitFunctionWidget::Scale(double *p1, double *p2, this->Transform->TransformPoint(origin,oNew); this->Transform->TransformPoint(p,pNew); - this->Box->SetOrigin(oNew); - this->Box->SetSpacing( (pNew[0]-oNew[0]), (pNew[1]-oNew[1]), (pNew[2]-oNew[2]) ); + myBox->SetOrigin(oNew); + myBox->SetSpacing( (pNew[0]-oNew[0]), (pNew[1]-oNew[1]), (pNew[2]-oNew[2]) ); this->UpdateRepresentation(); } -//================================================================== -// function: Push -// purpose : -//================================================================== -void VISU_ImplicitFunctionWidget::Push(double *p1, double *p2) -{ - //Get the motion vector - float v[3]; - v[0] = p2[0] - p1[0]; - v[1] = p2[1] - p1[1]; - v[2] = p2[2] - p1[2]; - - float z0 = this->Plane->GetOrigin()[2]; - double distance = vtkMath::Dot( v, myPlane2->GetNormal() ); - float z1 = z0 + distance * myPlane2->GetNormal()[2]; - if( z1 <= this->Box->GetOrigin()[2] ) - return; - - this->Plane->Push( vtkMath::Dot(v,this->Plane->GetNormal()) ); - this->SetOrigin(this->Plane->GetOrigin()); - myPlane2->Push( vtkMath::Dot(v,this->Plane->GetNormal()) ); - this->UpdateRepresentation(); -} -//================================================================== -// function: PushDistance -// purpose : -//================================================================== -void VISU_ImplicitFunctionWidget::PushDistance(double *p1, double *p2) -{ - float v[3], *anOrigin1, *aN1, *anOrigin2, *aN2, aD; - //Get the motion vector - v[0] = p2[0] - p1[0]; - v[1] = p2[1] - p1[1]; - v[2] = p2[2] - p1[2]; - // - anOrigin1 = Plane->GetOrigin(); - aN1 = Plane->GetNormal(); - anOrigin2 = myPlane2->GetOrigin(); - aN2 = myPlane2->GetNormal(); - - vtkMath::Normalize(aN1); - float* origin = new float[3]; - double distance = vtkMath::Dot( v, aN2 ); - for( int i = 0; i < 3; i++ ) - origin[i] = anOrigin2[i] + distance * aN2[i]; - float d = DistanceToPlane(origin, aN1, anOrigin1); - delete [] origin; - - if( d <= 0.0 ) - return; - - myPlane2->Push( vtkMath::Dot(v, myPlane2->GetNormal())); - aD=DistanceToPlane(anOrigin2, aN1, anOrigin1); - // - myDistance=aD; - // - this->UpdateRepresentation(); -} //================================================================== // function: CreateDefaultProperties @@ -1243,25 +1355,25 @@ void VISU_ImplicitFunctionWidget::PlaceWidget(float bds[6]) this->AdjustBounds(bds, bounds, origin); // Set up the bounding box - this->Box->SetOrigin(bounds[0],bounds[2],bounds[4]); - this->Box->SetSpacing((bounds[1]-bounds[0]),(bounds[3]-bounds[2]), + myBox->SetOrigin(bounds[0],bounds[2],bounds[4]); + myBox->SetSpacing((bounds[1]-bounds[0]),(bounds[3]-bounds[2]), (bounds[5]-bounds[4])); - this->Outline->Update(); + this->myOutline->Update(); if (this->Input || this->Prop3D) { - this->LineSource->SetPoint1(this->Plane->GetOrigin()); + this->LineSource->SetPoint1(myPlane1->GetOrigin()); if ( this->NormalToYAxis ) { - this->Plane->SetNormal(0,1,0); + myPlane1->SetNormal(0,1,0); myPlane2->SetNormal(0,-1,0); this->LineSource->SetPoint2(0,1,0); } else if ( this->NormalToZAxis ) { - this->Plane->SetNormal(0,0,1); + myPlane1->SetNormal(0,0,1); myPlane2->SetNormal(0,0,-1); this->LineSource->SetPoint2(0,0,1); } else{ //default or x-normal - this->Plane->SetNormal(1,0,0); + myPlane1->SetNormal(1,0,0); myPlane2->SetNormal(-1,0,0); this->LineSource->SetPoint2(1,0,0); } @@ -1279,7 +1391,7 @@ void VISU_ImplicitFunctionWidget::PlaceWidget(float bds[6]) } //================================================================== // function: SetOrigin -// purpose :Set the origin of the plane. +// purpose :Set the origin of the plane.(for external calls) //================================================================== void VISU_ImplicitFunctionWidget::SetOrigin(float x, float y, float z) { @@ -1290,12 +1402,12 @@ void VISU_ImplicitFunctionWidget::SetOrigin(float x, float y, float z) this->SetOrigin(origin); } //================================================================== -// function: SetOrigin -// purpose :Set the origin of the plane. +// function: SetOrigin +// purpose : Set the origin of the plane.(for external calls) //================================================================== -void VISU_ImplicitFunctionWidget::SetOrigin(float x[3]) +void VISU_ImplicitFunctionWidget::SetOrigin(float x[3]) { - float *bounds = this->Outline->GetOutput()->GetBounds(); + float *bounds = this->myOutline->GetOutput()->GetBounds(); for (int i=0; i<3; i++) { if ( x[i] < bounds[2*i] ) { x[i] = bounds[2*i]; @@ -1304,10 +1416,10 @@ void VISU_ImplicitFunctionWidget::SetOrigin(float x[3]) x[i] = bounds[2*i+1]; } } - this->Plane->SetOrigin(x); - float *origin, *normal, oNew[3]; - origin = Plane->GetOrigin(); - normal = Plane->GetNormal(); + myPlane1->SetOrigin(x); + float *origin, *normal, oNew[3]; + origin = myPlane1->GetOrigin(); + normal = myPlane1->GetNormal(); vtkMath::Normalize(normal); oNew[0] = origin[0] + myDistance*normal[0]; oNew[1] = origin[1] + myDistance*normal[1]; @@ -1321,12 +1433,12 @@ void VISU_ImplicitFunctionWidget::SetOrigin(float x[3]) //================================================================== float* VISU_ImplicitFunctionWidget::GetOrigin() { - return this->Plane->GetOrigin(); + return myPlane1->GetOrigin(); } void VISU_ImplicitFunctionWidget::GetOrigin(float xyz[3]) { - this->Plane->GetOrigin(xyz); + myPlane1->GetOrigin(xyz); } //================================================================== // function: SetNormal @@ -1339,7 +1451,7 @@ void VISU_ImplicitFunctionWidget::SetNormal(float x, float y, float z) n[1] = y; n[2] = z; vtkMath::Normalize(n); - this->Plane->SetNormal(n); + myPlane1->SetNormal(n); n[0] =- x; n[1] =- y; n[2] =- z; @@ -1362,7 +1474,7 @@ void VISU_ImplicitFunctionWidget::SetNormal(float n[3]) //================================================================== float* VISU_ImplicitFunctionWidget::GetNormal() { - return this->Plane->GetNormal(); + return myPlane1->GetNormal(); } //================================================================== // function: GetNormal @@ -1370,7 +1482,7 @@ float* VISU_ImplicitFunctionWidget::GetNormal() //================================================================== void VISU_ImplicitFunctionWidget::GetNormal(float xyz[3]) { - this->Plane->GetNormal(xyz); + myPlane1->GetNormal(xyz); } //================================================================== // function: SetDrawPlane @@ -1378,19 +1490,19 @@ void VISU_ImplicitFunctionWidget::GetNormal(float xyz[3]) //================================================================== void VISU_ImplicitFunctionWidget::SetDrawPlane(int drawPlane) { - if ( drawPlane == this->DrawPlane ) { + if ( drawPlane == this->myDrawPlane ) { return; } this->Modified(); - this->DrawPlane = drawPlane; + this->myDrawPlane = drawPlane; if ( this->Enabled ) { if ( drawPlane ) { - this->CurrentRenderer->AddActor(this->CutActor); + this->CurrentRenderer->AddActor(this->myCutActor1); this->CurrentRenderer->AddActor(myCutActor2); } else { - this->CurrentRenderer->RemoveActor(this->CutActor); + this->CurrentRenderer->RemoveActor(this->myCutActor1); this->CurrentRenderer->RemoveActor(myCutActor2); } this->Interactor->Render(); @@ -1447,7 +1559,7 @@ void VISU_ImplicitFunctionWidget::SetNormalToZAxis (int var) //================================================================== void VISU_ImplicitFunctionWidget::GetPolyData(vtkPolyData *pd) { - pd->ShallowCopy(this->Cutter->GetOutput()); + pd->ShallowCopy(this->myCutter1->GetOutput()); } //================================================================== // function: GetPolyDataSource @@ -1455,7 +1567,7 @@ void VISU_ImplicitFunctionWidget::GetPolyData(vtkPolyData *pd) //================================================================== vtkPolyDataSource *VISU_ImplicitFunctionWidget::GetPolyDataSource() { - return this->Cutter; + return this->myCutter1; } //================================================================== // function:GetPlane @@ -1467,8 +1579,8 @@ void VISU_ImplicitFunctionWidget::GetPlane(vtkPlane *plane) return; } - plane->SetNormal(this->Plane->GetNormal()); - plane->SetOrigin(this->Plane->GetOrigin()); + plane->SetNormal(myPlane1->GetNormal()); + plane->SetOrigin(myPlane1->GetOrigin()); } //================================================================== // function:UpdatePlacement @@ -1476,9 +1588,9 @@ void VISU_ImplicitFunctionWidget::GetPlane(vtkPlane *plane) //================================================================== void VISU_ImplicitFunctionWidget::UpdatePlacement(void) { - this->Outline->Update(); - this->Cutter->Update(); - this->Edges->Update(); + this->myOutline->Update(); + this->myCutter1->Update(); + this->myEdges1->Update(); } //================================================================== // function:UpdateRepresentation @@ -1490,12 +1602,12 @@ void VISU_ImplicitFunctionWidget::UpdateRepresentation() return; } - float *origin = this->Plane->GetOrigin(); - float *normal = this->Plane->GetNormal(); + float *origin = myPlane1->GetOrigin(); + float *normal = myPlane1->GetNormal(); float p2[3]; // Setup the plane normal - float d = this->Outline->GetOutput()->GetLength(); + float d = this->myOutline->GetOutput()->GetLength(); p2[0] = origin[0] + 0.30 * d * normal[0]; p2[1] = origin[1] + 0.30 * d * normal[1]; @@ -1521,7 +1633,7 @@ void VISU_ImplicitFunctionWidget::UpdateRepresentation() this->Sphere->SetCenter(origin); SphereActor->SetCenter(origin); - this->EdgesMapper->SetInput(this->Edges->GetOutput()); + this->myEdgesMapper1->SetInput(this->myEdges1->GetOutput()); } //================================================================== // function:SizeHandles @@ -1539,83 +1651,64 @@ void VISU_ImplicitFunctionWidget::SizeHandles() void VISU_ImplicitFunctionWidget::PrintSelf(ostream& os, vtkIndent indent) { this->Superclass::PrintSelf(os,indent); - - if ( this->NormalProperty ) - { - os << indent << "Normal Property: " << this->NormalProperty << "\n"; - } - else - { - os << indent << "Normal Property: (none)\n"; - } - if ( this->SelectedNormalProperty ) - { - os << indent << "Selected Normal Property: " - << this->SelectedNormalProperty << "\n"; - } - else - { - os << indent << "Selected Normal Property: (none)\n"; - } - - if ( this->PlaneProperty ) - { - os << indent << "Plane Property: " << this->PlaneProperty << "\n"; - } - else - { - os << indent << "Plane Property: (none)\n"; - } - if ( this->SelectedPlaneProperty ) - { - os << indent << "Selected Plane Property: " - << this->SelectedPlaneProperty << "\n"; - } - else - { - os << indent << "Selected Plane Property: (none)\n"; - } - - if ( this->OutlineProperty ) - { - os << indent << "Outline Property: " << this->OutlineProperty << "\n"; - } - else - { - os << indent << "Outline Property: (none)\n"; - } - if ( this->SelectedOutlineProperty ) - { - os << indent << "Selected Outline Property: " - << this->SelectedOutlineProperty << "\n"; - } - else - { - os << indent << "Selected Outline Property: (none)\n"; - } - - if ( this->EdgesProperty ) - { - os << indent << "Edges Property: " << this->EdgesProperty << "\n"; - } - else - { - os << indent << "Edges Property: (none)\n"; +} +//================================================================== +// function: IsValidPlane2Position +// purpose : +//================================================================== +bool IsValidPlane2Position(vtkPlane *pPx, + vtkDataSet *pDataSet, + float aTol) +{ + bool bRet; + int i, iFound; + float aD, aDmax, aPnts[24], aDiagonal; + float aTol1, aOr[3], aN[3]; + // + bRet=false; + aDiagonal=pDataSet->GetLength(); + aTol1=aDiagonal*aTol; + // + GetBndPoints(pDataSet, aPnts); + // + pPx->GetOrigin(aOr); + pPx->GetNormal(aN); + vtkMath::Normalize(aN); + // + iFound=0; + aDmax=0.; + for (i=0; i<24; i+=3){ + aD=-DistanceToPlane(aPnts+i, aN, aOr); + if (aD>aDmax){ + aDmax=aD; + iFound=1; } - - os << indent << "Normal To X Axis: " - << (this->NormalToXAxis ? "On" : "Off") << "\n"; - os << indent << "Normal To Y Axis: " - << (this->NormalToYAxis ? "On" : "Off") << "\n"; - os << indent << "Normal To Z Axis: " - << (this->NormalToZAxis ? "On" : "Off") << "\n"; - - os << indent << "Outline Translation: " - << (this->OutlineTranslation ? "On" : "Off") << "\n"; - os << indent << "Draw Plane: " << (this->DrawPlane ? "On" : "Off") << "\n"; + } + if (iFound && aDmax>aTol1) { + bRet=!bRet; + } + return bRet; +} +//================================================================== +// function: GetBndPoints +// purpose : +//================================================================== +void GetBndPoints(vtkDataSet *pDataSet, + float aPnts[24]) +{ + int aIndx[24]={ + 0,2,4,1,2,4,1,3,4,0,3,4, + 0,2,5,1,2,5,1,3,5,0,3,5 + }; + int i; + float *pBounds=pDataSet->GetBounds(); + // + for (i=0; i<24; ++i){ + aPnts[i]=pBounds[aIndx[i]]; + } } //================================================================== -// function:DistanceToPlane +// function: DistanceToPlane // purpose : //================================================================== float DistanceToPlane(const float x[3], diff --git a/src/PIPELINE/VISU_ImplicitFunctionWidget.h b/src/PIPELINE/VISU_ImplicitFunctionWidget.h index 99403779..4930989d 100644 --- a/src/PIPELINE/VISU_ImplicitFunctionWidget.h +++ b/src/PIPELINE/VISU_ImplicitFunctionWidget.h @@ -48,6 +48,7 @@ class vtkTransform; class vtkImplicitBoolean; class vtkImplicitFunction; class VISU_UnScaledActor; +class vtkDataSet; class VISU_ImplicitFunctionWidget : public vtkPolyDataSourceWidget { @@ -114,8 +115,9 @@ public: // plane interferes with the cut surface it produces producing // z-buffer artifacts.) void SetDrawPlane(int plane); - vtkGetMacro(DrawPlane,int); - vtkBooleanMacro(DrawPlane,int); + int GetDrawPlane(){ + return myDrawPlane; + } // Description: // Turn on/off the ability to translate the bounding box by grabbing it @@ -201,72 +203,88 @@ protected: void OnRightButtonDown(); void OnRightButtonUp(); void OnMouseMove(); + // + // Methods to manipulate the plane + void ConstrainOrigin(float x[3]); + void Rotate(int X, int Y, double *p1, double *p2, double *vpn); + void TranslatePlane(double *p1, double *p2); + void TranslateOutline(double *p1, double *p2); + void TranslateOrigin(double *p1, double *p2); + void Push(double *p1, double *p2); + void Scale(double *p1, double *p2, int X, int Y); + void PushDistance(double *p1, double *p2); + + void CreateDefaultProperties(); + + void GeneratePlane(); + virtual void SizeHandles(); + void HighlightPlane(int highlight); + void HighlightNormal(int highlight); + void HighlightOutline(int highlight); + void UpdateRepresentation(); + void SetOriginInternal(float x[3]); // Controlling ivars int NormalToXAxis; int NormalToYAxis; int NormalToZAxis; - void UpdateRepresentation(); + // Flags to handle mouse events bool HandleMoveEvent; bool HandleLeftButtonEvent; bool HandleMiddleButtonEvent; bool HandleRightButtonEvent; - // The actual plane which is being manipulated - vtkPlane *Plane; + vtkPlane *myPlane1; vtkPlane *myPlane2; + float myDistance; vtkImplicitBoolean *myImplicitFunction; + // The bounding box is represented by a single voxel image data - vtkImageData *Box; - vtkOutlineFilter *Outline; - vtkPolyDataMapper *OutlineMapper; - vtkActor *OutlineActor; - void HighlightOutline(int highlight); + vtkImageData *myBox; + vtkOutlineFilter *myOutline; + vtkPolyDataMapper *myOutlineMapper; + vtkActor *myOutlineActor; + int OutlineTranslation; //whether the outline can be moved // The cut plane is produced with a vtkCutter - vtkCutter *Cutter; - vtkPolyDataMapper *CutMapper; - vtkActor *CutActor; + vtkCutter *myCutter1; + vtkPolyDataMapper *myCutMapper1; + vtkActor *myCutActor1; vtkCutter *myCutter2; vtkPolyDataMapper *myCutMapper2; vtkActor *myCutActor2; - - int DrawPlane; - void HighlightPlane(int highlight); - // Optional tubes are represented by extracting boundary edges and tubing - vtkFeatureEdges *Edges; - //vtkTubeFilter *EdgesTuber; - vtkPolyDataMapper *EdgesMapper; - vtkActor *EdgesActor; - //int Tubing; //control whether tubing is on + vtkFeatureEdges *myEdges2; + vtkPolyDataMapper *myEdgesMapper2; + vtkActor *myEdgesActor2; + + int myDrawPlane; + + vtkFeatureEdges *myEdges1; + vtkPolyDataMapper *myEdgesMapper1; + vtkActor *myEdgesActor1; // The + normal cone vtkConeSource *ConeSource; vtkPolyDataMapper *ConeMapper; VISU_UnScaledActor *ConeActor; - void HighlightNormal(int highlight); - // The + normal line vtkLineSource *LineSource; vtkPolyDataMapper *LineMapper; vtkActor *LineActor; - // The - normal cone vtkConeSource *ConeSource2; vtkPolyDataMapper *ConeMapper2; VISU_UnScaledActor *ConeActor2; - // The - normal line vtkLineSource *LineSource2; vtkPolyDataMapper *LineMapper2; vtkActor *LineActor2; - // The origin positioning handle vtkSphereSource *Sphere; vtkPolyDataMapper *SphereMapper; @@ -277,17 +295,6 @@ protected: // Transform the normal (used for rotation) vtkTransform *Transform; - - // Methods to manipulate the plane - void ConstrainOrigin(float x[3]); - void Rotate(int X, int Y, double *p1, double *p2, double *vpn); - void TranslatePlane(double *p1, double *p2); - void TranslateOutline(double *p1, double *p2); - void TranslateOrigin(double *p1, double *p2); - void Push(double *p1, double *p2); - void Scale(double *p1, double *p2, int X, int Y); - void PushDistance(double *p1, double *p2); - // Properties used to control the appearance of selected objects and // the manipulator in general. vtkProperty *NormalProperty; @@ -298,11 +305,6 @@ protected: vtkProperty *SelectedOutlineProperty; vtkProperty *EdgesProperty; - void CreateDefaultProperties(); - - void GeneratePlane(); - virtual void SizeHandles(); - private: VISU_ImplicitFunctionWidget(const VISU_ImplicitFunctionWidget&); //Not implemented void operator=(const VISU_ImplicitFunctionWidget&); //Not implemented -- 2.39.2