1

我正在尝试使用 vedo 中的薄板变形功能来扭曲体积网格。但我一直没有成功。我什至尝试使用表面网格进行调试,但这也不起作用。以下是 vedo 提供的原始示例。

"""Warp the tip of a mesh using Thin Plate Splines.
Red points stay fixed while a single point in space
moves as the arrow indicates. """
from vedo import *


mesh = Mesh(dataurl+"man.vtk").color('w').lineWidth(0.1)

# a heavily decimated copy
meshdec = mesh.clone().triangulate().decimate(N=200)

sources = [[0.9, 0.0, 0.2]]  # this point moves
targets = [[1.2, 0.0, 0.4]]  # to this.
arrow = Arrow(sources[0], targets[0])

for pt in meshdec.points():
    if pt[0] < 0.3:          # these pts don't move
        sources.append(pt)   # source = target
        targets.append(pt)   #

warp = mesh.clone().thinPlateSpline(sources, targets)
warp.c("blue",0.3).lineWidth(0)

apts = Points(sources).c("red")

show(mesh, arrow, warp, apts, __doc__, viewup="z", axes=1)

以下是我进行的一些试验改编。这些都尝试用于表面和体积网格。

试验 1 using decimated mesh

from vedo import *
import numpy as np
import scipy.io
import os
import sys
import csv

meshfile = "C:\\..\\MyVirtMean.vtk";
sourcefile = "C:\\..\\MyVirtMean_meanSurfNodes.csv";
targetfile = "C:\\..\\virtShapeGeneration.mat";
matvariable = "newShape";
Sources = []
Targets = []

mesh = Mesh(meshfile).color('w').lineWidth(0.1) # This is the mean volumetric mesh

# a heavily decimated copy
meshdec = mesh.clone().triangulate().decimate(N=200)

# Collecting mean surface point data from csv file
with open(sourcefile) as csvDataFile:
    csvReader = csv.reader(csvDataFile)
    for row in csvReader:
        Sources.append(row)
Sources = np.array(Sources)
Sources = Sources.astype(np.float)
length = int(np.size(Sources)/3)
Sources = list(Sources.reshape(length,3)) # ?x3 array

# Collecting virtual subjects point data from .mat file
Targets = scipy.io.loadmat(targetfile)[matvariable][0]
length = int(np.size(Targets)/3)
Targets = list(Targets.reshape(length,3)) # ?x3 array
    
# 
arrow = Arrow(Sources[0], Targets[0])

for pt in meshdec.points():
    if pt[0] < 0.3:          # these pts don't move
        Sources.append(pt)   # source = target
        Targets.append(pt)   #

warp = mesh.clone().thinPlateSpline(Sources, Targets) 
warp.c("blue",0.3).lineWidth(0)

apts = Points(Sources).c("red")

show(mesh, arrow, warp, apts, __doc__, viewup="z", axes=1)

试验 2 using the full mesh

from vedo import *
import numpy as np
import scipy.io
import os
import sys
import csv

meshfile = "C:\\..\\MyVirtMean.vtk"
sourcefile = "C:\\..\\MyVirtMean_meanSurfNodes.csv"
targetfile = "C:\\..\\virtShapeGeneration.mat"
matvariable = "newShape";
Sources = []
Targets = []

mesh = Mesh(meshfile).color('w').lineWidth(0.1)
with open(sourcefile) as csvDataFile:
    csvReader = csv.reader(csvDataFile)
    for row in csvReader:
        Sources.append(row)
Sources = np.array(Sources)
Sources = Sources.astype(np.float)
length = int(np.size(Sources)/3)
Sources = list(Sources.reshape(length,3)) # ?x3 array

# Collecting virtual subjects point data from .mat file
Targets = scipy.io.loadmat(targetfile)[matvariable][0]
length = int(np.size(Targets)/3)
Targets = list(Targets.reshape(length,3)) # ?x3 array
    
# 
arrow = Arrow(Sources[0], Targets[0])

for pt in mesh.points():
    if pt[0] < 0.3:          # these pts don't move
        Sources.append(pt)   # source = target
        Targets.append(pt)   #

warp = mesh.clone().thinPlateSpline(Sources, Targets) 
warp.c("blue",0.3).lineWidth(0)

apts = Points(Sources).c("red")

show(mesh, arrow, warp, apts, __doc__, viewup="z", axes=1)

主要是内核在 warp 命令处冻结。在某些情况下,我还让内核死机并重新启动。我怀疑我在定义源和目标时做错了,但我不确定。
I'm using Python 3.7.3 64-bit in Spyder 4.1.5 (Windows 10).

4

1 回答 1

1

There were two issues with my code. As expected, the problem was in the way the Sources and Targets were defined.

  1. Both Sources and Targets had to be created using the .tolist() method.

  2. The Targets array that was imported from a ( .mat ) file had to be reshaped with a Fortran-like index order using

    Targets = (Targets.reshape((length,3), order='F'))
    Targets = Targets.tolist()

Another point is that I had to use a reduced number of Sources and Targets
for x in range(0, len(Targets), 50):
targets.append(Targets[x])

The result can be found through this link.

于 2021-07-12T10:17:24.450 回答