Skip to content

Commit

Permalink
Merge branch 'master' into tetgen-1.5
Browse files Browse the repository at this point in the history
  • Loading branch information
inducer committed May 27, 2014
2 parents 7f798c2 + 4a5865f commit ed6da73
Show file tree
Hide file tree
Showing 10 changed files with 280 additions and 136 deletions.
71 changes: 44 additions & 27 deletions aksetup_helper.py
Expand Up @@ -495,21 +495,28 @@ def __init__(self, lib_base_name, default_lib_name=None):
% humanize(lib_base_name))


def set_up_shipped_boost_if_requested(project_name, conf):
def set_up_shipped_boost_if_requested(project_name, conf, source_path=None,
boost_chrono=False):
"""Set up the package to use a shipped version of Boost.
Return a tuple of a list of extra C files to build and extra
defines to be used.
:arg boost_chrono: one of *False* and ``"header_only"``
(only relevant in shipped mode)
"""
from os.path import exists
import sys

if source_path is None:
source_path = "bpl-subset/bpl_subset"

if conf["USE_SHIPPED_BOOST"]:
if not exists("bpl-subset/bpl_subset/boost/version.hpp"):
if not exists("%s/boost/version.hpp" % source_path):
print(DASH_SEPARATOR)
print("The shipped Boost library was not found, but "
"USE_SHIPPED_BOOST is True.")
print("(The files should be under bpl-subset/.)")
print("(The files should be under %s/.)" % source_path)
print(DASH_SEPARATOR)
print("If you got this package from git, you probably want to do")
print("")
Expand All @@ -527,34 +534,37 @@ def set_up_shipped_boost_if_requested(project_name, conf):
count_down_delay(delay=10)

if conf["USE_SHIPPED_BOOST"]:
conf["BOOST_INC_DIR"] = ["bpl-subset/bpl_subset"]
conf["BOOST_INC_DIR"] = [source_path]
conf["BOOST_LIB_DIR"] = []
conf["BOOST_PYTHON_LIBNAME"] = []
conf["BOOST_THREAD_LIBNAME"] = []

from glob import glob
source_files = (glob("bpl-subset/bpl_subset/libs/*/*/*/*.cpp")
+ glob("bpl-subset/bpl_subset/libs/*/*/*.cpp")
+ glob("bpl-subset/bpl_subset/libs/*/*.cpp"))
source_files = (glob(source_path + "/libs/*/*/*/*.cpp")
+ glob(source_path + "/libs/*/*/*.cpp")
+ glob(source_path + "/libs/*/*.cpp"))

# make sure next line succeeds even on Windows
source_files = [f.replace("\\", "/") for f in source_files]

source_files = [f for f in source_files
if not f.startswith("bpl-subset/bpl_subset/libs/thread/src")]
if not f.startswith(source_path + "/libs/thread/src")]

if sys.platform == "win32":
source_files += glob(
"bpl-subset/bpl_subset/libs/thread/src/win32/*.cpp")
source_path + "/libs/thread/src/win32/*.cpp")
source_files += glob(
"bpl-subset/bpl_subset/libs/thread/src/tss_null.cpp")
source_path + "/libs/thread/src/tss_null.cpp")
else:
source_files += glob(
"bpl-subset/bpl_subset/libs/thread/src/pthread/*.cpp")
source_path + "/libs/thread/src/pthread/*.cpp")

source_files = [f for f in source_files
if not f.endswith("once_atomic.cpp")]

from os.path import isdir
main_boost_inc = "bpl-subset/bpl_subset/boost"
bpl_project_boost_inc = "bpl-subset/bpl_subset/%sboost" % project_name
main_boost_inc = source_path + "/boost"
bpl_project_boost_inc = source_path + "/%sboost" % project_name

if not isdir(bpl_project_boost_inc):
try:
Expand All @@ -565,18 +575,24 @@ def set_up_shipped_boost_if_requested(project_name, conf):
print("Copying files, hang on... (do not interrupt)")
copytree(main_boost_inc, bpl_project_boost_inc)

return (source_files,
{
# do not pick up libboost link dependency on windows
"BOOST_ALL_NO_LIB": 1,
"BOOST_THREAD_BUILD_DLL": 1,

"BOOST_MULTI_INDEX_DISABLE_SERIALIZATION": 1,
"BOOST_THREAD_DONT_USE_CHRONO": 1,
"BOOST_PYTHON_SOURCE": 1,
"boost": '%sboost' % project_name
}
)
defines = {
# do not pick up libboost link dependency on windows
"BOOST_ALL_NO_LIB": 1,
"BOOST_THREAD_BUILD_DLL": 1,

"BOOST_MULTI_INDEX_DISABLE_SERIALIZATION": 1,
"BOOST_PYTHON_SOURCE": 1,
"boost": '%sboost' % project_name,
}

