Dear gmsh/getsp community,
A blender-module for exporting meshes from blender to geo-format is attached to
this message.
You get different physical surfaces for partial surfaces in the blender mesh
that have different materials assigned.
(This is not possible with STL meshes.)
The module is tested with blender 2.66.
Clearly, this stuff comes without guarantee. I can also not promise to maintain
the file.
With best regards,
Tobias Naehring
# ##### BEGIN GPL LICENSE BLOCK #####
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software Foundation,
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
#
# ##### END GPL LICENSE BLOCK #####
bl_info = {
"name": "GEO format",
"author": "Tobias Naehring",
"version": (1, 0),
"blender": (2, 5, 7),
"api": 35622,
"location": "File > Export > GEO",
"description": "Export GEO files",
"warning": "Under Development",
"wiki_url": ("http://wiki.blender.org/index.php/Extensions:2.5/Py/"
"Scripts/"),
"tracker_url": "https://projects.blender.org/tracker/index.php?"
"func=detail&aid=22837",
"support": 'INOFFICIAL',
"category": "Import-Export"}
"""
Export GEO files
- Export can export with/without modifiers applied
Issues:
Import:
- Import not implemented yet
"""
import os
import bpy
from bpy.props import StringProperty, BoolProperty, FloatProperty, CollectionProperty
from bpy_extras.io_utils import ExportHelper
import itertools
def mesh_from_mesh(ob, apply_modifier=False, triangulate=True):
'''
From an object, return a generator over a list of faces.
Each faces is a list of his vertexes. Each vertex is a tuple of
his coordinate.
apply_modifier
Apply the preview modifier to the returned liste
triangulate
Split the quad into two triangles
'''
# get the modifiers
try:
mesh = ob.to_mesh(bpy.context.scene, apply_modifier, "PREVIEW")
mesh.name = ob.name;
except RuntimeError:
raise StopIteration
mesh.transform(ob.matrix_world)
return mesh
def write_geo(filename, mesh, scale_factor=1.0):
'''Write gmsh-geo-file to file with name filename.
All points can be scaled by scale_factor.
'''
with open(filename, 'w') as data:
data.write('// Geo file exported from blender\n')
name=mesh.name;
for v in mesh.vertices:
data.write('p%s[%d]=newp; Point(p%s[%d])={%g,%g,%g,mshSize};\n' % (name,v.index,name,v.index,scale_factor*v.co[0],scale_factor*v.co[1],scale_factor*v.co[2]));
for e in mesh.edges:
data.write('l%s[%d]=newl; Line(l%s[%d])={p%s[%d],p%s[%d]};\n' % (name,e.index+1,name,e.index+1,name,e.vertices[0],name,e.vertices[1]));
keys2edges=dict();
for e in mesh.edges:
keys2edges[tuple(e.vertices[:])] = e.index+1
for e in mesh.edges:
keys2edges[(e.vertices[1],e.vertices[0])] = -(e.index+1)
for f in mesh.polygons:
data.write('ll=newll; Line Loop(ll)={')
for i in range(len(f.vertices)-1):
e=keys2edges[(f.vertices[i],f.vertices[i+1])];
data.write( '%sl%s[%d],' % ('-' if e < 0 else '',name,abs(e)) )
e=keys2edges[(f.vertices[-1],f.vertices[0])]
data.write( '%sl%s[%d]}; ' % ('-' if e<0 else '',name,abs(e)) )
data.write('s%s[%d]=news; Plane Surface(s%s[%d])={ll};\n' % (name,f.index,name,f.index) )
# physical surfaces:
phSurfaces = dict()
phSurfaceEdges = dict()
for f in mesh.polygons:
i=f.material_index
if phSurfaces.get(i) == None:
phSurfaces[i]=set();
phSurfaceEdges[i]=set();
phSurfaces[i].add(f.index);
phSurfaceEdges[i].update(set(f.edge_keys));
for sk in phSurfaces.keys():
data.write('ps%s%d=newreg; Physical Surface(ps%s%d)={' % (name,sk,name,sk) );
first=True;
for i in phSurfaces[sk]:
if first:
first=False;
else:
data.write(',');
data.write('s%s[%d]' % (name,i));
data.write('};\n');
# Boundaries between physical surfaces:
sKeys2=set(phSurfaces.keys());
for sk in phSurfaces.keys():
sKeys2.remove(sk);
for sk2 in sKeys2:
lkSet = phSurfaceEdges[sk].intersection(phSurfaceEdges[sk2]);
if lkSet:
data.write('pl%s%d_%d=newreg; Physical Line(pl%s%d_%d)={' % (name,sk,sk2,name,sk,sk2));
first=True;
for lk in lkSet:
if first:
first=False;
else:
data.write(',');
data.write('l%s[%d]' % (name,keys2edges[lk]));
data.write('};\n');
class ExportGEO(bpy.types.Operator, ExportHelper):
'''
Save gmsh geometry data from the active object
'''
bl_idname = "export_mesh.stl"
bl_label = "Export GEO"
filename_ext = ".geo"
apply_modifiers = BoolProperty(name="Apply Modifiers",
description="Apply the modifiers "
"before saving",
default=True)
scale_factor = FloatProperty(name="Scale Factor",
description="Scale Factor",
default=1.0);
def execute(self, context):
ob = context.active_object
mesh = mesh_from_mesh(ob, self.apply_modifiers)
write_geo(self.filepath, mesh, self.scale_factor)
bpy.data.meshes.remove(mesh)
return {'FINISHED'}
def menu_export(self, context):
default_path = os.path.splitext(bpy.data.filepath)[0] + ".geo"
self.layout.operator(ExportGEO.bl_idname,
text="Geo (.geo)").filepath = default_path
def register():
bpy.utils.register_module(__name__)
bpy.types.INFO_MT_file_export.append(menu_export)
def unregister():
bpy.utils.unregister_module(__name__)
bpy.types.INFO_MT_file_export.remove(menu_export)
if __name__ == "__main__":
register()
_______________________________________________
gmsh mailing list
[email protected]
http://www.geuz.org/mailman/listinfo/gmsh