Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bend bugs and usability #81

Merged
merged 3 commits into from
Apr 26, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions Planner/Logic/vtkSlicerPlannerLogic.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -812,4 +812,21 @@ vtkVector3d vtkSlicerPlannerLogic::getNormalAtPoint(vtkVector3d point, vtkCellLo
normal.SetZ(n[2]);

return normal;
}

double vtkSlicerPlannerLogic::getDistanceToModel(vtkVector3d point, vtkPolyData* model)
{
vtkNew<vtkCellLocator> locator;
vtkNew<vtkTriangleFilter> triangulate;
triangulate->SetInputData(model);
triangulate->Update();
locator->SetDataSet(triangulate->GetOutput());
locator->BuildLocator();

double closestPoint[3];//the coordinates of the closest point will be returned here
double closestPointDist2; //the squared distance to the closest point will be returned here
vtkIdType cellId; //the cell id of the cell containing the closest point will be returned here
int subId; //this is rarely used (in triangle strips only, I believe)
locator->FindClosestPoint(point.GetData(), closestPoint, cellId, subId, closestPointDist2);
return std::sqrt(closestPointDist2);
}
6 changes: 4 additions & 2 deletions Planner/Logic/vtkSlicerPlannerLogic.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ class VTK_SLICER_PLANNER_MODULE_LOGIC_EXPORT vtkSlicerPlannerLogic :
vtkSmartPointer<vtkPoints> getTargetPoints() { return this->TargetPoints; }
void setBendType(BendModeType type) {this->bendMode = type;}
void setBendSide(BendSide side) { this->bendSide = side; }
double getDistanceToModel(vtkVector3d point, vtkPolyData* model);


protected:
vtkSlicerPlannerLogic();
Expand All @@ -116,9 +118,9 @@ class VTK_SLICER_PLANNER_MODULE_LOGIC_EXPORT vtkSlicerPlannerLogic :
vtkMRMLModelNode* mergeModel(vtkMRMLModelHierarchyNode* HierarchyNode, std::string name);
void generateSourcePoints();
vtkVector3d projectToModel(vtkVector3d point);
vtkVector3d projectToModel(vtkVector3d point, vtkPlane* plane);
vtkVector3d projectToModel(vtkVector3d point, vtkPolyData* model);
vtkVector3d projectToModel(vtkVector3d point, vtkPlane* plane);
vtkVector3d projectToModel(vtkVector3d point, vtkCellLocator* locator);
vtkVector3d projectToModel(vtkVector3d point, vtkPolyData* model);
vtkVector3d getNormalAtPoint(vtkVector3d point, vtkCellLocator* locator, vtkPolyData* model);
vtkSmartPointer<vtkPlane> createPlane(vtkVector3d A, vtkVector3d B, vtkVector3d C, vtkVector3d D);
void createBendingLocator();
Expand Down
153 changes: 82 additions & 71 deletions Planner/qSlicerPlannerModuleWidget.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@
//STD includes
#include <vector>
#include <sstream>
#include <array>

#define D(x) std::cout << x << std::endl;

Expand Down Expand Up @@ -150,9 +151,7 @@ class qSlicerPlannerModuleWidgetPrivate: public Ui_qSlicerPlannerModuleWidget
vtkMRMLCommandLineModuleNode* cmdNode;

//Bending Variables
vtkMRMLMarkupsFiducialNode* MovingPointA;
vtkMRMLMarkupsFiducialNode* MovingPointB;
vtkMRMLMarkupsFiducialNode* PlacingNode;
std::array<vtkMRMLMarkupsFiducialNode*, 2> BendPoints;
vtkMRMLNode* CurrentBendNode;
vtkSmartPointer<vtkPoints> Fiducials;
vtkSmartPointer<vtkPolyData> BendingData;
Expand All @@ -163,10 +162,12 @@ class qSlicerPlannerModuleWidgetPrivate: public Ui_qSlicerPlannerModuleWidget
bool BendDoubleSide;
bool ScalarsVsBrain;
bool BendASide;
vtkMRMLScene* scene;

