예제 #1
0
    def __init__(self,
                 fanout,
                 depth,
                 spread=default_spread,
                 rootColor=default_rootColor,
                 edgeColor=default_edgeColor,
                 scale=default_scale,
                 actor=None):
        Component.__init__(self, actor)
        self.fanout = fanout
        self.depth = depth
        self.spread = spread
        self.rootColor = rootColor
        self.edgeColor = edgeColor
        self.scale = scale
        self.rootScale = self.scale  # NOTE this will also apply to children
        #self.childScale = np.float32([1.0, 1.0, 1.0])  # NOTE this will get compounded if the radial tree is a true hierarchy, better to use scale = 1 (default)

        # Recursively generate radial tree
        treeRoot = self.createRadialTree(
            self.fanout, self.depth, self.spread,
            isRoot=True)  # creates full hierarchy and returns root actor
        treeRoot.components['Transform'] = Transform(
            rotation=np.random.uniform(-pi / 2, pi / 2, size=3),
            scale=self.rootScale,
            actor=treeRoot
        )  # NOTE random rotation ensures child vectors are not always generated close to the same canonical vectors
        treeRoot.components['Material'] = Material(color=self.rootColor,
                                                   actor=treeRoot)
        treeRoot.components['Mesh'] = Mesh.getMesh(src=self.treeRootModelFile,
                                                   actor=treeRoot)

        # Attach this hierarchy to current actor
        self.actor.children.append(treeRoot)
예제 #2
0
파일: Cube.py 프로젝트: Pallavistar/pyTANG
 def __init__(self, scale=cube_scale, actor=None):
   Component.__init__(self, actor)
   Trackable.__init__(self)
   self.scale = scale
   
   # Scale vertices of base cube, specify edges, and initialize list of markers
   self.vertices = cube_vertices * self.scale
   self.vertex_colors = cube_vertex_colors
   self.vertex_scale = 0.3 * self.scale  # NOTE for rendering only, depends on 3D model
   
   self.edges = cube_edges
   self.edge_scale = 0.1 * self.scale  # NOTE for rendering only, depends on 3D model
   self.edge_color = np.float32([0.8, 0.7, 0.5])  # NOTE for rendering only
   # TODO make some of these parameters come from XML
   
   # NOTE Mark generated child actors (corners and edges) as transient, to prevent them from being exported in XML
   
   # Add spheres at cube corners (vertices) with appropriate color; also add color markers
   for vertex, colorName in zip(self.vertices, self.vertex_colors):
     vertexActor = Actor(self.actor.renderer, isTransient=True)
     vertexActor.components['Transform'] = Transform(translation=vertex, scale=self.vertex_scale, actor=vertexActor)
     vertexActor.components['Material'] = Material(color=colors_by_name[colorName], actor=vertexActor)
     vertexActor.components['Mesh'] = Mesh.getMesh(src="SmallSphere.obj", actor=vertexActor)
     self.actor.children.append(vertexActor)
     marker = ColorMarker(self, colorName)
     marker.worldPos = vertex
     self.markers.append(marker)
   
   # Add edges
   for u, v in self.edges:
     if u < len(self.vertices) and v < len(self.vertices) and self.vertices[u] is not None and self.vertices[v] is not None:  # sanity check
       midPoint = (self.vertices[u] + self.vertices[v]) / 2.0
       diff = self.vertices[v] - self.vertices[u]
       mag = np.linalg.norm(diff, ord=2)
       xy_mag = hypot(diff[0], diff[1])
       #zx_mag = hypot(diff[2], diff[0])
       rotation = np.degrees(np.float32([atan2(diff[1], diff[0]), acos(diff[1] / mag), 0])) if (mag != 0 and xy_mag != 0) else np.float32([0.0, 0.0, 0.0])
       #print "u: ", self.vertices[u], ", v: ", self.vertices[v], ", v-u: ", diff, ", mag: ", mag, ", rot:", rotation
       edgeActor = Actor(self.actor.renderer, isTransient=True)
       edgeActor.components['Transform'] = Transform(translation=midPoint, rotation=rotation, scale=self.edge_scale, actor=edgeActor)
       edgeActor.components['Material'] = Material(color=self.edge_color, actor=edgeActor)
       edgeActor.components['Mesh'] = Mesh.getMesh(src="CubeEdge.obj", actor=edgeActor)  # TODO fix Z-fighting issue and use CubeEdge_cylinder.obj
       self.actor.children.append(edgeActor)
