def makeTile(x,y,tile):
     # the idea here is to make
     # all the needed nodes,
     # then instance them to all the LODNode's children that show them
     
     x2=x+size
     y2=y+size
     
     tileCenter=Vec3(x+x2,y+y2,0)/2
     
     collisionNode=NodePath(CollisionNode("tile_collisionNode")) if collision else None
     
     for l in levels: l.initForTile(tile)
     for f,levs in factoryToLevels.iteritems():
         f.draw(dict((l.lod,l.drawResourcesFactory) for l in levs),x,y,x2,y2,tileCenter,collisionNode)
         
     collisionUtil.colTree(collisionNode)
     lodNode=LODNode('tile_lod')
     lodNodePath=NodePath(lodNode)
     
     subTileNodeLists=[]
     s=size/2
     for f in subTileFactories:
         nodeList=[f(x,y,tile),f(x+s,y,tile),f(x,y+s,tile),f(x+s,y+s,tile)]
         subTileNodeLists.append(nodeList)
     
     for l in levels: l.finishTile()
     
     lodNodePath.setPos(tileCenter)
     if collision: collisionNode.setPos(tileCenter)
     for lod,levs in LODAndLevelList:
         holder=NodePath("holder")
         # instance regular meshes 
         for l in levs:
             n=l.node
             if n is not None:
                 n.instanceTo(holder)
         # instance subtile LOD nodes 
         if lod in LODtoSubTileFactoryIndexs:
             for i in LODtoSubTileFactoryIndexs[lod]:
                 for n in subTileNodeLists[i]:
                     instanceTo(holder)
                     
         holder.reparentTo(lodNodePath)
         lodNode.addSwitch(lod.high,lod.low)
     
     # TODO, better center LOD Node using bounds
     # lodNode.setCenter()
     
     for l in levels: l.clean()
     
     if collision:
         tileHolder=NodePath("tile_holder")
         collisionNode.reparentTo(tileHolder)
         lodNodePath.reparentTo(tileHolder)
         return tileHolder
     else:
         return lodNodePath
    def CreateGfx(self, loader, idx):
        #                __node
        #                /   \
        #  cellsNodePath   columnBox

        self.lod = LODNode("columnLOD")  # Level of detail node for Column
        self.__node = NodePath(
            self.lod
        )  # NodePath(PandaNode('column'))# loader.loadModel("models/box")
        self.__node.setPos(0, 0, 0)
        self.__node.setScale(1, 1, 1)

        self.idx = idx

        # self.__node.setTag('clickable',str(idx))#to be able to click on it

        self.__rhombusEnvelope = loader.loadModel(
            os.path.join(os.getcwd(), "models/rhombus"))
        self.__rhombusEnvelope.setPos(self.width / 2, self.width / 2, 0.0)

        self.__rhombusEnvelope.setScale(self.width / 2, self.width / 2, 0.5)
        self.__rhombusEnvelope.setName("columnBox")

        self.__cellsNodePath = NodePath(
            PandaNode("cellsNode"))  # to pack all cells into one node path
        self.__cellsNodePath.setName("column")
        self.__cellsNodePath.setTag(
            "id",
            str(idx))  # to be able to retrieve index of column for mouse click

        self.lod.addSwitch(100.0, 0.0)
        self.lod.addSwitch(5000.0, 100.0)

        self.__cellsNodePath.reparentTo(self.__node)
        self.__rhombusEnvelope.reparentTo(self.__node)

        x = 0
        y = 0
        idx = 0
        for n in self.cells:
            n.CreateGfx(loader, idx)
            idx += 1

            pos = self._TransformRhombToGlob([x, y], 1 + self.CELL_OFFSET, 0.0)

            n.getNode().setPos(pos[0], pos[1], 0)

            x += 1
            if x >= self.nOfCellsPerAxis:
                y += 1
                x = 0

            n.getNode().reparentTo(self.__cellsNodePath)

        self.gfxCreated = True
    def CreateGfx(self, loader, idx):
        #                __node
        #                /   \
        #  cellsNodePath   columnBox

        self.lod = LODNode("columnLOD")  # Level of detail node for Column
        self.__node = NodePath(
            self.lod
        )  # NodePath(PandaNode('column'))# loader.loadModel("models/box")
        self.__node.setPos(0, 0, 0)
        self.__node.setScale(1, 1, 1)

        self.idx = idx

        # self.__node.setTag('clickable',str(idx))#to be able to click on it

        self.__columnBox = loader.loadModel(os.path.join(os.getcwd(),"models/cube"))
        self.__columnBox.setPos(
            0, 0, -0.5 + (0 if len(self.cells) == 0 else len(self.cells)*(1+CELL_OFFSET) / 2)
        )
        self.__columnBox.setScale(
            0.5, 0.5, 0.5 * (1 if len(self.cells) == 0 else len(self.cells)*(1+CELL_OFFSET))
        )
        self.__columnBox.setName("columnBox")

        self.__cellsNodePath = NodePath(
            PandaNode("cellsNode")
        )  # to pack all cells into one node path
        self.__cellsNodePath.setName("column")
        self.__cellsNodePath.setTag(
            "id", str(idx)
        )  # to be able to retrieve index of column for mouse click

        self.lod.addSwitch(100.0, 0.0)
        self.lod.addSwitch(5000.0, 100.0)

        self.__cellsNodePath.reparentTo(self.__node)
        self.__columnBox.reparentTo(self.__node)

        z = 0
        idx = 0
        for n in self.cells:
            n.CreateGfx(loader, idx)
            idx += 1
            n.getNode().setPos(0, 0, z)
            z += 1+CELL_OFFSET
            n.getNode().reparentTo(self.__cellsNodePath)

        self.gfxCreated = True