//Bending methods
void beginPlacement(vtkMRMLScene* scene, int id);
int beginPlacement(vtkMRMLScene* scene, int id);
void endPlacement();
int ActivePoint;
void computeAndSetSourcePoints(vtkMRMLScene* scene);
void computeTransform(vtkMRMLScene* scene);
void clearControlPoints(vtkMRMLScene* scene);
Expand All @@ -187,25 +188,24 @@ class qSlicerPlannerModuleWidgetPrivate: public Ui_qSlicerPlannerModuleWidget
//-----------------------------------------------------------------------------
// qSlicerPlannerModuleWidgetPrivate methods


//-----------------------------------------------------------------------------
//Clear fiducials used for bending
void qSlicerPlannerModuleWidgetPrivate::clearControlPoints(vtkMRMLScene* scene)
{
if(this->MovingPointA)
{
scene->RemoveNode(this->MovingPointA);
this->MovingPointA = NULL;
}
if(this->MovingPointB)
if(this->BendPoints[0])
{
scene->RemoveNode(this->MovingPointB);
this->MovingPointB = NULL;
scene->RemoveNode(this->BendPoints[0]);
this->BendPoints[0] = NULL;
}
if(this->PlacingNode)
if(this->BendPoints[1])
{
scene->RemoveNode(this->PlacingNode);
this->PlacingNode = NULL;
scene->RemoveNode(this->BendPoints[1]);
this->BendPoints[1] = NULL;
}

this->ActivePoint = -1;

}

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -244,16 +244,17 @@ qSlicerPlannerModuleWidgetPrivate::qSlicerPlannerModuleWidgetPrivate()
this->cmdNode = NULL;
this->PreOpSet = false;
this->cliFreeze = false;
this->scene = NULL;

this->BendDoubleSide = true;
this->BendASide = true;
this->ScalarsVsBrain = true;

this->MovingPointA = NULL;
this->MovingPointB = NULL;
this->PlacingNode = NULL;
this->BendPoints[0] = NULL;
this->BendPoints[1] = NULL;
this->Fiducials = NULL;
this->BendMagnitude = 0;
this->ActivePoint = -1;

qSlicerAbstractCoreModule* splitModule =
qSlicerCoreApplication::application()->moduleManager()->module("SplitModel");
Expand All @@ -272,10 +273,34 @@ qSlicerPlannerModuleWidgetPrivate::qSlicerPlannerModuleWidgetPrivate()
//Complete placement of current fiducial
void qSlicerPlannerModuleWidgetPrivate::endPlacement()
{
this->MovingPointAButton->setEnabled(true);
this->MovingPointBButton->setEnabled(true);
this->placingActive = false;
this->PlacingNode = NULL;

//check that point in close to (i.e. on surface of) model to bend
//if not, retrigger placing and give it another go

vtkVector3d point;
double posa[3];
this->BendPoints[this->ActivePoint]->GetNthFiducialPosition(0, posa);
point.SetX(posa[0]);
point.SetY(posa[1]);
point.SetZ(posa[2]);

double dist = this->logic->getDistanceToModel(point, vtkMRMLModelNode::SafeDownCast(this->CurrentBendNode)->GetPolyData());
if (dist > 1.0)
{

this->scene->RemoveNode(this->BendPoints[this->ActivePoint]);
BendPoints[this->ActivePoint] = NULL;
this->beginPlacement(this->scene, this->ActivePoint);

}
else
{
this->MovingPointAButton->setEnabled(true);
this->MovingPointBButton->setEnabled(true);
this->placingActive = false;
this->ActivePoint = -1;
}

}

