/* 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.
 */

This directory contains templates for building extensions to OOF2, in
particular new types of Properties.  It requires OOF2 version 2.3.3 or
later.  To use the templates, run the oof2-extension-setup command,
which was installed when oof2 was installed.  Do not try to build and
run the files in these directories directly!

Some of the extension templates make use of Property base classes in
the main OOF2 program, and are designed to make it easy to change the
form of a Property's nonlinearity or variability, without requiring
the user to be familiar with the full Property API.

(0) Create a directory for your extension module's source code.  The
    directory should be outside of the OOF2 source directory so that
    it's not overwritten if a new version of OOF2 is installed.
    Multiple extensions may share the same directory.

(1) In a terminal window, cd to the directory you created in the
    previous step and run oof2-extension-setup there:

      oof2-extension-setup --template=nonconstant_force_density_example

    oof2-extension-setup has three required arguments (although for
    simplicity only the template argument was shown above):

    --template=<directory name>
         The template directory to copy.  It is one of the
         subdirectories of OOF2/EXTENSION_TEMPLATES.
    --module=<module name>
         The name of the python module to create.  The new Property
         will be importable from this module.  The module name needs
         to be unique and should not conflict with the name of any
         other Python module on your computer.
    --class=<name>
         The name of the C++ Property class.  This name must be a
         valid C++ variable name.  It will also be used for the name
         of the Property in the GUI and in scripts.

    There are also some optional arguments:

    --sequenceno=<number>
         This determines the ordering of this property in the
         GUI. Larger numbers appear later.  The default value is 1000,
         which will put it after any predefined Properties.
    --force
    	 If this option is given, oof2-extension-setup will overwrite
	 existing files.

(2) Step 1 created a directory whose name was given by the --module
    argument.  It contains a CMakeLists.txt file, a source directory,
    and empty "build" directory, Change to the source subdirectory.

(3) Inside the source subdirectory there are four files with the name
    of the module, plus a suffix: ".C" for C++ code, ".h" for C++
    headers, ".swg" for swig code, and ".spy" for python code that's
    imported into the swig file.  The files contain notes about what
    you will need to change.  In particular, edit the .C file to
    change the functions that determine the behavior of the Property
    class.

    For more information, see the on-line OOF2 manual.

(3a) If you need to add, remove, or change the Property's parameters
     (parameters which will be settable via the GUI and/or scripts),
     you'll need to change the Property's constructor and its
     arguments, in all four files in the source directory.  Change the
     parameters in the argument list of the constructor, which appears
     in the .C, .h, and .swg files.  The constructor should store the
     values of the parameters as data in the Property object.  Change
     the .h and .swg files so that they're consistent with the .C
     file.  You'll also have to change the parameter list in the
     PropertyRegistration in the .spy file.

(3b) If you want to change where the Property appears in the hierarchy
     in the Material page, edit the "name" parameter of the
     PropertyRegistration in the .spy file.  "name" is string in which
     colons mark the levels of the Property hierarchy, as displayed on
     the OOF2 Materials page.  To change where the Property is listed
     among other Properties at the same level of the hierarchy, change
     the "ordering" parameter.

(3c) Do not change the propertyType in the PropertyRegistration.

(3d) If you need to add new C++ source files, you can put them in the
     source directory and add them to the SOURCES list in
     CMakeLists.txt in that directory.

(4) Move to the empty build directory.  Type
        ccmake ..
    to start CMake, and press "c" to do the initial configuration.
    You probably don't need to change any parameters other than
    CMAKE_INSTALL_PREFIX and CMAKE_BUILD_TYPE.

    * CMAKE_BUILD_TYPE can be either Release or Debug.

    * CMAKE_INSTALL_PREFIX is the name of directory into which the
      extension will be installed.  It does *not* have to be the
      directory where OOF2 is installed.  When the extension is built,
      a subdirectory named by the module name that you used in step
      (1) will be created within the directory.

    * OOF2_PYTHON3_VERSION is preset to the version of Python that was
      used to build OOF2.  You should not have to change this, unless
      you are re-using a Property that you originally created with a
      different version of Python.  Make sure that the version of
      Python used here is the same as the one that was used when OOF2
      was built.

    * OOF2_SWIG_VERSION is preset to the version of swig that was used
      to build OOF2.  You should not have to change this unless you
      are rebuilding your extension after having rebuilt OOF2 with a
      different version of swig.

    Press "c" to configure the build.  If you change any parameters,
    press "c" again.  Press "g" to generate the Makefile and exit
    ccmake.

(5) Run "make" and "make install".  If you're installing into a
    system  directory, run "sudo make install" instead.

(6) The directory where the extension is installed, named by
    CMAKE_INSTALL_PREFIX, needs to be in Python's path, the list of
    directories where it searches for modules.  You can print the
    default value of the path by typing
       python -c "import sys; print(sys.path)"
    in a terminal window.  If the extension directory isn't listed,
    you will need to add it.  There are a number of ways to do that.

    (a) When you run oof2, use the --pathdir option to add the
        directory, eg
           oof2 --pathdir=~/oof2extensions
        if the extension was installed oof2extensions in your home
        directory.
	
    (b) Set the PYTHONPATH environment variable in the Unix shell.
        The way to do that depends on which shell you use.  In bash,
	for example, before running oof2 you could type
	    export PYTHONPATH=$PYTHONPATH:<prefix>
        where <prefix> is the value of CMAKE_INSTALL_PREFIX.  This
	will set PYTHONPATH for all future commands run in the current
	terminal window.  To make that change permanent, put the
	"export" line in the .profile file in your home directory.

    (c) Edit the .oof2rc file in your home directory, and add the line
            sys.path.append("<prefix>")
        where <prefix> is the value of CMAKE_INSTALL_PREFIX.  This
        will change the path for all future oof2 sessions, but not for
        any other uses of Python.  However it won't work if you load your
	extension module with --import (see below).

(7) Run OOF2 and load your extension.  One way to do this is start
    oof2 with the --import flag:
       oof2 --import <module>
    where <module> is the name you assigned to the --module option
    when you ran oof2-extension-setup. You can also use the
    File/Load/Module command in the main OOF2 menu bar, or type
       import <module>
    in the OOF2 Console window.  Because modules loaded with --import
    are loaded before .oof2rc is read, --import will not work if
    it requires a path that was set in .oof2rc.

    If you want to load the extension every time you run OOF2, put
       OOF.File.Load.Module(module="<module>")
    in the .oof2rc file in your home directory. In this case, it makes
    sense to set the path in .oof2rc as well.

    An important difference between using the menu command and using
    the bare "import" statement or --import option is that the menu
    command will be logged.  If you save a log of your oof2 session
    (File/Save/Python Log...) and reload it, the extension will not
    be imported unless it was logged.