예제 #3
0
 def __init__(self, fanout, depth, spread=default_spread, rootColor=default_rootColor, edgeColor=default_edgeColor, scale=default_scale, actor=None):
   Component.__init__(self, actor)
   self.fanout = fanout
   self.depth = depth
   self.spread = spread
   self.rootColor = rootColor
   self.edgeColor = edgeColor
   self.scale = scale
   self.rootScale = self.scale  # NOTE this will also apply to children
   #self.childScale = np.float32([1.0, 1.0, 1.0])  # NOTE this will get compounded if the radial tree is a true hierarchy, better to use scale = 1 (default)
   
   # Recursively generate radial tree
   treeRoot = self.createRadialTree(self.fanout, self.depth, self.spread, isRoot=True)  # creates full hierarchy and returns root actor
   treeRoot.components['Transform'] = Transform(rotation=np.random.uniform(-pi/2, pi/2, size=3), scale=self.rootScale, actor=treeRoot)  # NOTE random rotation ensures child vectors are not always generated close to the same canonical vectors 
   treeRoot.components['Material'] = Material(color=self.rootColor, actor=treeRoot)
   treeRoot.components['Mesh'] = Mesh.getMesh(src=self.treeRootModelFile, actor=treeRoot)
   
   # Attach this hierarchy to current actor
   self.actor.children.append(treeRoot)
예제 #4
0
 def createRadialTree(self, fanout, depth, spread, isRoot=False):
   if depth <= 0:
     return None
   
   # * Create this node (an actor)
   treeNode = Actor(self.actor.renderer, isTransient=True)
   
   # * Attach children if depth > 1
   if depth > 1:
     if isRoot:
       # ** Pick all random directions first, to ensure a good spread, and then generate children
       childVectors = np.float32(
         [[ -1, -1, -1 ],
          [  1, -1, -1 ],
          [  1,  1, -1 ],
          [ -1,  1, -1 ],
          [ -1, -1,  1 ],
          [  1, -1,  1 ],
          [  1,  1,  1 ],
          [ -1,  1,  1 ]])  # NOTE these canonical directions are same as cube vertices!
       
       # ** Perturb child vectors, and compute unit direction vectors
       perturbation = np.random.normal(scale=1.0, size=childVectors.shape)
       #print "RadialTree.__init__(): Child:-\norig. vectors:\n", childVectors, "\nperturbation :\n", perturbation
       childVectors += perturbation
       #print "pert. vectors:\n", childVectors
       childNorms = np.apply_along_axis(lambda vec:np.linalg.norm(vec, ord=2), 1, childVectors)
       #print "child norms:\n", childNorms
       childUnits = childVectors / childNorms[:, np.newaxis]
       
       # ** Use child unit vectors one by one to create fanout first-level children
       numChildren = fanout if fanout <= childUnits.shape[0] else childUnits.shape[0]  # NOTE assert/enforce: actual fanout <= childUnits.shape[0]
       # TODO randomly pick from child unit vectors without replacement?
       for unit in childUnits[0:numChildren]:
         translation = self.treeEdgeLength * unit
         phi = np.arctan2(-unit[2], unit[0])
         theta = np.arcsin(unit[1])
         rotation = np.degrees(np.float32([ 0, phi, theta ]))  # NOTE random X-axis rotation can be added (but won't make any difference): np.random.uniform(-pi, pi)
         
         #print "RadialTree.__init__(): Child:-\nunit:", unit, "[ norm = ", np.linalg.norm(unit, ord=2), "]\ntranslation:", translation, "\nrotation:", rotation
         childNode = self.createRadialTree(np.random.random_integers(3, 4), depth - 1, spread)  # recurse down, decreasing depth
         childNode.components['Transform'] = Transform(translation=translation, rotation=rotation, actor=childNode)  # NOTE scaling will accumulate, so use scale = 1 (default)
         childNode.components['Material'] = Material(color=self.edgeColor, actor=childNode)
         childNode.components['Mesh'] = Mesh.getMesh(src=self.treeEdgeModelFile, actor=childNode)
         treeNode.children.append(childNode)
     else:
       while len(treeNode.children) < fanout:
         # ** Pick a random direction for creating a new child
         spread_rad = np.radians(spread)
         phi = np.random.uniform(-spread_rad, spread_rad)  # rotation around Y axis
         theta = np.random.uniform(-spread_rad, spread_rad)  # rotation around Z axis
         rotation = np.degrees(np.float32([ 0.0, phi, theta ]))  # this will serve as orientation for the tree edge
         
         # TODO pick a random length; scale X axis accordingly (how? flatten tree hierarchy? pick from discrete lengths and use different models accordingly?)
         
         # ** Compute relative position of new child (in cartesian coordinates) and normalized unit vector
         translation = np.float32([
           self.treeEdgeLength * cos(theta) * cos(phi),
           self.treeEdgeLength * sin(theta),
           -self.treeEdgeLength * cos(theta) * sin(phi)
         ])
         norm = np.linalg.norm(translation, ord=2)
         unit = translation / norm
         
         # TODO check closeness condition (too close to existing nodes? parent? - need absolute coordinates for that!)
         
         # ** Generate and add child (with nested tree)
         childNode = self.createRadialTree(np.random.random_integers(3, 4), depth - 1, spread)  # recurse down, decreasing depth
         childNode.components['Transform'] = Transform(translation=translation, rotation=rotation, actor=childNode)  # NOTE scaling will accumulate, so use scale = 1 (default)
         childNode.components['Material'] = Material(color=self.edgeColor, actor=childNode)
         childNode.components['Mesh'] = Mesh.getMesh(src=self.treeEdgeModelFile, actor=childNode)
         treeNode.children.append(childNode)
   
   return treeNode
