//------------------------------------------------------------------------------ void vtkSlicerCollisionWarningLogic::RegisterNodes() { if( ! this->GetMRMLScene() ) { vtkWarningMacro( "MRML scene not yet created" ); return; } this->GetMRMLScene()->RegisterNodeClass( vtkSmartPointer< vtkMRMLCollisionWarningNode >::New() ); }
void vtkOSMesaRenderWindow::MakeCurrent() { TraceBegin("vtkOSMesaRenderWindow::MakeCurrent"); if (this->Internal->OffScreenContextId) { if (OSMesaMakeCurrent(this->Internal->OffScreenContextId, this->Internal->OffScreenWindow, GL_UNSIGNED_BYTE, this->Size[0], this->Size[1]) != GL_TRUE) { vtkWarningMacro("failed call to OSMesaMakeCurrent"); } } TraceEnd("vtkOSMesaRenderWindow::MakeCurrent"); }
void vtkSlicerCollisionWarningLogic::SetSecondModelNode( vtkMRMLModelNode* newModel, vtkMRMLCollisionWarningNode* moduleNode ) { if ( moduleNode == NULL ) { vtkWarningMacro( "SetSecondModelNode: Module node is invalid" ); return; } // Get the original color of the old model node vtkMRMLModelNode* previousModel=moduleNode->GetSecondModelNode(); if (previousModel==newModel) { // no change return; } double previousOriginalColor[3]={0.5,0.5,0.5}; if(previousModel) { moduleNode->GetOriginalColor(previousOriginalColor); } // Save the original color of the new model node if(newModel!=NULL) { double originalColor[3]={0.5,0.5,0.5}; if ( newModel->GetDisplayNode() != NULL ) { newModel->GetDisplayNode()->GetColor(originalColor); } moduleNode->SetOriginalColor(originalColor); } // Switch to the new model node moduleNode->SetAndObserveSecondModelNodeID( (newModel!=NULL) ? newModel->GetID() : NULL ); // Restore the color of the old model node if(previousModel!=NULL && previousModel->GetDisplayNode()!=NULL) { previousModel->GetDisplayNode()->SetColor(previousOriginalColor[0],previousOriginalColor[1],previousOriginalColor[2]); } }
//------------------------------------------------------------------------------ void vtkSlicerCollisionWarningLogic::OnMRMLSceneNodeRemoved( vtkMRMLNode* node ) { if ( node == NULL || this->GetMRMLScene() == NULL ) { vtkWarningMacro( "OnMRMLSceneNodeRemoved: Invalid MRML scene or node" ); return; } if ( node->IsA( "vtkMRMLCollisionWarningNode" ) ) { vtkDebugMacro( "OnMRMLSceneNodeRemoved" ); vtkUnObserveMRMLNodeMacro( node ); for (std::deque< vtkWeakPointer< vtkMRMLCollisionWarningNode > >::iterator it=this->WarningSoundPlayingNodes.begin(); it!=this->WarningSoundPlayingNodes.end(); ++it) { if (it->GetPointer()==node) { this->WarningSoundPlayingNodes.erase(it); break; } } this->SetWarningSoundPlaying(!this->WarningSoundPlayingNodes.empty()); } }
//------------------------------------------------------------------------------ void vtkSlicerCollisionWarningLogic::OnMRMLSceneNodeAdded( vtkMRMLNode* node ) { if ( node == NULL || this->GetMRMLScene() == NULL ) { vtkWarningMacro( "OnMRMLSceneNodeAdded: Invalid MRML scene or node" ); return; } vtkMRMLCollisionWarningNode* bwNode = vtkMRMLCollisionWarningNode::SafeDownCast(node); if ( bwNode ) { vtkDebugMacro( "OnMRMLSceneNodeAdded: Module node added." ); vtkUnObserveMRMLNodeMacro( bwNode ); // Remove previous observers. vtkNew<vtkIntArray> events; events->InsertNextValue( vtkCommand::ModifiedEvent ); events->InsertNextValue( vtkMRMLCollisionWarningNode::InputDataModifiedEvent ); vtkObserveMRMLNodeEventsMacro( bwNode, events.GetPointer() ); if(bwNode->GetPlayWarningSound() && bwNode->IsToolTipInsideModel()) { // Add to list of playing nodes (if not there already) std::deque< vtkWeakPointer< vtkMRMLCollisionWarningNode > >::iterator foundPlayingNodeIt = this->WarningSoundPlayingNodes.begin(); for (; foundPlayingNodeIt!=this->WarningSoundPlayingNodes.end(); ++foundPlayingNodeIt) { if (foundPlayingNodeIt->GetPointer()==bwNode) { // found, current bw node is already in the playing list break; } } if (foundPlayingNodeIt==this->WarningSoundPlayingNodes.end()) { this->WarningSoundPlayingNodes.push_back(bwNode); } this->SetWarningSoundPlaying(true); } } }
void StreamTracer::SetIntegratorType(int type) { vtkInitialValueProblemSolver* ivp=0; switch (type) { case RUNGE_KUTTA2: ivp = vtkRungeKutta2::New(); break; case RUNGE_KUTTA4: ivp = vtkRungeKutta4::New(); break; case RUNGE_KUTTA45: ivp = vtkRungeKutta45::New(); break; default: vtkWarningMacro("Unrecognized integrator type. Keeping old one."); break; } if (ivp) { this->SetIntegrator(ivp); ivp->Delete(); } }
void vtkSlicerCollisionWarningLogic::UpdateToolState( vtkMRMLCollisionWarningNode* bwNode ) { if ( bwNode == NULL ) { return; } vtkMRMLModelNode* modelNode = bwNode->GetWatchedModelNode(); vtkMRMLTransformNode* toolToRasNode = bwNode->GetToolTransformNode(); vtkMRMLModelNode* secondModelNode = bwNode->GetSecondModelNode(); if ( modelNode == NULL || secondModelNode == NULL ) { bwNode->SetClosestDistanceToModelFromToolTip(0); return; } //vtkCollisionDetectionFilter only accepts triangles, hope it works this way vtkSmartPointer<vtkTriangleFilter> triangleFilter0 = vtkSmartPointer<vtkTriangleFilter>::New(); vtkSmartPointer<vtkTriangleFilter> triangleFilter1 = vtkSmartPointer<vtkTriangleFilter>::New(); triangleFilter0->SetInputConnection(modelNode->GetPolyDataConnection()); triangleFilter1->SetInputConnection(secondModelNode->GetPolyDataConnection()); //triangleFilters are set vtkPolyData* body = triangleFilter0->GetOutput(); if ( body == NULL ) { vtkWarningMacro( "No surface model in first node" ); return; } vtkPolyData* secondBody = triangleFilter1->GetOutput(); if ( secondBody == NULL ) { vtkWarningMacro( "No surface model in second node" ); return; } vtkSmartPointer< vtkCollisionDetectionFilter> collisionDetectionFilter = vtkSmartPointer< vtkCollisionDetectionFilter>::New(); collisionDetectionFilter->SetCollisionModeToFirstContact(); // should be faster // start transform first model // Transform the first body poly data if there is a parent transform. vtkMRMLTransformNode* bodyParentTransform = modelNode->GetParentTransformNode(); if ( bodyParentTransform != NULL ) { vtkSmartPointer< vtkGeneralTransform > bodyToRasTransform = vtkSmartPointer< vtkGeneralTransform >::New(); bodyParentTransform->GetTransformToWorld( bodyToRasTransform ); vtkSmartPointer< vtkTransformPolyDataFilter > bodyToRasFilter = vtkSmartPointer< vtkTransformPolyDataFilter >::New(); #if (VTK_MAJOR_VERSION <= 5) bodyToRasFilter->SetInput( body ); #else bodyToRasFilter->SetInputData( body ); #endif bodyToRasFilter->SetTransform( bodyToRasTransform ); bodyToRasFilter->Update(); collisionDetectionFilter->SetInput(0, bodyToRasFilter->GetOutput() ); } else { collisionDetectionFilter->SetInput(0, body ); // no idea how expensive } // don't care about expensive now, jut want this to work // second model ---------------------------------- vtkMRMLTransformNode* secondBodyParentTransform = secondModelNode->GetParentTransformNode(); if ( secondBodyParentTransform != NULL ) { vtkSmartPointer< vtkGeneralTransform > secondBodyToRasTransform = vtkSmartPointer< vtkGeneralTransform >::New(); secondBodyParentTransform->GetTransformToWorld( secondBodyToRasTransform ); vtkSmartPointer< vtkTransformPolyDataFilter > secondBodyToRasFilter = vtkSmartPointer< vtkTransformPolyDataFilter >::New(); #if (VTK_MAJOR_VERSION <= 5) secondBodyToRasFilter->SetInput( secondBody ); #else secondBodyToRasFilter->SetInputData( secondBody ); #endif secondBodyToRasFilter->SetTransform( secondBodyToRasTransform ); secondBodyToRasFilter->Update(); collisionDetectionFilter->SetInput(0, secondBodyToRasFilter->GetOutput() ); } else { collisionDetectionFilter->SetInput(0, secondBody ); // no idea how expensive } // end transform second model vtkSmartPointer<vtkMatrix4x4> matrix0 = vtkSmartPointer<vtkMatrix4x4>::New(); vtkSmartPointer<vtkMatrix4x4> matrix1 = vtkSmartPointer<vtkMatrix4x4>::New(); collisionDetectionFilter->SetMatrix(0, matrix0); collisionDetectionFilter->SetMatrix(1, matrix1); collisionDetectionFilter->GenerateScalarsOff(); if (collisionDetectionFilter->GetNumberOfContacts() > 0) { bwNode->SetCollision(true); } else { bwNode->SetCollision(false); } // Note: Performance could be improved by // - keeping the filter in memory for all the observed nodes. // - in case of linear transform of model and tooltip: transform only the tooltip (with the tooltip to model transform), // and not transform the model at all // --> not valid for collision detection }
int vtkFractureTrace::RequestData(vtkInformation *request, vtkInformationVector **inputVector, vtkInformationVector *outputVector) { // get the info objects vtkInformation *inInfo = inputVector[0]->GetInformationObject(0); vtkInformation *outInfo = outputVector->GetInformationObject(0); // get the input and ouptut this->input = vtkPolyData::SafeDownCast( inInfo->Get(vtkDataObject::DATA_OBJECT())); this->output = vtkPolyData::SafeDownCast( outInfo->Get(vtkDataObject::DATA_OBJECT())); vtkCellArray* inCells = this->input->GetPolys(); inCells->InitTraversal(); vtkIdType nCells = inCells->GetNumberOfCells(); inPoints = input->GetPoints(); vtkIdType nPoints = inPoints->GetNumberOfPoints(); this->append = vtkAppendPolyData::New(); vtkIntArray* isNormal = vtkIntArray::New(); isNormal->SetName("Normal(0)_Dip(1)_Intersection(2)"); vtkIdType npts; vtkIdType* pts; for(vtkIdType i=0; i<nCells; ++i) { inCells->GetNextCell(npts, pts); if(npts < 3) { vtkWarningMacro("The cells should at least have three points"); continue; } double pt1[3], pt2[3], pt3[3]; inPoints->GetPoint(pts[0], pt1); inPoints->GetPoint(pts[1], pt2); inPoints->GetPoint(pts[2], pt3); double v1[] = {pt2[0]-pt1[0], pt2[1]-pt1[1], pt2[2]-pt1[2]}; double v2[] = {pt3[0]-pt1[0], pt3[1]-pt1[1], pt3[2]-pt1[2]}; double N[3]; vtkMath::Cross(v1, v2, N); vtkMath::Normalize(N); double center[3]; this->computeFractureCenter(npts, pts, center); double length = this->computeNormalLength(npts, pts); // projection of [0,0,-1] on the plane with normal V double dip[] = {N[0]*N[2], N[1]*N[2], -1.0 + N[2]*N[2]}; vtkMath::Normalize(dip); int n = this->addArrow(center, N, length, 0); //for(int count=0; count<n; ++count) isNormal->InsertNextValue(0); n = this->addArrow(center, dip, length, 1); //for(int count=0; count<n; ++count) isNormal->InsertNextValue(1); vtkIdType traversal = inCells->GetTraversalLocation(); for(vtkIdType j=i+1; j<nCells; ++j) { vtkIdType npts2; vtkIdType* pts2; inCells->GetNextCell(npts2, pts2); if(npts2 < 3) continue; double p1[3], p2[3], p3[3]; inPoints->GetPoint(pts2[0], p1); inPoints->GetPoint(pts2[1], p2); inPoints->GetPoint(pts2[2], p3); double v1[] = {p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2]}; double v2[] = {p3[0]-p1[0], p3[1]-p1[1], p3[2]-p1[2]}; double N2[3]; vtkMath::Cross(v1, v2, N2); vtkMath::Normalize(N2); double V[3]; vtkMath::Cross(N, N2, V); // the direction of the line double norm = vtkMath::Normalize(V); // check if the two fracture are parallel if(norm == 0) continue; // perform bounding box intersection first double s1, s2, a, b; // ax + by + cz + s = 0 s1 = (N[0]*pt1[0] + N[1]*pt1[1] + N[2]*pt1[2]); s2 = (N2[0]*p1[0] + N2[1]*p1[1] + N2[2]*p1[2]); double n1n2dot = vtkMath::Dot(N, N2); double n1normsqr = 1.;//vtkMath::Dot(N,N); double n2normsqr = 1.;//vtkMath::Dot(N2, N2); a = (s2 * n1n2dot - s1 * n2normsqr) / (n1n2dot*n1n2dot - n1normsqr * n2normsqr); b = (s1 * n1n2dot - s2 * n2normsqr) / (n1n2dot*n1n2dot - n1normsqr * n2normsqr); double lPoint[3]; // the point on the line lPoint[0] = a*N[0] + b*N2[0]; lPoint[1] = a*N[1] + b*N2[1]; lPoint[2] = a*N[2] + b*N2[2]; double lPoint2[] = {lPoint[0]+V[0], lPoint[1]+V[1], lPoint[2]+V[2]}; double t1, t2, t3, t4; if(!this->intersectWithCell(lPoint, V, npts, pts, t1, t2)) continue; if(!this->intersectWithCell(lPoint, V, npts2, pts2, t3, t4)) continue; double tLeft = std::max(t1, t3); double tRight = std::min(t2, t4); if(tLeft >= tRight) continue; p1[0] = lPoint[0] + V[0]*tLeft; p1[1] = lPoint[1] + V[1]*tLeft; p1[2] = lPoint[2] + V[2]*tLeft; p2[0] = lPoint[0] + V[0]*tRight; p2[1] = lPoint[1] + V[1]*tRight; p2[2] = lPoint[2] + V[2]*tRight; vtkLineSource *line = vtkLineSource::New(); line->SetPoint1(p1); line->SetPoint2(p2); line->SetResolution(2); line->Update(); vtkIntArray* props = vtkIntArray::New(); props->SetName("Normal(0)_Dip(1)_Intersection(2)"); props->InsertNextValue(2); line->GetOutput()->GetCellData()->AddArray(props); append->AddInput(line->GetOutput()); line->Delete(); } inCells->SetTraversalLocation(traversal); } this->append->Update(); this->output->DeepCopy(append->GetOutput()); this->append->Delete(); return 1; }