def intf_ENTPTS(E): """Supply a number on the stack and this function will return the geometry of that entity. If a list of entity IDs is supplied, return geometry data for each.""" if not inc.entid_or_LST_of_entids(E.The,1): print("Input Error: pts") print(intf_ENTPTS.__doc__) return # Without doing much of anything. myeids= E.The.StackPop().val if type(myeids)==type(list()): #myeids= map(lambda x:x.val, myeids) # Should now be a list of ints. myeids= [x.val for x in myeids] # Should now be a list of ints. else: myeids= [ myeids ] # Also a (1 item) list of ints. for myeid in myeids: # NEEDS TO CHECK IF EID EXISTS! if myeid in MMEL.El: # Check if eid exists. pids= MMEL.El[myeid].epts # List of point IDs for this entity. for pid in pids: x= mm.Entity.allplist.PLdict[pid].x y= mm.Entity.allplist.PLdict[pid].y z= mm.Entity.allplist.PLdict[pid].z z= objectifier.StackOB_VAL(z) # Can't be just regular Python ints. y= objectifier.StackOB_VAL(y) x= objectifier.StackOB_VAL(x) p= objectifier.StackOB_LST([x, y, z]) p.names= ['x','y','z'] E.The.StackPush(p) else: print("Warning: No entity #%d. Skipping." % myeid)
def intf_PSDEV(E): """Calculate the population standard deviation of a list of values. Use this when all of the members of the entire population are represented. This is the square root of the population variance [2.2 2.4 3.1 2.5 3.5 3.6 2.5 2.0 2.2 2.6 2.7 3.3] var -> 0.511262055006 [76 89 83 79 91 95 82 69 66 75 80 88] var -> 8.41088910613 """ if not inc.LST(E, 1): print("Input Error: psdev") print(intf_PSDEV.__doc__) return # Without doing much of anything. v1 = E.The.StackPop().val # A Python list of gg OBs. if not v1: # Input is empty list. E.The.StackPush(objectifier.StackOB_VAL(0)) return import math numlist = list() # List of just numeric values. for v in v1: if v.whatami == "SYM": if v.val in E.symtab: v = E.symtab[v.val].val else: v = v.val numlist.append(v) out = objectifier.StackOB_VAL(math.sqrt(variance(numlist, True))) E.The.StackPush(out)
def intf_ENTDUP(E): """Supply an entity ID or list of entity IDs on the stack and this function will create a new entity of the same type and using the same points. The new entity id or list of ids will be returned to the stack.""" if not inc.entid_or_LST_of_entids(E.The,1): print("Input Error: entdup") print(intf_ENTDUP.__doc__) return # Without doing much of anything. myeids= E.The.StackPop().val if type(myeids)==type(list()): #myeids= map(lambda x:x.val, myeids) # Should now be a list of ints. myeids= [x.val for x in myeids] # Should now be a list of ints. listify= True else: myeids= [ myeids ] # Also a (1 item) list of ints. listify= False new_eid= list() for myeid in myeids: if myeid in MMEL.El: # Check if eid exists. src_ent= MMEL.El[myeid] new_ent= src_ent.duplicate() MMEL.add_ent(new_ent) if listify: new_eid.append( objectifier.StackOB_VAL(new_ent.eid) ) else: new_eid= objectifier.StackOB_VAL(new_ent.eid) else: print("WARNING: Entity ID# %d does not exist." % myeid) if new_eid: if listify: new_eid= objectifier.StackOB_LST(new_eid) E.The.StackPush(new_eid)
def intf_DECR(E): """A decrement function. Will decrease a value by subracting 1. Will also try to subtract one from the value of a symbol (leaving nothing). Decrementing text will remove the last letter of the original string. Lists decrement by removing the last item.""" term = E.The.StackPop() if term.whatami == 'SYM': if E.symtab[term.val].whatami == 'VAL': # Needs a new object to break old refs links. v = objectifier.StackOB_VAL(E.symtab[term.val].val - 1) E.symtab[term.val] = v elif E.symtab[term.val].whatami == 'TXT': # Needs a new object to break old refs links. t = objectifier.StackOB_TXT(E.symtab[term.val].val[0:-1]) E.symtab[term.val] = t elif E.symtab[term.val].whatami == 'LST': # Needs a new object to break old refs links. t = objectifier.StackOB_LST(E.symtab[term.val].val[0:-1]) E.symtab[term.val] = t elif E.symtab[term.val].whatami == 'SYM': pass # This is not complete. Because it's hard. elif term.whatami == 'VAL': E.The.StackPush(objectifier.StackOB_VAL(term.val - 1)) elif term.whatami == 'TXT': newseq = term.val[0:-1] E.The.StackPush(objectifier.StackOB_TXT(newseq)) elif term.whatami == 'LST': newseq = term.val[0:-1] E.The.StackPush(objectifier.StackOB_LST(newseq)) E.Undo.StackPush([objectifier.StackOB_SYM('drop'), term])
def intf_INCR(E): """An increment function. Will increment a value by adding 1. Will also try to add one to the value of a symbol (leaving nothing). Incrementing text will append an extra copy of the last letter of the original string. Lists increment by adding another copy of the last item.""" term = E.The.StackPop() if term.whatami == 'SYM': if E.symtab[term.val].whatami == 'VAL': # Needs a new object to break old refs links. v = objectifier.StackOB_VAL(E.symtab[term.val].val + 1) E.symtab[term.val] = v elif E.symtab[term.val].whatami == 'TXT': # Needs a new object to break old refs links. t = objectifier.StackOB_TXT(E.symtab[term.val].val + E.symtab[term.val].val[-1]) E.symtab[term.val] = t elif E.symtab[term.val].whatami == 'LST': # Needs a new object to break old refs links. t = objectifier.StackOB_LST(E.symtab[term.val].val + [E.symtab[term.val].val[-1]]) E.symtab[term.val] = t elif E.symtab[term.val].whatami == 'SYM': pass # This is not complete. Because it's hard. elif term.whatami == 'VAL': E.The.StackPush(objectifier.StackOB_VAL(term.val + 1)) elif term.whatami == 'TXT': newseq = term.val + term.val[-1] E.The.StackPush(objectifier.StackOB_TXT(newseq)) elif term.whatami == 'LST': newseq = term.val + [term.val[-1]] # Orig. list + last item. E.The.StackPush(objectifier.StackOB_LST(newseq)) E.Undo.StackPush([objectifier.StackOB_SYM('drop'), term])
def intf_PCOV(E): """Calculate the population covariance of two lists of values taken from v1 and v2. The two lists should be the same length. Use this when all of the members of the entire population are represented. [2.2 2.4 3.1 2.5 3.5 3.6 2.5 2.0 2.2 2.6 2.7 3.3] [76 89 83 79 91 95 82 69 66 75 80 88 ] pcov -> 3.53194444444 """ if not inc.LST(E, 1) and not inc.LST(E, 2): print("Input Error: pcov") print(intf_PCOV.__doc__) return # Without doing much of anything. v1 = E.The.StackPop().val # A Python list of gg OBs. v2 = E.The.StackPop().val # A Python list of gg OBs. if not v1 or not v2 or len(v1) != len(v2): # An input is empty list. E.The.StackPush(objectifier.StackOB_VAL(0)) return numlist1 = list() # List of just numeric values. for v in v1: if v.whatami == "SYM": if v.val in E.symtab: v = E.symtab[v.val].val else: v = v.val numlist1.append(v) numlist2 = list() # List of just numeric values. for v in v2: if v.whatami == "SYM": if v.val in E.symtab: v = E.symtab[v.val].val else: v = v.val numlist2.append(v) out = objectifier.StackOB_VAL(covariance(numlist1, numlist2, True)) E.The.StackPush(out)
def intf_NOT(E): """Logical 'not' of level 1.""" A= E.The.StackPop() # Test object. if A: E.The.StackPush(objectifier.StackOB_VAL(0)) else: E.The.StackPush(objectifier.StackOB_VAL(1)) E.Undo.StackPush( [ objectifier.StackOB_SYM('drop'), A ] )
def intf_TANIMOTO(E): """The `tanimoto` function takes a list of properties of item A from v2 and a list of properties of item B from v1 and calculates the Tanimoto similarity coefficient. The idea is to compute a measure of how similar these things A and B are based on their characteristics. For example, if you're an alien naturalist and you find a mystery animal with "horns", "tail", "beard", "red", and "hoof", and you want to see if its more like a zebra ("tail", "stripes", "hoof", "mane") or a goat ("horns", "tail", "hoof", "beard") this might be helpful. In recommendation engines, this can be used to find people with similar properties. There is much confusion aboout the origin and use of this. It seems to be a generalization of the Jaccard Index applicable to sets, which is what this function assumes. The formula used here is `T= Ni/(Na+Nb-Ni)` where Ni is the number of items in both lists or the count of the intersection, Na is the number of items in list A, and Nb is the number of items in list B. Dissimilarity, a distance metric, can be acheived with `1 rot rot tanimoto -`. The properties can be specified as TXT or VAL or SYM. If they are SYM, they are resolved. [''horns'' ''tail'' ''beard'' ''red'' ''hoof''] |devil sto devil [''tail'' ''stripes'' ''hoof'' ''mane''] tanimoto -> 0.285714285714 devil [''horns'' ''beard'' ''tail'' ''hoof''] tanimoto -> .8 """ if not inc.LST(E, 1) and not inc.LST(E, 2): print("Input Error: tanimoto") print(intf_TANIMOTO.__doc__) return # Without doing much of anything. v2 = E.The.StackPop().val # A Python list of gg OBs. v1 = E.The.StackPop().val # A Python list of gg OBs. out = objectifier.StackOB_VAL(0) if not v1 or not v2: # An input is empty list. E.The.StackPush(out) return sl1 = list() # List of numric or text values. for v in v1: if v.whatami == "SYM": if v.val in E.symtab: v = E.symtab[v.val].val else: v = v.val sl1.append(v) sl2 = list() # List of just numeric values. for v in v2: if v.whatami == "SYM": if v.val in E.symtab: v = E.symtab[v.val].val else: v = v.val sl2.append(v) C = len(set(sl1) & set(sl2)) num = float(C) den = len(sl1) + len(sl2) - C if den: out = objectifier.StackOB_VAL(num / den) E.The.StackPush(out)
def intf_GT(E): """True if level 2 is 'greater than' level 1.""" B= E.The.StackPop() # Test object 2. A= E.The.StackPop() # Test object 1. if A.val > B.val: E.The.StackPush(objectifier.StackOB_VAL(1)) else: E.The.StackPush(objectifier.StackOB_VAL(0)) E.Undo.StackPush( [ objectifier.StackOB_SYM('drop'), A, B ] )
def intf_LT(E): """True if level 2 is 'less than' level 1.""" B= E.The.StackPop().val # Test object 2. A= E.The.StackPop().val # Test object 1. if A < B: E.The.StackPush(objectifier.StackOB_VAL(1)) else: E.The.StackPush(objectifier.StackOB_VAL(0)) E.Undo.StackPush( [ objectifier.StackOB_SYM('drop'), A, B ] )
def intf_GE(E): """True if level 2 is 'greater than or equal' to level 1.""" B= E.The.StackPop().val # Test object 2. A= E.The.StackPop().val # Test object 1. if A >= B: E.The.StackPush(objectifier.StackOB_VAL(1)) else: E.The.StackPush(objectifier.StackOB_VAL(0)) E.Undo.StackPush( [ objectifier.StackOB_SYM('drop'), A, B ] )
def intf_EQ(E): """True if level 1 and level 2 are 'equal'.""" B= E.The.StackPop().val # Test object 2. A= E.The.StackPop().val # Test object 1. if A == B: E.The.StackPush(objectifier.StackOB_VAL(1)) else: E.The.StackPush(objectifier.StackOB_VAL(0)) E.Undo.StackPush( [ objectifier.StackOB_SYM('drop'), A, B ] )
def intf_OR(E): """Logical 'or' of levels 1 and 2.""" A= E.The.StackPop() # Test object. B= E.The.StackPop() # Evaluation object. if A or B: E.The.StackPush(objectifier.StackOB_VAL(1)) else: E.The.StackPush(objectifier.StackOB_VAL(0)) E.Undo.StackPush( [ objectifier.StackOB_SYM('drop'), A, B ] )
def intf_WEIGHTEDMEAN(E): """The `weightedmean` function takes a list of numbers to be averaged from v2 and a list of weights to bias the result by. The lists must be or resolve to VALs and they must be the same length. This is commonly used to calculate weighted grades. If a student gets grades of C, A, A, D, B (corresponding to [2 4 4 1 3]) in classes of 4, 3, 3, 4, 3 credits respectively, the weighted average of these two lists will give a GPA adjusted for the "importantance" based on credits. This could also be used to make recommendations based on how well rated an item is by a list of people (list v2) and how closely each of those people match the user's previous tastes (list v1, the weights). [2 4 4 1 3] [4 3 3 4 3] weightedmean -> 2.64705882353 [2 4 4 1 3] mean -> 2.8 [76 89 83 79 91 95 82 69 66 75 80 88 ] [2.2 2.4 3.1 2.5 3.5 3.6 2.5 2.0 2.2 2.6 2.7 3.3] weightedmean -> 82.3834355828 [76 89 83 79 91 95 82 69 66 75 80 88 ] mean -> 81.0833333333 """ if not inc.LST(E, 1) and not inc.LST(E, 2): print("Input Error: weightedmean") print(intf_WEIGHTEDMEAN.__doc__) return # Without doing much of anything. v2 = E.The.StackPop().val # A Python list of gg OBs. v1 = E.The.StackPop().val # A Python list of gg OBs. n = len(v1) out = objectifier.StackOB_VAL(0) if not v1 or not v2 or n != len(v2): # An input is empty list. E.The.StackPush(out) return numlist1 = list() # List of just numeric values. for v in v1: if v.whatami == "SYM": if v.val in E.symtab: v = E.symtab[v.val].val else: v = v.val numlist1.append(v) numlist2 = list() # List of just numeric values. for v in v2: if v.whatami == "SYM": if v.val in E.symtab: v = E.symtab[v.val].val else: v = v.val numlist2.append(v) num = sum([numlist1[i] * numlist2[i] for i in range(n)]) den = sum([numlist2[i] for i in range(n)]) if den: out = objectifier.StackOB_VAL(num / den) E.The.StackPush(out)
def intf_ENTROPY(E): """Calculate the Shannon entropy for a list of items. This is a measure of how surprising a random selection of the data is. It can be used to measure the amount of disorder in a set. Lowering entropy during an iterative classification process could be a sign that the data is becoming better organized. Symbols do get resolved although other data stays as is. The formula is `H(X)=-sum[i=1,n](p(x)*log2(p(x)))` where p(x) is the probability that X is in state x. The n is the number of unique items in the original list. The log2 aspect causes this function to return output measured in bits of entropy. This entropy calculation is likely not correct for cryptographic keys and passphrases since the probabilities of a certain value are generally lower than this process assumes (by counting extant examples). [2.2 2.4 3.1 2.5 3.5 3.6 2.5 2.0 2.2 2.6 2.7 3.3] entropy -> 3.25162916739 [76 89 83 79 91 95 82 69 66 75 80 88] entropy -> 3.58496250072 [''p'' ''a'' ''s'' ''s'' ''w'' ''o'' ''r'' ''d''] entropy -> 2.75 [''3'' ''T'' ''^'' '','' ''d'' ''9'' ''9'' ''w''] entropy -> 2.75 100000 range entropy -> 16.6096404744 """ if not inc.LST(E, 1): print("Input Error: entropy") print(intf_ENTROPY.__doc__) return # Without doing much of anything. v1 = E.The.StackPop().val # A Python list of gg OBs. if not v1: # Input is empty list. E.The.StackPush(objectifier.StackOB_VAL(0)) return import math l = list() # List of just numeric values. for v in v1: if v.whatami == "SYM": if v.val in E.symtab: v = E.symtab[v.val].val else: v = v.val l.append(v) log2 = lambda x: math.log(x) / math.log(2) total = len(l) counts = dict() for item in l: counts.setdefault(item, 0) counts[item] += 1 ent = 0 for i in counts: p = float(counts[i]) / total ent -= p * log2(p) out = objectifier.StackOB_VAL(ent) E.The.StackPush(out)
def intf_DIST(E): """Given two points (LSTs of three VALs) on stack level 2 and 1, compute distance between the two supplied points. For example: [5 5 5] [8 9 5] dist -> 5 To get the length of a line use something like: <entID> pts dist -> """ if ( not E.The.StackSize() >= 2 or not inc.point_formatted_LST(E.The,1) or not inc.point_formatted_LST(E.The,2) ): print("Input Error: dist") print(intf_DIST.__doc__) return # Without doing much of anything. import math P1object= E.The.StackPop() #P1= map(lambda x:x.val, P1object.val) # Should now be a list of floats. P1= [x.val for x in P1object.val] # Should now be a list of floats. P0object= E.The.StackPop() #P0= map(lambda x:x.val, P0object.val) # Should now be a list of floats. P0= [x.val for x in P0object.val] # Should now be a list of floats. dx= (P1[0]-P0[0]) dy= (P1[1]-P0[1]) dz= (P1[2]-P0[2]) D= math.sqrt(dx*dx + dy*dy + dz*dz) d= objectifier.StackOB_VAL(D) # Can't be just regular Python ints. E.The.StackPush(d)
def intf_LOG10(E): """Base 10 logarithm of the value of level one.""" X= E.The.StackPop() # Numeric input object. x= X.val # Value of it. answer= objectifier.StackOB_VAL( math.log10(x) ) E.The.StackPush(answer) E.Undo.StackPush( [ objectifier.StackOB_SYM('drop'), X ] )
def intf_2RAD(E): """Sine of level one which should be in degrees.""" X= E.The.StackPop() # Numeric input object. d= X.val # Value of it. answer= objectifier.StackOB_VAL( math.radians(d) ) E.The.StackPush(answer) E.Undo.StackPush( [ objectifier.StackOB_SYM('drop'), X ] )
def intf_2DEG(E): """Converts a radian value to degrees.""" X= E.The.StackPop() # Numeric input object. r= X.val # Value of it. answer= objectifier.StackOB_VAL( math.degrees(r) ) E.The.StackPush(answer) E.Undo.StackPush( [ objectifier.StackOB_SYM('drop'), X ] )
def intf_FILTER(E): """Take two objects off the stack, an object to perform some function on other objects and a list of those other objects. For each item in the list, put that item on the stack twice and then evaluate the function object. Then do an if. If the function object made a true value, then the copy will remain, if not, it goes. At the end, put all the stack items into a list except for the first n items where n is the size of the stack before the filter command or its arguments were introduced. In English, this means that if you have a stack with some original items, those should remain on the stack after the filter, but all of the objects the mapped function may produce will be rounded up into a list. Now the weird thing is that it is possible to have your filter function eat more levels off the stack than just the one of the list. In that case, you could have a stack be smaller than n+1 items where n is the number of original items. Example: 1 |[dup 30 <::!] |[dup ++::!] while 0 2list |[7 mod not::!] filter --> LST:[VAL:7.0, VAL:14.0, VAL:21.0, VAL:28.0]""" fn= E.The.StackPop() # The function part. li= E.The.StackPop() # The list part. Ns= E.The.StackSize() # Starting items on the stack unrelated to the mapping. if "LST" == li.whatami: for i in li.val: # li.val being a list. E.The.StackPush(i) # Put the ith list item on stack alone. E.evaluate(fn) # Evaluate the function object. E.The.StackPush(i) # Put the ith list item on stack alone. intf_IF(E) Ne= E.The.StackSize() # Ending items on the stack with mapping. net= Ne-Ns # Net object gain/loss. if net > 0: # If stuff was actually added. E.The.StackPush(objectifier.StackOB_VAL(net)) # Number of list items. intf_2LIST(E) # Make a list using that perfectly good function.
def intf_ABS(E): """Absolute value.""" X= E.The.StackPop() # Numeric input object. x= X.val # Value of it. answer= objectifier.StackOB_VAL( math.fabs(x) ) E.The.StackPush(answer) E.Undo.StackPush( [ objectifier.StackOB_SYM('drop'), X ] )
def intf_FLOOR(E): """Floor, lowest whole integer.""" X= E.The.StackPop() # Numeric input object. x= X.val # Value of it. answer= objectifier.StackOB_VAL( math.floor(x) ) E.The.StackPush(answer) E.Undo.StackPush( [ objectifier.StackOB_SYM('drop'), X ] )
def intf_MAP(E): """Take two objects off the stack, an object to perform some function on other objects and a list of those other objects. For each item in the list, put that item on the stack and then evaluate the function object. At the end, put all the stack items into a list except for the first n items where n is the size of the stack before the map command or its arguments were introduced. In English, this means that if you have a stack with some original items, those should remain on the stack after the map, but all of the objects the mapped function may produce will be rounded up into a list. Now the weird thing is that it is possible to have your mapped function eat more levels off the stack than just the one of the list. In that case, you could have a stack be smaller than n+1 items where n is the number of original items.""" fn= E.The.StackPop() # The function part. li= E.The.StackPop() # The list part. Ns= E.The.StackSize() # Starting items on the stack unrelated to the mapping. if "LST" == li.whatami: for i in li.val: # li.val being a list. E.The.StackPush(i) # Put the ith list item on stack alone. E.evaluate(fn) # Evaluate the function object. Ne= E.The.StackSize() # Ending items on the stack with mapping. net= Ne-Ns # Net object gain/loss. if net > 0: # If stuff was actually added. E.The.StackPush(objectifier.StackOB_VAL(net)) # Number of list items. intf_2LIST(E) # Make a list using that perfectly good function.
def intf_EXP(E): """Constant e to the value of level one.""" X= E.The.StackPop() # Numeric input object. x= X.val # Value of it. answer= objectifier.StackOB_VAL( math.exp(x) ) E.The.StackPush(answer) E.Undo.StackPush( [ objectifier.StackOB_SYM('drop'), X ] )
def intf_CEIL(E): """Ceiling, highest whole integer.""" X= E.The.StackPop() # Numeric input object. x= X.val # Value of it. answer= objectifier.StackOB_VAL( math.ceil(x) ) E.The.StackPush(answer) E.Undo.StackPush( [ objectifier.StackOB_SYM('drop'), X ] )
def intf_ENTDUPS(E): """Returns a list of every entity ID in the memory model which has an earlier (lower EID) corresponding entity which shares all of the exact same points. This is handy for managing duplicate entities. To completely clean up a model of duplicated entities, all edup? ~ -> """ if not inc.entid_or_LST_of_entids(E.The,1): print("Input Error: doubles") print(intf_ENTERASE.__doc__) return # Without doing much of anything. myeids= E.The.StackPop().val if type(myeids)==type(list()): #myeids= map(lambda x:x.val, myeids) # Should now be a list of ints. myeids= [x.val for x in myeids] # Should now be a list of ints. else: myeids= [ myeids ] # Also a (1 item) list of ints. some_doubles= list() for myeid in myeids: if myeid in MMEL.El: # Check if eid exists. if not myeid in some_doubles: new_doubles= MMEL.find_doubles_of(MMEL.El[myeid]) some_doubles+= new_doubles else: print("WARNING: Entity ID# %d does not exist." % myeid) if some_doubles: some_doubles_so= [objectifier.StackOB_VAL(eid) for eid in some_doubles] some_doubles_so= objectifier.StackOB_LST(some_doubles_so) E.The.StackPush(some_doubles_so) else: E.The.StackPush( objectifier.StackOB_LST( list() ))
def intf_LASTENTID(E): """Taking nothing from the stack, return the entity ID for the most recent entity.""" #lasteid= sorted(MMEL.El.keys())[-1] lasteid= MMEL.last_ent() lasteid_so= objectifier.StackOB_VAL(lasteid) E.The.StackPush(lasteid_so)
def intf_LINE(E): """Take 2 values off the stack and make a new line entity. Both items must be LST comprised of exactly 3 VALs representing 2 x,y,z cartesian points. e.g.[0 0 0::x y z] [10 -5 3.2::x y z] line""" # == Check Input == # Check that there are 2 point items on the stack inputok= False # Assume the worst. if E.The.StackSize() >= 2: # Ensure something is here. # === Check Item #1 === check= E.The.StackCopyItemLast() # Input verification. Next item on stack now. if is_stack_ob_a_pt(check): # === Check Item #2 === check= E.The.StackCopyItemN(2) if is_stack_ob_a_pt(check): inputok= True if not inputok: print("Input Error: line") print(intf_LINE.__doc__) return # Without doing much of anything. # The pop is a StackOB_LST containing xyz StackOB_VAL which must be expanded. p1= [ xyz.val for xyz in E.The.StackPop().val ] p2= [ xyz.val for xyz in E.The.StackPop().val ] c1= mm.Coords(p1) c2= mm.Coords(p2) line_ent= mm.Line_Entity( [c1,c2] ) MMEL.add_ent(line_ent) lines_eid= objectifier.StackOB_VAL(line_ent.eid) E.The.StackPush(lines_eid) OUT.default(MMEL,E) # AUTODUMP
def intf_TRI(E): """Take 3 values off the stack and make a tri face entity. The 3 values must be lists each containing 3 coordinate values. e.g. [-20 -20 0] [20 -20 0] [0 20 0] tri""" # == Check Input == # Check that there are 3 point items on the stack inputok= False # Assume the worst. if E.The.StackSize() >= 3: # Ensure something is here. # === Check Item #1 === check= E.The.StackCopyItemLast() # Input verification. Next item on stack now. if is_stack_ob_a_pt(check): # === Check Item #2 === check= E.The.StackCopyItemN(2) if is_stack_ob_a_pt(check): # === Check Item #3 === check= E.The.StackCopyItemN(3) if is_stack_ob_a_pt(check): inputok= True if not inputok: print("Input Error: tri") print(intf_TRI.__doc__) return # Without doing much of anything. # == Construct Tri == p1= [ xyz.val for xyz in E.The.StackPop().val ] p2= [ xyz.val for xyz in E.The.StackPop().val ] p3= [ xyz.val for xyz in E.The.StackPop().val ] c1= mm.Coords(p1) c2= mm.Coords(p2) c3= mm.Coords(p3) tri_ent= mm.Tri_Entity( [c1,c2,c3] ) MMEL.add_ent(tri_ent) tris_eid= objectifier.StackOB_VAL(tri_ent.eid) E.The.StackPush(tris_eid) OUT.default(MMEL,E) # AUTODUMP
def intf_TAGQUERY(E): """From level one, a TXT object or a list of TXT objects is taken off the stack. The entities which are tagged with the specified text items are returned in a list. An empty list is returned if no entities are tagged with the supplied tags. ''mytag'' tag? -> [<entID> <entID>] [''mytag1'' ''mytag2''] tag? -> [<entID> <entID] This will find any entities tagged with both "roof" and "house". [''roof'' ''house''] tag? -> [<entID> <entID>] This usage implies an *and* operation where all tags supplied must apply to the entity. To achieve an *or* effect use a construction like this. [''roof'' ''house''] tag? [''roof'' ''barn''] tag? + -> [<entID> <entID>] """ if not inc.TXT_or_LST_of_TXTs(E.The,1): print("Input Error: tag?") print(intf_TAGQUERY.__doc__) return # Without doing much of anything. mytags= E.The.StackPop().val if type(mytags)==type(list()): #mytags= map(lambda x:x.val, mytags) # Should now be a list of TXTs. mytags= [x.val for x in mytags] # Should now be a list of TXTs. else: mytags= [ mytags ] # Also a (1 item) list of ints. qualifying_ents= list() for myeid in MMEL.El.keys(): alltagshere= True # Assume they're here until one is not found. for mytag in mytags: #print("Searching entity #%d for tag ''%s''" % (myeid,mytag)) if not MMEL.El[myeid].has_tag(mytag): alltagshere= False break if alltagshere: qualifying_ents.append( objectifier.StackOB_VAL(myeid) ) E.The.StackPush( objectifier.StackOB_LST(qualifying_ents) )