VTK计算网格模型上的最短路径

  Dijkstra algorithm to compute the graph geodesic.Takes as input a polygonal mesh and performs a single source shortest path calculation. Dijkstra‘s algorithm is used.

  用鼠标右键拾取平面网格上的点,观察输出路径:

#!usrbinenv python

import vtk

def loadSTL(filenameSTL):
    readerSTL = vtk.vtkSTLReader()
    readerSTL.SetFileName(filenameSTL)
    # ‘update‘ the reader i.e. read the .stl file
    readerSTL.Update()

    polydata = readerSTL.GetOutput()

    print "Number of Cells:",  polydata.GetNumberOfCells()
    print "Number of Points:", polydata.GetNumberOfPoints()

    # If there are no points in ‘vtkPolyData‘ something went wrong
    if polydata.GetNumberOfPoints() == 0:
        raise ValueError("No point data could be loaded from " + filenameSTL)
        return None

    return polydata

# Customize vtkInteractorStyleTrackballCamera
class MyInteractor(vtk.vtkInteractorStyleTrackballCamera):

    def __init__(self,parent=None):
        self.AddObserver("RightButtonPressEvent", self.RightButtonPressEvent)

    def RightButtonPressEvent(self,obj,event):
        clickPos = self.GetInteractor().GetEventPosition()
        print "Picking pixel: " , clickPos

        # Pick from this location
        picker = self.GetInteractor().GetPicker()
        picker.Pick(clickPos[0], clickPos[1], 0, self.GetDefaultRenderer())

        # If CellId = -1, nothing was picked
        if(picker.GetCellId() != -1):
            print "Pick position is: " , picker.GetPickPosition()
            print "Cell id is:",  picker.GetCellId()
            print "Point id is:", picker.GetPointId()

            pathList.append(picker.GetPointId())
            point_position = mesh.GetPoint(picker.GetPointId())

            # Create a sphere
            sphereSource = vtk.vtkSphereSource()
            sphereSource.SetCenter(point_position)
            #sphereSource.SetRadius(0.2)
            sphereSource.SetRadius(0.02)

            # Create a mapper and actor
            sphereMapper = vtk.vtkPolyDataMapper()
            sphereMapper.SetInputConnection(sphereSource.GetOutputPort())
            sphereActor = vtk.vtkActor()
            sphereActor.SetMapper(sphereMapper)
            sphereActor.GetProperty().SetColor(1.0, 0.0, 0.0)
            self.GetDefaultRenderer().AddActor(sphereActor)

            # find the shortest path
            if len(pathList) > 1:
                dijkstra.SetStartVertex(pathList[-2])
                dijkstra.SetEndVertex(pathList[-1])
                dijkstra.Update()

                # Get the vertex ids (of the input polydata) on the shortest path
                IdList = dijkstra.GetIdList()

                # store in pathList
                for i in range(IdList.GetNumberOfIds()-1, 0, -1):
                    pathList.insert(-1, IdList.GetId(i))

                self.drawPath()

        # Forward events
        self.OnRightButtonDown()
        return

    def drawPath(self):
        points = vtk.vtkPoints()
        for i in range(0, len(pathList)):
            points.InsertNextPoint(mesh.GetPoint(pathList[i])) 

        # draw intermediate points
        # pointsPolydata = vtk.vtkPolyData()
        # pointsPolydata.SetPoints(points)             

        # vertexFilter  = vtk.vtkVertexGlyphFilter()
        # vertexFilter.SetInputData(pointsPolydata)
        # vertexFilter.Update()

        # polydata = vtk.vtkPolyData()
        # polydata.ShallowCopy(vertexFilter.GetOutput())

        # mapper = vtk.vtkPolyDataMapper()
        # mapper.SetInputData(polydata)

        # polydataActor = vtk.vtkActor()
        # polydataActor.SetMapper(mapper)
        # polydataActor.GetProperty().SetPointSize(5)

        # self.GetDefaultRenderer().AddActor(polydataActor)

        # draw path
        polyLine = vtk.vtkPolyLine()
        polyLine.GetPointIds().SetNumberOfIds(len(pathList))
        for i in range(0, len(pathList)):
            polyLine.GetPointIds().SetId(i,i)

        #Create a cell array to store the lines in and add the lines to it
        cells = vtk.vtkCellArray()
        cells.InsertNextCell(polyLine)

        # Create a polydata to store everything in
        polyLine = vtk.vtkPolyData()
        polyLine.SetPoints(points) # Add the points to the dataset
        polyLine.SetLines(cells)   # Add the lines to the dataset

        # Setup mapper
        polyLineMapper = vtk.vtkPolyDataMapper()
        polyLineMapper.SetInputData(polyLine)

        # Create an actor to represent the polyline
        polyLineActor = vtk.vtkActor()
        polyLineActor.SetMapper(polyLineMapper)
        polyLineActor.GetProperty().SetColor(0,0,1)
        polyLineActor.GetProperty().SetLineWidth(2)

        self.GetDefaultRenderer().AddActor(polyLineActor)

