Python 如何使用三维点、线和曲面数据(.geo文件)打印体积

Python 如何使用三维点、线和曲面数据(.geo文件)打印体积,python,matplotlib,sketchup,Python,Matplotlib,Sketchup,我需要用曲面绘制三维体积, 使用线循环定义的曲面, 使用线定义的线循环, 用点定义的线 以下是一个例子: Point(1) = x1,y1,z1 Point(2) = x2,y2,z2 Point(3) = x3,y3,z3 Point(4) = x4,y4,z4 Point(5) = x5,y5,z5 Point(6) = x6,y6,z6 Point(7) = x7,y7,z7 Point(8) = x8,y8,z8 Line(1) = Point(1), Point(2) Line(2)

我需要用曲面绘制三维体积, 使用线循环定义的曲面, 使用线定义的线循环, 用点定义的线

以下是一个例子:

Point(1) = x1,y1,z1
Point(2) = x2,y2,z2
Point(3) = x3,y3,z3
Point(4) = x4,y4,z4
Point(5) = x5,y5,z5
Point(6) = x6,y6,z6
Point(7) = x7,y7,z7
Point(8) = x8,y8,z8
Line(1) = Point(1), Point(2)
Line(2) = Point(2), Point(3)
Line(3) = Point(3), Point(4)
Line(4) = Point(4), Point(1)
Line(5) = Point(5), Point(6)
Line(6) = Point(6), Point(7)
Line(7) = Point(7), Point(8)
Line(8) = Point(8), Point(5)
Line(9) = Point(1), Point(5)
Line(10) = Point(2), Point(6)
Line(11) = Point(3), Point(7)
Line(12) = Point(4), Point(8)
Line loop(1) = Line(1), Line(2), Line(3), Line(4)
Line loop(2) = Line(5), Line(6), Line(7), Line(8)
Line loop(3) = Line(1), Line(10), Line(-5), Line(-9)
Line loop(4) = Line(2), Line(11), Line(-6), Line(-10)
Line loop(5) = Line(3), Line(12), Line(-7), Line(-11)
Line loop(6) = Line(4), Line(9), Line(-8), Line(-12)
Surface(1) = Line Loop(1) #top
Surface(2) = Line Loop(2) #bottom
Surface(3) = Line Loop(3)
Surface(4) = Line Loop(4)
Surface(5) = Line Loop(5)
Surface(6) = Line Loop(6)
Volume(1) = Surface(1), Surface(2), Surface(3), Surface(4), Surface(5), Surface(6)

我尝试过matplotlib和mayavi.mlab绘图函数,但没有一个像我希望的那样有效。 我还查找了.geo导入函数,但没有找到

这些文件(.geo文件)从SketchUp(谷歌3D设计软件)导出,并导入到GMesh中以创建网格。 在我的例子中,我希望在将卷导入Gmesh之前用Python绘制卷


有人有没有办法绘制这种数据?

经过几天的工作,我得到了答案,用于显示.geo文件中的边:

from mpl_toolkits.mplot3d import Axes3D
from mpl_toolkits.mplot3d.art3d import Poly3DCollection, Line3DCollection
import matplotlib.pyplot as plt
import os
from os import system
from numpy import array, argsort, sqrt, unique, linspace
fig = plt.figure ()
ax = fig.add_subplot (1, 1, 1, projection = '3d', aspect = 1)

## Name of GEO file
fileName = "vfv8_fusion.geo"

## Reading GEO file
with open(fileName) as f:
  lineList = f.readlines()

V,P,L,LL,PS,SL = [],[],[],[],[],[]
e1,f1 = [],[]

## Separation of variables (points, lines, loop lines, plane surface, surface loop, volumes)
for ii in range(len(lineList)):

    if lineList[ii][0:5]=="Point":  
        a1 = lineList[ii]
        a2 = a1.split('{')
        a3 = a2[1].split('}')
        a4 = a3[0].split(',')
        coord = [float(a4[0]),float(a4[1]),float(a4[2])]
        P.append(coord)

    if lineList[ii][0:5]=="Line(":
        b1 = lineList[ii]
        b2 = b1.split('{ ')
        b3 = b2[1].split(' }')
        b4 = b3[0].split(',')
        points_to_line = [int(float(b4[0])),int(float(b4[1]))]
        L.append(points_to_line)      

    if lineList[ii][0:9]=="Line Loop": 
        c1 = lineList[ii]
        c2 = c1.split('{')
        c3 = c2[1].split('}')
        c4 = c3[0].split(',')
        line_to_lineloop = []
        for jj in range(len(c4)):
            line_to_lineloop.append(int(float(c4[jj])))
        LL.append(line_to_lineloop)      

    if lineList[ii][0:13]=="Plane Surface":
        d1 = lineList[ii]
        d2 = d1.split('{')
        d3 = d2[1].split('}')
        d4 = d3[0].split(',')
        lineloop_to_planesurface = []
        for jj in range(len(d4)):
            lineloop_to_planesurface.append(int(float(d4[jj])))
        PS.append(lineloop_to_planesurface)   

    if lineList[ii][0:12]=="Surface Loop":
        e1.append(lineList[ii])
        e2 = e1[-1].split('{')
        e3 = e2[1].split('}')
        e4 = e3[0].split(',')
        planesurface_to_surfaceloop = []
        for jj in range(len(e4)):
            planesurface_to_surfaceloop.append(int(float(e4[jj])))
        SL.append(planesurface_to_surfaceloop)   

    if lineList[ii][0:6]=="Volume":
        f1.append(lineList[ii])
        f2 = f1[-1].split('{')
        f3 = f2[1].split('}')
        f4 = f3[0].split(',')
        surfaceloop_to_volume = []
        for jj in range(len(f4)):
            surfaceloop_to_volume.append(int(float(f4[jj])))
        V.append(surfaceloop_to_volume)   


