1# ##### BEGIN GPL LICENSE BLOCK #####
2#
3#  The Blender Rock Creation tool is for rapid generation of mesh rocks.
4#  Copyright (C) 2011  Paul Marshall
5#
6#  This program is free software: you can redistribute it and/or modify
7#  it under the terms of the GNU General Public License as published by
8#  the Free Software Foundation, either version 3 of the License, or
9#  (at your option) any later version.
10#
11#  This program is distributed in the hope that it will be useful,
12#  but WITHOUT ANY WARRANTY; without even the implied warranty of
13#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14#  GNU General Public License for more details.
15#
16#  You should have received a copy of the GNU General Public License
17#  along with this program.  If not, see <http://www.gnu.org/licenses/>.
18#
19# ##### END GPL LICENSE BLOCK #####
20
21# <pep8 compliant>
22
23
24# Converts a formated string to a float tuple:
25#   IN - '(0.5, 0.2)' -> CONVERT -> OUT - (0.5, 0.2)
26def toTuple(stringIn):
27    sTemp = str(stringIn)[1:len(str(stringIn)) - 1].split(', ')
28    fTemp = []
29    for i in sTemp:
30        fTemp.append(float(i))
31    return tuple(fTemp)
32
33
34# Converts a formated string to a float tuple:
35#   IN - '[0.5, 0.2]' -> CONVERT -> OUT - [0.5, 0.2]
36def toList(stringIn):
37    sTemp = str(stringIn)[1:len(str(stringIn)) - 1].split(', ')
38    fTemp = []
39    for i in sTemp:
40        fTemp.append(float(i))
41    return fTemp
42
43
44# Converts each item of a list into a float:
45def toFloats(inList):
46    outList = []
47    for i in inList:
48        outList.append(float(i))
49    return outList
50
51
52# Converts each item of a list into an integer:
53def toInts(inList):
54    outList = []
55    for i in inList:
56        outList.append(int(i))
57    return outList
58
59
60# Sets all faces smooth.  Done this way since I can't
61# find a simple way without using bpy.ops:
62def smooth(mesh):
63    import bmesh
64    bm = bmesh.new()
65    bm.from_mesh(mesh)
66    for f in bm.faces:
67        f.smooth = True
68    bm.to_mesh(mesh)
69    return mesh
70
71
72# This try block allows for the script to psudo-intelligently select the
73# appropriate random to use.  If Numpy's random is present it will use that.
74# If Numpy's random is not present, it will through a "module not found"
75# exception and instead use the slower built-in random that Python has.
76try:
77    # from numpy.random import random_integers as randint
78    from numpy.random import normal as gauss
79    # from numpy.random import (beta,
80    # uniform,
81    # seed,
82    # weibull)
83    # print("Rock Generator: Numpy found.")
84    numpy = True
85except:
86    from random import (
87        # randint,
88        gauss,
89        # uniform,
90        # seed
91        )
92    # from random import betavariate as beta
93    # from random import weibullvariate as weibull
94    print("Rock Generator: Numpy not found.  Using Python's random.")
95    numpy = False
96# Artifically skews a normal (gaussian) distribution.  This will not create
97# a continuous distribution curve but instead acts as a piecewise finction.
98# This linearly scales the output on one side to fit the bounds.
99#
100# Example output historgrams:
101#
102# Upper skewed:                 Lower skewed:
103#  |                 ▄           |      _
104#  |                 █           |      █
105#  |                 █_          |      █
106#  |                 ██          |     _█
107#  |                _██          |     ██
108#  |              _▄███_         |     ██ _
109#  |             ▄██████         |    ▄██▄█▄_
110#  |          _█▄███████         |    ███████
111#  |         _██████████_        |   ████████▄▄█_ _
112#  |      _▄▄████████████        |   ████████████▄█_
113#  | _▄_ ▄███████████████▄_      | _▄███████████████▄▄_
114#   -------------------------     -----------------------
115#                    |mu               |mu
116#   Historgrams were generated in R (http://www.r-project.org/) based on the
117#   calculations below and manually duplicated here.
118#
119# param:  mu          - mu is the mean of the distribution.
120#         sigma       - sigma is the standard deviation of the distribution.
121#         bounds      - bounds[0] is the lower bound and bounds[1]
122#                       is the upper bound.
123#         upperSkewed - if the distribution is upper skewed.
124# return: out         - Rondomly generated value from the skewed distribution.
125#
126# @todo: Because NumPy's random value generators are faster when called
127#   a bunch of times at once, maybe allow this to generate and return
128#   multiple values at once?
129
130
131def skewedGauss(mu, sigma, bounds, upperSkewed=True):
132    raw = gauss(mu, sigma)
133
134    # Quicker to check an extra condition than do unnecessary math. . . .
135    if raw < mu and not upperSkewed:
136        out = ((mu - bounds[0]) / (3 * sigma)) * raw + ((mu * (bounds[0] - (mu - 3 * sigma))) / (3 * sigma))
137    elif raw > mu and upperSkewed:
138        out = ((mu - bounds[1]) / (3 * -sigma)) * raw + ((mu * (bounds[1] - (mu + 3 * sigma))) / (3 * -sigma))
139    else:
140        out = raw
141
142    return out
143
144
145# @todo create a def for generating an alpha and beta for a beta distribution
146#   given a mu, sigma, and an upper and lower bound.  This proved faster in
147#   profiling in addition to providing a much better distribution curve
148#   provided multiple iterations happen within this function; otherwise it was
149#   slower.
150#   This might be a scratch because of the bounds placed on mu and sigma:
151#
152#   For alpha > 1 and beta > 1:
153#   mu^2 - mu^3           mu^3 - mu^2 + mu
154#   ----------- < sigma < ----------------
155#      1 + mu                  2 - mu
156#
157# def generateBeta(mu, sigma, scale, repitions=1):
158    # results = []
159#
160    # return results
161