source: framspy/gui/framsutils/FramsLib.py @ 1316

Last change on this file since 1316 was 1198, checked in by Maciej Komosinski, 22 months ago

Added simple Python GUI for Framsticks library/server

File size: 10.6 KB
RevLine 
[1198]1import sys
2#sys.path.append("..") # why was needed?
3from typing import List, Dict, Any
4import frams
5from .creature import Creature
6from gui.framsutils.framsProperty import Property
7import os
8import glm
9from .utils import parseNeuronDToOrient
10
11class FramsLib:
12        def __init__(self):
13                self.frams = frams
14                self.connected = False
15
16        def initConnection(self, frams_path: str) -> None:
17                self.frams.init(frams_path, "-t") #enable ExtValue thread synchronization with "-t"
18                #self.messageCatcher = self.frams.MessageCatcher.new() # experiments with catching messages so that they could be later displayed in GUI... but let's rather print them on console
19                #self.messageCatcher.store = 1
20                self.connected = True
21               
22        def closeConnection(self) -> None:
23                self.connected = False
24
25        def getError(self) -> None or str:
26                #if self.messageCatcher.error_count._value() > 0:
27                #       return self.messageCatcher.messages._value()
28                return None
29
30        def writeCreatureFromString(self, groupNo: int, creature: str) -> None:
31                if self.connected:
32                        self.frams.Populations[groupNo].add(creature)
33
34        def step(self):
35                if self.connected:
36                        self.frams.Simulator.step()
37
38        def start(self):
39                if self.connected:
40                        self.frams.Simulator.start()
41
42        def stop(self):
43                if self.connected:
44                        self.frams.Simulator.stop()
45
46        def info(self, path:str = "/") -> List[Property]:
47                properties: List[Property] = []
48
49                if self.connected:
50                        if path.startswith('/'):
51                                path = path[1:]
52
53                        c = 0 if path == "" else path.count("/") + 1
54
55                        if path.endswith('/'):
56                                path = path[:-1]
57
58                        if c > 0:
59                                path += '/'
60
61                        current = self.frams.sim_params
62                        G = current._groupCount()
63                        for g in range(G):
64                                Id = current._groupName(g)
65                                name = Id.rsplit(': ', 1)[-1]
66                                Id = Id.replace(": ", "/")
67                                tmpId = Id + "/"
68                                prop = Property(Id=Id, Name=name, Type="o")
69                                if(Id.count('/') == c and tmpId.startswith(path)):
70                                        prop.p["id"] = Id.split('/')[-1]
71                                        properties.append(prop)
72
73                return properties
74
75        def infoList(self, path: str) -> List[Property]:
76                properties: List[Property] = []
77                raise Exception("unimplemented/unwanted")
78                return properties
79
80        def _VstyleParserColor(self, style: str):
81                f = "color=0x"
82                idx = style.find(f)
83                if idx > -1:
84                        hx = style[idx+len(f):idx+len(f)+6]
85                        r = int(hx[0:2], 16) / 255.0
86                        g = int(hx[2:4], 16) / 255.0
87                        b = int(hx[4:6], 16) / 255.0
88                        return r, g, b
89                return None, None, None
90
91        def readCreatures(self, groupNo: int, creatureNo: int, colors):
92                ret_creatures: List[Creature] = []
93                if self.connected:
94                        groups = [self.frams.Populations[groupNo]] if groupNo != '+' else self.frams.Populations
95                        for group in groups:
96                                creatures = [group[creatureNo]] if groupNo != '+' else group
97                                for c in creatures:
98                                        creature = Creature(c.population.index._int(), c.index._int())
99                                        numparts = c.numparts._int()
100                                        numjoints = c.numjoints._int()
101                                        numneurons = c.numneurons._int()
102
103                                        vstyle = c.model.Vstyle._value()
104                                        modelR, modelG, modelB = self._VstyleParserColor(vstyle)
105
106                                        mechPart = [0,0,0]
107                                        for i in range(numparts):
108                                                if i >= c.numparts._int():
109                                                        break
110                                                mp = c.getMechPart(i)
111                                                mechPart = [mp.x._double(), mp.y._double(), mp.z._double()]
112                                                creature.mechParts.append(mechPart)
113                                                if colors:
114                                                        vstyle = mp.part.Vstyle._value()
115                                                        r, g, b = self._VstyleParserColor(vstyle)
116
117                                                        tr = mp.part.vr._value()
118                                                        tg = mp.part.vg._value()
119                                                        tb = mp.part.vb._value()
120
121                                                        if modelR is not None:
122                                                                tr = modelR
123                                                                tg = modelG
124                                                                tb = modelB
125
126                                                        if r is not None:
127                                                                tr = r
128                                                                tg = g
129                                                                tb = b
130                                                       
131                                                        creature.colorsPart.append(glm.vec3(tr, tg, tb))
132                                                       
133                                                creature.stylePart.append(mp.part.Vstyle._value())
134                                                orient = mp.orient.toVector.toString._value()
135                                                orient = orient[orient.find('[')+1:orient.find(']')]
136                                                R = glm.mat4(glm.mat3(*[float(x) for x in orient.split(',')]))
137                                                creature.partOrient.append(R)
138                                        for i in range(numjoints):
139                                                if i >= c.numjoints._int():
140                                                        break
141                                                j = c.getJoint(i)
142                                                joint = [j.p1._int(), j.p2._int()]
143                                                creature.joints.append(joint)
144                                                if colors:
145                                                        vstyle = mp.part.Vstyle._value()
146                                                        r, g, b = self._VstyleParserColor(vstyle)
147
148                                                        tr = j.vr._value()
149                                                        tg = j.vg._value()
150                                                        tb = j.vb._value()
151
152                                                        if r is not None:
153                                                                tr = r
154                                                                tg = g
155                                                                tb = b
156                                                       
157                                                        creature.colorsJoint.append(glm.vec3(tr, tg, tb))
158
159                                                creature.styleJoint.append(j.Vstyle._value())
160
161                                        for i in range(numneurons):
162                                                if i >= c.numneurons._int():
163                                                        break
164                                                n = c.getNeuroDef(i)
165                                                d = n.d._value()
166                                                creature.neurons.append((n.p._value(), n.j._value()))
167                                                creature.styleNeuron.append(d.split(':')[0])
168                                               
169                                                rorient = parseNeuronDToOrient(d)
170
171                                                creature.neuronRelativeOrient.append(rorient)
172                                        ret_creatures.append(creature)
173                return ret_creatures
174
175        def readGenePoolsGroups(self) -> Dict[str, int]:
176                genotypes = {}
177                if self.connected:
178                        for gp in self.frams.GenePools:
179                                genotypes[getattr(gp, "name")._value()] = getattr(gp, "index")._value()
180                return genotypes
181
182        def readGenePools(self, props: List[str]) -> Dict[str, List[Dict[str, Any]]]:
183                genotypes = {}
184                if self.connected:
185                        for gp in self.frams.GenePools:
186                                group = gp.name._value()
187                                genotypes[group] = []
188                                for g in gp:
189                                        genotype = {}
190                                        for p in props:
191                                                genotype[p] = getattr(g, p)._value()
192                                        genotype["group"] = group
193                                        genotypes[group].append(genotype)
194                return genotypes
195
196        def readPopulationsGroups(self) -> Dict[str, int]:
197                creatures = {}
198                if self.connected:
199                        for p in self.frams.Populations:
200                                creatures[getattr(p, "name")._value()] = getattr(p, "index")._value()
201
202                return creatures
203
204        def readPopulations(self, props: List[str]) -> Dict[str, List[Dict[str, Any]]]:
205                creatures = {}
206                if self.connected:
207                        for p in self.frams.Populations:
208                                group = p.name._value()
209                                creatures[group] = []
210                                for c in p:
211                                        creature = {}
212                                        for p in props:
213                                                creature[p] = getattr(c, p)._value()
214                                        creature["group"] = group
215                                        creatures[group].append(creature)
216                return creatures
217
218        def readCreatureInfo(self, groupNo: int, creatureNo: str) -> List[Property]:
219                properties: List[Property] = []
220                if self.connected:
221                        creature = next(pop for group in self.frams.Populations for pop in group if pop.uid._string() == creatureNo)
222                        G = creature._groupCount()
223                        for g in range(G):
224                                groupName = creature._groupName(g)
225                                for m in range(creature._memberCount(g)):
226                                        p = creature._groupMember(g, m)
227                                        t = creature._propType(p)
228                                        if t[0] and t[0] not in "xople":
229                                                prop = Property(creature._propId(p), creature._propName(p), t)
230                                                prop.p["flags"] = creature._propFlags(p)
231                                                prop.p["value"] = getattr(creature, creature._propId(p))._string()
232                                                prop.p["help"] = creature._propHelp(p)
233                                                prop.p["group"] = groupName
234                                                properties.append(prop)
235
236                return properties
237
238        def readGenotypeInfo(self, groupNo: int, genotypeNo: str) -> List[Property]:
239                properties: List[Property] = []
240                if self.connected:
241                        genotype = next(gen for group in self.frams.GenePools for gen in group if gen.uid._string() == genotypeNo)
242                        G = genotype._groupCount()
243                        for g in range(G):
244                                groupName = genotype._groupName(g)
245                                for m in range(genotype._memberCount(g)):
246                                        p = genotype._groupMember(g, m)
247                                        t = genotype._propType(p)
248                                        if t[0] and t[0] not in "xople":
249                                                prop = Property(genotype._propId(p), genotype._propName(p), t)
250                                                prop.p["flags"] = genotype._propFlags(p)
251                                                prop.p["value"] = getattr(genotype, genotype._propId(p))._string()
252                                                prop.p["help"] = genotype._propHelp(p)
253                                                prop.p["group"] = groupName
254                                                properties.append(prop)
255
256                return properties
257
258        def readPropertyInfo(self, path: str) -> List[Property]:
259                properties: List[Property] = []
260                if self.connected:
261                        if path.startswith('/'):
262                                path = path[1:]
263
264                        c = path.count("/")
265
266                        if path.endswith('/'):
267                                path = path[:-1]
268
269                        current = self.frams.sim_params
270                        G = current._groupCount()
271                        for g in range(G):
272                                Id = current._groupName(g).replace(": ", "/")
273                                groupName = current._groupName(g)
274                                if(Id.count('/') == c and Id == path):
275                                        for m in range(current._memberCount(g)):
276                                                p = current._groupMember(g, m)
277                                                t = current._propType(p)
278                                                if t[0] and t[0] not in "xole":
279                                                        prop = Property(current._propId(p), current._propName(p), t)
280                                                        if not prop.p["id"].startswith("_"):
281                                                                prop.p["flags"] = current._propFlags(p)
282                                                                prop.p["value"] = getattr(current, current._propId(p)) if t[0] == 'p' else getattr(current, current._propId(p))._string()
283                                                                prop.p["help"] = current._propHelp(p)
284                                                                prop.p["v"] = current
285                                                                prop.p["group"] = groupName
286                                                                properties.append(prop)
287                                        break
288
289                return properties
290
291        def writeCreatureInfo(self, uid: str, prop: str, value: str) -> bool:
292                if self.connected:
293                        creature = next(pop for group in self.frams.Populations for pop in group if pop.uid._string() == uid)
294                        creature.__setattr__(prop, value)
295                        return True
296                return False
297
298        def writeGenotypeInfo(self, uid: str, prop: str, value: str) -> bool:
299                if self.connected:
300                        genotype = next(gen for group in self.frams.GenePools for gen in group if gen.uid._string() == uid)
301                        genotype.__setattr__(prop, value)
302                        return True
303                return False
304
305        def writePropertyInfo(self, path: str, prop: str, value: str):
306                if self.connected:
307                        current = self.frams.sim_params
308                        current.__setattr__(prop, value)
309                        return True
310                return False
311
312        def getSimulationStatus(self) -> bool:
313                if self.connected:
314                        return True if self.frams.Simulator.running._int() == 1 else False
315                return False
316
317        def loadFile(self, path: str) -> None:
318                self.frams.Simulator.load(path)
319
320        def importFile(self, path: str, options: int) -> None:
321                self.frams.Simulator.ximport(path, options)
322
323        def saveFile(self, path: str, options: int) -> None:
324                path = os.path.relpath(path, self.frams.res_dir + "\\scripts_output")
325                self.frams.Simulator.export(path, options, -1, -1)
326
327        def getWorldType(self) -> int:
328                return self.frams.World.wrldtyp._value()
329
330        def getWorldSize(self) -> float:
331                return self.frams.World.wrldsiz._value()
332
333        def getWorldWaterLevel(self) -> float:
334                return self.frams.World.wrldwat._value()
335
336        def getWorldBoundaries(self) -> int:
337                return self.frams.World.wrldbnd._value()
338
339        def getWorldMap(self) -> str:
340                return self.frams.WorldMap.getAsString("", "")._value()
341
342        def getSimtype(self) -> int:
343                return self.frams.World.simtype._value()
Note: See TracBrowser for help on using the repository browser.