nb_points,nb_line,nb_lineloop,nb_planesurface,nb_surfaceloop,nb_volume = len(P),len(L),len(LL),len(PS),len(SL),len(V)

## Rewriting the list of lines with the coordinates of the points
## line1 = [point1, point2] becomes line1 = [[x1,y1,z1],[x2,y2,z2]]

L_P = [[]]*len(L)
for ii in range(len(L)):
    L_P[ii] = [[]]*len(L[ii])
    for jj in range(len(L[ii])):
        L_P[ii][jj] = P[L[ii][jj]-1]


liste = [[]]*len(V)


## Rearrangement


for ii in range(len(V)):#for each volume
    listlignes = []
    Vn = V[ii]#the corresponding surface loop list is retrieved

    for jj in range(len(Vn)):#for each surface loop in the volume

        Vnj = Vn[jj]

        SLn = SL[Vnj-1]#we get the list of the corresponding surface plane list

        for kk in range(len(SLn)):#for each plane surface

            SLnk = SLn[kk]

            PSn = PS[SLnk-1]#we get the list of the corresponding line loops

            for mm in range(len(PSn)):#for each ligne loop

                PSnm = PSn[mm]

                LLn = LL[PSnm-1]#we get the correspondign list of lines

                for nn in range(len(LLn)):#for each line

                    LLnn = abs(LLn[nn])

                    Ln = L_P[LLnn-1]#we get the coordinates of the corresponding points

                    listlignes.append(Ln)#points are stored 2 by 2 (line by line)


    liste[ii] = listlignes#all lines are stored for each volume

## Definition of the limits of the graphic reference mark
minX,maxX,minY,maxY,minZ,maxZ = 0,0,0,0,0,0
for ii in range(len(P)):
    if P[ii][0]>maxX:
        maxX = P[ii][0]
    if P[ii][1]>maxY:
        maxY = P[ii][1]
    if P[ii][2]>maxZ:
        maxZ = P[ii][2]
    if P[ii][0]<minX:
        minX = P[ii][0]
    if P[ii][1]<minY:
        minY = P[ii][1]
    if P[ii][2]<minZ:
        minZ = P[ii][2]
MAX = max(maxX,maxY,maxZ)
MIN = min(minX,minY,minZ)

## Colors list
colors_list = [[0,255,255], #aqua
               [227,207,87], #banana
               [0,0,255],#blue
               [138,43,226], #blueviolet
               [255,64,64], #brown1
               [152,245,255], #cadetblue1
               [255,97,3], #cadmiumorange
               [127,255,0], #chartreuse1
               [61,89,171], #cobalt
               [0,100,0],   #darkgreen
               [153,50,204], #darkorchid
               [155,205,155], #darkseagreen3
               [255,20,147], #deeppink1
               [28,134,238], #dodgerblue2
               [255,48,48], #firebrick1
               [34,139,34], #forestgreen
               [112,112,112], #gray44
               [255,105,108], #hotpink
               [238,99,99], #indianred2
               [173,216,230], #lightblue
               [255,255,0]] #yellow1           

## Normalization of RGB values
colors_list_RBG = colors_list
for ii in range(len(colors_list)):
    colors_list_RBG[ii][0] = float(colors_list[ii][0])/255
    colors_list_RBG[ii][1] = float(colors_list[ii][1])/255
    colors_list_RBG[ii][2] = float(colors_list[ii][2])/255

## We store the volumes we want to display   
for ii in range(len(liste)):
    poly2 = Line3DCollection(liste[ii],colors=colors_list_RBG[ii])
    ax.add_collection3d(poly2)

ax.set_xlim(MIN,MAX)
ax.set_ylim(MIN,MAX)
ax.set_zlim(MIN,MAX)