Exemple #4
0
 def make_lod(self):
     shapes = loader.load_model("assets/shapes.bam")
     for shape in shapes.get_children():
         lod = LODNode(shape.name+ "_lod")
         lod_root = NodePath(lod)
         self.shapes[shape.name] = lod_root
         lod_shapes = list(shape.get_children())
         lod_shapes.sort(key=lambda x: x.name, reverse=True)
         prev = 2
         for l, lod_shape in enumerate(lod_shapes):
             lod_shape.clear_transform()
             far, near = ((l+2)*4)*100, prev-2
             lod.add_switch(far, near)
             lod_shape.reparent_to(lod_root)
             prev = far
Exemple #5
0
 def __init__(self, name, scene, visibleLODsDict={"eggfileName":("maxFar","minNear")}, collisionEgg=None, x0=0, y0=0, z0=0, parent=None, margin=0.02, mass=0,
              directRender=True, convex=True):
     self.name = name
     self.scene = scene
     NodePath.__init__(self,LODNode(name+"_LODNode"))
     ###LOD###
     for k in visibleLODsDict.keys():
         v=base.loader.loadModel(k)
         v.reparentTo(self)
         self.node().addSwitch(visibleLODsDict[k][0],visibleLODsDict[k][1])
     #########
     self.body = BulletRigidBodyNode(self.name + "_RigidBody")
     self.attachNewNode(self.body)
     if collisionEgg != None:
         m = self.scene.Base.loader.loadModel(collisionEgg)
         if convex:
             sTuple = modelToConvex(m)
         else:
             sTuple = modelToShape(m)
         sTuple[0].setMargin(margin)
         self.body.addShape(sTuple[0], sTuple[1])
         self.body.setMass(mass)
         self.body.setPythonTag("name", self.name + "_RigidBody")
         self.scene.world.attachRigidBody(self.body)
     self.setPos(x0, y0, z0)
     if directRender:
         self.reparentTo(self.scene.Base.render)
     elif parent != None:
         self.reparentTo(parent)