예제 #5
0
    def __init__(self, scale=cube_scale, actor=None):
        Component.__init__(self, actor)
        Trackable.__init__(self)
        self.scale = scale

        # Scale vertices of base cube, specify edges, and initialize list of markers
        self.vertices = cube_vertices * self.scale
        self.vertex_colors = cube_vertex_colors
        self.vertex_scale = 0.3 * self.scale  # NOTE for rendering only, depends on 3D model

        self.edges = cube_edges
        self.edge_scale = 0.1 * self.scale  # NOTE for rendering only, depends on 3D model
        self.edge_color = np.float32([0.8, 0.7,
                                      0.5])  # NOTE for rendering only
        # TODO make some of these parameters come from XML

        # NOTE Mark generated child actors (corners and edges) as transient, to prevent them from being exported in XML

        # Add spheres at cube corners (vertices) with appropriate color; also add color markers
        for vertex, colorName in zip(self.vertices, self.vertex_colors):
            vertexActor = Actor(self.actor.renderer, isTransient=True)
            vertexActor.components['Transform'] = Transform(
                translation=vertex, scale=self.vertex_scale, actor=vertexActor)
            vertexActor.components['Material'] = Material(
                color=colors_by_name[colorName], actor=vertexActor)
            vertexActor.components['Mesh'] = Mesh.getMesh(
                src="SmallSphere.obj", actor=vertexActor)
            self.actor.children.append(vertexActor)
            marker = ColorMarker(self, colorName)
            marker.worldPos = vertex
            self.markers.append(marker)

        # Add edges
        for u, v in self.edges:
            if u < len(self.vertices) and v < len(
                    self.vertices
            ) and self.vertices[u] is not None and self.vertices[
                    v] is not None:  # sanity check
                midPoint = (self.vertices[u] + self.vertices[v]) / 2.0
                diff = self.vertices[v] - self.vertices[u]
                mag = np.linalg.norm(diff, ord=2)
                xy_mag = hypot(diff[0], diff[1])
                #zx_mag = hypot(diff[2], diff[0])
                rotation = np.degrees(
                    np.float32([
                        atan2(diff[1], diff[0]),
                        acos(diff[1] / mag), 0
                    ])) if (mag != 0 and xy_mag != 0) else np.float32(
                        [0.0, 0.0, 0.0])
                #print "u: ", self.vertices[u], ", v: ", self.vertices[v], ", v-u: ", diff, ", mag: ", mag, ", rot:", rotation
                edgeActor = Actor(self.actor.renderer, isTransient=True)
                edgeActor.components['Transform'] = Transform(
                    translation=midPoint,
                    rotation=rotation,
                    scale=self.edge_scale,
                    actor=edgeActor)
                edgeActor.components['Material'] = Material(
                    color=self.edge_color, actor=edgeActor)
                edgeActor.components['Mesh'] = Mesh.getMesh(
                    src="CubeEdge.obj", actor=edgeActor
                )  # TODO fix Z-fighting issue and use CubeEdge_cylinder.obj
                self.actor.children.append(edgeActor)