## Display
plt.show ()
来自mpl_toolkits.mplot3d导入Axes3D
从mpl_toolkits.mplot3d.art3d导入Poly3DCollection,Line3DCollection
将matplotlib.pyplot作为plt导入
导入操作系统
从操作系统导入系统
来自numpy导入数组、argsort、sqrt、unique、linspace
图=plt.图()
ax=图添加_子图(1,1,1,投影='3d',纵横比=1)
##GEO文件名
fileName=“vfv8\u fusion.geo”
##读取地理文件
打开(文件名)为f时:
lineList=f.readlines()
五、 P、L、LL、PS、SL=[]、[]、[]、[]、[]、[]、[]、[]
e1,f1=[],[]
##变量分离(点、线、环线、平面、曲面环线、体积)
对于范围内的ii(len(线路列表)):
如果行列表[ii][0:5]=“点”:
a1=行列表[ii]
a2=a1.拆分(“{”)
a3=a2[1]。拆分(“}”)
a4=a3[0]。拆分(“,”)
坐标=[浮动(a4[0])、浮动(a4[1])、浮动(a4[2])]
P.追加(协调)
如果行列表[ii][0:5]=“行(”:
b1=行列表[ii]
b2=b1.split(“{”)
b3=b2[1]。拆分(“}”)
b4=b3[0]。拆分(',')
点到线=[int(浮点(b4[0])),int(浮点(b4[1])]
L.追加(点到线)
如果lineList[ii][0:9]=“线路回路”:
c1=行列表[ii]
c2=c1.split(“{”)
c3=c2[1]。拆分(“}”)
c4=c3[0]。拆分(“,”)
行到行循环=[]
对于范围内的jj(len(c4)):
行到行loop.append(int(float(c4[jj]))
LL.append(行到行循环)
如果lineList[ii][0:13]=“平面”:
d1=线路列表[ii]
d2=d1.split(“{”)
d3=d2[1]。拆分(“}”)
d4=d3[0]。拆分(“,”)
lineloop_到_平面=[]
对于范围内的jj(len(d4)):
lineloop_to_planesurface.append(int(float(d4[jj]))
PS.append(线环到平面)
如果lineList[ii][0:12]=“曲面回路”:
e1.追加(行列表[ii])
e2=e1[-1]。拆分(“{”)
e3=e2[1]。拆分(“}”)
e4=e3[0]。拆分(“,”)
平面到曲面顶部=[]
对于范围内的jj(len(e4)):
planesurface_to_surfaceloop.append(int(float(e4[jj]))
SL.append(平面到曲面)
如果行列表[ii][0:6]=“卷”:
f1.追加(行列表[ii])
f2=f1[-1]。拆分(“{”)
f3=f2[1]。拆分(“}”)
f4=f3[0]。拆分(“,”)
表面操作至体积=[]
对于范围内的jj(len(f4)):
surfaceloop_to_volume.append(int(float(f4[jj]))
V.追加(表面操作卷到卷)
nb_点、nb_线、nb_线环、nb_平面、nb_曲面顶、nb_体积=len(P)、len(L)、len(LL)、len(PS)、len(SL)、len(V)
##用点的坐标重写线列表
##line1=[point1,point2]变成line1=[x1,y1,z1],[x2,y2,z2]]
L_P=[[]]*len(L)
对于范围内的ii(len(L)):
L_P[ii]=[[]]*len(L[ii])
对于范围内的jj(len(L[ii]):
L_P[ii][jj]=P[L[ii][jj]-1]
列表=[[]]*len(V)
##重排
对于范围内的ii(len(V)):#对于每个卷
ListAlignes=[]
Vn=V[ii]#检索相应的曲面回路列表
对于范围内的jj(len(Vn)):#对于体积中的每个曲面回路
Vnj=Vn[jj]
SLn=SL[Vnj-1]#我们得到相应的曲面列表
对于范围内的kk(len(SLn)):#对于每个平面
SLnk=SLn[kk]
PSn=PS[SLnk-1]#我们得到相应线路回路的列表
对于范围内的毫米(len(PSn)):#对于每个直线回路
PSnm=PSn[mm]
LLn=LL[PSnm-1]#我们得到相应的行列表
对于范围内的nn(len(LLn)):#每行
LLnn=abs(LLn[nn])
Ln=L_P[LLnn-1]#我们得到相应点的坐标
listlignes.append(Ln)#点按2乘2(逐行)存储
liste[ii]=listlignes#为每个卷存储所有行
##图形参考标记界限的定义
minX,maxX,minY,maxY,minZ,maxZ=0,0,0,0,0,0
对于范围内的ii(len(P)):
如果P[ii][0]>maxX:
maxX=P[ii][0]
如果P[ii][1]>maxY:
maxY=P[ii][1]
如果P[ii][2]>maxZ:
maxZ=P[ii][2]

如果P[ii][0]从Gmsh导出到STL或其他什么东西,然后用Python读取如何?为什么需要Python?Gmsh可以可视化卷。您也可以使用Blender可视化导出的文件,它有完整的Python API,可以读取许多3d格式。