<div dir="auto">Thanks, Don.</div><div dir="auto"><br></div><div dir="auto">I think this work will help with x3djsonld.py,  but I don’t know when I will pick it up again.  I don’t have any big x3d.py projects besides that.</div><div dir="auto"><br></div><div dir="auto">The good news is, I passed the cardiologist’s tests with flying colors today, just a heart murmur/regurgitation, which is pretty much normal at my age.  My heart muscle shows no sign of muscle loss/death.  The next step is to schedule surgery this afternoon.</div><div dir="auto"><br></div><div dir="auto">I will probably do an update of X3DJSONLD this afternoon.  I’m about an hour away from home.   I will also start a non-schema JSON validation of the archive using the latest X3DJSAIL.   I am not aware of X3DJSAIL updates.   I don’t know if the JSON files need to be updated in my version of the archives.</div><div dir="auto"><br></div><div dir="auto">John <br><div class="gmail_quote" dir="auto"><div dir="ltr" class="gmail_attr">On Mon, Feb 28, 2022 at 11:28 AM Brutzman, Donald (Don) (CIV) <<a href="mailto:brutzman@nps.edu">brutzman@nps.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 lang="EN-US" link="#0563C1" vlink="#954F72" style="word-wrap:break-word"><div class="m_466321523779582255WordSection1"><p class="m_466321523779582255MsoPlainText">Based on the elegant list-comprehension expressions in the following two lines<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><ul style="margin-top:0in" type="disc"><li class="m_466321523779582255MsoPlainText"><span style="font-family:"Courier New"">coord = Coordinate( point = [ tuple(pt) for pt in point_coordinates] ),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></li></ul><p class="m_466321523779582255MsoPlainText"><span style="font-family:"Courier New""><u style="font-family:"Courier New""></u> <u style="font-family:"Courier New""></u></span></p><ul style="margin-top:0in" type="disc"><li class="m_466321523779582255MsoPlainText"><span style="font-family:"Courier New"">color = Color( color = [tuple(c) for c in point_colors])<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></li></ul><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">These types of expressions could certainly be added to MFVec3f, MFColor, etc. which would continue flexibility of current duck typing across full diversity of X3D field types.<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">Presumably the key precondition for applying them will be  proper detection of type, e.g.<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><ul style="margin-top:0in" type="disc"><li class="m_466321523779582255MsoPlainText"><span style="font-family:"Courier New"">if isinstance(value, np.array) # and further checking that elements of arrays are tuples<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></li></ul><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">I will eventually be able to fumble around and get something hacked together, putting it into the fieldtype value setter. (Or keep them as a separate utility if numpy dependency needs to be avoided.)<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">If you can help with type checking to avoid numpy GIGO problems, please toss me an example.  Presumably if we can get numpy working then we can support other lists of tuples as well.<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">FWIW, example target excerpted from package x3d.py follows.  (The triple-hash ### blocks were form used prior to latest refactoring, they’ll get deleted once confirmed that all functionality is handled in new code.)<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">===========================<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">class MFVec3f(_X3DArrayField):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    """<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    Field type MFVec3f is an array of SFVec3f values. Individual singleton SFVec3f array values are optionally separated by commas in XML syntax.<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    """<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New""># […snip…]<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New""><u style="font-family:"Courier New""></u> <u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    @property # getter - - - - - - - - - -<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    def value(self):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        """ Provide typed value of this field instance. """<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        return self.__value<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    @value.setter<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    def value(self, value):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        """ The value setter only allows correctly typed values. """<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        if isinstance(value,SFVec3f):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">            value = value.value # dereference<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        elif value is None:<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">            value = MFVec3f.DEFAULT_VALUE()<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">            # if _DEBUG: print('...DEBUG... set value to MFVec3f.DEFAULT_VALUE()=' + str(MFVec3f.DEFAULT_VALUE()))<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        elif isinstance(value, list):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">            for each in value: # check that elements are not tuples<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                if isinstance(each, tuple):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                    break<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">            else: # no tuples found, create 3-tuples<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                value = [(x, y, z) for x, y, z in value]<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###     elif not isinstance(value, list) and isValidSFVec3f(value):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###         print(' upcast to MF type', value)<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###         value = MFVec3f(SFVec3f(value))<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        elif isinstance(value, list):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">            if not value is None and not (isinstance(value,list) and len(value) == 0):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                _newValue = []<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                for each in value:<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                    _newValue.append(SFVec3f(each).value)<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                # if _DEBUG: print('...DEBUG... assign list, value=' + str(value), ', type=' + str(type(value)), ', _newValue=' + str(_newValue),flush=True)<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                value = _newValue<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        elif isinstance(value, str):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">            value = [ float(value) ]<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        self.__value = value<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New""><u style="font-family:"Courier New""></u> <u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New""># and<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New""><u style="font-family:"Courier New""></u> <u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    def append(self, value=None):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        """ Add to existing value list, first ensuring that a correctly typed value is applied. """<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        if  not value is None:<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New""><u style="font-family:"Courier New""></u> <u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">            # if _DEBUG: print('...DEBUG... append to list, value=' + str(self.__value), ', type=' + str(type(self.__value)), ', value=' + str(value),flush=True)<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">            if isinstance(value,SFVec3f):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                self.__value.append(value.value) # dereference<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">            elif not isinstance(value,list) and not isinstance(value,MFVec3f):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                self.__value.append(SFVec3f(value).value) # checks validity<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">            elif (isinstance(value,list) and len(value) > 0) or isinstance(value,MFVec3f):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                for each in value:<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                    self.__value.append(SFVec3f(each).value) # checks validity<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">            elif isinstance(value,str):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                self.__value.append(SFVec3f(value).value) # checks validity<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###     if  not value is None:<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###         if isValidSFVec3f(value):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###             if isinstance(value, SFVec3f):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###                 value = SFVec3f(value).value # dereference value from base type<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###             self.__value.append(value)<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###         elif isValidMFVec3f(value):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###             for each in value:<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###                 while isinstance(each, list) and len(each) == 1:<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###                     each = each[0] # dereference<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###                 if isinstance(each, SFVec3f):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###                     each = each.value # dereference<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###                 self.__value.append(each)<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###         else:<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ###             assertValidMFVec3f(value) # report type failure<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    def __bool__(self):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        if not isinstance(self.__value,list):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New""><u style="font-family:"Courier New""></u> <u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">            print('*** x3d.py internal error, MFVec3f self.__value type=' + str(type(self.__value)) + ' is not a list', flush=True)<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        return len(self.__value) > 0<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New""># […snip…]<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText">===========================<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">all the best, Don<u></u><u></u></p><p class="m_466321523779582255MsoPlainText">-- <u></u><u></u></p><p class="m_466321523779582255MsoPlainText">Don Brutzman  Naval Postgraduate School, Code USW/Br        <a href="mailto:brutzman@nps.edu" target="_blank">brutzman@nps.edu</a><u></u><u></u></p><p class="m_466321523779582255MsoPlainText">Watkins 270,  MOVES Institute, Monterey CA 93943-5000 USA    +1.831.656.2149<u></u><u></u></p><p class="m_466321523779582255MsoPlainText">X3D graphics, virtual worlds, Navy robotics https:// <a href="http://faculty.nps.edu/brutzman" target="_blank">faculty.nps.edu/brutzman</a><u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">-----Original Message-----<br>From: Brutzman, Donald (Don) (CIV) <<a href="mailto:brutzman@nps.edu" target="_blank">brutzman@nps.edu</a>> <br>Sent: Sunday, February 27, 2022 7:42 AM<br>To: <a href="mailto:vmarchetti@kshell.com" target="_blank">vmarchetti@kshell.com</a><br>Cc: X3D Public Mailing List (<a href="mailto:x3d-public@web3d.org" target="_blank">x3d-public@web3d.org</a>) <<a href="mailto:x3d-public@web3d.org" target="_blank">x3d-public@web3d.org</a>>; Hans Moritz Guenther <<a href="mailto:hgunther@mit.edu" target="_blank">hgunther@mit.edu</a>>; Brutzman, Donald (Don) (CIV) <<a href="mailto:brutzman@nps.edu" target="_blank">brutzman@nps.edu</a>><br>Subject: RE: example python code using numpy library</p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">[cc: Moritz]<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">Looks like our enterprise mail server (configured by Microsoft in a cloud)<u></u><u></u></p><p class="m_466321523779582255MsoPlainText">scrubs all .py attachments.<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">I was able to retrieve your example by going to the Web3D-archived version<u></u><u></u></p><p class="m_466321523779582255MsoPlainText">at<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">* <a href="http://web3d.org/pipermail/x3d-public_web3d.org/2022-February/016818.html" target="_blank"><span style="text-decoration:none;color:windowtext">http://web3d.org/pipermail/x3d-public_web3d.org/2022-February/016818.html</span></a><u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">and then saving attachment.bin as NumpyExample.py<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">Thank you Vince, looks interesting.  Am also copying source here in case<u></u><u></u></p><p class="m_466321523779582255MsoPlainText">anyone has further retrieval difficulties.<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">NumpyExample.py<u></u><u></u></p><p class="m_466321523779582255MsoPlainText">======================================<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">"""<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">Script to demonstrate setting the values of the coordinates, colors (by<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">vertex), and index arrays defining<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">an IndexedTriangleSet from data values in numpy arrays.<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">Tested Feb 24 2022 with x3d version 4.0.51   installed with pip<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">Vince Marchetti 24 Feb 2022<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">license : <a href="https://creativecommons.org/licenses/by/4.0/" target="_blank" style="font-family:"Courier New""><span style="text-decoration:none;font-family:"Courier New";color:windowtext">https://creativecommons.org/licenses/by/4.0/</span></a><u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">"""<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">from x3d.x3d import *<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">import numpy as np<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">def colored_tetrahedron( radius ):<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    """<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    returns (3,) tuple of numpy arrays<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    points_coordinate : a (N,3) array of vertex coordinates<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    points_colors : (N,3) array of colors<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    face_indices : (K,3) array of integer indices into points_* arrays<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    <u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    where N = number of vertices in mesh (N=4 for this tetrahedron)<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">          K = number of triangle faces in mesh (K=5 for tetrahedron)<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">          <u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    defines a mesh for a tetrahedron inscribed in sphere of with radius<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">specified by argument<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    centered at origin<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    """<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    point_coordinates = np.array([<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        ( 0.000,  1.000,   0.000),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        (-0.816, -0.344,   0.471),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        ( 0.816, -0.344,   0.471),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        ( 0.000, -0.344,  -0.942),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ]) * radius<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    <u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    point_colors = np.array([<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        (1.00,1.00,0.40),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        (0.70,0.40,1.00),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        (0.00,0.80,0.00),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        (1.00,0.80,0.90),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ])<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    face_indices = np.array([<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        (0,1,2),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        (0,2,3),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        (0,3,1),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">        (3,2,1)<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ])<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    <u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    return point_coordinates,point_colors,face_indices<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    <u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    <u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">point_coordinates,point_colors,face_indices = colored_tetrahedron( 2.0 )<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">newModel=X3D(profile='Immersive',version='3.3',<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">  head=head(<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    children=[<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    meta(content='NumpyExample.x3d',name='title'),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    meta(content='example of using Numpy library to generate coordinate<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">geometry and color',name='description'),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    meta(content='24 Feb 2022',name='created'),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    meta(content='Vince Marchetti',name='creator'),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New""> <u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">meta(content='<a href="https://www.web3d.org/x3d/content/examples/license.html" target="_blank" style="font-family:"Courier New"">https://www.web3d.org/x3d/content/examples/license.html</a>',name=<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">'license')<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">  ]),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">  Scene=Scene(<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    <u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    children=[<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    WorldInfo(title='NumpyExample.x3d'),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    Viewpoint(DEF='ViewUpClose', description='Initial Viewpoint'),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    Shape(geometry=IndexedTriangleSet(<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                # following code converts rank-2 numpy array of integers<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">into a python list for setting value of index field<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                index = list( face_indices.flatten() ),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                <u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                # following code converts rank-2 numpy array of float values<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">into a Python list of Python tuples of floats<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                # to set x3d values of type MFVec3f and MFColor<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                coord = Coordinate( point = [ tuple(pt) for pt in<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">point_coordinates] ),<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                color = Color( color = [tuple(c) for c in point_colors])<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">                )<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">          )<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">    ])<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">) <u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">newModelXML= newModel.XML() <u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-size:10pt;font-family:"Courier New"">print(newModelXML)<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText">======================================<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">all the best, Don<u></u><u></u></p><p class="m_466321523779582255MsoPlainText">-- <u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><span style="font-family:"Courier New"">Don Brutzman  Naval Postgraduate School, Code USW/Br        <a href="mailto:brutzman@nps.edu" target="_blank" style="font-family:"Courier New""><span style="text-decoration:none;font-family:"Courier New";color:windowtext">brutzman@nps.edu</span></a><u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-family:"Courier New"">Watkins 270,  MOVES Institute, Monterey CA 93943-5000 USA    +1.831.656.2149<u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><span style="font-family:"Courier New"">X3D graphics, virtual worlds, Navy robotics <a href="https://faculty.nps.edu/brutzman" target="_blank" style="font-family:"Courier New""><span style="text-decoration:none;font-family:"Courier New";color:windowtext">https://faculty.nps.edu/brutzman</span></a><u style="font-family:"Courier New""></u><u style="font-family:"Courier New""></u></span></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">-----Original Message-----<u></u><u></u></p><p class="m_466321523779582255MsoPlainText">From: <a href="mailto:vmarchetti@kshell.com" target="_blank"><span style="text-decoration:none;color:windowtext">vmarchetti@kshell.com</span></a> <<a href="mailto:vmarchetti@kshell.com" target="_blank"><span style="text-decoration:none;color:windowtext">vmarchetti@kshell.com</span></a>> <u></u><u></u></p><p class="m_466321523779582255MsoPlainText">Sent: Friday, February 25, 2022 3:50 AM<u></u><u></u></p><p class="m_466321523779582255MsoPlainText">To: X3D-Public <<a href="mailto:x3d-public@web3d.org" target="_blank"><span style="text-decoration:none;color:windowtext">x3d-public@web3d.org</span></a>>; Brutzman, Donald (Don) (CIV)<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><<a href="mailto:brutzman@nps.edu" target="_blank"><span style="text-decoration:none;color:windowtext">brutzman@nps.edu</span></a>><u></u><u></u></p><p class="m_466321523779582255MsoPlainText">Subject: example python code using numpy library<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">Attached is a Python script that defines the coordinates, colors, and face<u></u><u></u></p><p class="m_466321523779582255MsoPlainText">indices for a tetrahedron as numpy rank-2 arrays, then converts those values<u></u><u></u></p><p class="m_466321523779582255MsoPlainText">in order to initialize the field values for an x3d IndexedTriangleSet node.<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">This may serve as a demonstration example for using numpy together with the x3d package.<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">This script runs with the pip installation of x3d and was tested at version 4.0.51<u></u><u></u></p><p class="m_466321523779582255MsoPlainText"><u></u> <u></u></p><p class="m_466321523779582255MsoPlainText">Vince Marchetti<u></u><u></u></p></div></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>