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

Reply via email to