# This file was automatically generated by SWIG (https://www.swig.org).
# Version 4.1.1
#
# Do not make changes to this file unless you know what you are doing - modify
# the SWIG interface file instead.

from sys import version_info as _swig_python_version_info
# Import the low-level C/C++ module
if __package__ or "." in __name__:
    from . import _contour
else:
    import _contour

try:
    import builtins as __builtin__
except ImportError:
    import __builtin__

def _swig_repr(self):
    try:
        strthis = "proxy of " + self.this.__repr__()
    except __builtin__.Exception:
        strthis = ""
    return "<%s.%s; %s >" % (self.__class__.__module__, self.__class__.__name__, strthis,)


def _swig_setattr_nondynamic_instance_variable(set):
    def set_instance_attr(self, name, value):
        if name == "this":
            set(self, name, value)
        elif name == "thisown":
            self.this.own(value)
        elif hasattr(self, name) and isinstance(getattr(type(self), name), property):
            set(self, name, value)
        else:
            raise AttributeError("You cannot add instance attributes to %s" % self)
    return set_instance_attr


def _swig_setattr_nondynamic_class_variable(set):
    def set_class_attr(cls, name, value):
        if hasattr(cls, name) and not isinstance(getattr(cls, name), property):
            set(cls, name, value)
        else:
            raise AttributeError("You cannot add class attributes to %s" % cls)
    return set_class_attr


def _swig_add_metaclass(metaclass):
    """Class decorator for adding a metaclass to a SWIG wrapped class - a slimmed down version of six.add_metaclass"""
    def wrapper(cls):
        return metaclass(cls.__name__, cls.__bases__, cls.__dict__.copy())
    return wrapper


class _SwigNonDynamicMeta(type):
    """Meta class to enforce nondynamic attributes (no new attributes) for a class"""
    __setattr__ = _swig_setattr_nondynamic_class_variable(type.__setattr__)


import ooflib.SWIG.engine.masterelement
import ooflib.SWIG.engine.element
import ooflib.SWIG.common.coord
import ooflib.SWIG.engine.csubproblem
import ooflib.SWIG.common.doublevec
import ooflib.SWIG.common.lock
import ooflib.SWIG.engine.equation
import ooflib.SWIG.engine.fieldindex
import ooflib.SWIG.engine.planarity
import ooflib.SWIG.engine.flux
import ooflib.SWIG.engine.outputval
import ooflib.SWIG.engine.nodalequation
import ooflib.SWIG.engine.femesh
import ooflib.SWIG.common.cmicrostructure
import ooflib.SWIG.common.pixelgroup
import ooflib.SWIG.common.pixelattribute
import ooflib.SWIG.common.timestamp
import ooflib.SWIG.engine.field
import ooflib.SWIG.engine.freedom
import ooflib.SWIG.engine.pointdata
import ooflib.SWIG.engine.node
import ooflib.SWIG.engine.material
import ooflib.SWIG.common.abstractimage
import ooflib.SWIG.common.ccolor
import ooflib.SWIG.engine.property
import ooflib.SWIG.engine.meshiterator
import ooflib.SWIG.engine.linearizedsystem
import ooflib.SWIG.engine.sparsemat
import ooflib.SWIG.engine.edge
import ooflib.SWIG.engine.mastercoord
import ooflib.SWIG.engine.elementnodeiterator
import ooflib.SWIG.engine.gausspoint
class ContourCoord(ooflib.SWIG.engine.mastercoord.MasterCoord):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined")
    __repr__ = _swig_repr
    value = property(_contour.ContourCoord_value_get, _contour.ContourCoord_value_set)
    __swig_destroy__ = _contour.delete_ContourCoord

