Skip to content

Commit

Permalink
Simplify/unify gLucifer drawing objects, fix 3d support in python
Browse files Browse the repository at this point in the history
Drawing on mesh or at user defined grid and cross section vs 3d now all
handled within single drawing objects in backend

From python, add "onMesh=True" in drawing object creation to draw on the
mesh nodes.

In 3d to plot Surface() or VectorArrows() cross sections, pass:
crossSection="AXIS=VAL" where axis is x/y/z and val is exact position or
percentage, eg: crossSection="z=50%"
  • Loading branch information
OKaluza committed Mar 10, 2017
1 parent 449e85a commit a3b50e9
Show file tree
Hide file tree
Showing 32 changed files with 579 additions and 2,231 deletions.
90 changes: 12 additions & 78 deletions glucifer/objects.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,13 @@

#TODO: Drawing Objects to implement
# IsoSurface, IsoSurfaceCrossSection
# MeshSurface/MeshSampler (surface/volumes using MeshCrossSection sampler)
# Contour, ContourCrossSection
# HistoricalSwarmTrajectory
# VectorArrowMeshCrossSection?
#
# Maybe later...
# TextureMap
# SwarmShapes, SwarmRGB, SwarmVectors
# EigenVectors, EigenVectorCrossSection
# FeVariableSurface

#Some preset colourmaps
# aim to reduce banding artifacts by being either
Expand Down Expand Up @@ -343,15 +340,20 @@ class CrossSection(Drawing):
Cross Section definition, eg. z=0.
resolution : unsigned
Surface rendered sampling resolution.
onMesh : boolean
Sample the mesh nodes directly, as opposed to sampling across a regular grid. This flag
should be used in particular where a mesh has been deformed.
"""
_objectsDict = { "_dr": "lucCrossSection" }

def __init__(self, mesh, fn, crossSection="", resolution=100,
colours=None, colourMap=None, colourBar=True,
valueRange=None, logScale=False, discrete=False, offsetEdges=None,
valueRange=None, logScale=False, discrete=False, offsetEdges=None, onMesh=False,
*args, **kwargs):

self._onMesh = onMesh

self._fn = _underworld.function.Function.convert(fn)

if not isinstance(mesh,_uwmesh.FeMesh):
Expand Down Expand Up @@ -387,7 +389,8 @@ def _add_to_stg_dict(self,componentDictionary):
componentDictionary[self._dr.name].update( {
"Mesh": self._mesh._cself.name,
"crossSection": self._crossSection,
"resolution" : self._resolution
"resolution" : self._resolution,
"onMesh" : self._onMesh
} )

@property
Expand All @@ -396,72 +399,6 @@ def crossSection(self):
"""
return self._crossSection

class SurfaceOnMesh(CrossSection):
"""
This drawing object class draws a surface using the provided scalar field.
This object differs from the `Surface` class in that it samples the mesh
nodes directly, as opposed to sampling across a regular grid. This class
should be used in particular where a mesh has been deformed.
See parent class for further parameter details. Also see property docstrings.
Notes
-----
The interface to this object will be revised in future versions.
Parameters
---------
mesh : underworld.mesh.FeMesh
Mesh over which cross section is rendered.
fn : underworld.function.Function
Function used to determine values to render.
drawSides : str
Sides (x,y,z,X,Y,Z) for which the surface should be drawn.
For example, "xyzXYZ" would render the provided function across
all surfaces of the domain in 3D. In 2D, this object always renders
across the entire domain.
"""

# let's just build both objects because we aint sure yet which one we want to use yet
_objectsDict = { "_dr" : "lucScalarFieldOnMesh" }

def __init__(self, mesh, fn, drawSides="xyzXYZ",
colours=None, colourMap=None, colourBar=True,
valueRange=None, logScale=False, discrete=False,
*args, **kwargs):

if not isinstance(drawSides,str):
raise ValueError("'drawSides' parameter must be of python type 'str'")
self._drawSides = drawSides

#Default properties
self.properties = {"cullface" : True}
# TODO: disable lighting if 2D (how to get dims?)
#self.properties["lit"] = False

# build parent
super(SurfaceOnMesh,self).__init__( mesh=mesh, fn=fn,
colours=colours, colourMap=colourMap, colourBar=colourBar,
valueRange=valueRange, logScale=logScale, discrete=discrete, *args, **kwargs)


def _add_to_stg_dict(self,componentDictionary):
# lets build up component dictionary
# append random string to provided name to ensure unique component names
# call parents method

super(SurfaceOnMesh,self)._add_to_stg_dict(componentDictionary)

componentDictionary[self._dr.name]["drawSides"] = self._drawSides
componentDictionary[self._dr.name][ "Mesh"] = self._mesh._cself.name

def _setup(self):
_libUnderworld.gLucifer._lucMeshCrossSection_SetFn( self._cself, self._fn._fncself )

def __del__(self):
super(SurfaceOnMesh,self).__del__()


class Surface(CrossSection):
"""
This drawing object class draws a surface using the provided scalar field.
Expand All @@ -481,7 +418,6 @@ class Surface(CrossSection):
across the entire domain.
"""

# let's just build both objects because we aint sure yet which one we want to use yet
_objectsDict = { "_dr" : "lucScalarField" }

def __init__(self, mesh, fn, drawSides="xyzXYZ",
Expand All @@ -493,16 +429,14 @@ def __init__(self, mesh, fn, drawSides="xyzXYZ",
raise ValueError("'drawSides' parameter must be of python type 'str'")
self._drawSides = drawSides

#Default properties
self.properties = {"cullface" : True}
# TODO: disable lighting if 2D (how to get dims?)
#self.properties["lit"] = False

# build parent
super(Surface,self).__init__( mesh=mesh, fn=fn,
colours=colours, colourMap=colourMap, colourBar=colourBar,
valueRange=valueRange, logScale=logScale, discrete=discrete, *args, **kwargs)

#Default properties
is3d = len(self._crossSection) == 0
self.properties.update({"cullface" : is3d, "lit" : is3d})

def _add_to_stg_dict(self,componentDictionary):
# lets build up component dictionary
Expand All @@ -520,7 +454,6 @@ def _setup(self):
def __del__(self):
super(Surface,self).__del__()


class Points(Drawing):
"""
This drawing object class draws a swarm of points.
Expand Down Expand Up @@ -711,6 +644,7 @@ def __init__(self, mesh, fn,
colours=None, colourMap=None, colourBar=True,
valueRange=None, logScale=False, discrete=False,
*args, **kwargs):

# build parent
if mesh.dim == 2:
raise ValueError("Volume rendered requires a three dimensional mesh.")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,8 @@ void _lucContourCrossSection_AssignFromXML( void* drawingObject, Stg_ComponentFa

void _lucContourCrossSection_Build( void* drawingObject, void* data )
{
lucScalarFieldCrossSection* self = (lucScalarFieldCrossSection*)drawingObject;

/* Build field variable in parent */
_lucCrossSection_Build(self, data);
_lucCrossSection_Build(drawingObject, data);
}

void _lucContourCrossSection_Initialise( void* drawingObject, void* data ) {}
Expand Down

0 comments on commit a3b50e9

Please sign in to comment.