diff --git a/core/node_id_dict.py b/core/node_id_dict.py index ccecd6de89a5d8c94f1ed9d871263712cd82977d..c81087bfe955b3cdac691cc5e2a017b2713a0e7c 100644 --- a/core/node_id_dict.py +++ b/core/node_id_dict.py @@ -49,9 +49,9 @@ class SvNodesDict: tree_id = node_tree.tree_id if not tree_id in self.sv_node_dict_cache: self.load_nodes(node_tree) - - if n_id in self.sv_node_dict_cache[tree_id]: - del self.sv_node_dict_cache[tree_id][n_id] + else: + if n_id in self.sv_node_dict_cache[tree_id]: + del self.sv_node_dict_cache[tree_id][n_id] def load_nodes(self, node_tree): tree_id = node_tree.tree_id diff --git a/core/sockets.py b/core/sockets.py index fd55b796d8a973fab18c57e7d2b9069deae85d8b..94f54c7678e22ab5e3be52b1ede19aed5784c079 100644 --- a/core/sockets.py +++ b/core/sockets.py @@ -290,7 +290,12 @@ class SvObjectSocket(NodeSocket, SvSocketCommon): bl_idname = "SvObjectSocket" bl_label = "Object Socket" - object_ref: StringProperty(update=process_from_socket) + # object_ref: StringProperty(update=process_from_socket) + object_ref: bpy.props.PointerProperty( + name="Object Reference", + poll=lambda s, o: True, # optionally filter items out of the list of Collections presented to user + type=bpy.types.Object, # what kind of objects are we showing + update=process_from_socket) def draw(self, context, layout, node, text): if self.custom_draw: @@ -306,7 +311,7 @@ class SvObjectSocket(NodeSocket, SvSocketCommon): if self.is_linked and not self.is_output: return self.convert_data(SvGetSocket(self, deepcopy), implicit_conversions) elif self.object_ref: - obj_ref = bpy.data.objects.get(self.object_ref.strip()) + obj_ref = self.node.get_bpy_data_from_name(self.object_ref, bpy.data.objects) if not obj_ref: raise SvNoDataError(self) return [obj_ref] diff --git a/docs/nodes/modifier_change/merge_by_distance.rst b/docs/nodes/modifier_change/merge_by_distance.rst deleted file mode 100644 index 4431e5d905799b3b7358bc01b7b083d9088edae7..0000000000000000000000000000000000000000 --- a/docs/nodes/modifier_change/merge_by_distance.rst +++ /dev/null @@ -1,52 +0,0 @@ -Merge by Distance -================= - -Functionality -------------- - -This merges vertices that are closer that a defined threshold, as do same-named command in blender - -Inputs ------- - -- **Distance** -- **Vertices** -- **PolyEdge** -- **FaceData**. List containing an arbitrary data item for each face of input - mesh. For example, this may be used to provide material indexes of input - mesh faces. Optional input. -- **Mask**. Vector mask to select the affected vertices - - -Parameters ----------- - -+-----------+-----------+-----------+-------------------------------------------+ -| Param | Type | Default | Description | -+===========+===========+===========+===========================================+ -| Distance | Float | 0.001 | Maximum distance to weld vertices | -+-----------+-----------+-----------+-------------------------------------------+ - -Outputs -------- - -This node has the following outputs: - -- **Vertices** -- **Edges** -- **Polygons** -- **Doubles**. Vertices, that were deleted. -- **FaceData**. List containing data items from the **FaceData** input, which - contains one item for each output mesh face. -- **Mask** The mask after the merge - -Examples of usage ------------------ - -.. image:: https://raw.githubusercontent.com/vicdoval/sverchok/docs_images/images_for_docs/modifier_change/merge_by_distance/sverchok_blender_merge_by_distance_example_01.png - -.. image:: https://raw.githubusercontent.com/vicdoval/sverchok/docs_images/images_for_docs/modifier_change/merge_by_distance/sverchok_blender_merge_by_distance_example_02.png - -.. image:: https://raw.githubusercontent.com/vicdoval/sverchok/docs_images/images_for_docs/modifier_change/merge_by_distance/sverchok_blender_merge_by_distance_example_03.png - -.. image:: https://raw.githubusercontent.com/vicdoval/sverchok/docs_images/images_for_docs/modifier_change/merge_by_distance/sverchok_blender_merge_by_distance_example_04.png diff --git a/docs/nodes/modifier_change/modifier_change_index.rst b/docs/nodes/modifier_change/modifier_change_index.rst index 9f2b95d7d0d00c88c3109d6e7187c5c634860b16..f2a76585aa0a722c6be43ebcc7a2f7ee17adf66d 100644 --- a/docs/nodes/modifier_change/modifier_change_index.rst +++ b/docs/nodes/modifier_change/modifier_change_index.rst @@ -19,7 +19,6 @@ Modifier Change extrude_region holes_fill flip_normals - merge_by_distance mesh_join mesh_separate objects_along_edge @@ -28,6 +27,7 @@ Modifier Change edge_boom polygons_to_edges recalc_normals + remove_doubles triangulate triangulate_heavy planar_faces diff --git a/docs/old/nodes/remove_doubles.rst b/docs/nodes/modifier_change/remove_doubles.rst similarity index 100% rename from docs/old/nodes/remove_doubles.rst rename to docs/nodes/modifier_change/remove_doubles.rst diff --git a/index.md b/index.md index 6d47277356fa3723cee87e820935e8b7a33de6dd..5832d905a98875a651f027549ed94ad4b8e52a1e 100644 --- a/index.md +++ b/index.md @@ -185,7 +185,7 @@ ## Modifier Change SvDeleteLooseNode - SvMergeByDistanceNode + SvRemoveDoublesNode SvSeparateMeshNode SvSeparatePartsToIndexes SvLimitedDissolve diff --git a/json_examples/Design/Adaptive_Voronoi_panel.json b/json_examples/Design/Adaptive_Voronoi_panel.json index 18d31293ba6b1820d564b85dfacdf742b877de55..4ced47be05c0e37048d47283d6d77ffbdb7e4321 100644 --- a/json_examples/Design/Adaptive_Voronoi_panel.json +++ b/json_examples/Design/Adaptive_Voronoi_panel.json @@ -9,13 +9,13 @@ "List Math.001": "Frame.001", "Map Range": "Frame.001", "Map Range.001": "Frame", - "Merge by Distance": "Frame.002", "Mesh Expression": "Frame", "Move.001": "Frame.003", "Note": "Frame.002", "Note.001": "Frame.002", "Origins": "Frame.001", "Plane": "Frame.003", + "Remove Doubles": "Frame.002", "Vector Math": "Frame.003", "Vector Math.001": "Frame.003", "Vector Noise": "Frame.001", @@ -216,20 +216,6 @@ }, "width": 140.0 }, - "Merge by Distance": { - "bl_idname": "SvMergeByDistanceNode", - "height": 100.0, - "hide": false, - "label": "", - "location": [ - 184.88937377929688, - 143.97623443603516 - ], - "params": { - "distance": 0.10000000149011612 - }, - "width": 140.0 - }, "Mesh Expression": { "bl_idname": "SvMeshEvalNode", "geom": "{\n \"defaults\": {\n \"Close\": 0.0\n },\n \"vertices\": [\n [\n 0.0,\n 0.0,\n 0.0\n ],\n [\n 2.0,\n 0.0,\n 0.0\n ],\n [\n 0.0,\n 2.0,\n 0.0\n ],\n [\n 2.0,\n 2.0,\n 0.0\n ],\n [\n 0.0,\n 0.2,\n 0.0\n ],\n [\n 2.0,\n 0.2,\n 0.0\n ],\n [\n 2.0,\n 1.0,\n 0.0\n ],\n [\n 0.0,\n 1.0,\n 0.0\n ],\n [\n 0.0,\n \"0.2 + Close\",\n 0.7,\n [\n \"Selected\"\n ]\n ],\n [\n 2.0,\n \"0.2 + Close\",\n 0.7,\n [\n \"Selected\"\n ]\n ],\n [\n 2.0,\n \"1.0 + Close\",\n 0.7,\n [\n \"Selected\"\n ]\n ],\n [\n 0.0,\n \"1.0 + Close\",\n 0.7,\n [\n \"Selected\"\n ]\n ]\n ],\n \"edges\": [\n [\n 0,\n 4\n ],\n [\n 0,\n 1\n ],\n [\n 3,\n 6\n ],\n [\n 2,\n 3\n ],\n [\n 1,\n 5\n ],\n [\n 4,\n 5\n ],\n [\n 2,\n 7\n ],\n [\n 6,\n 7\n ],\n [\n 8,\n 11\n ],\n [\n 8,\n 9\n ],\n [\n 9,\n 10\n ],\n [\n 10,\n 11\n ],\n [\n 5,\n 9\n ],\n [\n 4,\n 8\n ],\n [\n 7,\n 11\n ],\n [\n 6,\n 10\n ]\n ],\n \"faces\": [\n [\n 7,\n 6,\n 3,\n 2\n ],\n [\n 0,\n 1,\n 5,\n 4\n ],\n [\n 4,\n 5,\n 9,\n 8\n ],\n [\n 8,\n 9,\n 10,\n 11\n ],\n [\n 6,\n 7,\n 11,\n 10\n ]\n ],\n \"vertexdata\": [],\n \"facedata\": [\n 0,\n 0,\n 0,\n 0,\n 0\n ]\n}", @@ -336,6 +322,20 @@ "use_custom_color": true, "width": 140.0 }, + "Remove Doubles": { + "bl_idname": "SvRemoveDoublesNode", + "height": 100.0, + "hide": false, + "label": "", + "location": [ + 177.19818115234375, + 128.98429107666016 + ], + "params": { + "distance": 0.10000000149011612 + }, + "width": 140.0 + }, "Reroute": { "bl_idname": "NodeReroute", "height": 100.0, @@ -575,23 +575,23 @@ [ "Voronoi 2D", 0, - "Merge by Distance", - 0 + "Remove Doubles", + 1 ], [ "Voronoi 2D", 1, - "Merge by Distance", - 1 + "Remove Doubles", + 2 ], [ - "Merge by Distance", + "Remove Doubles", 0, "Fill Holes", 0 ], [ - "Merge by Distance", + "Remove Doubles", 1, "Fill Holes", 1 @@ -610,14 +610,14 @@ ], [ "Flip normals", - "Polygons", - "Reroute", + "Vertices", + "Reroute.001", "Input" ], [ "Flip normals", - "Vertices", - "Reroute.001", + "Polygons", + "Reroute", "Input" ], [ @@ -641,57 +641,57 @@ [ "Vector Noise", 0, - "List Math.001", + "List Math", 0 ], [ "Vector Noise", 0, - "List Math", + "List Math.001", 0 ], [ "Vector Noise", 0, - "Map Range.001", + "Map Range", 0 ], [ "List Math", 0, - "Map Range.001", + "Map Range", 1 ], [ "List Math.001", 0, - "Map Range.001", + "Map Range", 2 ], - [ - "Map Range.001", - 0, - "Mesh Expression", - 0 - ], [ "Vector Noise", 0, - "Map Range", + "Map Range.001", 0 ], [ "List Math", 0, - "Map Range", + "Map Range.001", 1 ], [ "List Math.001", 0, - "Map Range", + "Map Range.001", 2 ], + [ + "Map Range.001", + 0, + "Mesh Expression", + 0 + ], [ "Reroute.001", "Output", @@ -735,27 +735,27 @@ 2 ], [ - "Voronoi 2D", + "Move.001", 0, - "Viewer Draw Mk3.001", + "Viewer Draw Mk3.002", 0 ], [ - "Voronoi 2D", + "Plane", 1, - "Viewer Draw Mk3.001", + "Viewer Draw Mk3.002", 1 ], [ - "Move.001", + "Voronoi 2D", 0, - "Viewer Draw Mk3.002", + "Viewer Draw Mk3.001", 0 ], [ - "Plane", + "Voronoi 2D", 1, - "Viewer Draw Mk3.002", + "Viewer Draw Mk3.001", 1 ] ] diff --git a/json_examples/Shapes/Holes_in_cone.json b/json_examples/Shapes/Holes_in_cone.json index 008e6d3de0389e934f618d630952b83f4477376b..fa38bb8601a88ac3870d16a2446acf2698c244ad 100644 --- a/json_examples/Shapes/Holes_in_cone.json +++ b/json_examples/Shapes/Holes_in_cone.json @@ -4,9 +4,9 @@ "Circle": "Frame.001", "Crop mesh 2D": "Frame.001", "Matrix Apply.001": "Frame.002", - "Merge by Distance": "Frame.002", "Origins": "Frame", "Polygon Boom": "Frame", + "Remove Doubles": "Frame.002", "Vector Drop": "Frame" }, "groups": {}, @@ -73,7 +73,7 @@ }, "Frame": { "bl_idname": "NodeFrame", - "height": 274.2661437988281, + "height": 273.26617431640625, "hide": false, "label": "Take each face and put it into XOY plane", "location": [ @@ -93,11 +93,11 @@ 10.079999923706055 ], "params": {}, - "width": 442.3966064453125 + "width": 442.39654541015625 }, "Frame.002": { "bl_idname": "NodeFrame", - "height": 335.32904052734375, + "height": 293.3472900390625, "hide": false, "label": "Put faces back in their places", "location": [ @@ -105,7 +105,7 @@ 10.079999923706055 ], "params": {}, - "width": 419.053955078125 + "width": 466.843505859375 }, "Matrix Apply.001": { "bl_idname": "SvMatrixApplyJoinNode", @@ -121,18 +121,6 @@ }, "width": 141.03147888183594 }, - "Merge by Distance": { - "bl_idname": "SvMergeByDistanceNode", - "height": 100.0, - "hide": false, - "label": "", - "location": [ - 1569.7108039855957, - 63.329030990600586 - ], - "params": {}, - "width": 140.0 - }, "Origins": { "bl_idname": "SvOrigins", "height": 100.0, @@ -160,6 +148,18 @@ "params": {}, "width": 140.0 }, + "Remove Doubles": { + "bl_idname": "SvRemoveDoublesNode", + "height": 100.0, + "hide": false, + "label": "", + "location": [ + 1617.5003547668457, + 54.68060874938965 + ], + "params": {}, + "width": 140.0 + }, "Solidify": { "bl_idname": "SvSolidifyNode", "height": 100.0, @@ -169,9 +169,7 @@ 1814.6839599609375, 116.75218963623047 ], - "params": { - "thickness": 0.09999999403953552 - }, + "params": {}, "width": 140.0 }, "Vector Drop": { @@ -292,23 +290,23 @@ [ "Matrix Apply.001", 0, - "Merge by Distance", - 0 + "Remove Doubles", + 1 ], [ "Matrix Apply.001", 2, - "Merge by Distance", - 1 + "Remove Doubles", + 2 ], [ - "Merge by Distance", + "Remove Doubles", 0, "Solidify", 1 ], [ - "Merge by Distance", + "Remove Doubles", 2, "Solidify", 2 diff --git a/node_scripts/SNLite_templates/demo/Genetic_algorithm.py b/node_scripts/SNLite_templates/demo/Genetic_algorithm.py index eff89288dd8c624b3de48ad5bb9cb5ea22640b2b..0b130b479a4241a54dd8b26f70fd9293c3851806 100644 --- a/node_scripts/SNLite_templates/demo/Genetic_algorithm.py +++ b/node_scripts/SNLite_templates/demo/Genetic_algorithm.py @@ -13,9 +13,7 @@ in population s d=20 n=2 in generations s d=10000 n=2 in threshold s d=0.9 n=2 in mutator s d=0.1 n=2 -in mutofactor s d=0.1 n=2 in selector s d=0.2 n=2 -in random_seed s d=0 n=2 in all_apart s d=0 n=2 out vers_final v out vers_descr v @@ -64,7 +62,7 @@ def compare_two_lists(agent_list,pattern): def ga(): agents = init_agents(population, in_str_len) - stepper = 0.76 + stepper = 0.1 for generation in range(generations): @@ -77,14 +75,14 @@ def ga(): if any(agent.fitness >= stepper for agent in agents): combo.append(sorted(agents, key=lambda agent: agent.fitness, reverse=True)[0].string) - print(f"GA fitness >= {round(stepper,2)}, in #{generation} generation") - stepper += 0.02 + stepper += 0.1 if any(agent.fitness >= threshold for agent in agents): + print (f'Last generation #{str(generation)}') agent = sorted(agents, key=lambda agent: agent.fitness, reverse=True)[0] - print (f'GA ended \ - \nGA fitness: {round(agent.fitness,4)}, in #{str(generation)} generation \ - \nGA values: {[[round(i,2) for i in x] for x in agent.string[:2]]} ... ') + print (f'GA ended with {type(agent.string)} {len(agent.string)}, \ + \n{agent.string[:3]}... \ + \nFitness: {agent.fitness}') return agent.string return [None] @@ -138,7 +136,7 @@ def mutation(agents): for agent in agents: for idx, param in enumerate(agent.string): - if random.uniform(0.0, 1.0) <= mutofactor: + if random.uniform(0.0, 1.0) <= mutator: if all_apart == 0: agent.string = agent.string[0:idx] + \ [(random.choice(data[0]))] + \ @@ -155,16 +153,14 @@ def mutation(agents): return agents if data and pattern: - random.seed(random_seed) in_str = pattern[0] emax = lambda a,b: a if (a > b) else b emin = lambda a,b: a if (a < b) else b all_max = reduce(emax,[reduce(emax, x) for x in in_str]) all_min = reduce(emin,[reduce(emin, x) for x in in_str]) all_dif = all_max-all_min - print(f'------------------------------------ \ - \nGA started \ - \nGA values: {[[round(i,2) for i in x] for x in in_str[:2]]} ...') + print(f'GA initialised with {type(in_str)} {len(in_str)} \ + \n{in_str[:3]}...') in_str_len = len(in_str) combo = [] vers_final = [ga()] diff --git a/node_scripts/SNLite_templates/demo/recursive_subdivision.py b/node_scripts/SNLite_templates/demo/recursive_subdivision.py index 4d84e4684e8c4bdd67e37d2763f7784f0e78b702..e110d8285592b49b3a9049fdf6f9ad8c38931610 100644 --- a/node_scripts/SNLite_templates/demo/recursive_subdivision.py +++ b/node_scripts/SNLite_templates/demo/recursive_subdivision.py @@ -5,13 +5,12 @@ in seed s d=1 n=2 in random_factor s d=0.1 n=2 in iterations s d=1 n=2 out verts v -out edges s out faces s """ from sverchok.utils.modules.geom_utils import interp_v3_v3v3 as lerp from sverchok.utils.sv_mesh_utils import mesh_join -from sverchok.utils.sv_bmesh_utils import remove_doubles +from sverchok.nodes.modifier_change.remove_doubles import remove_doubles import random # loosly based on https://www.youtube.com/watch?v=GhquYJ9m1Oc @@ -20,7 +19,7 @@ sort = lambda vex, pox: [vex[i] for i in pox] def random_subdiv_mesh(verts_m, pols_m, iteration): - verts, faces = [], [] + verts, faces =[],[] for pol in pols_m: verts_out, faces_out = [], [] new_quad = faces_out.append @@ -36,7 +35,7 @@ def random_subdiv_mesh(verts_m, pols_m, iteration): pos_f = lerp(pos_d, pos_b, 1-Y) # indices = 0, 1, 2, 3 - verts_out.extend(pts) + verts_out.extend(pts) # indices = 4, 5, 6, 7, 8, 9 verts_out.extend([pos_a, pos_b, pos_c, pos_d, pos_e, pos_f]) @@ -47,17 +46,16 @@ def random_subdiv_mesh(verts_m, pols_m, iteration): new_quad([7, 9, 6, 3]) faces.append(faces_out) verts.append(verts_out) - - verts, _, faces = mesh_join(verts, [], faces) - if iteration < 2 : - return verts, faces + + verts, _, faces = mesh_join(verts, [],faces) + if iteration <2 : + return verts,faces else: return random_subdiv_mesh(verts, faces, iteration - 1) - + if quad_verts and quad_faces: random.seed(seed) - verts, faces = random_subdiv_mesh(quad_verts[0], quad_faces[0], iterations) - verts, edges, faces = remove_doubles(verts, [], faces, 1e-5) + verts, faces = random_subdiv_mesh(quad_verts[0], quad_faces[0], iterations) + verts, _, faces, _, _ = remove_doubles(verts, faces, 1e-5, False) verts = [verts] - edges = [edges] faces = [faces] diff --git a/node_scripts/SNLite_templates/demo/subidivide_to_quads.py b/node_scripts/SNLite_templates/demo/subidivide_to_quads.py index 4ba97780ad06465097396fd699819dab04d3e5cd..15b52130957001d025de4e15c3c31cc9dbe9a35c 100644 --- a/node_scripts/SNLite_templates/demo/subidivide_to_quads.py +++ b/node_scripts/SNLite_templates/demo/subidivide_to_quads.py @@ -6,12 +6,11 @@ in random_factor s d=0. n=1 in seed s d=1 n=1 out verts v -out edges s out faces s """ from sverchok.utils.modules.geom_utils import interp_v3_v3v3 as lerp -from sverchok.utils.sv_bmesh_utils import remove_doubles +from sverchok.nodes.modifier_change.remove_doubles import remove_doubles from sverchok.data_structure import match_long_repeat as mlr import random @@ -71,7 +70,6 @@ def subdiv_mesh_to_quads(verts_mesh, pols_m, it, random_f): if verts_in and faces_in: verts = [] - edges = [] faces = [] seed_l = enusure_list(seed) iterations_l = enusure_list(iterations) @@ -79,8 +77,7 @@ if verts_in and faces_in: for v, f, s, it, r in zip(*mlr([verts_in, faces_in, seed_l, iterations_l, random_fac])): random.seed(s) - verts_out, faces_out = subdiv_mesh_to_quads(v, f, min(it, 5), r) - verts_out, edges_out, faces_out = remove_doubles(verts_out, [], faces_out, 1e-5) + verts_out, faces_out = subdiv_mesh_to_quads(v, f, min(it,5), r) + verts_out, _, faces_out, _, _ = remove_doubles(verts_out, faces_out, 1e-5, False) verts.append(verts_out) - edges.append(edges_out) faces.append(faces_out) diff --git a/node_tree.py b/node_tree.py index a33f57d3348fcd35f06af834e8e27f99b1fa945b..0caa9ffb16473631418daf2c5e8463bd89da0e23 100644 --- a/node_tree.py +++ b/node_tree.py @@ -841,6 +841,38 @@ class SverchCustomTreeNode: except Exception as err: print('failed to get gl scale info', err) + def get_bpy_data_from_name(self, identifier, bpy_data_kind): + """ + fail gracefuly? + + This function acknowledges that the identifier being passed can be a string or an object proper. + for a long time Sverchok stored the result of a prop_search as a StringProperty, and many nodes will + be stored with that data in .blends, here we try to permit older blends having data stored as a string, + but newly used prop_search results will be stored as a pointerproperty of type bpy.types.Object + + regarding the need to trim the first 3 chars of a stored StringProperty, best let Blender devs enlighten you + https://developer.blender.org/T58641 + + example usage inside a node: + + text = self.get_bpy_data_from_name(self.filename, bpy.data.texts) + + if the text does not exist you get None + + + """ + + if isinstance(identifier, str): + if identifier in bpy_data_kind: + return bpy_data_kind.get(identifier) + elif identifier[3:] in bpy_data_kind: + return bpy_data_kind.get(identifier[3:]) + elif isinstance(identifier, bpy.types.Object) and identifier.name in bpy_data_kind: + return identifier + + self.error(f"identifier '{identifier}' not found in {bpy_data_kind}") + return None + classes = [ SverchCustomTree, diff --git a/nodes/generator/script1_lite.py b/nodes/generator/script1_lite.py index d2878e305fb9fa53929d875cf6d595a951c007bb..7f8cb773382bba9907e70278d6d49edbe90ec221 100644 --- a/nodes/generator/script1_lite.py +++ b/nodes/generator/script1_lite.py @@ -274,14 +274,14 @@ class SvScriptNodeLite(bpy.types.Node, SverchCustomTreeNode): def load(self): - ''' ----- ''' if not self.script_name: return - if self.script_name in bpy.data.texts: - self.script_str = bpy.data.texts.get(self.script_name).as_string() + text = self.get_bpy_data_from_name(self.script_name, bpy.data.texts) + if text: + self.script_str = text.as_string() else: - print('bpy.data.texts not read yet') + print(f'bpy.data.texts not read yet, self.script_name="{self.script_name}"') if self.script_str: print('but script loaded locally anyway.') diff --git a/nodes/generators_extended/polygon_grid.py b/nodes/generators_extended/polygon_grid.py index 7297b07dc2e5242c8ba67877843040ba61137cb9..d10b64001ad6378112c0d896c6b558a4ab3adc75 100644 --- a/nodes/generators_extended/polygon_grid.py +++ b/nodes/generators_extended/polygon_grid.py @@ -26,7 +26,7 @@ from sverchok.data_structure import updateNode, match_long_repeat from sverchok.ui.sv_icons import custom_icon from sverchok.utils.geom import circle from sverchok.utils.sv_mesh_utils import mesh_join -from sverchok.utils.sv_bmesh_utils import remove_doubles +from sverchok.nodes.modifier_change.remove_doubles import remove_doubles grid_layout_items = [ ("RECTANGLE", "Rectangle", "", custom_icon("SV_HEXA_GRID_RECTANGLE"), 0), @@ -216,7 +216,7 @@ def generate_tiles(tile_settings): if not separate: vert_list, edge_list, poly_list = mesh_join(vert_list, edge_list, poly_list) if scale == 1.0: - vert_list, edge_list, poly_list = remove_doubles(vert_list, [], poly_list, 0.001) + vert_list, edge_list, poly_list, _, _ = remove_doubles(vert_list, poly_list, 0.01, False) vert_grid_list.append(vert_list) edge_grid_list.append(edge_list) diff --git a/nodes/modifier_change/merge_by_distance.py b/nodes/modifier_change/merge_by_distance.py deleted file mode 100644 index fbcb765f41f55711a4a3ead7dbd298f9e5af74f6..0000000000000000000000000000000000000000 --- a/nodes/modifier_change/merge_by_distance.py +++ /dev/null @@ -1,165 +0,0 @@ -# ##### BEGIN GPL LICENSE BLOCK ##### -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# ##### END GPL LICENSE BLOCK ##### -from itertools import chain, repeat -import bpy -from bpy.props import FloatProperty -import bmesh - -from sverchok.node_tree import SverchCustomTreeNode -from sverchok.data_structure import updateNode, Vector_generate, repeat_last, zip_long_repeat -from sverchok.utils.sv_bmesh_utils import bmesh_from_pydata, face_data_from_bmesh_faces, vert_data_from_bmesh_verts -from sverchok.utils.logging import info, debug - - -def remove_doubles(vertices, faces, distance, face_data=None, find_doubles=False, mask=[], output_mask=False): - - if faces: - edge_mode = (len(faces[0]) == 2) - else: - edge_mode = False - if face_data: - mark_face_data = True - else: - mark_face_data = False - - bm = bmesh_from_pydata( - vertices, - faces if edge_mode else [], - [] if edge_mode else faces, - markup_face_data=mark_face_data, - markup_vert_data=output_mask) - bm_verts = bm.verts - - if mask: - mask_full = chain(mask, repeat(mask[-1])) - bm_verts = [v for v, m in zip(bm_verts, mask_full) if m] - - if find_doubles: - res = bmesh.ops.find_doubles(bm, verts=bm_verts, dist=distance) - doubles = [vert.co[:] for vert in res['targetmap'].keys()] - else: - doubles = [] - - bmesh.ops.remove_doubles(bm, verts=bm_verts, dist=distance) - edges = [] - faces = [] - face_data_out = [] - bm.verts.index_update() - verts = [vert.co[:] for vert in bm.verts[:]] - - bm.edges.index_update() - bm.faces.index_update() - for edge in bm.edges[:]: - edges.append([v.index for v in edge.verts[:]]) - for face in bm.faces: - faces.append([v.index for v in face.verts[:]]) - if face_data: - face_data_out = face_data_from_bmesh_faces(bm, face_data) - if output_mask: - mask_out = vert_data_from_bmesh_verts(bm, mask) - else: - mask_out = [] - - bm.clear() - bm.free() - return (verts, edges, faces, face_data_out, doubles, mask_out) - - -class SvMergeByDistanceNode(bpy.types.Node, SverchCustomTreeNode): - """ - Triggers: Remove Doubles - Tooltip: Merge Vertices that are closer than a distance. - """ - bl_idname = 'SvMergeByDistanceNode' - bl_label = 'Merge by Distance' - bl_icon = 'OUTLINER_OB_EMPTY' - sv_icon = 'SV_REMOVE_DOUBLES' - - distance: FloatProperty( - name='Distance', description='Remove distance', - default=0.001, precision=3, min=0, update=updateNode) - - def sv_init(self, context): - self.inputs.new('SvVerticesSocket', 'Vertices') - self.inputs.new('SvStringsSocket', 'PolyEdge') - self.inputs.new('SvStringsSocket', 'FaceData') - self.inputs.new('SvStringsSocket', 'Mask') - self.inputs.new('SvStringsSocket', 'Distance').prop_name = 'distance' - - self.outputs.new('SvVerticesSocket', 'Vertices') - self.outputs.new('SvStringsSocket', 'Edges') - self.outputs.new('SvStringsSocket', 'Polygons') - self.outputs.new('SvStringsSocket', 'FaceData') - self.outputs.new('SvVerticesSocket', 'Doubles') - self.outputs.new('SvStringsSocket', 'Mask') - - def draw_buttons(self, context, layout): - #layout.prop(self, 'distance', text="Distance") - pass - - def process(self): - if not any(s.is_linked for s in self.outputs): - return - - if not self.inputs['Vertices'].is_linked: - return - - verts = Vector_generate(self.inputs['Vertices'].sv_get()) - polys = self.inputs['PolyEdge'].sv_get(default=[[]]) - face_data = self.inputs['FaceData'].sv_get(default=[[]]) - distance = self.inputs['Distance'].sv_get(default=[self.distance])[0] - has_double_out = self.outputs['Doubles'].is_linked - mask_s = self.inputs['Mask'].sv_get(default=[[]], deepcopy=False) - has_mask_out = self.inputs['Mask'].is_linked, self.outputs['Mask'].is_linked - verts_out = [] - edges_out = [] - polys_out = [] - face_data_out = [] - d_out = [] - mask_out = [] - - for v, p, ms, d, mask in zip_long_repeat(verts, polys, face_data, distance, mask_s): - res = remove_doubles(v, p, d, ms, has_double_out, mask=mask, output_mask=has_mask_out) - if not res: - return - verts_out.append(res[0]) - edges_out.append(res[1]) - polys_out.append(res[2]) - face_data_out.append(res[3]) - d_out.append(res[4]) - mask_out.append(res[5]) - - self.outputs['Vertices'].sv_set(verts_out) - - # restrict setting this output when there is no such input - if self.inputs['PolyEdge'].is_linked: - self.outputs['Edges'].sv_set(edges_out) - self.outputs['Polygons'].sv_set(polys_out) - - self.outputs['FaceData'].sv_set(face_data_out) - self.outputs['Doubles'].sv_set(d_out) - - self.outputs['Mask'].sv_set(mask_out) - - -def register(): - bpy.utils.register_class(SvMergeByDistanceNode) - - -def unregister(): - bpy.utils.unregister_class(SvMergeByDistanceNode) diff --git a/old_nodes/remove_doubles.py b/nodes/modifier_change/remove_doubles.py similarity index 98% rename from old_nodes/remove_doubles.py rename to nodes/modifier_change/remove_doubles.py index 32ef27b2b8f9697cb96d1d8a4f9c14959ca58600..ebda3059f2e63ecd2ac1c2c67b8f6ceb1ce1b011 100644 --- a/old_nodes/remove_doubles.py +++ b/nodes/modifier_change/remove_doubles.py @@ -91,8 +91,6 @@ class SvRemoveDoublesNode(bpy.types.Node, SverchCustomTreeNode): bl_icon = 'OUTLINER_OB_EMPTY' sv_icon = 'SV_REMOVE_DOUBLES' - replacement_nodes = [('SvMergeByDistanceNode', None, None)] - distance: FloatProperty( name='Distance', description='Remove distance', default=0.001, precision=3, min=0, update=updateNode) diff --git a/utils/sv_default_macros.py b/utils/sv_default_macros.py index 134ddf7f6e55e89b507eea05bda308c0a5d73c9f..a8f6b23247232888fbb8c44adccab1c7f7157894 100644 --- a/utils/sv_default_macros.py +++ b/utils/sv_default_macros.py @@ -186,7 +186,6 @@ class DefaultMacros(): elif 'snl' in term: file = term.split(' ')[1] snlite = nodes.new('SvScriptNodeLite') - snlite.location = context.space_data.cursor_location sn_loader(snlite, script_name=file) elif term == 'monad info': diff --git a/utils/text_editor_plugins.py b/utils/text_editor_plugins.py index 468d45080f8b23026583d7a96429b1f89692f328..ffe6efb4b0a6ee23c463408628298aba5c856e6c 100644 --- a/utils/text_editor_plugins.py +++ b/utils/text_editor_plugins.py @@ -91,4 +91,49 @@ class SvNodeRefreshFromTextEditor(bpy.types.Operator): ng.sv_update() - return {'FINISHED'} \ No newline at end of file + return {'FINISHED'} + + + +# store keymaps here to access after registration +addon_keymaps = [] + + +def add_keymap(): + + # handle the keymap + wm = bpy.context.window_manager + kc = wm.keyconfigs.addon + + if not kc: + debug('no keyconfig path found. that\'s ok') + return + + km = kc.keymaps.new(name='Text', space_type='TEXT_EDITOR') + keymaps = km.keymap_items + + if 'noderefresh_from_texteditor' in dir(bpy.ops.text): + ''' SHORTCUT 1 Node Refresh: Ctrl + Return ''' + ident_str = 'text.noderefresh_from_texteditor' + if not (ident_str in keymaps): + new_shortcut = keymaps.new(ident_str, 'RET', 'PRESS', ctrl=1, head=0) + addon_keymaps.append((km, new_shortcut)) + + debug('Sverchok added keyboard items to Text Editor.') + + +def remove_keymap(): + for km, kmi in addon_keymaps: + km.keymap_items.remove(kmi) + addon_keymaps.clear() + + +def register(): + bpy.utils.register_class(SvNodeRefreshFromTextEditor) + add_keymap() + + +def unregister(): + remove_keymap() + bpy.utils.unregister_class(SvNodeRefreshFromTextEditor) +