Exemple #6
0
    def __init__(self):
        # The basics
        ShowBase.__init__(self)
        base.disableMouse()
        # Add the model

        lod = LODNode('Tree LOD node')
        tree = NodePath(lod)
        tree.reparentTo(render)

        tree2 = self.loader.loadModel("tree2")
        lod.addSwitch(50.0, 0.0)
        tree2.reparentTo(tree)

        tree1 = self.loader.loadModel("tree1")
        lod.addSwitch(100.0, 50.0)
        tree1.reparentTo(tree)

        tree0 = self.loader.loadModel("tree0")
        lod.addSwitch(999999.0, 100.0)
        tree0.reparentTo(tree)

        # Bookkeeping for the rotation around the model
        self.direction = 0.0
        self.distance = 20.0
        self.speed = 20.0
        self.last_time = 0.0

        # Initial camera setup
        self.camera.set_pos(0, -self.distance, self.distance)
        self.camera.look_at(0, 0, 5)

        # Key events and camera movement task
        self.accept("arrow_up", self.adjust_distance, [-1.0])
        self.accept("arrow_up-up", self.adjust_distance, [1.0])
        self.accept("arrow_down", self.adjust_distance, [1.0])
        self.accept("arrow_down-up", self.adjust_distance, [-1.0])
        self.accept("escape", sys.exit)
        self.taskMgr.add(self.update_camera, 'adjust camera', sort=10)
    def __init__(self):
        # The basics
        ShowBase.__init__(self)
        base.disableMouse()
        # Add the model
        
        lod = LODNode('Tree LOD node')
        tree = NodePath(lod)
        tree.reparentTo(render)
        
        tree2 = self.loader.loadModel("tree2")
        lod.addSwitch(50.0, 0.0)
        tree2.reparentTo(tree)
        
        tree1 = self.loader.loadModel("tree1")
        lod.addSwitch(100.0, 50.0)
        tree1.reparentTo(tree)
        
        tree0 = self.loader.loadModel("tree0")
        lod.addSwitch(999999.0, 100.0)
        tree0.reparentTo(tree)
        
        # Bookkeeping for the rotation around the model
        self.direction = 0.0
        self.distance = 20.0
        self.speed = 20.0
        self.last_time = 0.0

        # Initial camera setup
        self.camera.set_pos(0, -self.distance, self.distance)
        self.camera.look_at(0,0,5)

        # Key events and camera movement task
        self.accept("arrow_up", self.adjust_distance, [-1.0])
        self.accept("arrow_up-up", self.adjust_distance, [1.0])
        self.accept("arrow_down", self.adjust_distance, [1.0])
        self.accept("arrow_down-up", self.adjust_distance, [-1.0])
        self.accept("escape", sys.exit)
        self.taskMgr.add(self.update_camera, 'adjust camera', sort = 10)
Exemple #8
0
class cMinicolumn:
    def __init__(self, nameOfLayer, nOfCellsPerColumn):
        self.cells = []
        for i in range(nOfCellsPerColumn):
            n = cCell(self)
            self.cells.append(n)

        self.parentLayer = nameOfLayer
        self.transparency = 1.0
        self.gfxCreated = False
        self.LodDistance1Stored = 100.0
        self.LodDistance2Stored = 5000.0

        self.bursting = False
        self.active = False
        self.oneOfCellPredictive = False
        self.oneOfCellCorrectlyPredicted = False
        self.oneOfCellFalselyPredicted = False

    def CreateGfx(self, loader, idx):
        #                __node
        #                /   \
        #  cellsNodePath   columnBox

        self.lod = LODNode("columnLOD")  # Level of detail node for Column
        self.__node = NodePath(
            self.lod
        )  # NodePath(PandaNode('column'))# loader.loadModel("models/box")
        self.__node.setPos(0, 0, 0)
        self.__node.setScale(1, 1, 1)

        # self.__node.setTag('clickable',str(idx))#to be able to click on it

        self.__columnBox = loader.loadModel("models/cube")
        self.__columnBox.setPos(
            0, 0, -0.5 + (0 if len(self.cells) == 0 else len(self.cells) *
                          (1 + CELL_OFFSET) / 2))
        self.__columnBox.setScale(
            0.5, 0.5, 0.5 * (1 if len(self.cells) == 0 else len(self.cells) *
                             (1 + CELL_OFFSET)))
        self.__columnBox.setName("columnBox")

        self.__cellsNodePath = NodePath(
            PandaNode("cellsNode"))  # to pack all cells into one node path
        self.__cellsNodePath.setName("column")
        self.__cellsNodePath.setTag(
            "id",
            str(idx))  # to be able to retrieve index of column for mouse click

        self.lod.addSwitch(100.0, 0.0)
        self.lod.addSwitch(5000.0, 100.0)

        self.__cellsNodePath.reparentTo(self.__node)
        self.__columnBox.reparentTo(self.__node)

        z = 0
        idx = 0
        for n in self.cells:
            n.CreateGfx(loader, idx)
            idx += 1
            n.getNode().setPos(0, 0, z)
            z += 1 + CELL_OFFSET
            n.getNode().reparentTo(self.__cellsNodePath)

        self.gfxCreated = True

    def LODUpdateSwitch(self, lodDistance, lodDistance2):
        self.lodDistance1Stored = lodDistance
        self.lodDistance2Stored = lodDistance2

        self.lod.clearSwitches()
        self.lod.addSwitch(lodDistance, 0.0)
        self.lod.addSwitch(lodDistance2, lodDistance)

    def LODUpdateSwitch_long(self):
        self.lod.clearSwitches()
        self.lod.addSwitch(self.lodDistance2Stored, 0.0)
        self.lod.addSwitch(self.lodDistance2Stored, self.lodDistance2Stored)

    def LODUpdateSwitch_normal(self):
        self.LODUpdateSwitch(self.lodDistance1Stored, self.lodDistance2Stored)

    def UpdateState(self, bursting, activeColumn, oneOfCellPredictive,
                    oneOfCellCorrectlyPredicted, oneOfCellFalselyPredicted):

        self.bursting = bursting
        self.active = activeColumn
        self.oneOfCellPredictive = oneOfCellPredictive
        self.oneOfCellCorrectlyPredicted = oneOfCellCorrectlyPredicted
        self.oneOfCellFalselyPredicted = oneOfCellFalselyPredicted

        # update column box color (for LOD in distance look)
        if self.oneOfCellCorrectlyPredicted:
            COL_COLUMN_ONEOFCELLCORRECTLY_PREDICTED.setW(self.transparency)
            col = COL_COLUMN_ONEOFCELLCORRECTLY_PREDICTED
            self.__columnBox.setColor(col)
        elif self.oneOfCellFalselyPredicted:
            COL_COLUMN_ONEOFCELLFALSELY_PREDICTED.setW(self.transparency)
            col = COL_COLUMN_ONEOFCELLFALSELY_PREDICTED
            self.__columnBox.setColor(col)
        elif self.oneOfCellPredictive:
            COL_COLUMN_ONEOFCELLPREDICTIVE.setW(self.transparency)
            col = COL_COLUMN_ONEOFCELLPREDICTIVE
            self.__columnBox.setColor(col)
        elif self.active:
            COL_COLUMN_ACTIVE.setW(self.transparency)
            col = COL_COLUMN_ACTIVE
            self.__columnBox.setColor(col)
        else:
            COL_COLUMN_INACTIVE.setW(self.transparency)
            col = COL_COLUMN_INACTIVE
            self.__columnBox.setColor(col)

