GeneratorExample.py

GeneratorExample.py#

:GeneratorExample.py
GeneratorExample.py

Non-destructive geometry generator example

1# The basic generator example, just to demonstrate the principles of generators, look the \ref TreesGenerator.cpp for the more sophisticated example.
2
3import coat
4import random
5
6# This is the simplest non-destructive generator example.
7# It is registered as tool in the Sculpt->Objects tools section.
8# The tool name is the same as the class name
9
10class SimpleGenerator:
11 # initialize the parameters
12 def __init__(self):
13 super().__init__()
14 self.numSpheres = 200
15 self.FigureRadius = 30
16 self.FigureRadiusVariation = 0.1
17 self.SpheresRadius = 10
18 self.SpheresRadiusVariation = 0.5
19 self.Seed = 0
20 # load the sphere mesh
21 self.m = coat.Mesh()
22 self.m.Read("data/Samples/Sphere.obj")
23
24 # the default names alias for the generated objects
25 def getDefaultObjectName(self) :
26 return "Spheres"
27
28 # expose the generator parameters
29 def ui(self) :
30 return [
31 "numSpheres,[1,1000]",
32 "FigureRadius,[1,100]",
33 "FigureRadiusVariation,[0,100]",
34 "SpheresRadius,[1,100]",
35 "SpheresRadiusVariation,[0,100]",
36 "Seed,[0,10000]"
37 ]
38
39 # generate random value with variation, it is just helper
40 def random_var(value, variation) :
41 return random.uniform(value, value * (1.0 + variation))
42
43 # generate the example object, in this case it are the random spheres
44 def generate(self, v) :
45 random.seed(self.Seed)
46 # Coat's random generator used in coat.vec3.RandNormal(), so need to set seed for it too
47 coat.math.Randomize(self.Seed)
48 # the mesh shere we collect objects
49 summ = coat.Mesh()
50 for i in range(self.numSpheres) :
51 # create transformation matrix.
52 # scaling to the sphere radius
53 transform = coat.mat4.Scaling(SimpleGenerator.random_var(self.SpheresRadius, self.SpheresRadiusVariation))
54 # translate using the random vector
55 dv = coat.vec3.RandNormal() * SimpleGenerator.random_var(self.FigureRadius, self.FigureRadiusVariation)
56 tr=coat.mat4.Translation(dv)
57 transform = transform * tr
58 # add the sphere to the summary mesh
59 summ.addTransformed(self.m, transform)
60 # insert the collection into the scene
61 v.mergeMesh(summ, coat.mat4.Identity, coat.BoolOpType.BOOL_MERGE)
62
63 # fast and rough generating, the function is overriden from the SculptGenerator
64 def GeneratePreview(self, scene) :
65 # we remove previously generates object
66 scene.removeSubtree()
67 # we add the new object as sub-object to the current
68 t = scene.addChild("Simple")
69 v = t.Volume()
70 # turn the new volume to surface
71 v.toSurface()
72 # resore to the identoty transform
73 t.setTransform(coat.mat4.Identity)
74 # we generate as if there is no transform
75 self.generate(t.Volume())
76 # we apply the transform that user made manually
77 t.setTransform(t.getTransform() * scene.getTransform())
78 # we select the generated object
79 scene.selectOne()
80
81 # generage the object in "final quality", the function is overriden from the SculptGenerator
82 def GenerateFinalObject(self, scene) :
83 # in simplest case the final quality object is same as preview
84 self.GeneratePreview(scene)
85
86# there we check if generator with same name already registered
87present = coat.ui.checkIfExtensionPresent("SimpleGenerator")
88# this command inserts the generatior into the toolset, Sculpt->Objects->SimpleGenerator
89# if generater already registered, it is replaced with the new one
90coat.ui.addExtension("Voxels","Objects",SimpleGenerator())
91# we do it only first time when we register the tool:
92if not present :
93 coat.ui.toRoom("Sculpt")
94 # activate the tool
95 coat.ui.cmd("$SimpleGenerator")
:GeneratorExample.py
 1     # The basic generator example, just to demonstrate the principles of generators, look the \ref TreesGenerator.cpp for the more sophisticated example.
 2
 3     import coat
 4     import random
 5
 6     # This is the simplest non-destructive generator example.
 7     # It is registered as tool in the Sculpt->Objects tools section.
 8     # The tool name is the same as the class name
 9