def CreateScene():
    # Create a rendering window and renderer
    renWin = vtk.vtkRenderWindow()
    # Set window size
    renWin.SetSize(600, 600)
    ren = vtk.vtkRenderer()
    # Set background color
    ren.GradientBackgroundOn()
    ren.SetBackground(.1, .1, .1)
    ren.SetBackground2(0.8,0.8,0.8)

    renWin.AddRenderer(ren)

    # Create a renderwindowinteractor
    iren = vtk.vtkRenderWindowInteractor()
    iren.SetRenderWindow(renWin)

    style = MyInteractor()
    style.SetDefaultRenderer(ren)
    iren.SetInteractorStyle(style)

    # vtkCellPicker will shoot a ray into a 3D scene and return information about
    # the first object that the ray hits.
    cellPicker = vtk.vtkCellPicker()
    iren.SetPicker(cellPicker)

    # load STL file
    global mesh
    mesh = loadSTL("untitled.stl")

    global dijkstra
    global pathList
    pathList = []
    dijkstra = vtk.vtkDijkstraGraphGeodesicPath()
    dijkstra.SetInputData(mesh)

    mapper = vtk.vtkPolyDataMapper()
    mapper.SetInputData(mesh)         # maps polygonal data to graphics primitives
    actor = vtk.vtkLODActor()
    actor.SetMapper(mapper)
    actor.GetProperty().EdgeVisibilityOn()
    actor.GetProperty().SetColor(0.0,0.9,0.9)
    actor.GetProperty().SetLineWidth(0.3)
    ren.AddActor(actor)

    # Enable user interface interactor
    iren.Initialize()
    iren.Start()

if __name__ == "__main__":
    CreateScene()

  立体网格:

参考:

Dijkstra算法(一)之 C语言详解

Python/GeometricObjects/PolyLine

VTKExamples/Cxx/Graphs/ShortestPath

VTKExamples/Cxx/PolyData/DijkstraGraphGeodesicPath

VTK: vtkDijkstraGraphGeodesicPath Class Reference

vtkDijkstraGraphGeodesicPath在曲面上寻找最短路径的应用

原文地址:https://www.cnblogs.com/21207-iHome/p/9127171.html

时间: 2024-12-22 03:15:42

VTK计算网格模型上的最短路径的相关文章

Direct-X学习笔记--封装一个网格模型类

之前学习了网格模型的导入,绘制,了解了X文件等相关知识,但是,那样绘制比较麻烦,而且绘制一个模型需要好多代码,完全是面向过程的思维,这次,学习一下怎么把网格模型的导入以及绘制等功能封装在一个类中.顺便加深一下对World Transform的理解.感觉自己的3D思维还是没有培养起来,想绘制一个对象,绘制出来和想象中的位置相差甚远. 一.复习一下网格模型相关知识 网格模型就是一个我们在美术工具中制作好的资源,通过一些API接口我们可以将美术童鞋做好的模型很方便的导入程序中.我们只需要了解怎样从文件