if boost_chrono is False:
defines["BOOST_THREAD_DONT_USE_CHRONO"] = 1
elif boost_chrono == "header_only":
defines["BOOST_CHRONO_HEADER_ONLY"] = 1
else:
raise ValueError("invalid value of 'boost_chrono'")

return (source_files, defines)
else:
return [], {}

Expand Down Expand Up @@ -707,7 +723,7 @@ def _run_git_command(cmd):
print("Hit Ctrl-C now if you'd like to think about the situation.")
print(DASH_SEPARATOR)
count_down_delay(delay=5)
return stdout.decode("ascii"), git_error
return stdout.decode("utf-8"), git_error


def check_git_submodules():
Expand All @@ -733,7 +749,8 @@ def check_git_submodules():
status = l[0]
sha, package = l[1:].split(" ", 1)

if package == "bpl-subset":
if package == "bpl-subset" or (
package.startswith("boost") and package.endswith("subset")):
# treated separately
continue

Expand Down
2 changes: 1 addition & 1 deletion doc/_templates/layout.html
@@ -1,2 +1,2 @@
{% extends "!layout.html" %}
{% set css_files = css_files + ['_static/akdoc.css']%}
{% set bootswatch_css_custom = ['_static/akdoc.css']%}
6 changes: 5 additions & 1 deletion doc/conf.py
Expand Up @@ -23,7 +23,11 @@

# Add any Sphinx extension module names here, as strings. They can be extensions
# coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
#extensions = []
extensions = [
'sphinx.ext.autodoc',
'sphinx.ext.viewcode',
'sphinx.ext.intersphinx',
]

# Add any paths that contain templates here, relative to this directory.
templates_path = ['_templates']
Expand Down
4 changes: 4 additions & 0 deletions doc/geometry.rst
@@ -0,0 +1,4 @@
Geometry Generation
===================

.. automodule:: meshpy.geometry
5 changes: 5 additions & 0 deletions doc/gmsh.rst
@@ -0,0 +1,5 @@
Gmsh interface
===================

.. automodule:: meshpy.gmsh_reader

21 changes: 11 additions & 10 deletions doc/index.rst
@@ -1,20 +1,19 @@
.. MeshPy documentation master file, created by sphinx-quickstart on Tue Jul 1 12:35:03 2008.
You can adapt this file completely to your liking, but it should at least
contain the root `toctree` directive.
Welcome to MeshPy's documentation!
==================================

MeshPy offers quality triangular and tetrahedral mesh generation for Python.
Meshes of this type are chiefly used in finite-element simulation codes, but
also have many other applications ranging from computer graphics to robotics.


In order to generate these 2D and 3D meshes, MeshPy provides Python interfaces
to two well-regarded mesh generators, `Triangle
<http://www.cs.cmu.edu/~quake/triangle.html>`_ by J. Shewchuk and `TetGen
<http://tetgen.berlios.de/>`_ by Hang Si. Both are included in the package in
slightly modified versions.
to a few well-regarded mesh generators:

* `Triangle <http://www.cs.cmu.edu/~quake/triangle.html>`_ by J. Shewchuk.
* `TetGen <http://tetgen.berlios.de/>`_ by Hang Si.
* `Gmsh <http://geuz.org/gmsh/>`_ by Christophe Geuzaine and Jean-François Remacle.

Triangle and TetGen are included in the package in slightly modified versions. Gmsh
is called as a subprocess.

Show me! I need examples!
-------------------------
Expand Down Expand Up @@ -78,7 +77,9 @@ Contents
:maxdepth: 2

installation
reference
tri-tet
geometry
gmsh
faq

MeshPy has its own `web page <http://mathema.tician.de/software/meshpy>`_, where you
Expand Down
52 changes: 2 additions & 50 deletions doc/reference.rst → doc/tri-tet.rst
@@ -1,5 +1,5 @@
Reference Documentation
=======================
Triangle/TetGen interface
=========================

Some common notions
-------------------
Expand Down Expand Up @@ -363,51 +363,3 @@ Some common notions

:param insert_points: a :class:`MeshInfo` object specifying additional points to be inserted

.. data:: EXT_OPEN
.. data:: EXT_CLOSED_IN_RZ

.. function:: generate_extrusion(rz_points, base_shape, closure=EXT_OPEN, point_idx_offset=0, ring_point_indices=None, ring_markers=None, rz_closure_marker=0)

Extrude a given connected *base_shape* (a list of (x,y) points)
along the z axis. For each step in the extrusion, the base shape
is multiplied by a radius and shifted in the z direction. Radius
and z offset are given by *rz_points*, which is a list of
(r, z) tuples.