#        for n in self.cells:
#            n.active = active
#            n.UpdateState()

    def getNode(self):
        return self.__node

    def updateWireframe(self, value):
        for cell in self.cells:
            cell.updateWireframe(value)
        if value:
            self.__columnBox.setRenderModeFilledWireframe(LColor(0, 0, 0, 1.0))
        else:
            self.__columnBox.setRenderModeFilled()

    # -- Create proximal synapses
    # inputObjects - list of names of inputs(areas)
    # inputs - panda vis input object
    # synapses - list of the second points of synapses (first point is this cortical column)
    # NOTE: synapses are now DENSE
    def CreateProximalSynapses(self, inputObjects, inputs, synapses):

        for child in self.__cellsNodePath.getChildren():
            if child.getName() == "ProximalSynapseLine":
                child.removeNode()

        printLog("Creating proximal synapses", verbosityMedium)
        printLog("To inputs called:" + str(inputObjects), verbosityMedium)
        printLog("Synapses count:" + str(len(synapses)), verbosityMedium)
        printLog("active:" + str(sum([i for i in synapses])), verbosityHigh)

        # inputs are divided into separate items in list - [input1,input2,input3]
        # synapses are one united array [1,0,0,1,0,1,0...]
        # length is the same

        # synapses can be connected to one input or to several inputs
        # if to more than one - split synapses array
        synapsesDiv = []
        offset = 0
        for inputObj in inputObjects:
            synapsesDiv.append(synapses[offset:offset +
                                        inputs[inputObj].count])
            offset += inputs[inputObj].count

        for i in range(len(synapsesDiv)):  # for each input object

            inputs[
                inputObjects[i]].resetProximalFocus()  # clear color highlight

            for y in range(len(synapsesDiv[i])
                           ):  # go through every synapse and check activity
                if synapsesDiv[i][y] == 1:

                    form = GeomVertexFormat.getV3()
                    vdata = GeomVertexData("ProximalSynapseLine", form,
                                           Geom.UHStatic)
                    vdata.setNumRows(1)
                    vertex = GeomVertexWriter(vdata, "vertex")

                    vertex.addData3f(
                        inputs[inputObjects[i]].inputBits[y].getNode().getPos(
                            self.__node))
                    vertex.addData3f(0, 0, 0)
                    # vertex.addData3f(self.__node.getPos())
                    # printLog("Inputs:"+str(i)+"bits:"+str(y))
                    # printLog(inputs[i].inputBits[y].getNode().getPos(self.__node))

                    # highlight
                    inputs[inputObjects[i]].inputBits[y].setProximalFocus(
                    )  # highlight connected bits

                    prim = GeomLines(Geom.UHStatic)
                    prim.addVertices(0, 1)

                    geom = Geom(vdata)
                    geom.addPrimitive(prim)

                    node = GeomNode("ProximalSynapse")
                    node.addGeom(geom)

                    nodePath = self.__cellsNodePath.attachNewNode(node)

                    nodePath.setRenderModeThickness(2)
                    # color of the line
                    if inputs[inputObjects[i]].inputBits[y].active:
                        nodePath.setColor(COL_PROXIMAL_SYNAPSES_ACTIVE)
                    else:
                        nodePath.setColor(COL_PROXIMAL_SYNAPSES_INACTIVE)

    def setTransparency(self, transparency):
        self.transparency = transparency
        for cell in self.cells:
            cell.setTransparency(transparency)

        self.UpdateState(self.bursting, self.active, self.oneOfCellPredictive,
                         self.oneOfCellCorrectlyPredicted,
                         self.oneOfCellFalselyPredicted)

    def DestroyProximalSynapses(self):
        for syn in self.__cellsNodePath.findAllMatches("ProximalSynapse"):
            syn.removeNode()

    def DestroyDistalSynapses(self):
        for cell in self.cells:
            cell.DestroyDistalSynapses()
            cell.resetPresynapticFocus()  # also reset distal focus

    def getDescription(self):
        txt = ""
        txt += "Active:" + str(self.active) + "\n"
        txt += "One of cell is predictive:" + str(
            self.oneOfCellPredictive) + "\n"
        txt += "One of cell correctly predicted:" + str(
            self.oneOfCellCorrectlyPredicted) + "\n"
        txt += "One of cell false predicted:" + str(
            self.oneOfCellFalselyPredicted) + "\n"
        return txt