//-----------------------------------------------------------------------------
Expand All @@ -286,8 +311,8 @@ void qSlicerPlannerModuleWidgetPrivate::computeAndSetSourcePoints(vtkMRMLScene*

double posa[3];
double posb[3];
this->MovingPointA->GetNthFiducialPosition(0, posa);
this->MovingPointB->GetNthFiducialPosition(0, posb);
this->BendPoints[0]->GetNthFiducialPosition(0, posa);
this->BendPoints[1]->GetNthFiducialPosition(0, posb);
this->Fiducials->InsertNextPoint(posa[0], posa[1], posa[2]);
this->Fiducials->InsertNextPoint(posb[0], posb[1], posb[2]);

Expand Down Expand Up @@ -365,54 +390,38 @@ void qSlicerPlannerModuleWidgetPrivate::computeTransform(vtkMRMLScene* scene)
}
//-----------------------------------------------------------------------------
//Initialize placement of a fiducial
void qSlicerPlannerModuleWidgetPrivate::beginPlacement(vtkMRMLScene* scene, int id)
int qSlicerPlannerModuleWidgetPrivate::beginPlacement(vtkMRMLScene* scene, int id)
{

vtkNew<vtkMRMLMarkupsFiducialNode> fiducial;

if(id == 2) //Place fiducial MA
{
if(this->MovingPointA)
{
scene->RemoveNode(this->MovingPointA);
MovingPointA = NULL;
}
this->MovingPointA = fiducial.GetPointer();
this->MovingPointA->SetName("A");
this->PlacingNode = this->MovingPointA;

}

if(id == 3) //Place fiducial MB
if (this->BendPoints[id])
{
if(this->MovingPointB)
{
scene->RemoveNode(this->MovingPointB);
MovingPointB = NULL;
}
this->MovingPointB = fiducial.GetPointer();
this->MovingPointB->SetName("B");
this->PlacingNode = this->MovingPointB;

scene->RemoveNode(this->BendPoints[id]);
BendPoints[id] = NULL;
}

//add new fiducial to scene
scene->AddNode(this->PlacingNode);
this->PlacingNode->CreateDefaultDisplayNodes();
vtkMRMLMarkupsDisplayNode* disp = vtkMRMLMarkupsDisplayNode::SafeDownCast(this->PlacingNode->GetDisplayNode());
this->BendPoints[id] = fiducial.GetPointer();
std::string name = "BendPoint" + std::to_string(id);
this->BendPoints[id]->SetName(name.c_str());
scene->AddNode(this->BendPoints[id]);
this->BendPoints[id]->CreateDefaultDisplayNodes();
vtkMRMLMarkupsDisplayNode* disp = vtkMRMLMarkupsDisplayNode::SafeDownCast(this->BendPoints[id]->GetDisplayNode());
disp->SetTextScale(0.1);
disp->SetGlyphScale(5);
this->placingActive = true;

//activate placing
vtkMRMLInteractionNode* interaction = qSlicerCoreApplication::application()->applicationLogic()->GetInteractionNode();
vtkMRMLSelectionNode* selection = qSlicerCoreApplication::application()->applicationLogic()->GetSelectionNode();
selection->SetReferenceActivePlaceNodeClassName("vtkMRMLMarkupsFiducialNode");
selection->SetActivePlaceNodeID(this->PlacingNode->GetID());
selection->SetActivePlaceNodeID(this->BendPoints[id]->GetID());
interaction->SetCurrentInteractionMode(vtkMRMLInteractionNode::Place);




//deactivate buttons
this->MovingPointAButton->setEnabled(false);
this->MovingPointBButton->setEnabled(false);
this->ActivePoint = id;
return EXIT_SUCCESS;
}