Linux内核(7) - 设备模型(上)

对于驱动开发来说,设备模型的理解是根本,毫不夸张得说,理解了设备模型,再去看那些五花八门的驱动程序,你会发现自己站在了另一个高度,从而有了一种俯视的感觉,就像凤姐俯视知音和故事会,韩峰同志俯视女下属. 顾名而思义就知道设备模型是关于设备的模型,既不是任小强们的房模,也不是张导的炮模.对咱们写驱动的和不写驱动的人来说,设备的概念就是总线和与其相连的各种设备了.电脑城的IT工作者都会知道设备是通过总线连到计算机上的,而且还需要对应的驱动才能用,可是总线是如何发现设备的,设备又是如何和驱动对应起来的,

unity3d动画帧事件回调脚本必须直接挂在模型上

unity3d动画帧事件回调脚本必须直接挂在模型上,即与Animator同级,不能挂接在模型的父节点或者子节点,否则无法找到回调函数 以上在idle动作中新增帧事件skill,回调模型脚本中的skill()函数

ML学习分享系列(1)_计算广告小窥[上]

原作:面包包包包包包 改动:寒小阳 && 龙心尘 时间:2016年1月 出处:http://blog.csdn.net/breada/article/details/50572914 http://blog.csdn.net/han_xiaoyang/article/details/50580423 声明:版权全部.转载请联系作者并注明出处 1. 引言 提笔写这篇博客.我的内心是惶恐的.原因非常简单.作为一个资历尚浅的研究生,是没有资格对计算广告这样一个伟大的行业.领域和学科来评头论足的.

201507221403_《backbone之一——新建模型和集合、实例化模型、模型上监听事件的方法、模型设置和获取后台数据、配置理由方法、视图绑定事件的方法、绑定模型等》

一 . 新建 var model_1 = new Backbone.Model({'name':'hello'}); var model_2 = new Backbone.Model({'name':'hi'}); var models = new Backbone.Collection(); models.add( model_1 ); models.add( model_2 ); alert( JSON.stringify(models) ); 二. 实例化模型 var M = Backbo

Java 输入一个整数,计算它各位上数字的和。(注意:是任意位的整数)

import java.util.*; /* * 输入一个整数,计算它各位上数字的和. * (注意:是任意位的整数) */ public class Sum02 { public static void main(String[] args) { System.out.print("请输入任意一个整数:"); Scanner s = new Scanner(System.in); int sum = 0; int t = s.nextInt(); while(t!=0){ sum =

unity 在模型上绘画

using UnityEngine; /// <summary> /// 在模型上绘画 /// </summary> public class DrawOnModel:BaseMonoBehaviour{ [Tooltip("颜色")] public Color color=Color.cyan; [Tooltip("笔刷大小")] public float brushSize=10f; private Camera m_mainCamera

iOS - Scenekit3D引擎初探之 - 导入模型+上传服务器+下载并简单设置

SceneKit是ios8之后苹果推出了一个3D模型渲染框架. SceneKit现在可以支持有限的几种模型,截止到我写这篇文章为止似乎只有.dae和.abc后一种模型我没有使用过.这篇文章只针对.dae模型写. 首先如果是希望加载一个已有的,不需要程序在运行的时候动态添加的dae模型.那么我们可以直接新建一个game类型的工程.在选项中选择SceneKit,在程序中加载自带模型的那句话中将模型名称替换即可.本文主要讲一下如何导出dae模型,并在server端动态下载并显示. 首先我们手中有一个.

计算LDA模型困惑度

http://www.52nlp.cn/lda-math-lda-%E6%96%87%E6%9C%AC%E5%BB%BA%E6%A8%A1 LDA主题模型评估方法--Perplexity http://www.52nlp.cn/lda-math-lda-%E6%96%87%E6%9C%AC%E5%BB%BA%E6%A8%A1 LDA-math-LDA 文本建模 http://www.iyunv.com/thread-59890-1-1.html 用python计算lda语言模型的困惑度并作图 h