Exemple #9
0
        def makeTile(x, y, tile):
            # the idea here is to make
            # all the needed nodes,
            # then instance them to all the LODNode's children that show them

            x2 = x + size
            y2 = y + size

            tileCenter = Vec3(x + x2, y + y2, 0) / 2

            collisionNode = NodePath(
                CollisionNode("tile_collisionNode")) if collision else None

            for l in levels:
                l.initForTile(tile)
            for f, levs in factoryToLevels.iteritems():
                f.draw(dict((l.lod, l.drawResourcesFactory) for l in levs), x,
                       y, x2, y2, tileCenter, collisionNode)

            collisionUtil.colTree(collisionNode)
            lodNode = LODNode('tile_lod')
            lodNodePath = NodePath(lodNode)

            subTileNodeLists = []
            s = size / 2
            for f in subTileFactories:
                nodeList = [
                    f(x, y, tile),
                    f(x + s, y, tile),
                    f(x, y + s, tile),
                    f(x + s, y + s, tile)
                ]
                subTileNodeLists.append(nodeList)

            for l in levels:
                l.finishTile()

            lodNodePath.setPos(tileCenter)
            if collision: collisionNode.setPos(tileCenter)
            for lod, levs in LODAndLevelList:
                holder = NodePath("holder")
                # instance regular meshes
                for l in levs:
                    n = l.node
                    if n is not None:
                        n.instanceTo(holder)
                # instance subtile LOD nodes
                if lod in LODtoSubTileFactoryIndexs:
                    for i in LODtoSubTileFactoryIndexs[lod]:
                        for n in subTileNodeLists[i]:
                            instanceTo(holder)

                holder.reparentTo(lodNodePath)
                lodNode.addSwitch(lod.high, lod.low)

            # TODO, better center LOD Node using bounds
            # lodNode.setCenter()

            for l in levels:
                l.clean()

            if collision:
                tileHolder = NodePath("tile_holder")
                collisionNode.reparentTo(tileHolder)
                lodNodePath.reparentTo(tileHolder)
                return tileHolder
            else:
                return lodNodePath