10     class SimpleGenerator:
11             # initialize the parameters
12             def __init__(self):
13                     super().__init__()
14                     self.numSpheres = 200
15                     self.FigureRadius = 30
16                     self.FigureRadiusVariation = 0.1
17                     self.SpheresRadius = 10
18                     self.SpheresRadiusVariation = 0.5
19                     self.Seed = 0
20                     # load the sphere mesh
21                     self.m = coat.Mesh()
22                     self.m.Read("data/Samples/Sphere.obj")
23
24             # the default names alias for the generated objects
25             def getDefaultObjectName(self) :
26                     return "Spheres"
27
28             # expose the generator parameters
29             def ui(self) :
30                     return [
31                             "numSpheres,[1,1000]",
32                             "FigureRadius,[1,100]",
33                             "FigureRadiusVariation,[0,100]",
34                             "SpheresRadius,[1,100]",
35                             "SpheresRadiusVariation,[0,100]",
36                             "Seed,[0,10000]"
37                     ]
38
39             # generate random value with variation, it is just helper
40             def random_var(value, variation) :
41                     return random.uniform(value, value * (1.0 + variation))
42
43             # generate the example object, in this case it are the random spheres
44             def generate(self, v) :
45                     random.seed(self.Seed)
46                     # Coat's random generator used in coat.vec3.RandNormal(), so need to set seed for it too
47                     coat.math.Randomize(self.Seed)
48                     # the mesh shere we collect objects
49                     summ = coat.Mesh()
50                     for i in range(self.numSpheres) :
51                             # create transformation matrix.
52                             # scaling to the sphere radius
53                             transform = coat.mat4.Scaling(SimpleGenerator.random_var(self.SpheresRadius, self.SpheresRadiusVariation))
54                             # translate using the random vector
55                             dv = coat.vec3.RandNormal() * SimpleGenerator.random_var(self.FigureRadius, self.FigureRadiusVariation)
56                             tr=coat.mat4.Translation(dv)
57                             transform = transform * tr
58                             # add the sphere to the summary mesh
59                             summ.addTransformed(self.m, transform)
60                     # insert the collection into the scene
61                     v.mergeMesh(summ, coat.mat4.Identity, coat.BoolOpType.BOOL_MERGE)
62
63             # fast and rough generating, the function is overriden from the SculptGenerator
64             def GeneratePreview(self, scene) :
65                     # we remove previously generates object
66                     scene.removeSubtree()
67                     # we add the new object as sub-object to the current
68                     t = scene.addChild("Simple")
69                     v = t.Volume()
70                     # turn the new volume to surface
71                     v.toSurface()
72                     # resore to the identoty transform
73                     t.setTransform(coat.mat4.Identity)
74                     # we generate as if there is no transform
75                     self.generate(t.Volume())
76                     # we apply the transform that user made manually
77                     t.setTransform(t.getTransform() * scene.getTransform())
78                     # we select the generated object
79                     scene.selectOne()
80
81             # generage the object in "final quality", the function is overriden from the SculptGenerator
82             def GenerateFinalObject(self, scene) :
83                     # in simplest case the final quality object is same as preview
84                     self.GeneratePreview(scene)
85
86     # there we check if generator with same name already registered
87     present = coat.ui.checkIfExtensionPresent("SimpleGenerator")
88     # this command inserts the generatior into the toolset, Sculpt->Objects->SimpleGenerator
89     # if generater already registered, it is replaced with the new one
90     coat.ui.addExtension("Voxels","Objects",SimpleGenerator())
91     # we do it only first time when we register the tool:
92     if not present :
93             coat.ui.toRoom("Sculpt")
94             # activate the tool
95             coat.ui.cmd("$SimpleGenerator")