<div dir="auto">Moritz, I’m not sure if you’ve seen this, but GitHub is capable of rendering STL (think monochromatic triangles) on a web page.   I am unsure of integration with python, numpy, etc.   I have written a small X3D JSON to STL converter, see below link.   But it’s JavaScript, so it would require conversion to python for you!<div><a href="https://github.com/coderextreme/X3DJSONLD/blob/master/src/main/node/convertJsonToStl.js">https://github.com/coderextreme/X3DJSONLD/blob/master/src/main/node/convertJsonToStl.js</a></div><div dir="auto"><br></div><div dir="auto">This would be especially helpful if you want to reduce the number of Transforms in your scenegraph.   I would like to include more types of getting geometry, but I’m not energetic enough to do the triangularization for all the X3D geometries.   The code has been languishing for some time.</div><div dir="auto"><br></div><div dir="auto">Note that my code produces higher than 3 vertex polygons, so it’s not true STL.</div><div dir="auto"><br></div><div dir="auto">Here’s an STL example on GitHub:</div><div dir="auto"><br></div><div dir="auto"><div><a href="https://github.com/coderextreme/X3DJSONLD/blob/master/src/main/stl/example.stl">https://github.com/coderextreme/X3DJSONLD/blob/master/src/main/stl/example.stl</a></div><div dir="auto"><br></div><div dir="auto">I would like to improve the SuperCobra.stl example.</div><br></div><div dir="auto"><br></div><div dir="auto">So limited use case, but handy if you want to render graphics on GitHub!  “Safe” graphics!</div></div><div dir="auto"><br></div><div dir="auto"><br></div><div dir="auto"><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Feb 9, 2022 at 10:24 AM Hans Moritz Guenther <<a href="mailto:hgunther@mit.edu">hgunther@mit.edu</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;padding-left:1ex;border-left-color:rgb(204,204,204)">
  

    
  
  <div>
    <p>Hi,</p>
    <p>I'm starting to use the x3d.py library to generate x3d output.
      I'm very much a Python programmer using what people call the
      "scientific stack" in Python (the libraries numpy, scipy, pandas,
      etc.) with very little experience in 3D visualization or
      web-programming.</p>
    <p>I understand that you autogenerate the programming language API
      from the X3DOUM, but I do not know which, if any, of the comments
      generalize to the APIs in other programming languages or which
      ones are specific to the Python implementation in x3d.py.</p>
    <p>For a little bit of background, I'm an astronomer and one of the
      things I do is ray-tracing of the designs for new space-based
      observatories. It is then very useful to have some form of output
      that allows me to put images of how the instrument looks and what
      path the photons take into presentations or on the web. As it
      turns out, X3D is a great format for that, see e.g. <a href="https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fspace.mit.edu%2Fhome%2Fguenther%2FARCUS%2F3Dview.html&data=04%7C01%7Cbrutzman%40nps.edu%7Cdb2b534b2a804d7bfdd208d9ea4aeafa%7C6d936231a51740ea9199f7578963378e%7C0%7C0%7C637798431440614306%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=%2FT7oRCpoMKrtbHjscVH9lQp%2FBP070YtGI6t4TF%2BPoL0%3D&reserved=0" target="_blank">
        https://space.mit.edu/home/guenther/ARCUS/3Dview.html</a> In
      that past, I've generated the X3D output through a python package
      called mayavi (<a href="https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fdocs.enthought.com%2Fmayavi%2Fmayavi%2F&data=04%7C01%7Cbrutzman%40nps.edu%7Cdb2b534b2a804d7bfdd208d9ea4aeafa%7C6d936231a51740ea9199f7578963378e%7C0%7C0%7C637798431440614306%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=CdLWWXcET8e3si%2BUjGRjAkGfv2TvSQ9KKIlM9bc66oA%3D&reserved=0" target="_blank">https://docs.enthought.com/mayavi/mayavi/</a>)
      but that is a rather heavy dependency for this very limited
      purpose. So, I'm trying to convert to use your x3d.py library
      instead. </p>
    <p>First, let me thank you for your effort to make x3d.py at all. In
      general it works great!</p>
    <p>I'd like to mention a few glitches I've run into so far:</p>
    <p>- IndexTriangleSet: Coordinates are given as a list of tuples
      [(x1, y1, z1), (x2, y2, y3), ...]. I think that makes sense. It
      orders stuff in a natural way and is easy to understand. However,
      the index needs to be given as a flat list [ind11, ind12, ind13,
      ind21, ind22, ind23, ...]. Since there are three indices per
      triangle, I think the same list of tuples as for the coordinates
      would make more sense [( ind11, ind12, ind13), (ind21, ind22,
      ind23) ...]. I've not checked if the same thought applied to e.g.
      the IndexedFaceSet etc. I'm still pretty new to this and can't
      claim to know all relevant nodes.<br>
    </p>
    <p>- the __init__.py file. The file is present, but not correct. It
      lists all the classes in __all__ but does not actually import
      them. Thus, that can't actually be used.</p>
    <p>I<span style="font-family:"Courier New"">n [1]: import
        x3d<br>
        <br>
        In [2]: x3d.IndexedTriangleSet<br>
---------------------------------------------------------------------------<br>
        AttributeError                            Traceback (most recent
        call last)<br>
        <ipython-input-2-93a98d5f0414> in <module><br>
        ----> 1 x3d.IndexedTriangleSet</span></p>
    <p>Instead, I need to use "x3d.x3d". That's of course possible but a
      little cumbersome.</p>
    <p><span style="font-family:"Courier New"">In [4]: import
        x3d.x3d<br>
        x3d.py package loaded, have fun with X3D Graphics!<br>
        <br>
        In [5]: x3d.x3d.IndexedTriangleSet<br>
        Out[5]: x3d.x3d.IndexedTriangleSet</span></p>
    <p>I think all that's missing is the following line in the
      __init__.py</p>
    <p><span style="font-family:"Courier New"">from x3d import
        *</span></p>
    <p>which will import everything that's defined in x3d.py into the
      __init__.py namespace and than the user an get it from "import
      x3d" which gives you the names defined in x3d/__init__.py</p>
    - Python usually makes heavy use of duck-typing (you can use any
    object as long as it behaves as you expect) instead of explicit
    "isinstance" checks. A lot of numerical computations in Python are
    done using the numpy (<a href="https://nam10.safelinks.protection.outlook.com/?url=https%3A%2F%2Fnumpy.org%2F&data=04%7C01%7Cbrutzman%40nps.edu%7Cdb2b534b2a804d7bfdd208d9ea4aeafa%7C6d936231a51740ea9199f7578963378e%7C0%7C0%7C637798431440614306%7CUnknown%7CTWFpbGZsb3d8eyJWIjoiMC4wLjAwMDAiLCJQIjoiV2luMzIiLCJBTiI6Ik1haWwiLCJXVCI6Mn0%3D%7C2000&sdata=DgLaPPURD5FLJTT9FnjaglzyPNA9oeH93qpXmJIcHvM%3D&reserved=0" target="_blank">https://numpy.org</a>)
    library, which implements array-based math and is optimized in C.
    Numpy has datatypes that are essentially similar to Python int but
    fail an isinstance check, and I can pass those in some, but not all
    places in x3d.py. Here is an example that fails:
    <pre style="font-family:monospace"> </pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">~/mambaforge/envs/kitchensink/lib/python3.10/site-packages/x3d/x3d.py</span> in <span style="font-family:monospace">__init__</span><span style="font-family:monospace">(self, ccw, colorPerVertex, index, normalPerVertex, solid, color, coord, fogCoord, normal, texCoord, attrib, DEF, USE, IS, metadata, class_, id_, style_)</span></pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">  48191</span>         self<span style="font-family:monospace">.</span>ccw <span style="font-family:monospace">=</span> ccw</pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">  48192</span>         self<span style="font-family:monospace">.</span>colorPerVertex <span style="font-family:monospace">=</span> colorPerVertex</pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">> 48193</span><span style="font-family:monospace">         </span>self<span style="font-family:monospace">.</span>index <span style="font-family:monospace">=</span> index</pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">  48194</span>         self<span style="font-family:monospace">.</span>normalPerVertex <span style="font-family:monospace">=</span> normalPerVertex</pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">  48195</span>         self<span style="font-family:monospace">.</span>solid <span style="font-family:monospace">=</span> solid</pre>
    <pre style="font-family:monospace"> </pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">~/mambaforge/envs/kitchensink/lib/python3.10/site-packages/x3d/x3d.py</span> in <span style="font-family:monospace">index</span><span style="font-family:monospace">(self, index)</span></pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">  48230</span>         <span style="font-family:monospace">if</span>  index <span style="font-family:monospace">is</span> <span style="font-family:monospace">None</span><span style="font-family:monospace">:</span></pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">  48231</span>             index <span style="font-family:monospace">=</span> MFInt32<span style="font-family:monospace">.</span>DEFAULT_VALUE<span style="font-family:monospace">()</span></pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">> 48232</span><span style="font-family:monospace">         </span>assertValidMFInt32<span style="font-family:monospace">(</span>index<span style="font-family:monospace">)</span></pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">  48233</span>         assertNonNegative<span style="font-family:monospace">('index',</span> index<span style="font-family:monospace">)</span></pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">  48234</span>         self<span style="font-family:monospace">.</span>__index <span style="font-family:monospace">=</span> index</pre>
    <pre style="font-family:monospace"> </pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">~/mambaforge/envs/kitchensink/lib/python3.10/site-packages/x3d/x3d.py</span> in <span style="font-family:monospace">assertValidMFInt32</span><span style="font-family:monospace">(value)</span></pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">   2622</span>         <span style="font-family:monospace">if</span> <span style="font-family:monospace">not</span> isinstance<span style="font-family:monospace">(</span>each<span style="font-family:monospace">,</span> int<span style="font-family:monospace">):</span></pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">   2623</span>             <span style="font-family:monospace"># print(flush=True)</span></pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">-> 2624</span><span style="font-family:monospace">             </span><span style="font-family:monospace">raise</span> X3DTypeError<span style="font-family:monospace">('MFInt32 list has contained value='</span> <span style="font-family:monospace">+</span> str<span style="font-family:monospace">(</span>each<span style="font-family:monospace">)</span> <span style="font-family:monospace">+</span> <span style="font-family:monospace">' with type='</span> <span style="font-family:monospace">+</span> str<span style="font-family:monospace">(</span>type<span style="font-family:monospace">(</span>each<span style="font-family:monospace">))</span> <span style="font-family:monospace">+</span> <span style="font-family:monospace">' which is not a valid int')</span></pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">   2625</span>     <span style="font-family:monospace">if</span> <span style="font-family:monospace">not</span> isValidMFInt32<span style="font-family:monospace">(</span>value<span style="font-family:monospace">):</span></pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">   2626</span>         <span style="font-family:monospace"># print(flush=True)</span></pre>
    <pre style="font-family:monospace"> </pre>
    <pre style="font-family:monospace"><span style="font-family:monospace">X3DTypeError</span>: MFInt32 list has contained value=1 with type=<class 'numpy.int64'> which is not a valid int</pre>
    <pre style="font-family:monospace"> </pre>
    <pre style="font-family:monospace"> </pre>
    <pre style="font-family:monospace">There is an easy workaround:</pre>
    <pre style="font-family:monospace"> </pre>
    <pre style="font-family:monospace">x3d.IndexedTriangleSet(index = [int(x) for x in myindex]</pre>
    <pre style="font-family:monospace"> </pre>
    <pre style="font-family:monospace">but it would be nice if IndexedTriangleSet accepted my numbers directly. </pre>
    <pre style="font-family:monospace">There are several ways of doing that, but the easiest is probably to change line 2622 to:</pre>
    <pre style="font-family:monospace"> </pre>
    <pre style="font-family:monospace">if not int(x) == x: </pre>
    <pre style="font-family:monospace"> </pre>
    <p>That will work for any object that can be converted to an int,
      including numpy, python decimal, fraction, ..</p>
    <p>- Numpy: One might consider taking numpy arrays directly, i.e.
      instead of </p>
    <p>x3d.Coordinate(point=[(x1, y1, z1), (x2, y2, y3), ...])</p>
    <p>one could do </p>
    <p>x3d.Coordinate(point=arr)</p>
    <p>where arr is a (3, n) numpy array. Now, if done naively that
      would require numpy as a dependency to x3d.py and it's probably
      good to avoid that. However, there are ways to accept numpy arrays
      without requiring numpy. That's a little more involved, but can be
      done (for example using decorators or a separate module
      (x3d.numpy_interface) or separate package (x3d-numpy)). Not sure
      if it's worth the effort at this point - that depends on what your
      future plans for this package are and how fast this is developing.</p>
    <p>- Changelog. From the pypi entry and the docs on <a href="https://www.web3d.org/x3d/stylesheets/python/python.html" target="_blank">
        https://www.web3d.org/x3d/stylesheets/python/python.html</a> it
      was not quite clear to me how stable the package is or where I
      would see changes listed, for example, if you do the change that I
      suggested above (accepting index values as tuples instead of a
      flat list) that would break the interface. Would you do that?
      Where would I find a list of changes from one version to another?</p>
    <p>- Jupyter notebook: The Jupyter notebook seems like an ideal tool
      for work with X3D in Python, since it is rendered on the web and
      can display any web output. Here is a simple addition of a
      `_repr_html_`method to the Scene class in the x3d.py that will
      render any valid scene with no additional effort to the screen.
      Sure, the header is a little simplistic, but it's just a quick way
      to look at what your are specifying. Since I did not want to edit
      x3d.py itself, I simply made a new class that inherits from the
      x3d.Scene, but it would obviously be even easier if this was part
      of x3d itself. See
<a href="http://nbviewer.org/github/hamogu/x3d-experiements/blob/main/Scence_for_notebook.ipynb" target="_blank">http://nbviewer.org/github/hamogu/x3d-experiements/blob/main/Scence_for_notebook.ipynb</a>
      for an example and note how the X3D output at the bottom is not
      just a screenshot, but a live output that your can zoom and rotate
      with your mouse, even though the notebook is not running live, but
      instead you just see the rendered output of what I run some time
      in the past on my laptop. (I admit that this is a naive
      implementation and it might be useful to add a few <meta> or
      <WorldInfo> nodes. Also, maybe Scene is not the best node,
      or not the only node, where to define this functionality, but it
      seems to work well.)<br>
    </p>
    <div style="font-family:Menlo,Monaco,"Courier New",monospace;font-weight:normal;font-size:12px;line-height:18px;white-space:pre-wrap;background-color:rgb(255,255,255);color:rgb(0,0,0)"><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,255)">class</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)"> </span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(38,127,153)">Scene</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">(</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(38,127,153)">x3d</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">.</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(38,127,153)">Scene</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">):</span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">    </span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,16,128)">js_source</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)"> = </span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">'<a href="https://www.x3dom.org/download/x3dom.js" target="_blank" style="font-family:Menlo,Monaco,"Courier New",monospace">https://www.x3dom.org/download/x3dom.js</a>'</span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">    </span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,16,128)">css_source</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)"> = </span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">'<a href="https://www.x3dom.org/download/x3dom.css" target="_blank" style="font-family:Menlo,Monaco,"Courier New",monospace">https://www.x3dom.org/download/x3dom.css</a>'</span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">    </span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,16,128)">dimension_px</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)"> = (</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(9,134,88)">600</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">, </span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(9,134,88)">400</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">)</span></div>