Exemple #10
0
class cMinicolumn:
    def __init__(self, nameOfLayer, nOfCellsPerColumn):
        self.cells = []
        self.nOfCellsPerColumn = nOfCellsPerColumn

        for i in range(nOfCellsPerColumn):
            n = cCell(self)
            self.cells.append(n)

        self.idx = -1
        self.parentLayer = nameOfLayer
        self.transparency = 1.0
        self.gfxCreated = False
        self.LodDistance1Stored = 100.0
        self.LodDistance2Stored = 5000.0

        self.bursting = False
        self.active = False
        self.oneOfCellPredictive = False
        self.oneOfCellCorrectlyPredicted = False
        self.oneOfCellFalselyPredicted = False

        self.cntSegments = None  # info about how many segments are on this cell

    def CreateGfx(self, loader, idx):
        #                __node
        #                /   \
        #  cellsNodePath   columnBox

        self.lod = LODNode("columnLOD")  # Level of detail node for Column
        self.__node = NodePath(
            self.lod
        )  # NodePath(PandaNode('column'))# loader.loadModel("models/box")
        self.__node.setPos(0, 0, 0)
        self.__node.setScale(1, 1, 1)

        self.idx = idx

        # self.__node.setTag('clickable',str(idx))#to be able to click on it

        self.__columnBox = loader.loadModel(
            os.path.join(os.getcwd(), "models/cube"))
        self.__columnBox.setPos(
            0, 0, -0.5 + (0 if len(self.cells) == 0 else len(self.cells) *
                          (1 + CELL_OFFSET) / 2))
        self.__columnBox.setScale(
            0.5, 0.5, 0.5 * (1 if len(self.cells) == 0 else len(self.cells) *
                             (1 + CELL_OFFSET)))
        self.__columnBox.setName("columnBox")

        self.__cellsNodePath = NodePath(
            PandaNode("cellsNode"))  # to pack all cells into one node path
        self.__cellsNodePath.setName("column")
        self.__cellsNodePath.setTag(
            "id",
            str(idx))  # to be able to retrieve index of column for mouse click

        self.lod.addSwitch(100.0, 0.0)
        self.lod.addSwitch(5000.0, 100.0)

        self.__cellsNodePath.reparentTo(self.__node)
        self.__columnBox.reparentTo(self.__node)

        z = 0
        idx = 0
        for n in self.cells:
            n.CreateGfx(loader, idx)
            idx += 1
            n.getNode().setPos(0, 0, z)
            z += 1 + CELL_OFFSET
            n.getNode().reparentTo(self.__cellsNodePath)

        self.gfxCreated = True

    def LODUpdateSwitch(self, lodDistance, lodDistance2):
        self.lodDistance1Stored = lodDistance
        self.lodDistance2Stored = lodDistance2

        self.lod.clearSwitches()
        self.lod.addSwitch(lodDistance, 0.0)
        self.lod.addSwitch(lodDistance2, lodDistance)

    def LODUpdateSwitch_long(self):
        self.lod.clearSwitches()
        self.lod.addSwitch(self.lodDistance2Stored, 0.0)
        self.lod.addSwitch(self.lodDistance2Stored, self.lodDistance2Stored)

    def LODUpdateSwitch_normal(self):
        self.LODUpdateSwitch(self.lodDistance1Stored, self.lodDistance2Stored)

    def UpdateState(self, bursting, activeColumn, oneOfCellPredictive,
                    oneOfCellCorrectlyPredicted, oneOfCellFalselyPredicted):

        self.bursting = bursting
        self.active = activeColumn
        self.oneOfCellPredictive = oneOfCellPredictive
        self.oneOfCellCorrectlyPredicted = oneOfCellCorrectlyPredicted
        self.oneOfCellFalselyPredicted = oneOfCellFalselyPredicted

        # update column box color (for LOD in distance look)
        if self.oneOfCellCorrectlyPredicted:
            COL_COLUMN_ONEOFCELLCORRECTLY_PREDICTED.setW(self.transparency)
            col = COL_COLUMN_ONEOFCELLCORRECTLY_PREDICTED
            self.__columnBox.setColor(col)
        elif self.oneOfCellFalselyPredicted:
            COL_COLUMN_ONEOFCELLFALSELY_PREDICTED.setW(self.transparency)
            col = COL_COLUMN_ONEOFCELLFALSELY_PREDICTED
            self.__columnBox.setColor(col)
        elif self.bursting:
            COL_COLUMN_BURSTING.setW(self.transparency)
            col = COL_COLUMN_BURSTING
            self.__columnBox.setColor(col)
        elif self.active and self.oneOfCellPredictive:
            COL_COLUMN_ACTIVE_AND_ONEOFCELLPREDICTIVE.setW(self.transparency)
            col = COL_COLUMN_ACTIVE_AND_ONEOFCELLPREDICTIVE
            self.__columnBox.setColor(col)
        elif self.oneOfCellPredictive:
            COL_COLUMN_ONEOFCELLPREDICTIVE.setW(self.transparency)
            col = COL_COLUMN_ONEOFCELLPREDICTIVE
            self.__columnBox.setColor(col)
        elif self.active:
            COL_COLUMN_ACTIVE.setW(self.transparency)
            col = COL_COLUMN_ACTIVE
            self.__columnBox.setColor(col)

        else:
            COL_COLUMN_INACTIVE.setW(self.transparency)
            col = COL_COLUMN_INACTIVE
            self.__columnBox.setColor(col)