Returns *(points, facets, facet_holestarts, markers)*, where *points* is a list
of (3D) points and facets is a list of polygons. Each polygon is, in turn,
represented by a tuple of indices into *points*. If *point_idx_offset* is
not zero, these indices start at that number. *markers* is a list equal in
length to *facets*, each specifying the facet marker of that facet.
*facet_holestarts* is also equal in length to *facets*, each element is a list of
hole starting points for the corresponding facet.

Use :meth:`MeshInfo.set_facets_ex` to add the extrusion to a :class:`MeshInfo`
structure.

The extrusion proceeds by generating quadrilaterals connecting each
ring. If any given radius in *rz_points* is 0, triangle fans are
produced instead of quads to provide non-degenerate closure.

If *closure* is :data:`EXT_OPEN`, no efforts are made to put end caps on the
extrusion.

If *closure* is :data:`EXT_CLOSED_IN_RZ`, then a torus-like structure
is assumed and the last ring is just connected to the first.

If *ring_markers* is not None, it is an list of markers added to each
ring. There should be len(rz_points)-1 entries in this list.
If rings are added because of closure options, they receive the
corresponding *XXX_closure_marker*. If *facet_markers* is given, this function
returns (points, facets, markers), where markers is is a list containing
a marker for each generated facet. Unspecified markers generally
default to 0.

If *ring_point_indices* is given, it must be a list of the same
length as *rz_points*. Each entry in the list may either be None,
or a list of point indices. This list must contain the same number
of points as the *base_shape*; it is taken as the indices of
pre-existing points that are to be used for the given ring, instead
of generating new points.

.. function:: generate_surface_of_revolution(rz_points, closure=EXT_OPEN, radial_subdiv=16, point_idx_offset=0, ring_point_indices=None, ring_markers=None, rz_closure_marker=0)
46 changes: 46 additions & 0 deletions meshpy/geometry.py
@@ -1,6 +1,40 @@
from __future__ import division
import numpy as np

__doc__ = """
Geometry builder
----------------
.. autoclass:: GeometryBuilder
Geometries
----------
These functions are designed so that their output can be splat-passed to
:meth:`GeometryBuilder.add_geometry`::
builder = GeometryBuilder()
builder.add_geometry(*make_ball(10))
.. autoclass:: Marker
:members:
:undoc-members:
.. autofunction:: make_box
.. autofunction:: make_circle
.. autofunction:: make_ball
.. autofunction:: make_cylinder
Extrusions and surfaces of revolution
-------------------------------------
.. data:: EXT_OPEN
.. data:: EXT_CLOSED_IN_RZ
.. autofunction:: generate_extrusion
.. autofunction:: generate_surface_of_revolution
"""

# {{{ geometry building

Expand Down Expand Up @@ -36,6 +70,14 @@ def offset_point_indices(facets, offset):


class GeometryBuilder(object):
"""
.. automethod:: add_geometry
.. automethod:: set
.. automethod:: wrap_in_box
.. automethod:: bounding_box
.. automethod:: center
.. automethod:: apply_transform
"""
def __init__(self):
self.points = []
self.facets = []
Expand Down Expand Up @@ -96,6 +138,10 @@ def dimensions(self):
return len(self.points[0])

def set(self, mesh_info):
"""Transfer the built geometry into a :class:`meshpy.triangle.MeshInfo`
or a :class:`meshpy.tet.MeshInfo`.
"""

mesh_info.set_points(self.points, self.point_markers)
if self.facet_hole_starts or is_multi_polygon(self.facets):
mesh_info.set_facets_ex(self.facets,
Expand Down
12 changes: 5 additions & 7 deletions meshpy/gmsh.py
Expand Up @@ -2,8 +2,8 @@ class GmshError(RuntimeError):
pass


# {{{ tools

# tools -----------------------------------------------------------------------
def _erase_dir(dir):
from os import listdir, unlink, rmdir
from os.path import join
Expand All @@ -12,7 +12,6 @@ def _erase_dir(dir):
rmdir(dir)



class _TempDirManager(object):
def __init__(self):
from tempfile import mkdtemp
Expand All @@ -29,10 +28,8 @@ def error_clean_up(self):
_erase_dir(self.path)




class GmshRunner(object):
def __init__(self, source, dimensions, order=None,
def __init__(self, source, dimensions, order=None,
incomplete_elements=None, other_options=[],
extension="geo", gmsh_executable="gmsh"):
self.source = source
Expand Down Expand Up @@ -70,8 +67,9 @@ def __enter__(self):
cmdline.extend(["-order", str(self.order)])

if self.incomplete_elements is not None:
cmdline.extend(["-string",
"Mesh.SecondOrderIncomplete = %d;" % int(self.incomplete_elements)])
cmdline.extend(["-string",
"Mesh.SecondOrderIncomplete = %d;"
% int(self.incomplete_elements)])

cmdline.extend(self.other_options)
cmdline.append(source_file_name)
Expand Down

0 comments on commit ed6da73

Please sign in to comment.