<div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">    </span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,255)">def</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)"> </span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(121,94,38)">_repr_html_</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">(</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,16,128)">self</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">):</span></div>
<div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">        </span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(175,0,219)">return</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">(</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,255)">f</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">"""</span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)"><html></span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">  <head></span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">    <meta http-equiv="X-UA-Compatible" content="IE=edge"/> </span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">     <script type='text/javascript' src='</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,255)">{</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,16,128)">self</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">.</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,16,128)">js_source</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,255)">}</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">'> </script> </span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">     <link rel='stylesheet' type='text/css' href='</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,255)">{</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,16,128)">self</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">.</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,16,128)">css_source</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,255)">}</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">'></link> </span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">  </head></span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">  <body></span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">    <x3d width='</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,255)">{</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,16,128)">self</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">.</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,16,128)">dimension_px</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">[</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(9,134,88)">0</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">]</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,255)">}</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">px' height='</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,255)">{</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,16,128)">self</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">.</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,16,128)">dimension_px</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">[</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(9,134,88)">1</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">]</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,255)">}</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">px'> </span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">      </span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,255)">{</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,16,128)">self</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">.XML()</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,255)">}</span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">    </x3d></span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">  </body></span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)"></html></span></div><div style="font-family:Menlo,Monaco,"Courier New",monospace"><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(163,21,21)">"""</span><span style="font-family:Menlo,Monaco,"Courier New",monospace;color:rgb(0,0,0)">)</span></div></div>
    <p><br>
    </p>
    <p>Please let me know if there is anything I can do to help with
      this awesome package, that really makes generating X3D from Python
      so much simpler already.</p>
    <p>Yours,</p>
    Moritz
    <pre cols="72" style="font-family:monospace">-- 
Hans Moritz Günther
Massachusetts Institute of Technology
Kavli Institute for Astrophysics and Space Research
<a href="https://www.google.com/maps/search/77+Massachusetts+Avenue?entry=gmail&source=g" style="font-family:monospace">77 Massachusetts Avenue</a>
NE83-569
Cambridge, MA 02139
<a href="mailto:hgunther@mit.edu" target="_blank" style="font-family:monospace">hgunther@mit.edu</a>
<a href="https://space.mit.edu/home/guenther/" target="_blank" style="font-family:monospace">https://space.mit.edu/home/guenther/</a></pre>
  </div>

_______________________________________________<br>
x3d-public mailing list<br>
<a href="mailto:x3d-public@web3d.org" target="_blank">x3d-public@web3d.org</a><br>
<a href="http://web3d.org/mailman/listinfo/x3d-public_web3d.org" rel="noreferrer" target="_blank">http://web3d.org/mailman/listinfo/x3d-public_web3d.org</a><br>
</blockquote></div></div>