#        for n in self.cells:
#            n.active = active
#            n.UpdateState()

    def getNode(self):
        return self.__node

    def updateWireframe(self, value):
        for cell in self.cells:
            cell.updateWireframe(value)
        if value:
            self.__columnBox.setRenderModeFilledWireframe(LColor(0, 0, 0, 1.0))
        else:
            self.__columnBox.setRenderModeFilled()

    def CreateSynapses(self, regionObjects, columnConnections, synapsesType,
                       sourceRegions, activeOnly):
        printLog("Creating synapses", verbosityMedium)

        ConnectionFactory.CreateSynapses(
            callbackCreateSynapse=self._CreateOneSynapse,
            synapsesType=synapsesType,
            regionObjects=regionObjects,
            connections=columnConnections,
            idx=self.idx,
            sourceRegions=sourceRegions,
            activeOnly=activeOnly)

        for arr in columnConnections:
            if arr[0] == self.idx:  # find this column
                self.cntSegments = len(arr[1])
                break

    # creates synapse, that will go from presynCell to this cell
    # presynCell - cell object
    def _CreateOneSynapse(self, presynCell, synapsesType):

        form = GeomVertexFormat.getV3()
        vdata = GeomVertexData("SynapseLine", form, Geom.UHStatic)
        vdata.setNumRows(1)
        vertex = GeomVertexWriter(vdata, "vertex")

        vertex.addData3f(presynCell.getNode().getPos(self.__node))
        vertex.addData3f(0, 0, 0)
        # vertex.addData3f(self.__node.getPos())
        # printLog("inputObj:"+str(i)+"bits:"+str(y))
        # printLog(inputObj[i].inputBits[y].getNode().getPos(self.__node))

        prim = GeomLines(Geom.UHStatic)
        prim.addVertices(0, 1)

        geom = Geom(vdata)
        geom.addPrimitive(prim)

        node = GeomNode("Synapse_" + str(synapsesType))
        node.addGeom(geom)

        nodePath = self.__cellsNodePath.attachNewNode(node)

        nodePath.setRenderModeThickness(2)
        # color of the line
        if presynCell.active:
            nodePath.setColor(COL_PROXIMAL_SYNAPSES_ACTIVE)
        else:
            nodePath.setColor(COL_PROXIMAL_SYNAPSES_INACTIVE)

    def setTransparency(self, transparency):
        self.transparency = transparency
        for cell in self.cells:
            cell.setTransparency(transparency)

        self.UpdateState(self.bursting, self.active, self.oneOfCellPredictive,
                         self.oneOfCellCorrectlyPredicted,
                         self.oneOfCellFalselyPredicted)

    def DestroySynapses(self, synapseType=None):
        if synapseType is None:
            synapseType = '*'

        if not self.gfxCreated:
            return

        if synapseType == 'proximal':
            for syn in self.__cellsNodePath.findAllMatches("Synapse_" +
                                                           str(synapseType)):
                syn.removeNode()

        for cell in self.cells:
            cell.DestroySynapses(synapseType)

    def getDescription(self):
        txt = ""
        txt += "ID:" + str(self.idx) + "\n"
        txt += "Active:" + str(self.active) + "\n"
        txt += "One of cell is predictive:" + str(
            self.oneOfCellPredictive) + "\n"
        txt += "One of cell correctly predicted:" + str(
            self.oneOfCellCorrectlyPredicted) + "\n"
        txt += "One of cell false predicted:" + str(
            self.oneOfCellFalselyPredicted) + "\n"
        txt += "Number of segments:" + str(self.cntSegments) + "\n"
        return txt
