def add_text(self, text, shading={}, **kwargs): shading.update(kwargs) sh = self.__get_shading(shading) tt = p3s.TextTexture(string=text, color=sh["text_color"]) sm = p3s.SpriteMaterial(map=tt) self.text = p3s.Sprite(material=sm, scaleToTexture=True) self.scene.add(self.text)
def _create_text_sprite(position, bounding_box, display_text): # Position offset in y text_position = tuple(position.value + np.array([0, 0.8 * bounding_box[1], 0])) text = p3.TextTexture(string=display_text, color='black', size=300) text_material = p3.SpriteMaterial(map=text, transparent=True) size = 1.0 return p3.Sprite(material=text_material, position=text_position, scale=[size, size, size])
def _make_axis_tick(self, string, position, color="black", size=1.0): """ Make a text-based sprite for axis tick """ sm = p3.SpriteMaterial(map=p3.TextTexture(string=string, color=color, size=300, squareTexture=True), transparent=True) return p3.Sprite(material=sm, position=position, scaleToTexture=True, scale=[size, size, size])
def add_labels(element_groups, key_elements, use_label_arrays): """Create label elements for the scene.""" import pythreejs as pjs group_labels = pjs.Group() unique_label_sets = {} for el in element_groups["atoms"]: if "label" in el and el.label is not None: unique_label_sets.setdefault( (("label", el.label), ("color", el.get("font_color", "black"))), []).append(el) if unique_label_sets: key_elements["group_labels"] = group_labels for el_hash, els in unique_label_sets.items(): el = els[0] data = dict(el_hash) # depthWrite=depthTest=False is required, for the sprite to remain on top, # and not have the whitespace obscure objects behind, see: # https://stackoverflow.com/questions/11165345/three-js-webgl-transparent-planes-hiding-other-planes-behind-them # TODO can this be improved? text_material = pjs.SpriteMaterial( map=pjs.TextTexture( string=el.label, color=el.get("font_color", "black"), size=2000, # this texttexture size seems to work, not sure why? ), opacity=1.0, transparent=True, depthWrite=False, depthTest=False, ) data["material"] = text_material key_elements.setdefault("label_arrays", []).append(data) if use_label_arrays: text_sprite = pjs.Sprite(material=text_material) label_array = pjs.CloneArray( original=text_sprite, positions=[e.position.tolist() for e in els], merge=False, ) else: label_array = [ pjs.Sprite(material=text_material, position=e.position.tolist()) for e in els ] group_labels.add(label_array) return group_labels
def add_text(self, text, shading={}): self.update_shading(shading) tt = p3s.TextTexture(string=text, color=self.s["text_color"]) sm = p3s.SpriteMaterial(map=tt) self.text = p3s.Sprite(material=sm, scaleToTexture=True) self.scene.add(self.text)
def create_jslabelmesh_view(gobject, mapping=None, jslink=False): """create PyThreeJS Text Mesh for GeometricObject and with one-way synchronisation Properties ---------- gobject : GeometricObject mapping : None or dict if None, use default gobject->jsobject mapping jslink : bool if True, where possible, create client side links http://ipywidgets.readthedocs.io/en/latest/examples/Widget%20Events.html#The-difference-between-linking-in-the-kernel-and-linking-in-the-client Examples -------- >>> import pandas3js as pjs >>> sphere = pjs.models.Sphere() >>> lmesh = pjs.views.create_jslabelmesh_view(sphere) >>> lmesh.position [0.0, 0.0, 0.0] >>> str(lmesh.material.map.string) '-' >>> lmesh.scale [1.0, 1.0, 1.0] >>> sphere.position = (1,0,0) >>> lmesh.position [1.0, 0.0, 0.0] >>> sphere.label = 'test' >>> str(lmesh.material.map.string) 'test' >>> sphere.radius = 3.0 >>> lmesh.scale [1.0, 3.0, 1.0] """ if jslink: direct_link = widget.jsdlink else: direct_link = trait.dlink class_str = obj_to_str(gobject) if hasattr(gobject, '_use_default_viewmap'): class_map = copy.deepcopy(gobject_jsmapping['default']) class_map['grep'] = 'pythreejs.' + class_str.split('.')[-1] # directly link all traits to geometry object for trait_name in gobject.class_own_traits(): class_map['gdmap'][trait_name] = trait_name if gobject._use_default_viewmap is not None: class_map['show_label'] = True class_map['label_height'] = gobject._use_default_viewmap elif not class_str in gobject_jsmapping: raise ValueError( 'No pythreejs mapping available for {}'.format(class_str)) else: class_map = gobject_jsmapping[class_str] text_map = js.TextTexture(string=gobject.label, color=colors.to_hex(gobject.label_color), size=100, squareTexture=False) material = js.SpriteMaterial(map=text_map, opacity=gobject.label_transparency, transparent=False, depthTest=False, depthWrite=True) height = class_map['label_height'] height_attr = getattr(gobject, height) if isinstance( height, basestring) else height mesh = js.Sprite(material=material, position=gobject.position, scaleToTexture=True, scale=[1, height_attr, 1]) # add special traits mesh.add_traits(gobject_id=HashableType()) mesh.gobject_id = gobject.id mesh.add_traits(other_info=trait.CUnicode().tag(sync=True)) if not class_map['show_label']: mesh.visible = False return mesh # add directional synchronisation direct_link((gobject, 'other_info'), (mesh, 'other_info')) direct_link((gobject, 'label'), (text_map, 'string')) direct_link((gobject, 'position'), (mesh, 'position')) direct_link((gobject, 'label_visible'), (mesh, 'visible')) direct_link((gobject, 'label_transparency'), (material, 'opacity')) trait.dlink((gobject, 'label_color'), (text_map, 'color'), colors.to_hex) trait.dlink((gobject, 'label_transparency'), (material, 'transparent'), lambda t: True if t <= 0.999 else False) if isinstance(height, basestring): def change_height(change): mesh.scale = [1, change.new, 1] gobject.observe(change_height, names=height) return mesh