# Register ContourCoord in _contour:
_contour.ContourCoord_swigregister(ContourCoord)
class CContour(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")
    __repr__ = _swig_repr

    def __init__(self, arg2, arg3):
        _contour.CContour_swiginit(self, _contour.new_CContour(arg2, arg3))
    __swig_destroy__ = _contour.delete_CContour

    def compute(self, arg2, arg3, arg4):
        return _contour.CContour_compute(self, arg2, arg3, arg4)

    def getCurves(self):
        return _contour.CContour_getCurves(self)

    def getLoops(self):
        return _contour.CContour_getLoops(self)
    value = property(_contour.CContour_value_get)

# Register CContour in _contour:
_contour.CContour_swigregister(CContour)
class ContourCellSet(object):
    thisown = property(lambda x: x.this.own(), lambda x, v: x.this.own(v), doc="The membership flag")

    def __init__(self, *args, **kwargs):
        raise AttributeError("No constructor defined")
    __repr__ = _swig_repr

    def getCorners(self):
        return _contour.ContourCellSet_getCorners(self)

    def findIntercepts(self, arg2):
        return _contour.ContourCellSet_findIntercepts(self, arg2)
    __swig_destroy__ = _contour.delete_ContourCellSet

# Register ContourCellSet in _contour:
_contour.ContourCellSet_swigregister(ContourCellSet)

def contourCellCache(arg1, arg2):
    return _contour.contourCellCache(arg1, arg2)

def clearCache():
    return _contour.clearCache()
# -*- python -*-

# This software was produced by NIST, an agency of the U.S. government,
# and by statute is not subject to copyright in the United States.
# Recipients of this software assume all responsibilities associated
# with its operation, modification and maintenance. However, to
# facilitate maintenance we ask that before distributing modified
# versions of this software, you first contact the authors at
# oof_manager@nist.gov.

from ooflib.common import debug
from ooflib.common import primitives
from ooflib.common.IO import whoville

class Contour(CContour):
# Class representing a single contour of a function.  This class
# does not figure out which line segments are part of the contour,
# but it does assemble those segments into a set of curves and
# loops.

    def map(self, mesh, element, posOutput):
# Use the posOutput Output to map the contours from master
# space to display space.
        self.curves = self.getCurves()
        self.loops = self.getLoops()

        self.curves = [primitives.Curve(posOutput.evaluate(mesh, [element],
                                                           [curve]))
                       for curve in self.curves]

        self.loops = [primitives.Polygon(posOutput.evaluate(mesh, [element],
                                                            [loop]))
                      for loop in self.loops]

    def __repr__(self):
        return "Contour(value=%f, curves=%s, loops=%s)" % (self.value,
                                                           self.getCurves(),
                                                           self.getLoops())

#########################

def findContours(mesh, element,
                 posOutput,             # Output for positions of nodes
                 valueOutput,           # Output for function being plotted
                 clevels,               # list of contour levels
                 nbins,                 # number of cells in each direction
                 closecontours):        # close contours at element perimeter?
# Compute the contours crossing an element.
# This would be an Element method, but it's more convenient to put
# it here.
    master = element.masterelement()
    cells = contourCellCache(master, nbins) # ContourCellSet object

# Create a Contour object for each value provided
    contours = [Contour(clevels[i], i) for i in range(len(clevels))]

# Evaluate the output function at the corners of the cells.
    cellcorners = cells.getCorners()
    cornervalues = list(map(float, valueOutput.evaluate(mesh, [element],
                                                        [cellcorners])))
# Assign values, and find the element maximum and minimum.
    elmax = cornervalues[0]
    elmin = elmax
    for val, corner in zip(cornervalues, cellcorners):
        corner.value = val
        elmax = max(elmax, val)
        elmin = min(elmin, val)

# Find the contour intercepts on all of the cell edges.
    cells.findIntercepts(clevels)
    for contour in contours:
        contour.compute(cells, master, closecontours)

    for contour in contours:
        contour.map(mesh, element, posOutput)

    return (contours, elmin, elmax)

###################

def _ContourCoord___repr__(self):
    try:
        return "ContourCoord(%f, %f, [%f])" % (self[0], self[1], self.value)
    except AttributeError:
        return "ContourCoord(%f, %f)" % (self[0], self[1])

ContourCoord.__repr__ = _ContourCoord___repr__

## ## ##

# WhoProxy for the topmost contourable mesh -- this one is potentially
# confusing -- it returns the mesh associated with the topmost
# contourable layer in the graphics window, unless there is no such
# layer, in which case it returns the topmost mesh.

class ContourableMesh(whoville.WhoProxyClass):
    def resolve(self, proxy, gfxwindow):
        layer = gfxwindow.topcontourable()
        if layer:
            return layer.who.resolve(gfxwindow)
        else:
            return gfxwindow.topwho( ('Mesh') )
    def getTimeStamp(self, proxy, gfxwindow):
        return gfxwindow.getLayerChangeTimeStamp()

ContourableMesh('<contourable>')


cvar = _contour.cvar