class cGridCellModule:
    def __init__(self, nOfCellsPerAxis):
        self.cells = []
        self.nOfCellsPerAxis = nOfCellsPerAxis
        self.cellCount = nOfCellsPerAxis * nOfCellsPerAxis
        self.CELL_OFFSET = 0.4  # space between cells

        for i in range(self.cellCount):
            self.cells.append(cCell(None))

        self.idx = -1

        self.transparency = 1.0
        self.gfxCreated = False
        self.LodDistance1Stored = 100.0
        self.LodDistance2Stored = 5000.0

        self.width = self.nOfCellsPerAxis * (1 + self.CELL_OFFSET
                                             )  # width of the module

    def CreateGfx(self, loader, idx):
        #                __node
        #                /   \
        #  cellsNodePath   columnBox

        self.lod = LODNode("columnLOD")  # Level of detail node for Column
        self.__node = NodePath(
            self.lod
        )  # NodePath(PandaNode('column'))# loader.loadModel("models/box")
        self.__node.setPos(0, 0, 0)
        self.__node.setScale(1, 1, 1)

        self.idx = idx

        # self.__node.setTag('clickable',str(idx))#to be able to click on it

        self.__rhombusEnvelope = loader.loadModel(
            os.path.join(os.getcwd(), "models/rhombus"))
        self.__rhombusEnvelope.setPos(self.width / 2, self.width / 2, 0.0)

        self.__rhombusEnvelope.setScale(self.width / 2, self.width / 2, 0.5)
        self.__rhombusEnvelope.setName("columnBox")

        self.__cellsNodePath = NodePath(
            PandaNode("cellsNode"))  # to pack all cells into one node path
        self.__cellsNodePath.setName("column")
        self.__cellsNodePath.setTag(
            "id",
            str(idx))  # to be able to retrieve index of column for mouse click

        self.lod.addSwitch(100.0, 0.0)
        self.lod.addSwitch(5000.0, 100.0)

        self.__cellsNodePath.reparentTo(self.__node)
        self.__rhombusEnvelope.reparentTo(self.__node)

        x = 0
        y = 0
        idx = 0
        for n in self.cells:
            n.CreateGfx(loader, idx)
            idx += 1

            pos = self._TransformRhombToGlob([x, y], 1 + self.CELL_OFFSET, 0.0)

            n.getNode().setPos(pos[0], pos[1], 0)

            x += 1
            if x >= self.nOfCellsPerAxis:
                y += 1
                x = 0

            n.getNode().reparentTo(self.__cellsNodePath)

        self.gfxCreated = True

        # transoforms coordinate system from rhombus to global
    def _TransformRhombToGlob(self, position, scale, orientation):
        t = np.radians(orientation)  # theta
        r = np.radians(60)  # rhombus skew
        s = scale

        # create Rotation Matrix
        R = np.array(((s * np.cos(t), s * np.cos(t + r)), (s * np.sin(t),
                                                           s * np.sin(t + r))))

        return np.matmul(R, position)  # multiply

    # transforms coordinate system from global to rhombus
    def _TransformGlobToRhomb(self, position, scale, orientation):
        t = np.radians(orientation)  # theta
        r = np.radians(60)  # rhombus skew
        s = scale
        # TODO add scale - use www.wolframalpha.com
        # create Rotation Matrix - inverse of the one in _TransformRhombToGlob()
        R = np.array(((np.sin(t + r) / np.sin(r), -np.cos(t + r) / np.sin(r)),
                      (-np.sin(t) / np.sin(r), np.cos(t) / np.sin(r))))

    def LODUpdateSwitch(self, lodDistance, lodDistance2):
        self.lodDistance1Stored = lodDistance
        self.lodDistance2Stored = lodDistance2

        self.lod.clearSwitches()
        self.lod.addSwitch(lodDistance, 0.0)
        self.lod.addSwitch(lodDistance2, lodDistance)

    def LODUpdateSwitch_long(self):
        self.lod.clearSwitches()
        self.lod.addSwitch(self.lodDistance2Stored, 0.0)
        self.lod.addSwitch(self.lodDistance2Stored, self.lodDistance2Stored)

    def LODUpdateSwitch_normal(self):
        self.LODUpdateSwitch(self.lodDistance1Stored, self.lodDistance2Stored)

    def UpdateState(self, activeCells):
        for cellID in range(len(self.cells)):  # for each cell
            isActive = activeCells[cellID]

            self.cells[cellID].UpdateState(active=isActive,
                                           predictive=False,
                                           winner=False,
                                           focused=False,
                                           presynapticFocus=False,
                                           showPredictionCorrectness=False,
                                           prev_predictive=False)

    def getNode(self):
        return self.__node

    def updateWireframe(self, value):
        for cell in self.cells:
            cell.updateWireframe(value)
        if value:
            self.__rhombusEnvelope.setRenderModeFilledWireframe(
                LColor(0, 0, 0, 1.0))
        else:
            self.__rhombusEnvelope.setRenderModeFilled()

    def setTransparency(self, transparency):
        self.transparency = transparency
        for cell in self.cells:
            cell.setTransparency(transparency)

    def DestroySynapses(self, synapseType):
        if not self.gfxCreated:
            return
        for cell in self.cells:
            cell.DestroySynapses(synapseType)

        self.resetPresynapticFocus()

    def resetPresynapticFocus(self):
        if not self.gfxCreated:
            return
        for cell in self.cells:
            cell.resetPresynapticFocus()  # also reset distal focus

    def getDescription(self):
        txt = ""
        txt += "TODO GridCellModule desc ID:" + str(self.idx) + "\n"
        return txt