//-----------------------------------------------------------------------------
Expand Down Expand Up @@ -632,21 +641,14 @@ vtkMRMLMarkupsPlanesNode* qSlicerPlannerModuleWidgetPrivate::createPlaneNode(
QString planesName = refNode->GetName();
planesName += "Planner_Planes";
planes->SetName(planesName.toLatin1());

vtkNew<vtkMRMLMarkupsDisplayNode> newDisplay;
vtkMRMLNode* display = scene->AddNode(newDisplay.GetPointer());
planes->SetAndObserveDisplayNodeID(display->GetID());

refNode->SetNodeReferenceID(
this->sceneModel()->planesReferenceRole(), planes->GetID());
/**
vtkMRMLTransformDisplayNode* display2 =
vtkMRMLTransformDisplayNode::SafeDownCast(refNode ?
refNode->GetNodeReference(this->sceneModel()->transformDisplayReferenceRole()) : NULL);
planes->SetNodeReferenceID(
this->sceneModel()->transformDisplayReferenceRole(), display2->GetID());
**/
//planes->SetAndObserveTransformNodeID(display2->GetID());


return planes;
}

Expand Down Expand Up @@ -1174,6 +1176,8 @@ void qSlicerPlannerModuleWidget::setup()
qMRMLPlannerModelHierarchyModel* sceneModel =
new qMRMLPlannerModelHierarchyModel(this);

d->scene = this->mrmlScene();

d->logic = this->plannerLogic();
qSlicerAbstractCoreModule* wrapperModule =
qSlicerCoreApplication::application()->moduleManager()->module("ShrinkWrap");
Expand Down Expand Up @@ -1532,7 +1536,7 @@ void qSlicerPlannerModuleWidget::updateWidgetFromMRML()
d->TemplateReferenceOpacitySliderWidget);

//Bending init button
if(d->MovingPointA && d->MovingPointB && d->CurrentBendNode)
if(d->BendPoints[0] && d->BendPoints[1] && d->CurrentBendNode)
{
d->InitButton->setEnabled(true);
d->BendingInfoLabel->setText("You can move the points after they are placed by clicking and dragging in the"
Expand Down Expand Up @@ -1735,16 +1739,21 @@ void qSlicerPlannerModuleWidget::placeFiducialButtonClicked()
{
Q_D(qSlicerPlannerModuleWidget);
QObject* obj = sender();

int success;
if(obj == d->MovingPointAButton)
{
d->beginPlacement(this->mrmlScene(), 2);
success = d->beginPlacement(this->mrmlScene(), 0);
}
if(obj == d->MovingPointBButton)
{
d->beginPlacement(this->mrmlScene(), 3);
success = d->beginPlacement(this->mrmlScene(), 1);
}
if (success != EXIT_SUCCESS)
{
return;
}

d->scene = this->mrmlScene();
qvtkConnect(qSlicerCoreApplication::application()->applicationLogic()->GetInteractionNode(), vtkMRMLInteractionNode::EndPlacementEvent, this, SLOT(cancelFiducialButtonClicked()));
return;
}
Expand All @@ -1764,6 +1773,7 @@ void qSlicerPlannerModuleWidget::cancelBendButtonClicked()
d->clearBendingData(this->mrmlScene());
d->bendingActive = false;
d->bendingOpen = false;
qvtkDisconnect(qSlicerCoreApplication::application()->applicationLogic()->GetInteractionNode(), vtkMRMLInteractionNode::EndPlacementEvent, this, SLOT(cancelFiducialButtonClicked()));
this->updateWidgetFromMRML();

}
Expand Down Expand Up @@ -1834,14 +1844,15 @@ void qSlicerPlannerModuleWidget::finshBendClicked()
d->clearBendingData(this->mrmlScene());
d->bendingActive = false;
d->bendingOpen = false;
qvtkDisconnect(qSlicerCoreApplication::application()->applicationLogic()->GetInteractionNode(), vtkMRMLInteractionNode::EndPlacementEvent, this, SLOT(cancelFiducialButtonClicked()));
this->updateWidgetFromMRML();
}

//-----------------------------------------------------------------------------
//Cancel placement of current fiducial
void qSlicerPlannerModuleWidget::cancelFiducialButtonClicked()
{
Q_D(qSlicerPlannerModuleWidget);
Q_D(qSlicerPlannerModuleWidget);
d->endPlacement();
this->updateWidgetFromMRML();

Expand Down