예제 #6
0
    def createRadialTree(self, fanout, depth, spread, isRoot=False):
        if depth <= 0:
            return None

        # * Create this node (an actor)
        treeNode = Actor(self.actor.renderer, isTransient=True)

        # * Attach children if depth > 1
        if depth > 1:
            if isRoot:
                # ** Pick all random directions first, to ensure a good spread, and then generate children
                childVectors = np.float32(
                    [[-1, -1, -1], [1, -1, -1], [1, 1, -1], [-1, 1, -1],
                     [-1, -1, 1], [1, -1, 1],
                     [1, 1, 1], [-1, 1, 1]]
                )  # NOTE these canonical directions are same as cube vertices!

                # ** Perturb child vectors, and compute unit direction vectors
                perturbation = np.random.normal(scale=1.0,
                                                size=childVectors.shape)
                #print "RadialTree.__init__(): Child:-\norig. vectors:\n", childVectors, "\nperturbation :\n", perturbation
                childVectors += perturbation
                #print "pert. vectors:\n", childVectors
                childNorms = np.apply_along_axis(
                    lambda vec: np.linalg.norm(vec, ord=2), 1, childVectors)
                #print "child norms:\n", childNorms
                childUnits = childVectors / childNorms[:, np.newaxis]

                # ** Use child unit vectors one by one to create fanout first-level children
                numChildren = fanout if fanout <= childUnits.shape[
                    0] else childUnits.shape[
                        0]  # NOTE assert/enforce: actual fanout <= childUnits.shape[0]
                # TODO randomly pick from child unit vectors without replacement?
                for unit in childUnits[0:numChildren]:
                    translation = self.treeEdgeLength * unit
                    phi = np.arctan2(-unit[2], unit[0])
                    theta = np.arcsin(unit[1])
                    rotation = np.degrees(
                        np.float32([0, phi, theta])
                    )  # NOTE random X-axis rotation can be added (but won't make any difference): np.random.uniform(-pi, pi)

                    #print "RadialTree.__init__(): Child:-\nunit:", unit, "[ norm = ", np.linalg.norm(unit, ord=2), "]\ntranslation:", translation, "\nrotation:", rotation
                    childNode = self.createRadialTree(
                        np.random.random_integers(3, 4), depth - 1,
                        spread)  # recurse down, decreasing depth
                    childNode.components['Transform'] = Transform(
                        translation=translation,
                        rotation=rotation,
                        actor=childNode
                    )  # NOTE scaling will accumulate, so use scale = 1 (default)
                    childNode.components['Material'] = Material(
                        color=self.edgeColor, actor=childNode)
                    childNode.components['Mesh'] = Mesh.getMesh(
                        src=self.treeEdgeModelFile, actor=childNode)
                    treeNode.children.append(childNode)
            else:
                while len(treeNode.children) < fanout:
                    # ** Pick a random direction for creating a new child
                    spread_rad = np.radians(spread)
                    phi = np.random.uniform(
                        -spread_rad, spread_rad)  # rotation around Y axis
                    theta = np.random.uniform(
                        -spread_rad, spread_rad)  # rotation around Z axis
                    rotation = np.degrees(np.float32([
                        0.0, phi, theta
                    ]))  # this will serve as orientation for the tree edge

                    # TODO pick a random length; scale X axis accordingly (how? flatten tree hierarchy? pick from discrete lengths and use different models accordingly?)

                    # ** Compute relative position of new child (in cartesian coordinates) and normalized unit vector
                    translation = np.float32([
                        self.treeEdgeLength * cos(theta) * cos(phi),
                        self.treeEdgeLength * sin(theta),
                        -self.treeEdgeLength * cos(theta) * sin(phi)
                    ])
                    norm = np.linalg.norm(translation, ord=2)
                    unit = translation / norm

                    # TODO check closeness condition (too close to existing nodes? parent? - need absolute coordinates for that!)

                    # ** Generate and add child (with nested tree)
                    childNode = self.createRadialTree(
                        np.random.random_integers(3, 4), depth - 1,
                        spread)  # recurse down, decreasing depth
                    childNode.components['Transform'] = Transform(
                        translation=translation,
                        rotation=rotation,
                        actor=childNode
                    )  # NOTE scaling will accumulate, so use scale = 1 (default)
                    childNode.components['Material'] = Material(
                        color=self.edgeColor, actor=childNode)
                    childNode.components['Mesh'] = Mesh.getMesh(
                        src=self.treeEdgeModelFile, actor=childNode)
                    treeNode.children.append(childNode)

        return treeNode