-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
48 changed files
with
2,409 additions
and
374 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Binary file modified
BIN
+16.5 KB
(100%)
examples/TopologicEnergy/TopologicBuildingWithDictionaries.blend
Binary file not shown.
Binary file modified
BIN
+48 Bytes
(100%)
examples/TopologicEnergy/TopologicBuildingWithDictionaries.blend1
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,140 @@ | ||
import bpy | ||
from bpy.props import StringProperty, BoolProperty, FloatProperty, EnumProperty | ||
from sverchok.node_tree import SverchCustomTreeNode | ||
from sverchok.data_structure import updateNode | ||
import idprop | ||
|
||
import topologic | ||
from topologic import Vertex, Edge, Wire, Face, Shell, Cell, CellComplex, Cluster, Topology, Dictionary | ||
import time | ||
|
||
# From https://stackabuse.com/python-how-to-flatten-list-of-lists/ | ||
def flatten(element): | ||
returnList = [] | ||
if isinstance(element, list) == True: | ||
for anItem in element: | ||
returnList = returnList + flatten(anItem) | ||
else: | ||
returnList = [element] | ||
return returnList | ||
|
||
def listAttributeValues(listAttribute): | ||
listAttributes = listAttribute.ListValue() | ||
returnList = [] | ||
for attr in listAttributes: | ||
if isinstance(attr, topologic.IntAttribute): | ||
returnList.append(attr.IntValue()) | ||
elif isinstance(attr, topologic.DoubleAttribute): | ||
returnList.append(attr.DoubleValue()) | ||
elif isinstance(attr, topologic.StringAttribute): | ||
returnList.append(attr.StringValue()) | ||
return returnList | ||
|
||
def valueAtKey(item, key): | ||
try: | ||
attr = item.ValueAtKey(key) | ||
except: | ||
raise Exception("Dictionary.ValueAtKey - Error: Could not retrieve a Value at the specified key ("+key+")") | ||
if isinstance(attr, topologic.IntAttribute): | ||
return (attr.IntValue()) | ||
elif isinstance(attr, topologic.DoubleAttribute): | ||
return (attr.DoubleValue()) | ||
elif isinstance(attr, topologic.StringAttribute): | ||
return (attr.StringValue()) | ||
elif isinstance(attr, topologic.ListAttribute): | ||
return (listAttributeValues(attr)) | ||
else: | ||
return None | ||
|
||
def processKeysValues(keys, values): | ||
if len(keys) != len(values): | ||
raise Exception("DictionaryByKeysValues - Keys and Values do not have the same length") | ||
stl_keys = [] | ||
stl_values = [] | ||
for i in range(len(keys)): | ||
if keys[i] in '_RNA_UI': | ||
continue | ||
if isinstance(keys[i], str): | ||
stl_keys.append(keys[i]) | ||
else: | ||
stl_keys.append(str(keys[i])) | ||
if isinstance(values[i], list) and len(values[i]) == 1: | ||
value = values[i][0] | ||
else: | ||
value = values[i] | ||
if isinstance(value, idprop.types.IDPropertyArray): | ||
value = value.to_list() | ||
if isinstance(value, bool): | ||
if value == False: | ||
stl_values.append(topologic.IntAttribute(0)) | ||
else: | ||
stl_values.append(topologic.IntAttribute(1)) | ||
elif isinstance(value, int): | ||
stl_values.append(topologic.IntAttribute(value)) | ||
elif isinstance(value, float): | ||
stl_values.append(topologic.DoubleAttribute(value)) | ||
elif isinstance(value, str): | ||
stl_values.append(topologic.StringAttribute(value)) | ||
elif isinstance(value, list): | ||
l = [] | ||
for v in value: | ||
if isinstance(v, bool): | ||
l.append(topologic.IntAttribute(v)) | ||
elif isinstance(v, int): | ||
l.append(topologic.IntAttribute(v)) | ||
elif isinstance(v, float): | ||
l.append(topologic.DoubleAttribute(v)) | ||
elif isinstance(v, str): | ||
l.append(topologic.StringAttribute(v)) | ||
stl_values.append(topologic.ListAttribute(l)) | ||
else: | ||
stl_values.append(topologic.StringAttribute(str(value))) | ||
myDict = topologic.Dictionary.ByKeysValues(stl_keys, stl_values) | ||
return myDict | ||
|
||
def processItem(source): | ||
#keys = source.keys() | ||
#print(keys) | ||
print(source["name"]) | ||
#if len(keys) < 1: | ||
#raise Exception("DictionaryByCustomProperties - Error: The source has no custom properties") | ||
values = [] | ||
for aKey in keys: | ||
value = source[aKey] | ||
values.append(source[aKey]) | ||
return processKeysValues(keys, values) | ||
|
||
class SvDictionaryByCustomProperties(bpy.types.Node, SverchCustomTreeNode): | ||
|
||
""" | ||
Triggers: Topologic | ||
Tooltip: Creates a dictionary from the custom properties of the input Blender Object | ||
""" | ||
bl_idname = 'SvDictionaryByCustomProperties' | ||
bl_label = 'Dictionary.ByCustomProperties' | ||
|
||
def sv_init(self, context): | ||
self.inputs.new('SvStringsSocket', 'Source') | ||
self.outputs.new('SvStringsSocket', 'Dictionary') | ||
|
||
def process(self): | ||
start = time.time() | ||
if not any(socket.is_linked for socket in self.outputs): | ||
return | ||
if not any(socket.is_linked for socket in self.inputs): | ||
self.outputs['Dictionary'].sv_set([]) | ||
return | ||
sourceList = self.inputs['Source'].sv_get(deepcopy=True) | ||
sourceList = flatten(sourceList) | ||
outputs = [] | ||
for anInput in sourceList: | ||
outputs.append(processItem(anInput)) | ||
self.outputs['Dictionary'].sv_set(outputs) | ||
end = time.time() | ||
print("Dictionary.ByCustomProperties Operation consumed "+str(round(end - start,2))+" seconds") | ||
|
||
def register(): | ||
bpy.utils.register_class(SvDictionaryByCustomProperties) | ||
|
||
def unregister(): | ||
bpy.utils.unregister_class(SvDictionaryByCustomProperties) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,151 @@ | ||
import bpy | ||
from bpy.props import FloatProperty, StringProperty, EnumProperty | ||
from sverchok.node_tree import SverchCustomTreeNode | ||
from sverchok.data_structure import updateNode | ||
|
||
import topologic | ||
|
||
# From https://stackabuse.com/python-how-to-flatten-list-of-lists/ | ||
def flatten(element): | ||
returnList = [] | ||
if isinstance(element, list) == True: | ||
for anItem in element: | ||
returnList = returnList + flatten(anItem) | ||
else: | ||
returnList = [element] | ||
return returnList | ||
|
||
def repeat(list): | ||
maxLength = len(list[0]) | ||
for aSubList in list: | ||
newLength = len(aSubList) | ||
if newLength > maxLength: | ||
maxLength = newLength | ||
for anItem in list: | ||
if (len(anItem) > 0): | ||
itemToAppend = anItem[-1] | ||
else: | ||
itemToAppend = None | ||
for i in range(len(anItem), maxLength): | ||
anItem.append(itemToAppend) | ||
return list | ||
|
||
# From https://stackoverflow.com/questions/34432056/repeat-elements-of-list-between-each-other-until-we-reach-a-certain-length | ||
def onestep(cur,y,base): | ||
# one step of the iteration | ||
if cur is not None: | ||
y.append(cur) | ||
base.append(cur) | ||
else: | ||
y.append(base[0]) # append is simplest, for now | ||
base = base[1:]+[base[0]] # rotate | ||
return base | ||
|
||
def iterate(list): | ||
maxLength = len(list[0]) | ||
returnList = [] | ||
for aSubList in list: | ||
newLength = len(aSubList) | ||
if newLength > maxLength: | ||
maxLength = newLength | ||
for anItem in list: | ||
for i in range(len(anItem), maxLength): | ||
anItem.append(None) | ||
y=[] | ||
base=[] | ||
for cur in anItem: | ||
base = onestep(cur,y,base) | ||
# print(base,y) | ||
returnList.append(y) | ||
return returnList | ||
|
||
def trim(list): | ||
minLength = len(list[0]) | ||
returnList = [] | ||
for aSubList in list: | ||
newLength = len(aSubList) | ||
if newLength < minLength: | ||
minLength = newLength | ||
for anItem in list: | ||
anItem = anItem[:minLength] | ||
returnList.append(anItem) | ||
return returnList | ||
|
||
# Adapted from https://stackoverflow.com/questions/533905/get-the-cartesian-product-of-a-series-of-lists | ||
def interlace(ar_list): | ||
if not ar_list: | ||
yield [] | ||
else: | ||
for a in ar_list[0]: | ||
for prod in interlace(ar_list[1:]): | ||
yield [a,]+prod | ||
|
||
def transposeList(l): | ||
length = len(l[0]) | ||
returnList = [] | ||
for i in range(length): | ||
tempRow = [] | ||
for j in range(len(l)): | ||
tempRow.append(l[j][i]) | ||
returnList.append(tempRow) | ||
return returnList | ||
|
||
def processItem(item): | ||
edge = item[0] | ||
parameter = item[1] | ||
vertex = None | ||
try: | ||
vertex = topologic.EdgeUtility.PointAtParameter(edge, parameter) | ||
except: | ||
vertex = None | ||
return vertex | ||
|
||
replication = [("Trim", "Trim", "", 1),("Iterate", "Iterate", "", 2),("Repeat", "Repeat", "", 3),("Interlace", "Interlace", "", 4)] | ||
|
||
class SvEdgeVertexByParameter(bpy.types.Node, SverchCustomTreeNode): | ||
""" | ||
Triggers: Topologic | ||
Tooltip: Creates a Vertex at the parameter value of the input Edge | ||
""" | ||
bl_idname = 'SvEdgeVertexByParameter' | ||
bl_label = 'Edge.VertexByParameter' | ||
Parameter: FloatProperty(name="Parameter", default=0.5, precision=4, min=0, max=1, update=updateNode) | ||
Replication: EnumProperty(name="Replication", description="Replication", default="Iterate", items=replication, update=updateNode) | ||
|
||
def sv_init(self, context): | ||
self.inputs.new('SvStringsSocket', 'Edge') | ||
self.inputs.new('SvStringsSocket', 'Parameter').prop_name='Parameter' | ||
self.outputs.new('SvStringsSocket', 'Vertex') | ||
|
||
def draw_buttons(self, context, layout): | ||
layout.prop(self, "Replication",text="") | ||
|
||
def process(self): | ||
if not any(socket.is_linked for socket in self.outputs): | ||
return | ||
edgeList = self.inputs['Edge'].sv_get(deepcopy=False) | ||
parameterList = self.inputs['Parameter'].sv_get(deepcopy=False) | ||
edgeList = flatten(edgeList) | ||
parameterList = flatten(parameterList) | ||
inputs = [edgeList, parameterList] | ||
if ((self.Replication) == "Trim"): | ||
inputs = trim(inputs) | ||
inputs = transposeList(inputs) | ||
elif ((self.Replication) == "Iterate"): | ||
inputs = iterate(inputs) | ||
inputs = transposeList(inputs) | ||
elif ((self.Replication) == "Repeat"): | ||
inputs = repeat(inputs) | ||
inputs = transposeList(inputs) | ||
elif ((self.Replication) == "Interlace"): | ||
inputs = list(interlace(inputs)) | ||
outputs = [] | ||
for anInput in inputs: | ||
outputs.append(processItem(anInput)) | ||
self.outputs['Vertex'].sv_set(outputs) | ||
|
||
def register(): | ||
bpy.utils.register_class(SvEdgeVertexByParameter) | ||
|
||
def unregister(): | ||
bpy.utils.unregister_class(SvEdgeVertexByParameter) |
Oops, something went wrong.