Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Eisel <eiseljulian@gmail.com>2020-03-05 15:02:11 +0300
committerJulian Eisel <eiseljulian@gmail.com>2020-03-05 15:02:11 +0300
commitc444673d3c8e21e44f570ff8185218f39081a87b (patch)
treec38cbc4cd9398d66e68962d43bc48786494e2525
parent9ad518d1147af41fe4ad42e5ebf2007f11d0801d (diff)
parentbf2cf4d6010b7efee66da47d3f0b50f9e43a2b24 (diff)
Merge branch 'master' into soc-2019-openxr
-rw-r--r--.arcconfig1
-rw-r--r--add_camera_rigs/__init__.py4
-rw-r--r--add_curve_extra_objects/__init__.py8
-rw-r--r--add_curve_extra_objects/add_curve_aceous_galore.py4
-rw-r--r--add_curve_extra_objects/add_curve_braid.py5
-rw-r--r--add_curve_extra_objects/add_curve_celtic_links.py5
-rw-r--r--add_curve_extra_objects/add_curve_curly.py7
-rw-r--r--add_curve_extra_objects/add_curve_simple.py7
-rw-r--r--add_curve_extra_objects/add_curve_spirals.py4
-rw-r--r--add_curve_extra_objects/add_curve_spirofit_bouncespline.py4
-rw-r--r--add_curve_extra_objects/add_curve_torus_knots.py7
-rw-r--r--add_curve_extra_objects/add_surface_plane_cone.py2
-rw-r--r--add_curve_extra_objects/beveltaper_curve.py7
-rw-r--r--add_curve_ivygen.py4
-rw-r--r--add_curve_sapling/__init__.py7
-rw-r--r--add_mesh_BoltFactory/__init__.py6
-rw-r--r--add_mesh_discombobulator/__init__.py4
-rw-r--r--add_mesh_extra_objects/__init__.py4
-rw-r--r--add_mesh_extra_objects/add_mesh_rocks/__init__.py5
-rw-r--r--add_mesh_extra_objects/add_mesh_triangles.py7
-rw-r--r--add_mesh_geodesic_domes/__init__.py7
-rw-r--r--amaranth/__init__.py2
-rw-r--r--animation_add_corrective_shape_key.py4
-rw-r--r--animation_animall.py4
-rw-r--r--ant_landscape/__init__.py4
-rw-r--r--archimesh/__init__.py4
-rw-r--r--archimesh/achm_tools.py15
-rw-r--r--archipack/__init__.py2
-rw-r--r--archipack/archipack_gl.py4
-rw-r--r--archipack/archipack_keymaps.py2
-rw-r--r--blender_id/__init__.py4
-rw-r--r--blenderkit/__init__.py9
-rw-r--r--blenderkit/bg_blender.py1
-rw-r--r--blenderkit/colors.py2
-rw-r--r--blenderkit/oauth.py2
-rw-r--r--blenderkit/search.py35
-rw-r--r--blenderkit/tasks_queue.py2
-rw-r--r--blenderkit/ui.py14
-rw-r--r--blenderkit/ui_panels.py21
-rw-r--r--blenderkit/utils.py2
-rw-r--r--bone_selection_sets.py4
-rw-r--r--btrace/__init__.py7
-rw-r--r--btrace/bTrace_props.py2
-rw-r--r--camera_turnaround.py7
-rw-r--r--curve_assign_shapekey.py6
-rw-r--r--curve_simplify.py4
-rw-r--r--curve_tools/__init__.py9
-rw-r--r--curve_tools/cad.py2
-rw-r--r--curve_tools/fillet.py5
-rw-r--r--curve_tools/outline.py2
-rw-r--r--curve_tools/path_finder.py5
-rw-r--r--depsgraph_debug.py5
-rw-r--r--development_edit_operator.py7
-rw-r--r--development_icon_get.py6
-rw-r--r--development_iskeyfree.py6
-rw-r--r--io_anim_bvh/__init__.py4
-rw-r--r--io_anim_camera.py4
-rw-r--r--io_anim_nuke_chan/__init__.py4
-rw-r--r--io_coat3D/__init__.py4
-rw-r--r--io_curve_svg/__init__.py4
-rw-r--r--io_export_dxf/__init__.py4
-rw-r--r--io_export_dxf/model/dxfLibrary.py1354
-rw-r--r--io_export_dxf/model/model.py68
-rw-r--r--io_export_dxf/test2.txt2
-rw-r--r--io_export_paper_model.py4
-rw-r--r--io_export_pc2.py7
-rw-r--r--io_import_dxf/__init__.py4
-rw-r--r--io_import_images_as_planes.py4
-rw-r--r--io_import_palette/__init__.py7
-rw-r--r--io_mesh_atomic/__init__.py4
-rw-r--r--io_mesh_atomic/utility_gui.py1
-rw-r--r--io_mesh_ply/__init__.py4
-rw-r--r--io_mesh_stl/__init__.py4
-rw-r--r--io_mesh_uv_layout/__init__.py4
-rw-r--r--io_mesh_uv_layout/export_uv_eps.py2
-rw-r--r--io_mesh_uv_layout/export_uv_svg.py2
-rw-r--r--io_scene_fbx/__init__.py4
-rwxr-xr-xio_scene_gltf2/__init__.py41
-rwxr-xr-xio_scene_gltf2/blender/com/gltf2_blender_conversion.py1
-rwxr-xr-xio_scene_gltf2/blender/com/gltf2_blender_data_path.py1
-rw-r--r--io_scene_gltf2/blender/com/gltf2_blender_extras.py1
-rwxr-xr-xio_scene_gltf2/blender/com/gltf2_blender_json.py1
-rwxr-xr-xio_scene_gltf2/blender/com/gltf2_blender_material_helpers.py1
-rwxr-xr-xio_scene_gltf2/blender/com/gltf2_blender_math.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_export.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_export_keys.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_extract.py37
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather.py6
-rw-r--r--io_scene_gltf2/blender/exp/gltf2_blender_gather_accessors.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py4
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py3
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py11
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_cache.py13
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_cameras.py1
-rw-r--r--io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py4
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_image.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py1
-rw-r--r--io_scene_gltf2/blender/exp/gltf2_blender_gather_light_spots.py1
-rw-r--r--io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_material_normal_texture_info_class.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_material_occlusion_texture_info_class.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py21
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_sampler.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_texture.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gather_texture_info.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_get.py5
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_gltf2_exporter.py1
-rw-r--r--io_scene_gltf2/blender/exp/gltf2_blender_image.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_search_node_tree.py1
-rwxr-xr-xio_scene_gltf2/blender/exp/gltf2_blender_utils.py1
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py1
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_unlit.py1
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_animation.py1
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py45
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_animation_node.py2
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_animation_utils.py1
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_animation_weight.py1
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_camera.py1
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_gltf.py17
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_image.py1
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_light.py1
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_material.py1
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_material_utils.py149
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_mesh.py13
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_node.py69
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_pbrMetallicRoughness.py14
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_primitive.py13
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_scene.py1
-rwxr-xr-xio_scene_gltf2/blender/imp/gltf2_blender_skin.py1
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_texture.py33
-rw-r--r--io_scene_gltf2/blender/imp/gltf2_blender_vnode.py40
-rwxr-xr-xio_scene_gltf2/io/__init__.py1
-rwxr-xr-xio_scene_gltf2/io/com/gltf2_io.py1
-rw-r--r--io_scene_gltf2/io/com/gltf2_io_color_management.py1
-rwxr-xr-xio_scene_gltf2/io/com/gltf2_io_constants.py1
-rwxr-xr-xio_scene_gltf2/io/com/gltf2_io_debug.py1
-rw-r--r--io_scene_gltf2/io/com/gltf2_io_extensions.py1
-rw-r--r--io_scene_gltf2/io/com/gltf2_io_lights_punctual.py1
-rwxr-xr-xio_scene_gltf2/io/exp/gltf2_io_binary_data.py1
-rwxr-xr-xio_scene_gltf2/io/exp/gltf2_io_buffer.py1
-rw-r--r--io_scene_gltf2/io/exp/gltf2_io_draco_compression_extension.py1
-rwxr-xr-xio_scene_gltf2/io/exp/gltf2_io_export.py1
-rwxr-xr-xio_scene_gltf2/io/exp/gltf2_io_image_data.py1
-rw-r--r--io_scene_gltf2/io/exp/gltf2_io_user_extensions.py1
-rwxr-xr-xio_scene_gltf2/io/imp/__init__.py1
-rwxr-xr-xio_scene_gltf2/io/imp/gltf2_io_binary.py1
-rwxr-xr-xio_scene_gltf2/io/imp/gltf2_io_gltf.py1
-rw-r--r--io_scene_obj/__init__.py7
-rw-r--r--io_scene_x3d/__init__.py4
-rw-r--r--io_shape_mdd/__init__.py7
-rw-r--r--lighting_dynamic_sky.py6
-rw-r--r--lighting_tri_lights.py4
-rw-r--r--magic_uv/__init__.py6
-rw-r--r--magic_uv/lib/bglx.py1
-rw-r--r--materials_library_vx/__init__.py7
-rw-r--r--materials_library_vx/categories.txt2
-rw-r--r--materials_utils/__init__.py6
-rw-r--r--measureit/__init__.py4
-rw-r--r--measureit/measureit_geometry.py3
-rw-r--r--mesh_auto_mirror.py7
-rw-r--r--mesh_bsurfaces.py4
-rw-r--r--mesh_f2.py4
-rw-r--r--mesh_inset/__init__.py11
-rw-r--r--mesh_looptools.py4
-rw-r--r--mesh_snap_utilities_line/__init__.py5
-rw-r--r--mesh_snap_utilities_line/snap_context_l/utils_projection.py1
-rw-r--r--mesh_tiny_cad/__init__.py6
-rw-r--r--mesh_tissue/__init__.py5
-rw-r--r--mesh_tools/__init__.py4
-rw-r--r--mesh_tools/mesh_cut_faces.py3
-rw-r--r--mesh_tools/mesh_edge_roundifier.py3
-rw-r--r--mesh_tools/mesh_edges_floor_plan.py5
-rw-r--r--mesh_tools/mesh_edges_length.py4
-rw-r--r--mesh_tools/mesh_edgetools.py7
-rw-r--r--mesh_tools/mesh_extrude_and_reshape.py7
-rw-r--r--mesh_tools/mesh_filletplus.py5
-rw-r--r--mesh_tools/mesh_mextrude_plus.py5
-rw-r--r--mesh_tools/mesh_offset_edges.py9
-rw-r--r--mesh_tools/mesh_relax.py4
-rw-r--r--mesh_tools/mesh_vertex_chamfer.py5
-rw-r--r--mesh_tools/pkhg_faces.py2
-rw-r--r--mesh_tools/random_vertices.py5
-rw-r--r--mesh_tools/split_solidify.py5
-rw-r--r--mesh_tools/vertex_align.py5
-rw-r--r--node_arrange.py648
-rw-r--r--node_presets.py4
-rw-r--r--node_wrangler.py51
-rw-r--r--object_boolean_tools.py4
-rw-r--r--object_carver/__init__.py448
-rw-r--r--object_carver/carver_draw.py940
-rw-r--r--object_carver/carver_operator.py2620
-rw-r--r--object_carver/carver_preferences.py354
-rw-r--r--object_carver/carver_profils.py806
-rw-r--r--object_carver/carver_utils.py1580
-rw-r--r--object_collection_manager/__init__.py4
-rw-r--r--object_collection_manager/internals.py1
-rw-r--r--object_color_rules.py4
-rw-r--r--object_edit_linked.py4
-rw-r--r--object_fracture_cell/__init__.py4
-rw-r--r--object_print3d_utils/__init__.py2
-rw-r--r--object_scatter/__init__.py2
-rw-r--r--object_skinify.py7
-rw-r--r--oscurart_tools/__init__.py4
-rw-r--r--oscurart_tools/files/reload_images.py2
-rw-r--r--oscurart_tools/files/save_incremental.py2
-rw-r--r--oscurart_tools/mesh/apply_linked_meshes.py5
-rw-r--r--oscurart_tools/mesh/flipped_uvs.py2
-rw-r--r--oscurart_tools/mesh/overlap_island.py3
-rw-r--r--oscurart_tools/mesh/overlap_uvs.py1
-rw-r--r--oscurart_tools/mesh/remove_modifiers.py3
-rw-r--r--oscurart_tools/mesh/select_doubles.py3
-rw-r--r--oscurart_tools/mesh/vertex_color_id.py3
-rw-r--r--oscurart_tools/object/distribute.py1
-rw-r--r--oscurart_tools/object/search_and_select.py3
-rw-r--r--oscurart_tools/render/batch_maker.py1
-rw-r--r--oscurart_tools/render/material_overrides.py1
-rw-r--r--paint_palette.py4
-rwxr-xr-xpower_sequencer/__init__.py2
-rw-r--r--power_sequencer/scripts/BPSProxy/bpsproxy/commands.py2
-rw-r--r--power_sequencer/scripts/BPSProxy/bpsproxy/utils.py2
-rw-r--r--power_sequencer/scripts/BPSRender/bpsrender/__init__.py1
-rw-r--r--power_sequencer/scripts/BPSRender/bpsrender/helpers.py2
-rw-r--r--precision_drawing_tools/__init__.py2
-rw-r--r--presets/pov/light/17_(1700K)_135W_Low_Pressure_Sodium.py2
-rw-r--r--presets/pov/world/4_Cartoony_Sky.py2
-rw-r--r--presets/pov/world/5_Under_Water.py2
-rw-r--r--render_auto_tile_size.py4
-rw-r--r--render_copy_settings/__init__.py4
-rw-r--r--render_freestyle_svg.py4
-rw-r--r--render_povray/__init__.py2
-rw-r--r--rigify/__init__.py7
-rw-r--r--rigify/base_generate.py1
-rw-r--r--rigify/legacy/__init__.py7
-rw-r--r--rigify/rigs/experimental/super_chain.py2
-rw-r--r--rigify/rot_mode.py7
-rw-r--r--rigify/utils/metaclass.py1
-rw-r--r--space_clip_editor_refine_solution.py4
-rw-r--r--space_view3d_3d_navigation.py4
-rw-r--r--space_view3d_align_tools.py4
-rw-r--r--space_view3d_brush_menus/__init__.py5
-rw-r--r--space_view3d_copy_attributes.py4
-rw-r--r--space_view3d_math_vis/__init__.py4
-rw-r--r--space_view3d_math_vis/draw.py2
-rw-r--r--space_view3d_modifier_tools.py4
-rw-r--r--space_view3d_pie_menus/__init__.py10
-rw-r--r--space_view3d_pie_menus/pie_align_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_animation_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_apply_transform_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_defaults_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_delete_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_editor_switch_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_manipulator_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_modes_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_origin.py4
-rw-r--r--space_view3d_pie_menus/pie_proportional_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_save_open_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_sculpt_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_select_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_shading_menu.py2
-rw-r--r--space_view3d_pie_menus/pie_views_numpad_menu.py2
-rw-r--r--space_view3d_spacebar_menu/__init__.py32
-rw-r--r--space_view3d_spacebar_menu/edit_mesh.py302
-rw-r--r--space_view3d_spacebar_menu/snap_origin_cursor.py406
-rw-r--r--space_view3d_stored_views/__init__.py4
-rw-r--r--space_view3d_stored_views/io.py2
-rw-r--r--space_view3d_stored_views/operators.py2
-rw-r--r--space_view3d_stored_views/properties.py2
-rw-r--r--space_view3d_stored_views/stored_views_test.py4
-rw-r--r--sun_position/__init__.py7
-rw-r--r--sun_position/geo.py4
-rw-r--r--sun_position/properties.py1
-rw-r--r--system_blend_info.py4
-rw-r--r--system_demo_mode/__init__.py4
-rw-r--r--system_property_chart.py4
-rw-r--r--ui_translate/__init__.py5
283 files changed, 5425 insertions, 5606 deletions
diff --git a/.arcconfig b/.arcconfig
index 44782a8b..bb8a12dd 100644
--- a/.arcconfig
+++ b/.arcconfig
@@ -1,6 +1,7 @@
{
"project_id" : "Blender Addons",
"conduit_uri" : "https://developer.blender.org/",
+ "phabricator.uri" : "https://developer.blender.org/",
"git.default-relative-commit" : "origin/master",
"arc.land.update.default" : "rebase"
}
diff --git a/add_camera_rigs/__init__.py b/add_camera_rigs/__init__.py
index 9c742e6a..faf06314 100644
--- a/add_camera_rigs/__init__.py
+++ b/add_camera_rigs/__init__.py
@@ -23,8 +23,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D > Add > Camera > Dolly or Crane Rig",
"description": "Adds a Camera Rig with UI",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "camera/camera_rigs.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "camera/camera_rigs.html",
"tracker_url": "https://github.com/waylow/add_camera_rigs/issues",
"category": "Camera",
}
diff --git a/add_curve_extra_objects/__init__.py b/add_curve_extra_objects/__init__.py
index 1e63e812..6f4ac24f 100644
--- a/add_curve_extra_objects/__init__.py
+++ b/add_curve_extra_objects/__init__.py
@@ -28,10 +28,10 @@ bl_info = {
"location": "View3D > Add > Curve > Extra Objects",
"description": "Add extra curve object types",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "add_curve/extra_objects.html",
- "category": "Add Curve"
- }
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "add_curve/extra_objects.html",
+ "category": "Add Curve",
+}
if "bpy" in locals():
import importlib
diff --git a/add_curve_extra_objects/add_curve_aceous_galore.py b/add_curve_extra_objects/add_curve_aceous_galore.py
index dfe8753f..463b05a0 100644
--- a/add_curve_extra_objects/add_curve_aceous_galore.py
+++ b/add_curve_extra_objects/add_curve_aceous_galore.py
@@ -25,8 +25,8 @@ bl_info = {
"location": "View3D > Add > Curve",
"description": "Adds many different types of Curves",
"warning": "",
- "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
- "Scripts/Curve/Curves_Galore",
+ "doc_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Curve/Curves_Galore",
"category": "Add Curve",
}
"""
diff --git a/add_curve_extra_objects/add_curve_braid.py b/add_curve_extra_objects/add_curve_braid.py
index 8041b4bf..5f52d455 100644
--- a/add_curve_extra_objects/add_curve_braid.py
+++ b/add_curve_extra_objects/add_curve_braid.py
@@ -9,8 +9,9 @@ bl_info = {
"location": "View3D > Add > Mesh > New Braid",
"description": "Adds a new Braid",
"warning": "",
- "wiki_url": "",
- "category": "Add Mesh"}
+ "doc_url": "",
+ "category": "Add Mesh",
+}
"""
import bpy
diff --git a/add_curve_extra_objects/add_curve_celtic_links.py b/add_curve_extra_objects/add_curve_celtic_links.py
index d3136bdb..663f8b7e 100644
--- a/add_curve_extra_objects/add_curve_celtic_links.py
+++ b/add_curve_extra_objects/add_curve_celtic_links.py
@@ -30,8 +30,9 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D > Add > Curve",
"warning": "",
- "wiki_url": "https://github.com/BorisTheBrave/celtic-knot/wiki",
- "category": "Add Curve"}
+ "doc_url": "https://github.com/BorisTheBrave/celtic-knot/wiki",
+ "category": "Add Curve",
+}
import bpy
import bmesh
diff --git a/add_curve_extra_objects/add_curve_curly.py b/add_curve_extra_objects/add_curve_curly.py
index 637269b5..72f82f05 100644
--- a/add_curve_extra_objects/add_curve_curly.py
+++ b/add_curve_extra_objects/add_curve_curly.py
@@ -10,9 +10,10 @@ bl_info = {
"location": "View3D > Add > Curve > Curly Curve",
"description": "Adds a new Curly Curve",
"warning": "",
- "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/"
- "Py/Scripts/Curve/Curly_Curves",
- "category": "Add Curve"}
+ "doc_url": "https://wiki.blender.org/index.php/Extensions:2.6/"
+ "Py/Scripts/Curve/Curly_Curves",
+ "category": "Add Curve",
+}
import bpy
from bpy.types import Operator
diff --git a/add_curve_extra_objects/add_curve_simple.py b/add_curve_extra_objects/add_curve_simple.py
index af055589..c994acb9 100644
--- a/add_curve_extra_objects/add_curve_simple.py
+++ b/add_curve_extra_objects/add_curve_simple.py
@@ -24,9 +24,10 @@ bl_info = {
"location": "View3D > Add > Curve",
"description": "Adds Simple Curve",
"warning": "",
- "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/"
- "Py/Scripts/Curve/Simple_curves",
- "category": "Add Curve"}
+ "doc_url": "https://wiki.blender.org/index.php/Extensions:2.6/"
+ "Py/Scripts/Curve/Simple_curves",
+ "category": "Add Curve",
+}
# ------------------------------------------------------------
diff --git a/add_curve_extra_objects/add_curve_spirals.py b/add_curve_extra_objects/add_curve_spirals.py
index 55495ddf..2ccdc51a 100644
--- a/add_curve_extra_objects/add_curve_spirals.py
+++ b/add_curve_extra_objects/add_curve_spirals.py
@@ -9,8 +9,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D > Add > Curve",
"warning": "",
- "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.4/Py/"
- "Scripts/Object/Spirals",
+ "doc_url": "https://wiki.blender.org/index.php/Extensions:2.4/Py/"
+ "Scripts/Object/Spirals",
"tracker_url": "http://alexvaqp.googlepages.com?"
"func=detail&aid=<number>",
"category": "Add Curve",
diff --git a/add_curve_extra_objects/add_curve_spirofit_bouncespline.py b/add_curve_extra_objects/add_curve_spirofit_bouncespline.py
index 97310799..764e4ff5 100644
--- a/add_curve_extra_objects/add_curve_spirofit_bouncespline.py
+++ b/add_curve_extra_objects/add_curve_spirofit_bouncespline.py
@@ -26,9 +26,9 @@ bl_info = {
"description": "SpiroFit, BounceSpline and Catenary adds "
"splines to selected mesh or objects",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Object",
- }
+}
import bpy
from bpy.types import (
diff --git a/add_curve_extra_objects/add_curve_torus_knots.py b/add_curve_extra_objects/add_curve_torus_knots.py
index 427aaf4a..d394484d 100644
--- a/add_curve_extra_objects/add_curve_torus_knots.py
+++ b/add_curve_extra_objects/add_curve_torus_knots.py
@@ -25,9 +25,10 @@ bl_info = {
"location": "View3D > Add > Curve",
"description": "Adds many types of (torus) knots",
"warning": "",
- "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
- "Scripts/Curve/Torus_Knot",
- "category": "Add Curve"}
+ "doc_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Curve/Torus_Knot",
+ "category": "Add Curve",
+}
"""
import bpy
diff --git a/add_curve_extra_objects/add_surface_plane_cone.py b/add_curve_extra_objects/add_surface_plane_cone.py
index 2cd148d6..67026c16 100644
--- a/add_curve_extra_objects/add_surface_plane_cone.py
+++ b/add_curve_extra_objects/add_surface_plane_cone.py
@@ -8,7 +8,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D > Add > Surface",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Add Mesh"
}
diff --git a/add_curve_extra_objects/beveltaper_curve.py b/add_curve_extra_objects/beveltaper_curve.py
index 6e11ada6..c6ce4f93 100644
--- a/add_curve_extra_objects/beveltaper_curve.py
+++ b/add_curve_extra_objects/beveltaper_curve.py
@@ -25,9 +25,10 @@ bl_info = {
"location": "View3D > Object > Bevel/Taper",
"description": "Adds bevel and/or taper curve to active curve",
"warning": "",
- "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/"
- "Py/Scripts/Curve/Bevel_-Taper_Curve",
- "category": "Curve"}
+ "doc_url": "https://wiki.blender.org/index.php/Extensions:2.6/"
+ "Py/Scripts/Curve/Bevel_-Taper_Curve",
+ "category": "Curve",
+}
import bpy
diff --git a/add_curve_ivygen.py b/add_curve_ivygen.py
index f6f0f8a3..07228e1b 100644
--- a/add_curve_ivygen.py
+++ b/add_curve_ivygen.py
@@ -27,8 +27,8 @@ bl_info = {
"description": "Adds generated ivy to a mesh object starting "
"at the 3D cursor",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "add_curve/ivy_gen.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "add_curve/ivy_gen.html",
"category": "Add Curve",
}
diff --git a/add_curve_sapling/__init__.py b/add_curve_sapling/__init__.py
index 554f13f3..8d607616 100644
--- a/add_curve_sapling/__init__.py
+++ b/add_curve_sapling/__init__.py
@@ -26,9 +26,10 @@ bl_info = {
"description": ("Adds a parametric tree. The method is presented by "
"Jason Weber & Joseph Penn in their paper 'Creation and Rendering of "
"Realistic Trees'"),
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "add_curve/sapling.html",
- "category": "Add Curve"}
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "add_curve/sapling.html",
+ "category": "Add Curve",
+}
if "bpy" in locals():
import importlib
diff --git a/add_mesh_BoltFactory/__init__.py b/add_mesh_BoltFactory/__init__.py
index ec9d5dc8..d763d13f 100644
--- a/add_mesh_BoltFactory/__init__.py
+++ b/add_mesh_BoltFactory/__init__.py
@@ -23,8 +23,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D > Add > Mesh",
"description": "Add a bolt or nut",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "add_mesh/boltfactory.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "add_mesh/boltfactory.html",
"category": "Add Mesh",
}
@@ -45,7 +45,7 @@ import bpy
def register():
- Boltfactory.register()
+ Boltfactory.register()
diff --git a/add_mesh_discombobulator/__init__.py b/add_mesh_discombobulator/__init__.py
index 42a368c9..b6a6e84a 100644
--- a/add_mesh_discombobulator/__init__.py
+++ b/add_mesh_discombobulator/__init__.py
@@ -27,8 +27,8 @@ bl_info = {
"location": "View3D > Add > Mesh",
"description": "Add Discombobulator",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "add_mesh/discombobulator.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "add_mesh/discombobulator.html",
"category": "Add Mesh",
}
diff --git a/add_mesh_extra_objects/__init__.py b/add_mesh_extra_objects/__init__.py
index 14a0398b..cea0cb2d 100644
--- a/add_mesh_extra_objects/__init__.py
+++ b/add_mesh_extra_objects/__init__.py
@@ -31,8 +31,8 @@ bl_info = {
"location": "View3D > Add > Mesh",
"description": "Add extra mesh object types",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "add_mesh/mesh_extra_objects.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "add_mesh/mesh_extra_objects.html",
"category": "Add Mesh",
}
diff --git a/add_mesh_extra_objects/add_mesh_rocks/__init__.py b/add_mesh_extra_objects/add_mesh_rocks/__init__.py
index 6b0218dd..40c52584 100644
--- a/add_mesh_extra_objects/add_mesh_rocks/__init__.py
+++ b/add_mesh_extra_objects/add_mesh_rocks/__init__.py
@@ -39,10 +39,11 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D > Add > Rock Generator",
"description": "Adds a mesh rock to the Add Mesh menu",
- "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "doc_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
"Scripts/Add_Mesh/Rock_Generator",
"tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
- "category": "Add Mesh"}
+ "category": "Add Mesh",
+}
if "bpy" in locals():
import importlib
diff --git a/add_mesh_extra_objects/add_mesh_triangles.py b/add_mesh_extra_objects/add_mesh_triangles.py
index 64a56ef2..5373c5fb 100644
--- a/add_mesh_extra_objects/add_mesh_triangles.py
+++ b/add_mesh_extra_objects/add_mesh_triangles.py
@@ -8,9 +8,10 @@ bl_info = {
"blender": (2, 68, 0),
"location": "View3D > Add > Mesh",
"warning": "First Version",
- "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
- "Scripts/Triangles",
- "category": "Add Mesh"}
+ "doc_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Triangles",
+ "category": "Add Mesh",
+}
"""
This script provides a triangle mesh primitive
diff --git a/add_mesh_geodesic_domes/__init__.py b/add_mesh_geodesic_domes/__init__.py
index 98820da7..dc153993 100644
--- a/add_mesh_geodesic_domes/__init__.py
+++ b/add_mesh_geodesic_domes/__init__.py
@@ -27,9 +27,10 @@ bl_info = {
"location": "View3D > Add > Mesh",
"description": "Create geodesic dome type objects.",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "add_mesh/geodesic_domes.html",
- "category": "Add Mesh"}
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "add_mesh/geodesic_domes.html",
+ "category": "Add Mesh",
+}
if "bpy" in locals():
import importlib
diff --git a/amaranth/__init__.py b/amaranth/__init__.py
index 98fd8b1c..83aaac68 100644
--- a/amaranth/__init__.py
+++ b/amaranth/__init__.py
@@ -91,7 +91,7 @@ bl_info = {
"location": "Everywhere!",
"description": "A collection of tools and settings to improve productivity",
"warning": "",
- "wiki_url": "https://pablovazquez.art/amaranth",
+ "doc_url": "https://pablovazquez.art/amaranth",
"tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
"category": "Interface",
}
diff --git a/animation_add_corrective_shape_key.py b/animation_add_corrective_shape_key.py
index c58e862b..6faca951 100644
--- a/animation_add_corrective_shape_key.py
+++ b/animation_add_corrective_shape_key.py
@@ -25,8 +25,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "Object Data > Shape Keys Specials or Search",
"description": "Creates a corrective shape key for the current pose",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "animation/corrective_shape_keys.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "animation/corrective_shape_keys.html",
"category": "Animation",
}
diff --git a/animation_animall.py b/animation_animall.py
index 3867155d..efc4e841 100644
--- a/animation_animall.py
+++ b/animation_animall.py
@@ -24,8 +24,8 @@ bl_info = {
"location": "3D View > Toolbox > Animation tab > AnimAll",
"description": "Allows animation of mesh, lattice, curve and surface data",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "animation/animall.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "animation/animall.html",
"category": "Animation",
}
diff --git a/ant_landscape/__init__.py b/ant_landscape/__init__.py
index 0e10b8b4..5af0d261 100644
--- a/ant_landscape/__init__.py
+++ b/ant_landscape/__init__.py
@@ -27,8 +27,8 @@ bl_info = {
"location": "View3D > Sidebar > Create Tab",
"description": "Another Noise Tool: Landscape and Displace",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "add_mesh/ant_landscape.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "add_mesh/ant_landscape.html",
"category": "Add Mesh",
}
diff --git a/archimesh/__init__.py b/archimesh/__init__.py
index 8a2e1474..10d6c9a6 100644
--- a/archimesh/__init__.py
+++ b/archimesh/__init__.py
@@ -32,8 +32,8 @@ bl_info = {
"version": (1, 2, 2),
"blender": (2, 80, 0),
"description": "Generate rooms, doors, windows, and other architecture objects",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "add_mesh/archimesh.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "add_mesh/archimesh.html",
"category": "Add Mesh"
}
diff --git a/archimesh/achm_tools.py b/archimesh/achm_tools.py
index 4aab64c4..0527d330 100644
--- a/archimesh/achm_tools.py
+++ b/archimesh/achm_tools.py
@@ -333,10 +333,8 @@ def create_diffuse_material(matname, replace, r, g, b, rv=0.8, gv=0.8, bv=0.8, m
nodes = mat.node_tree.nodes
# support for multilanguage
- node = nodes[get_node_index(nodes, 'BSDF_DIFFUSE')]
+ node = nodes.new('ShaderNodeBsdfDiffuse')
node.name = 'Diffuse BSDF'
- node.label = 'Diffuse BSDF'
-
node.inputs[0].default_value = [r, g, b, 1]
node.location = 200, 320
@@ -417,10 +415,8 @@ def create_translucent_material(matname, replace, r, g, b, rv=0.8, gv=0.8, bv=0.
nodes = mat.node_tree.nodes
# support for multilanguage
- node = nodes[get_node_index(nodes, 'BSDF_DIFFUSE')]
+ node = nodes.new('ShaderNodeBsdfDiffuse')
node.name = 'Diffuse BSDF'
- node.label = 'Diffuse BSDF'
-
node.inputs[0].default_value = [r, g, b, 1]
node.location = 200, 320
@@ -500,7 +496,8 @@ def create_glass_material(matname, replace, rv=0.333, gv=0.342, bv=0.9):
node.inputs[0].default_value = 0.1
node.location = 690, 290
- node = nodes[get_node_index(nodes, 'OUTPUT_MATERIAL')]
+ node = nodes.new('ShaderNodeOutputMaterial')
+ node.name = 'OUTPUT_MATERIAL'
node.location = 920, 290
# Connect nodes
@@ -786,10 +783,8 @@ def create_fabric_material(matname, replace, r, g, b, rv=0.8, gv=0.636, bv=0.315
nodes = mat.node_tree.nodes
# support for multilanguage
- node = nodes[get_node_index(nodes, 'BSDF_DIFFUSE')]
+ node = nodes.new('ShaderNodeBsdfDiffuse')
node.name = 'Diffuse BSDF'
- node.label = 'Diffuse BSDF'
-
node.inputs[0].default_value = [r, g, b, 1]
node.location = 810, 270
diff --git a/archipack/__init__.py b/archipack/__init__.py
index 331afcc3..6c014756 100644
--- a/archipack/__init__.py
+++ b/archipack/__init__.py
@@ -35,7 +35,7 @@ bl_info = {
'blender': (2, 80, 0),
'location': 'View3D > Sidebar > Create > Archipack',
'warning': '',
- 'wiki_url': 'https://github.com/s-leger/archipack/wiki',
+ 'doc_url': 'https://github.com/s-leger/archipack/wiki',
'tracker_url': 'https://github.com/s-leger/archipack/issues',
'link': 'https://github.com/s-leger/archipack',
'support': 'COMMUNITY',
diff --git a/archipack/archipack_gl.py b/archipack/archipack_gl.py
index f3ef034a..f0bf8482 100644
--- a/archipack/archipack_gl.py
+++ b/archipack/archipack_gl.py
@@ -85,7 +85,7 @@ in vec2 pos;
void main()
{
- gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
+ gl_Position = ModelViewProjectionMatrix * vec4(pos, 0.0, 1.0);
}
'''
@@ -97,7 +97,7 @@ out vec4 fragColor;
void main()
{
- fragColor = color;
+ fragColor = color;
}
'''
diff --git a/archipack/archipack_keymaps.py b/archipack/archipack_keymaps.py
index f5b95957..05458b9c 100644
--- a/archipack/archipack_keymaps.py
+++ b/archipack/archipack_keymaps.py
@@ -119,4 +119,4 @@ class Keymaps:
k.alt, k.ctrl, k.shift, k.type, k.value, sub, k.name)
file = open(filename, "w")
file.write(str)
- file.close() \ No newline at end of file
+ file.close()
diff --git a/blender_id/__init__.py b/blender_id/__init__.py
index cdd0b223..9dd8a504 100644
--- a/blender_id/__init__.py
+++ b/blender_id/__init__.py
@@ -28,8 +28,8 @@ bl_info = {
'location': 'Add-on preferences',
'description':
'Stores your Blender ID credentials for usage with other add-ons',
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "system/blender_id.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "system/blender_id.html",
'category': 'System',
'support': 'OFFICIAL',
}
diff --git a/blenderkit/__init__.py b/blenderkit/__init__.py
index d64ea133..a45c9b9a 100644
--- a/blenderkit/__init__.py
+++ b/blenderkit/__init__.py
@@ -24,8 +24,8 @@ bl_info = {
"location": "View3D > Properties > BlenderKit",
"description": "Online BlenderKit library (materials, models, brushes and more)",
"warning": "",
- "wiki_url": "https://youtu.be/1hVgcQhIAo8"
- "Scripts/Add_Mesh/BlenderKit",
+ "doc_url": "https://youtu.be/1hVgcQhIAo8"
+ "Scripts/Add_Mesh/BlenderKit",
"category": "3D View",
}
@@ -1527,6 +1527,11 @@ class BlenderKitAddonPreferences(AddonPreferences):
min=0,
max=20000)
+ first_run: BoolProperty(
+ name="First run",
+ description="Detects if addon was already registered/run.",
+ default=True
+ )
# allow_proximity : BoolProperty(
# name="allow proximity data reports",
# description="This sends anonymized proximity data \n \
diff --git a/blenderkit/bg_blender.py b/blenderkit/bg_blender.py
index e8ccb04d..8a37f6ce 100644
--- a/blenderkit/bg_blender.py
+++ b/blenderkit/bg_blender.py
@@ -239,4 +239,3 @@ def unregister():
bpy.utils.unregister_class(KillBgProcess)
if bpy.app.timers.is_registered(bg_update):
bpy.app.timers.unregister(bg_update)
-
diff --git a/blenderkit/colors.py b/blenderkit/colors.py
index d01bdb0a..c61d9fa0 100644
--- a/blenderkit/colors.py
+++ b/blenderkit/colors.py
@@ -20,4 +20,4 @@
TEXT = (.9, .9, .9, .6)
GREEN = (.9, 1, .9, .6)
-RED = (1, .5, .5, .8) \ No newline at end of file
+RED = (1, .5, .5, .8)
diff --git a/blenderkit/oauth.py b/blenderkit/oauth.py
index 95c6bae6..06e57298 100644
--- a/blenderkit/oauth.py
+++ b/blenderkit/oauth.py
@@ -104,4 +104,4 @@ class SimpleOAuthAuthenticator(object):
return self._get_tokens(authorization_code=authorization_code)
def get_refreshed_token(self, refresh_token):
- return self._get_tokens(refresh_token=refresh_token, grant_type="refresh_token") \ No newline at end of file
+ return self._get_tokens(refresh_token=refresh_token, grant_type="refresh_token")
diff --git a/blenderkit/search.py b/blenderkit/search.py
index bf430d91..94b0c94c 100644
--- a/blenderkit/search.py
+++ b/blenderkit/search.py
@@ -130,35 +130,38 @@ def fetch_server_data():
first_time = True
last_clipboard = ''
+def check_clipboard():
+ # clipboard monitoring to search assets from web
+ global last_clipboard
+ if bpy.context.window_manager.clipboard != last_clipboard:
+ last_clipboard = bpy.context.window_manager.clipboard
+ instr = 'asset_base_id:'
+ # first check if contains asset id, then asset type
+ if last_clipboard[:len(instr)] == instr:
+ atstr = 'asset_type:'
+ ati = last_clipboard.find(atstr)
+ # this only checks if the asset_type keyword is there but let's the keywords update function do the parsing.
+ if ati > -1:
+ search_props = utils.get_search_props()
+ search_props.search_keywords = last_clipboard
+ # don't run search after this - assigning to keywords runs the search_update function.
@bpy.app.handlers.persistent
def timer_update():
# this makes a first search after opening blender. showing latest assets.
global first_time
preferences = bpy.context.preferences.addons['blenderkit'].preferences
- if first_time:
+ if first_time:# first time
first_time = False
- if preferences.show_on_start:
+ if preferences.show_on_start or preferences.first_run:
search()
+ preferences.first_run = False
if preferences.tips_on_start:
ui.get_largest_3dview()
ui.update_ui_size(ui.active_area, ui.active_region)
ui.add_report(text='BlenderKit Tip: ' + random.choice(rtips), timeout=12, color=colors.GREEN)
- # clipboard monitoring to search assets from web
- global last_clipboard
- if bpy.context.window_manager.clipboard != last_clipboard:
- last_clipboard = bpy.context.window_manager.clipboard
- instr = 'asset_base_id:'
- # first check if contains asset id, then asset type
- if last_clipboard[:len(instr)] == instr:
- atstr = 'asset_type:'
- ati = last_clipboard.find(atstr)
- #this only checks if the asset_type keyword is there but let's the keywords update function do the parsing.
- if ati > -1:
- search_props = utils.get_search_props()
- search_props.search_keywords = last_clipboard
- # don't run search after this - assigning to keywords runs the search_update function.
+ check_clipboard()
global search_threads
# don't do anything while dragging - this could switch asset during drag, and make results list length different,
diff --git a/blenderkit/tasks_queue.py b/blenderkit/tasks_queue.py
index 95ffb1a6..4f500bbf 100644
--- a/blenderkit/tasks_queue.py
+++ b/blenderkit/tasks_queue.py
@@ -103,5 +103,3 @@ def register():
def unregister():
bpy.app.handlers.load_post.remove(scene_load)
-
-
diff --git a/blenderkit/ui.py b/blenderkit/ui.py
index b0753a08..f5efae7d 100644
--- a/blenderkit/ui.py
+++ b/blenderkit/ui.py
@@ -1288,10 +1288,7 @@ class AssetBarOperator(bpy.types.Operator):
update_ui_size(self.area, self.region)
- if context.region != self.region:
- print(time.time(), 'pass through because of region')
- print(context.region.type, self.region.type)
- return {'PASS_THROUGH'}
+
# this was here to check if sculpt stroke is running, but obviously that didn't help,
# since the RELEASE event is cought by operator and thus there is no way to detect a stroke has ended...
@@ -1313,6 +1310,11 @@ class AssetBarOperator(bpy.types.Operator):
ui_props.draw_tooltip = False
return {'CANCELLED'}
+ if context.region != self.region:
+ # print(time.time(), 'pass through because of region')
+ # print(context.region.type, self.region.type)
+ return {'PASS_THROUGH'}
+
if ui_props.down_up == 'UPLOAD':
ui_props.mouse_x = 0
@@ -1504,8 +1506,8 @@ class AssetBarOperator(bpy.types.Operator):
asset_search_index = ui_props.active_index
asset_data = sr[asset_search_index]
if not asset_data['can_download']:
- message = 'Asset locked. Find out how to unlock Everything and ...'
- link_text = 'support all BlenderKit artists.'
+ message = "Let's support asset creators and Blender development."
+ link_text = 'Unlock the asset.'
url = paths.get_bkit_url() + '/get-blenderkit/' + asset_data['id'] + '/?from_addon'
bpy.ops.wm.blenderkit_url_dialog('INVOKE_REGION_WIN', url=url, message=message,
link_text=link_text)
diff --git a/blenderkit/ui_panels.py b/blenderkit/ui_panels.py
index cacc1df4..0330bf88 100644
--- a/blenderkit/ui_panels.py
+++ b/blenderkit/ui_panels.py
@@ -470,13 +470,20 @@ class VIEW3D_PT_blenderkit_profile(Panel):
# plan information
- # pcoll = icons.icon_collections["main"]
- # my_icon = pcoll['free']
- # row = layout.row()
- # row.label(text='My plan:')
- # row.label(text='Free plan', icon_value=my_icon.icon_id)
- # layout.operator("wm.url_open", text="Change plan",
- # icon='URL').url = paths.get_bkit_url() + paths.BLENDERKIT_PLANS
+ if me.get('currentPlanName') is not None:
+ pn = me['currentPlanName']
+ pcoll = icons.icon_collections["main"]
+ if pn == 'Free':
+ my_icon = pcoll['free']
+ else:
+ my_icon = pcoll['full']
+
+ row = layout.row()
+ row.label(text='My plan:')
+ row.label(text='%s plan' % pn, icon_value=my_icon.icon_id)
+ if pn =='Free':
+ layout.operator("wm.url_open", text="Change plan",
+ icon='URL').url = paths.get_bkit_url() + paths.BLENDERKIT_PLANS
# storage statistics
# if me.get('sumAssetFilesSize') is not None: # TODO remove this when production server has these too.
diff --git a/blenderkit/utils.py b/blenderkit/utils.py
index fe80e1a0..b9bd17f1 100644
--- a/blenderkit/utils.py
+++ b/blenderkit/utils.py
@@ -558,4 +558,4 @@ def guard_from_crash():
return False;
if bpy.context.preferences.addons['blenderkit'].preferences is None:
return False;
- return True \ No newline at end of file
+ return True
diff --git a/bone_selection_sets.py b/bone_selection_sets.py
index ee17eb66..8862244b 100644
--- a/bone_selection_sets.py
+++ b/bone_selection_sets.py
@@ -24,8 +24,8 @@ bl_info = {
"location": "Properties > Object Data (Armature) > Selection Sets",
"description": "List of Bone sets for easy selection while animating",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "animation/bone_selection_sets.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "animation/bone_selection_sets.html",
"category": "Animation",
}
diff --git a/btrace/__init__.py b/btrace/__init__.py
index 55d49e44..d0f41d5e 100644
--- a/btrace/__init__.py
+++ b/btrace/__init__.py
@@ -25,9 +25,10 @@ bl_info = {
"location": "View3D > Sidebar > Create Tab",
"description": "Tools for converting/animating objects/particles into curves",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "add_curve/btracer.html",
- "category": "Add Curve"}
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "add_curve/btracer.html",
+ "category": "Add Curve",
+}
import bpy
diff --git a/btrace/bTrace_props.py b/btrace/bTrace_props.py
index 4476e0f6..b7e824c8 100644
--- a/btrace/bTrace_props.py
+++ b/btrace/bTrace_props.py
@@ -565,5 +565,3 @@ class TracerProperties(PropertyGroup):
description="",
default='tool_help'
)
-
-
diff --git a/camera_turnaround.py b/camera_turnaround.py
index 8711a930..5742fb79 100644
--- a/camera_turnaround.py
+++ b/camera_turnaround.py
@@ -23,9 +23,10 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D > Sidebar > View Tab > Turnaround Camera",
"description": "Add a camera rotation around selected object",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "animation/turnaround_camera.html",
- "category": "Animation"}
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "animation/turnaround_camera.html",
+ "category": "Animation",
+}
import bpy
diff --git a/curve_assign_shapekey.py b/curve_assign_shapekey.py
index 1ca8d10a..7e971035 100644
--- a/curve_assign_shapekey.py
+++ b/curve_assign_shapekey.py
@@ -24,12 +24,12 @@ bl_info = {
"name": "Assign Shape Keys",
"author": "Shrinivas Kulkarni",
"version": (1, 0, 1),
+ "blender": (2, 80, 0),
"location": "View 3D > Sidebar > Edit Tab",
"description": "Assigns one or more Bezier curves as shape keys to another Bezier curve",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "add_curve/assign_shape_keys.html",
"category": "Add Curve",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "add_curve/assign_shape_keys.html",
- "blender": (2, 80, 0),
}
alignList = [('minX', 'Min X', 'Align vertices with Min X'),
diff --git a/curve_simplify.py b/curve_simplify.py
index 2817aef2..85df1dba 100644
--- a/curve_simplify.py
+++ b/curve_simplify.py
@@ -24,8 +24,8 @@ bl_info = {
"location": "3D View, Dopesheet & Graph Editors",
"description": "Simplify Curves: 3dview, Dopesheet, Graph. Distance Merge: 3d view curve edit",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "add_curve/simplify_curves.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "add_curve/simplify_curves.html",
"category": "Add Curve",
}
diff --git a/curve_tools/__init__.py b/curve_tools/__init__.py
index 17108ef1..50641f0a 100644
--- a/curve_tools/__init__.py
+++ b/curve_tools/__init__.py
@@ -29,10 +29,11 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D > Tool Shelf > Edit Tab",
"warning": "WIP",
- "wiki_url": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "add_curve/curve_tools.html",
- "category": "Add Curve"}
+ "doc_url": "",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "add_curve/curve_tools.html",
+ "category": "Add Curve",
+}
import os, bpy, importlib, math
diff --git a/curve_tools/cad.py b/curve_tools/cad.py
index 8e62e295..3d3f87bd 100644
--- a/curve_tools/cad.py
+++ b/curve_tools/cad.py
@@ -22,7 +22,7 @@ bl_info = {
'version': (1, 0, 0),
'blender': (2, 80, 0),
'category': 'Curve',
- 'wiki_url': 'https://github.com/Lichtso/curve_cad',
+ 'doc_url': 'https://github.com/Lichtso/curve_cad',
'tracker_url': 'https://github.com/lichtso/curve_cad/issues'
}
diff --git a/curve_tools/fillet.py b/curve_tools/fillet.py
index c9fcb688..911d88c4 100644
--- a/curve_tools/fillet.py
+++ b/curve_tools/fillet.py
@@ -24,9 +24,10 @@ bl_info = {
'location': 'Curve Tools addon. (N) Panel',
'description': 'Various types of fillet (chamfering)',
'warning': '', # used for warning icon and text in addons panel
- 'wiki_url': '',
+ 'doc_url': '',
'tracker_url': '',
- 'category': 'Curve'}
+ 'category': 'Curve',
+}
import bpy
diff --git a/curve_tools/outline.py b/curve_tools/outline.py
index b1f8561e..4122482c 100644
--- a/curve_tools/outline.py
+++ b/curve_tools/outline.py
@@ -23,10 +23,10 @@ END GPL LICENCE BLOCK
bl_info = {
"name": "Curve Outline",
"description": "creates an Outline",
- "category": "Object",
"author": "Yann Bertrand (jimflim), Vladimir Spivak (cwolf3d)",
"version": (0, 5),
"blender": (2, 69, 0),
+ "category": "Object",
}
import bpy
diff --git a/curve_tools/path_finder.py b/curve_tools/path_finder.py
index 9093f5f2..e0b3fa98 100644
--- a/curve_tools/path_finder.py
+++ b/curve_tools/path_finder.py
@@ -24,9 +24,10 @@ bl_info = {
'location': 'Curve Tools addon. (N) Panel',
'description': 'PathFinder - quick search, selection, removal of splines',
'warning': '', # used for warning icon and text in addons panel
- 'wiki_url': '',
+ 'doc_url': '',
'tracker_url': '',
- 'category': 'Curve'}
+ 'category': 'Curve',
+}
import time
import threading
diff --git a/depsgraph_debug.py b/depsgraph_debug.py
index 76f25290..c0906005 100644
--- a/depsgraph_debug.py
+++ b/depsgraph_debug.py
@@ -30,9 +30,10 @@ bl_info = {
"blender": (2, 80, 0),
"description": "Various dependency graph debugging tools",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"tracker_url": "",
- "category": "Development"}
+ "category": "Development",
+}
def _get_depsgraph(context):
diff --git a/development_edit_operator.py b/development_edit_operator.py
index 884050cf..21947f78 100644
--- a/development_edit_operator.py
+++ b/development_edit_operator.py
@@ -25,9 +25,10 @@ bl_info = {
"location": "Text Editor > Sidebar > Edit Operator",
"description": "Opens source file of chosen operator or call locations, if source not available",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "development/edit_operator.html",
- "category": "Development"}
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "development/edit_operator.html",
+ "category": "Development",
+}
import bpy
import sys
diff --git a/development_icon_get.py b/development_icon_get.py
index 37fae00a..d2278bed 100644
--- a/development_icon_get.py
+++ b/development_icon_get.py
@@ -26,9 +26,9 @@ bl_info = {
"version": (1, 4, 0),
"blender": (2, 80, 0),
"location": "Text Editor > Dev Tab > Icon Viewer",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "development/icon_viewer.html",
- "category": "Development"
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "development/icon_viewer.html",
+ "category": "Development",
}
import bpy
diff --git a/development_iskeyfree.py b/development_iskeyfree.py
index 3a5e3327..8893eed1 100644
--- a/development_iskeyfree.py
+++ b/development_iskeyfree.py
@@ -25,9 +25,9 @@ bl_info = {
"blender": (2, 80, 0),
"location": "Text Editor > Sidebar > Dev Tab",
"description": "Find free shortcuts, inform about used and print a key list",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "development/is_key_free.html",
- "category": "Development"
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "development/is_key_free.html",
+ "category": "Development",
}
import bpy
diff --git a/io_anim_bvh/__init__.py b/io_anim_bvh/__init__.py
index 6112ee42..1065b25f 100644
--- a/io_anim_bvh/__init__.py
+++ b/io_anim_bvh/__init__.py
@@ -26,8 +26,8 @@ bl_info = {
"location": "File > Import-Export",
"description": "Import-Export BVH from armature objects",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/io_anim_bvh.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/anim_bvh.html",
"support": 'OFFICIAL',
"category": "Import-Export",
}
diff --git a/io_anim_camera.py b/io_anim_camera.py
index 1c77c361..24972a5d 100644
--- a/io_anim_camera.py
+++ b/io_anim_camera.py
@@ -26,8 +26,8 @@ bl_info = {
"location": "File > Export > Cameras & Markers (.py)",
"description": "Export Cameras & Markers (.py)",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/anim_camera.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/anim_camera.html",
"support": 'OFFICIAL',
"category": "Import-Export",
}
diff --git a/io_anim_nuke_chan/__init__.py b/io_anim_nuke_chan/__init__.py
index 8d6cc7c9..6c33ff57 100644
--- a/io_anim_nuke_chan/__init__.py
+++ b/io_anim_nuke_chan/__init__.py
@@ -26,8 +26,8 @@ bl_info = {
"location": "File > Import/Export > Nuke (.chan)",
"description": "Import/Export object's animation with nuke",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/anim_nuke_chan.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/anim_nuke_chan.html",
"category": "Import-Export",
}
diff --git a/io_coat3D/__init__.py b/io_coat3D/__init__.py
index f3cd7671..ea199bea 100644
--- a/io_coat3D/__init__.py
+++ b/io_coat3D/__init__.py
@@ -24,8 +24,8 @@ bl_info = {
"location": "Scene > 3D-Coat Applink",
"description": "Transfer data between 3D-Coat/Blender",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/coat3D.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/coat3D.html",
"category": "Import-Export",
}
diff --git a/io_curve_svg/__init__.py b/io_curve_svg/__init__.py
index e32223a7..a7a3fe3a 100644
--- a/io_curve_svg/__init__.py
+++ b/io_curve_svg/__init__.py
@@ -25,8 +25,8 @@ bl_info = {
"location": "File > Import > Scalable Vector Graphics (.svg)",
"description": "Import SVG as curves",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/io_curve_svg.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/curve_svg.html",
"support": 'OFFICIAL',
"category": "Import-Export",
}
diff --git a/io_export_dxf/__init__.py b/io_export_dxf/__init__.py
index cb0f1322..e4d035c3 100644
--- a/io_export_dxf/__init__.py
+++ b/io_export_dxf/__init__.py
@@ -24,8 +24,8 @@ bl_info = {
"location": "File > Export > AutoCAD DXF",
"description": "The script exports Blender geometry to DXF format r12 version.",
"warning": "Under construction! Visit Wiki for details.",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/scene_dxf.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/scene_dxf.html",
"category": "Import-Export",
}
diff --git a/io_export_dxf/model/dxfLibrary.py b/io_export_dxf/model/dxfLibrary.py
index 2dffaabe..50aa4d56 100644
--- a/io_export_dxf/model/dxfLibrary.py
+++ b/io_export_dxf/model/dxfLibrary.py
@@ -89,94 +89,94 @@ ______________________________________________________________
#import BPyMessages
try:
- import copy
- #from struct import pack
+ import copy
+ #from struct import pack
except:
- copy = None
+ copy = None
####1) Private (only for developers)
_HEADER_POINTS=['insbase','extmin','extmax']
#---helper functions-----------------------------------
def _point(x,index=0):
- """Convert tuple to a dxf point"""
- return '\n'.join([' %s\n%s'%((i+1)*10+index,float(x[i])) for i in range(len(x))])
+ """Convert tuple to a dxf point"""
+ return '\n'.join([' %s\n%s'%((i+1)*10+index,float(x[i])) for i in range(len(x))])
def _points(plist):
- """Convert a list of tuples to dxf points"""
- out = '\n'.join([_point(plist[i],i)for i in range(len(plist))])
- return out
+ """Convert a list of tuples to dxf points"""
+ out = '\n'.join([_point(plist[i],i)for i in range(len(plist))])
+ return out
#---base classes----------------------------------------
class _Call:
- """Makes a callable class."""
- def copy(self):
- """Returns a copy."""
- return copy.deepcopy(self)
+ """Makes a callable class."""
+ def copy(self):
+ """Returns a copy."""
+ return copy.deepcopy(self)
- def __call__(self,**attrs):
- """Returns a copy with modified attributes."""
- copied=self.copy()
- for attr in attrs:setattr(copied,attr,attrs[attr])
- return copied
+ def __call__(self,**attrs):
+ """Returns a copy with modified attributes."""
+ copied=self.copy()
+ for attr in attrs:setattr(copied,attr,attrs[attr])
+ return copied
#-------------------------------------------------------
class _Entity(_Call):
- """Base class for _common group codes for entities."""
- def __init__(self,paperspace=None,color=None,layer='0',
- lineType=None,lineTypeScale=None,lineWeight=None,
- extrusion=None,elevation=None,thickness=None,
- parent=None):
- """None values will be omitted."""
- self.paperspace = paperspace
- self.color = color
- self.layer = layer
- self.lineType = lineType
- self.lineTypeScale = lineTypeScale
- self.lineWeight = lineWeight
- self.extrusion = extrusion
- self.elevation = elevation
- self.thickness = thickness
- #self.visible = visible
- self.parent = parent
-
- def _common(self):
- """Return common group codes as a string."""
- if self.parent:parent=self.parent
- else:parent=self
- result =''
- if parent.paperspace==1: result+=' 67\n1\n'
- if parent.layer!=None: result+=' 8\n%s\n'%parent.layer
- if parent.color!=None: result+=' 62\n%s\n'%parent.color
- if parent.lineType!=None: result+=' 6\n%s\n'%parent.lineType
- # TODO: if parent.lineWeight!=None: result+='370\n%s\n'%parent.lineWeight
- # TODO: if parent.visible!=None: result+='60\n%s\n'%parent.visible
- if parent.lineTypeScale!=None: result+=' 48\n%s\n'%parent.lineTypeScale
- if parent.elevation!=None: result+=' 38\n%s\n'%parent.elevation
- if parent.thickness!=None: result+=' 39\n%s\n'%parent.thickness
- if parent.extrusion!=None: result+='%s\n'%_point(parent.extrusion,200)
- return result
+ """Base class for _common group codes for entities."""
+ def __init__(self,paperspace=None,color=None,layer='0',
+ lineType=None,lineTypeScale=None,lineWeight=None,
+ extrusion=None,elevation=None,thickness=None,
+ parent=None):
+ """None values will be omitted."""
+ self.paperspace = paperspace
+ self.color = color
+ self.layer = layer
+ self.lineType = lineType
+ self.lineTypeScale = lineTypeScale
+ self.lineWeight = lineWeight
+ self.extrusion = extrusion
+ self.elevation = elevation
+ self.thickness = thickness
+ #self.visible = visible
+ self.parent = parent
+
+ def _common(self):
+ """Return common group codes as a string."""
+ if self.parent:parent=self.parent
+ else:parent=self
+ result =''
+ if parent.paperspace==1: result+=' 67\n1\n'
+ if parent.layer!=None: result+=' 8\n%s\n'%parent.layer
+ if parent.color!=None: result+=' 62\n%s\n'%parent.color
+ if parent.lineType!=None: result+=' 6\n%s\n'%parent.lineType
+ # TODO: if parent.lineWeight!=None: result+='370\n%s\n'%parent.lineWeight
+ # TODO: if parent.visible!=None: result+='60\n%s\n'%parent.visible
+ if parent.lineTypeScale!=None: result+=' 48\n%s\n'%parent.lineTypeScale
+ if parent.elevation!=None: result+=' 38\n%s\n'%parent.elevation
+ if parent.thickness!=None: result+=' 39\n%s\n'%parent.thickness
+ if parent.extrusion!=None: result+='%s\n'%_point(parent.extrusion,200)
+ return result
#--------------------------
class _Entities:
- """Base class to deal with composed objects."""
- def __dxf__(self):
- return []
+ """Base class to deal with composed objects."""
+ def __dxf__(self):
+ return []
- def __str__(self):
- return ''.join([str(x) for x in self.__dxf__()])
+ def __str__(self):
+ return ''.join([str(x) for x in self.__dxf__()])
#--------------------------
class _Collection(_Call):
- """Base class to expose entities methods to main object."""
- def __init__(self,entities=[]):
- self.entities=copy.copy(entities)
- #link entities methods to drawing
- for attr in dir(self.entities):
- if attr[0]!='_':
- attrObject=getattr(self.entities,attr)
- if callable(attrObject):
- setattr(self,attr,attrObject)
+ """Base class to expose entities methods to main object."""
+ def __init__(self,entities=[]):
+ self.entities=copy.copy(entities)
+ #link entities methods to drawing
+ for attr in dir(self.entities):
+ if attr[0]!='_':
+ attrObject=getattr(self.entities,attr)
+ if callable(attrObject):
+ setattr(self,attr,attrObject)
####2) Constants
#---color values
@@ -199,7 +199,7 @@ TOP_CENTER = 2
TOP_RIGHT = 3
MIDDLE_LEFT = 4
MIDDLE_CENTER = 5
-MIDDLE_RIGHT = 6
+MIDDLE_RIGHT = 6
BOTTOM_LEFT = 7
BOTTOM_CENTER = 8
BOTTOM_RIGHT = 9
@@ -212,14 +212,14 @@ AT_LEAST = 1 #taller characters will override
EXACT = 2 #taller characters will not override
#---polyline flag 70
-CLOSED =1 # This is a closed polyline (or a polygon mesh closed in the M direction)
-CURVE_FIT =2 # Curve-fit vertices have been added
-SPLINE_FIT =4 # Spline-fit vertices have been added
-POLYLINE_3D =8 # This is a 3D polyline
-POLYGON_MESH =16 # This is a 3D polygon mesh
-CLOSED_N =32 # The polygon mesh is closed in the N direction
-POLYFACE_MESH =64 # The polyline is a polyface mesh
-CONTINOUS_LINETYPE_PATTERN =128 # The linetype pattern is generated continuously around the vertices of this polyline
+CLOSED =1 # This is a closed polyline (or a polygon mesh closed in the M direction)
+CURVE_FIT =2 # Curve-fit vertices have been added
+SPLINE_FIT =4 # Spline-fit vertices have been added
+POLYLINE_3D =8 # This is a 3D polyline
+POLYGON_MESH =16 # This is a 3D polygon mesh
+CLOSED_N =32 # The polygon mesh is closed in the N direction
+POLYFACE_MESH =64 # The polyline is a polyface mesh
+CONTINOUS_LINETYPE_PATTERN =128 # The linetype pattern is generated continuously around the vertices of this polyline
#---polyline flag 75, = curve type
QUADRIC_NURBS = 5
@@ -237,7 +237,7 @@ MIDDLE = 4 #if vertical alignment = 0
FIT = 5 #if vertical alignment = 0
#vertical
BASELINE = 0
-BOTTOM = 1
+BOTTOM = 1
MIDDLE = 2
TOP = 3
@@ -245,682 +245,682 @@ TOP = 3
#---entitities -----------------------------------------------
#--------------------------
class Arc(_Entity):
- """Arc, angles in degrees."""
- def __init__(self,center=(0,0,0),radius=1,
- startAngle=0.0,endAngle=90,**common):
- """Angles in degrees."""
- _Entity.__init__(self,**common)
- self.center=center
- self.radius=radius
- self.startAngle=startAngle
- self.endAngle=endAngle
- def __str__(self):
- return ' 0\nARC\n%s%s\n 40\n%s\n 50\n%s\n 51\n%s\n'%\
- (self._common(),_point(self.center),
- self.radius,self.startAngle,self.endAngle)
+ """Arc, angles in degrees."""
+ def __init__(self,center=(0,0,0),radius=1,
+ startAngle=0.0,endAngle=90,**common):
+ """Angles in degrees."""
+ _Entity.__init__(self,**common)
+ self.center=center
+ self.radius=radius
+ self.startAngle=startAngle
+ self.endAngle=endAngle
+ def __str__(self):
+ return ' 0\nARC\n%s%s\n 40\n%s\n 50\n%s\n 51\n%s\n'%\
+ (self._common(),_point(self.center),
+ self.radius,self.startAngle,self.endAngle)
#-----------------------------------------------
class Circle(_Entity):
- """Circle"""
- def __init__(self,center=(0,0,0),radius=1,**common):
- _Entity.__init__(self,**common)
- self.center=center
- self.radius=radius
- def __str__(self):
- return ' 0\nCIRCLE\n%s%s\n 40\n%s\n'%\
- (self._common(),_point(self.center),self.radius)
+ """Circle"""
+ def __init__(self,center=(0,0,0),radius=1,**common):
+ _Entity.__init__(self,**common)
+ self.center=center
+ self.radius=radius
+ def __str__(self):
+ return ' 0\nCIRCLE\n%s%s\n 40\n%s\n'%\
+ (self._common(),_point(self.center),self.radius)
#-----------------------------------------------
class Face(_Entity):
- """3dface"""
- def __init__(self,points,**common):
- _Entity.__init__(self,**common)
- while len(points)<4: #fix for r12 format
- points.append(points[-1])
- self.points=points
+ """3dface"""
+ def __init__(self,points,**common):
+ _Entity.__init__(self,**common)
+ while len(points)<4: #fix for r12 format
+ points.append(points[-1])
+ self.points=points
- def __str__(self):
- out = ' 0\n3DFACE\n%s%s\n' %(self._common(),_points(self.points))
- return out
+ def __str__(self):
+ out = ' 0\n3DFACE\n%s%s\n' %(self._common(),_points(self.points))
+ return out
#-----------------------------------------------
class Insert(_Entity):
- """Block instance."""
- def __init__(self,name,point=(0,0,0),
- xscale=None,yscale=None,zscale=None,
- cols=None,colspacing=None,rows=None,rowspacing=None,
- rotation=None,
- **common):
- _Entity.__init__(self,**common)
- self.name=name
- self.point=point
- self.xscale=xscale
- self.yscale=yscale
- self.zscale=zscale
- self.cols=cols
- self.colspacing=colspacing
- self.rows=rows
- self.rowspacing=rowspacing
- self.rotation=rotation
-
- def __str__(self):
- result=' 0\nINSERT\n 2\n%s\n%s%s\n'%\
- (self.name,self._common(),_point(self.point))
- if self.xscale!=None:result+=' 41\n%s\n'%self.xscale
- if self.yscale!=None:result+=' 42\n%s\n'%self.yscale
- if self.zscale!=None:result+=' 43\n%s\n'%self.zscale
- if self.rotation:result+=' 50\n%s\n'%self.rotation
- if self.cols!=None:result+=' 70\n%s\n'%self.cols
- if self.colspacing!=None:result+=' 44\n%s\n'%self.colspacing
- if self.rows!=None:result+=' 71\n%s\n'%self.rows
- if self.rowspacing!=None:result+=' 45\n%s\n'%self.rowspacing
- return result
+ """Block instance."""
+ def __init__(self,name,point=(0,0,0),
+ xscale=None,yscale=None,zscale=None,
+ cols=None,colspacing=None,rows=None,rowspacing=None,
+ rotation=None,
+ **common):
+ _Entity.__init__(self,**common)
+ self.name=name
+ self.point=point
+ self.xscale=xscale
+ self.yscale=yscale
+ self.zscale=zscale
+ self.cols=cols
+ self.colspacing=colspacing
+ self.rows=rows
+ self.rowspacing=rowspacing
+ self.rotation=rotation
+
+ def __str__(self):
+ result=' 0\nINSERT\n 2\n%s\n%s%s\n'%\
+ (self.name,self._common(),_point(self.point))
+ if self.xscale!=None:result+=' 41\n%s\n'%self.xscale
+ if self.yscale!=None:result+=' 42\n%s\n'%self.yscale
+ if self.zscale!=None:result+=' 43\n%s\n'%self.zscale
+ if self.rotation:result+=' 50\n%s\n'%self.rotation
+ if self.cols!=None:result+=' 70\n%s\n'%self.cols
+ if self.colspacing!=None:result+=' 44\n%s\n'%self.colspacing
+ if self.rows!=None:result+=' 71\n%s\n'%self.rows
+ if self.rowspacing!=None:result+=' 45\n%s\n'%self.rowspacing
+ return result
#-----------------------------------------------
class Line(_Entity):
- """Line"""
- def __init__(self,points,**common):
- _Entity.__init__(self,**common)
- self.points=points
- def __str__(self):
- return ' 0\nLINE\n%s%s\n' %(
- self._common(), _points(self.points))
+ """Line"""
+ def __init__(self,points,**common):
+ _Entity.__init__(self,**common)
+ self.points=points
+ def __str__(self):
+ return ' 0\nLINE\n%s%s\n' %(
+ self._common(), _points(self.points))
#-----------------------------------------------
class PolyLine(_Entity):
- def __init__(self,points,org_point=[0,0,0],flag70=0,flag75=0,width=None,**common):
- #width = number, or width = list [width_start=None, width_end=None]
- #for 2d-polyline: points = [ [[x, y, z], vflag=None, [width_start=None, width_end=None], bulge=0 or None] ...]
- #for 3d-polyline: points = [ [[x, y, z], vflag=None], ...]
- #for polyface: points = [points_list, faces_list]
- _Entity.__init__(self,**common)
- self.points=points
- self.org_point=org_point
- self.pflag70 = flag70
- self.pflag75 = flag75
- self.polyface = False
- self.polyline2d = False
- self.faces = [] # dummy value
- self.width= None # dummy value
- if self.pflag70 & POLYFACE_MESH:
- self.polyface=True
- self.points=points[0]
- self.faces=points[1]
- self.p_count=len(self.points)
- self.f_count=len(self.faces)
- elif not (self.pflag70 & POLYLINE_3D):
- self.polyline2d = True
- if width:
- if type(width)!='list': width=[width,width]
- self.width=width
-
- def __str__(self):
- result= ' 0\nPOLYLINE\n%s 70\n%s\n' %(self._common(),self.pflag70)
- result+=' 66\n1\n'
- result+='%s\n' %_point(self.org_point)
- if self.polyface:
- result+=' 71\n%s\n' %self.p_count
- result+=' 72\n%s\n' %self.f_count
- elif self.polyline2d:
- if self.width!=None: result+=' 40\n%s\n 41\n%s\n' %(self.width[0],self.width[1])
- if self.pflag75:
- result+=' 75\n%s\n' %self.pflag75
- for point in self.points:
- result+=' 0\nVERTEX\n'
- result+=' 8\n%s\n' %self.layer
- if self.polyface:
- result+='%s\n' %_point(point)
- result+=' 70\n192\n'
- elif self.polyline2d:
- result+='%s\n' %_point(point[0])
- flag = point[1]
- if len(point)>2:
- [width1, width2] = point[2]
- if width1!=None: result+=' 40\n%s\n' %width1
- if width2!=None: result+=' 41\n%s\n' %width2
- if len(point)==4:
- bulge = point[3]
- if bulge: result+=' 42\n%s\n' %bulge
- if flag:
- result+=' 70\n%s\n' %flag
- else:
- result+='%s\n' %_point(point[0])
- flag = point[1]
- if flag:
- result+=' 70\n%s\n' %flag
-
- for face in self.faces:
- result+=' 0\nVERTEX\n'
- result+=' 8\n%s\n' %self.layer
- result+='%s\n' %_point(self.org_point)
- result+=' 70\n128\n'
- result+=' 71\n%s\n' %face[0]
- result+=' 72\n%s\n' %face[1]
- result+=' 73\n%s\n' %face[2]
- if len(face)==4: result+=' 74\n%s\n' %face[3]
- result+=' 0\nSEQEND\n'
- result+=' 8\n%s\n' %self.layer
- return result
+ def __init__(self,points,org_point=[0,0,0],flag70=0,flag75=0,width=None,**common):
+ #width = number, or width = list [width_start=None, width_end=None]
+ #for 2d-polyline: points = [ [[x, y, z], vflag=None, [width_start=None, width_end=None], bulge=0 or None] ...]
+ #for 3d-polyline: points = [ [[x, y, z], vflag=None], ...]
+ #for polyface: points = [points_list, faces_list]
+ _Entity.__init__(self,**common)
+ self.points=points
+ self.org_point=org_point
+ self.pflag70 = flag70
+ self.pflag75 = flag75
+ self.polyface = False
+ self.polyline2d = False
+ self.faces = [] # dummy value
+ self.width= None # dummy value
+ if self.pflag70 & POLYFACE_MESH:
+ self.polyface=True
+ self.points=points[0]
+ self.faces=points[1]
+ self.p_count=len(self.points)
+ self.f_count=len(self.faces)
+ elif not (self.pflag70 & POLYLINE_3D):
+ self.polyline2d = True
+ if width:
+ if type(width)!='list': width=[width,width]
+ self.width=width
+
+ def __str__(self):
+ result= ' 0\nPOLYLINE\n%s 70\n%s\n' %(self._common(),self.pflag70)
+ result+=' 66\n1\n'
+ result+='%s\n' %_point(self.org_point)
+ if self.polyface:
+ result+=' 71\n%s\n' %self.p_count
+ result+=' 72\n%s\n' %self.f_count
+ elif self.polyline2d:
+ if self.width!=None: result+=' 40\n%s\n 41\n%s\n' %(self.width[0],self.width[1])
+ if self.pflag75:
+ result+=' 75\n%s\n' %self.pflag75
+ for point in self.points:
+ result+=' 0\nVERTEX\n'
+ result+=' 8\n%s\n' %self.layer
+ if self.polyface:
+ result+='%s\n' %_point(point)
+ result+=' 70\n192\n'
+ elif self.polyline2d:
+ result+='%s\n' %_point(point[0])
+ flag = point[1]
+ if len(point)>2:
+ [width1, width2] = point[2]
+ if width1!=None: result+=' 40\n%s\n' %width1
+ if width2!=None: result+=' 41\n%s\n' %width2
+ if len(point)==4:
+ bulge = point[3]
+ if bulge: result+=' 42\n%s\n' %bulge
+ if flag:
+ result+=' 70\n%s\n' %flag
+ else:
+ result+='%s\n' %_point(point[0])
+ flag = point[1]
+ if flag:
+ result+=' 70\n%s\n' %flag
+
+ for face in self.faces:
+ result+=' 0\nVERTEX\n'
+ result+=' 8\n%s\n' %self.layer
+ result+='%s\n' %_point(self.org_point)
+ result+=' 70\n128\n'
+ result+=' 71\n%s\n' %face[0]
+ result+=' 72\n%s\n' %face[1]
+ result+=' 73\n%s\n' %face[2]
+ if len(face)==4: result+=' 74\n%s\n' %face[3]
+ result+=' 0\nSEQEND\n'
+ result+=' 8\n%s\n' %self.layer
+ return result
#-----------------------------------------------
class Point(_Entity):
- """Point."""
- def __init__(self,points=None,**common):
- _Entity.__init__(self,**common)
- self.points=points
- def __str__(self): # TODO:
- return ' 0\nPOINT\n%s%s\n' %(self._common(),
- _points(self.points)
- )
+ """Point."""
+ def __init__(self,points=None,**common):
+ _Entity.__init__(self,**common)
+ self.points=points
+ def __str__(self): # TODO:
+ return ' 0\nPOINT\n%s%s\n' %(self._common(),
+ _points(self.points)
+ )
#-----------------------------------------------
class Solid(_Entity):
- """Colored solid fill."""
- def __init__(self,points=None,**common):
- _Entity.__init__(self,**common)
- self.points=points
- def __str__(self):
- return ' 0\nSOLID\n%s%s\n' %(self._common(),
- _points(self.points[:2]+[self.points[3],self.points[2]])
- )
+ """Colored solid fill."""
+ def __init__(self,points=None,**common):
+ _Entity.__init__(self,**common)
+ self.points=points
+ def __str__(self):
+ return ' 0\nSOLID\n%s%s\n' %(self._common(),
+ _points(self.points[:2]+[self.points[3],self.points[2]])
+ )
#-----------------------------------------------
class Text(_Entity):
- """Single text line."""
- def __init__(self,text='',point=(0,0,0),alignment=None,
- flag=None,height=1,justifyhor=None,justifyver=None,
- rotation=None,obliqueAngle=None,style=None,xscale=None,**common):
- _Entity.__init__(self,**common)
- self.text=text
- self.point=point
- self.alignment=alignment
- self.flag=flag
- self.height=height
- self.justifyhor=justifyhor
- self.justifyver=justifyver
- self.rotation=rotation
- self.obliqueAngle=obliqueAngle
- self.style=style
- self.xscale=xscale
- def __str__(self):
- result= ' 0\nTEXT\n%s%s\n 40\n%s\n 1\n%s\n'%\
- (self._common(),_point(self.point),self.height,self.text)
- if self.rotation: result+=' 50\n%s\n'%self.rotation
- if self.xscale: result+=' 41\n%s\n'%self.xscale
- if self.obliqueAngle: result+=' 51\n%s\n'%self.obliqueAngle
- if self.style: result+=' 7\n%s\n'%self.style
- if self.flag: result+=' 71\n%s\n'%self.flag
- if self.justifyhor: result+=' 72\n%s\n'%self.justifyhor
- if self.alignment: result+='%s\n'%_point(self.alignment,1)
- if self.justifyver: result+=' 73\n%s\n'%self.justifyver
- return result
+ """Single text line."""
+ def __init__(self,text='',point=(0,0,0),alignment=None,
+ flag=None,height=1,justifyhor=None,justifyver=None,
+ rotation=None,obliqueAngle=None,style=None,xscale=None,**common):
+ _Entity.__init__(self,**common)
+ self.text=text
+ self.point=point
+ self.alignment=alignment
+ self.flag=flag
+ self.height=height
+ self.justifyhor=justifyhor
+ self.justifyver=justifyver
+ self.rotation=rotation
+ self.obliqueAngle=obliqueAngle
+ self.style=style
+ self.xscale=xscale
+ def __str__(self):
+ result= ' 0\nTEXT\n%s%s\n 40\n%s\n 1\n%s\n'%\
+ (self._common(),_point(self.point),self.height,self.text)
+ if self.rotation: result+=' 50\n%s\n'%self.rotation
+ if self.xscale: result+=' 41\n%s\n'%self.xscale
+ if self.obliqueAngle: result+=' 51\n%s\n'%self.obliqueAngle
+ if self.style: result+=' 7\n%s\n'%self.style
+ if self.flag: result+=' 71\n%s\n'%self.flag
+ if self.justifyhor: result+=' 72\n%s\n'%self.justifyhor
+ if self.alignment: result+='%s\n'%_point(self.alignment,1)
+ if self.justifyver: result+=' 73\n%s\n'%self.justifyver
+ return result
#-----------------------------------------------
class Mtext(Text):
- """Surrogate for mtext, generates some Text instances."""
- def __init__(self,text='',point=(0,0,0),width=250,spacingFactor=1.5,down=0,spacingWidth=None,**options):
- Text.__init__(self,text=text,point=point,**options)
- if down:spacingFactor*=-1
- self.spacingFactor=spacingFactor
- self.spacingWidth=spacingWidth
- self.width=width
- self.down=down
- def __str__(self):
- texts=self.text.replace('\r\n','\n').split('\n')
- if not self.down:texts.reverse()
- result=''
- x=y=0
- if self.spacingWidth:spacingWidth=self.spacingWidth
- else:spacingWidth=self.height*self.spacingFactor
- for text in texts:
- while text:
- result+='%s' %Text(text[:self.width],
- point=(self.point[0]+x*spacingWidth,
- self.point[1]+y*spacingWidth,
- self.point[2]),
- alignment=self.alignment,flag=self.flag,height=self.height,
- justifyhor=self.justifyhor,justifyver=self.justifyver,
- rotation=self.rotation,obliqueAngle=self.obliqueAngle,
- style=self.style,xscale=self.xscale,parent=self
- )
- text=text[self.width:]
- if self.rotation:x+=1
- else:y+=1
- return result[1:]
+ """Surrogate for mtext, generates some Text instances."""
+ def __init__(self,text='',point=(0,0,0),width=250,spacingFactor=1.5,down=0,spacingWidth=None,**options):
+ Text.__init__(self,text=text,point=point,**options)
+ if down:spacingFactor*=-1
+ self.spacingFactor=spacingFactor
+ self.spacingWidth=spacingWidth
+ self.width=width
+ self.down=down
+ def __str__(self):
+ texts=self.text.replace('\r\n','\n').split('\n')
+ if not self.down:texts.reverse()
+ result=''
+ x=y=0
+ if self.spacingWidth:spacingWidth=self.spacingWidth
+ else:spacingWidth=self.height*self.spacingFactor
+ for text in texts:
+ while text:
+ result+='%s' %Text(text[:self.width],
+ point=(self.point[0]+x*spacingWidth,
+ self.point[1]+y*spacingWidth,
+ self.point[2]),
+ alignment=self.alignment,flag=self.flag,height=self.height,
+ justifyhor=self.justifyhor,justifyver=self.justifyver,
+ rotation=self.rotation,obliqueAngle=self.obliqueAngle,
+ style=self.style,xscale=self.xscale,parent=self
+ )
+ text=text[self.width:]
+ if self.rotation:x+=1
+ else:y+=1
+ return result[1:]
#-----------------------------------------------
##class _Mtext(_Entity):
- """Mtext not functioning for minimal dxf."""
- """
- def __init__(self,text='',point=(0,0,0),attachment=1,
- charWidth=None,charHeight=1,direction=1,height=100,rotation=0,
- spacingStyle=None,spacingFactor=None,style=None,width=100,
- xdirection=None,**common):
- _Entity.__init__(self,**common)
- self.text=text
- self.point=point
- self.attachment=attachment
- self.charWidth=charWidth
- self.charHeight=charHeight
- self.direction=direction
- self.height=height
- self.rotation=rotation
- self.spacingStyle=spacingStyle
- self.spacingFactor=spacingFactor
- self.style=style
- self.width=width
- self.xdirection=xdirection
- def __str__(self):
- input=self.text
- text=''
- while len(input)>250:
- text+='3\n%s\n'%input[:250]
- input=input[250:]
- text+='1\n%s\n'%input
- result= '0\nMTEXT\n%s\n%s\n40\n%s\n41\n%s\n71\n%s\n72\n%s%s\n43\n%s\n50\n%s\n'%\
- (self._common(),_point(self.point),self.charHeight,self.width,
- self.attachment,self.direction,text,
- self.height,
- self.rotation)
- if self.style:result+='7\n%s\n'%self.style
- if self.xdirection:result+='%s\n'%_point(self.xdirection,1)
- if self.charWidth:result+='42\n%s\n'%self.charWidth
- if self.spacingStyle:result+='73\n%s\n'%self.spacingStyle
- if self.spacingFactor:result+='44\n%s\n'%self.spacingFactor
- return result
- """
+ """Mtext not functioning for minimal dxf."""
+ """
+ def __init__(self,text='',point=(0,0,0),attachment=1,
+ charWidth=None,charHeight=1,direction=1,height=100,rotation=0,
+ spacingStyle=None,spacingFactor=None,style=None,width=100,
+ xdirection=None,**common):
+ _Entity.__init__(self,**common)
+ self.text=text
+ self.point=point
+ self.attachment=attachment
+ self.charWidth=charWidth
+ self.charHeight=charHeight
+ self.direction=direction
+ self.height=height
+ self.rotation=rotation
+ self.spacingStyle=spacingStyle
+ self.spacingFactor=spacingFactor
+ self.style=style
+ self.width=width
+ self.xdirection=xdirection
+ def __str__(self):
+ input=self.text
+ text=''
+ while len(input)>250:
+ text+='3\n%s\n'%input[:250]
+ input=input[250:]
+ text+='1\n%s\n'%input
+ result= '0\nMTEXT\n%s\n%s\n40\n%s\n41\n%s\n71\n%s\n72\n%s%s\n43\n%s\n50\n%s\n'%\
+ (self._common(),_point(self.point),self.charHeight,self.width,
+ self.attachment,self.direction,text,
+ self.height,
+ self.rotation)
+ if self.style:result+='7\n%s\n'%self.style
+ if self.xdirection:result+='%s\n'%_point(self.xdirection,1)
+ if self.charWidth:result+='42\n%s\n'%self.charWidth
+ if self.spacingStyle:result+='73\n%s\n'%self.spacingStyle
+ if self.spacingFactor:result+='44\n%s\n'%self.spacingFactor
+ return result
+ """
#---tables ---------------------------------------------------
#-----------------------------------------------
class Block(_Collection):
- """Use list methods to add entities, eg append."""
- def __init__(self,name,layer='0',flag=0,base=(0,0,0),entities=[]):
- self.entities=copy.copy(entities)
- _Collection.__init__(self,entities)
- self.layer=layer
- self.name=name
- self.flag=0
- self.base=base
- def __str__(self): # TODO:
- e=''.join([str(x)for x in self.entities])
- return ' 0\nBLOCK\n 8\n%s\n 2\n%s\n 70\n%s\n%s\n 3\n%s\n%s 0\nENDBLK\n'%\
- (self.layer,self.name.upper(),self.flag,_point(self.base),self.name.upper(),e)
+ """Use list methods to add entities, eg append."""
+ def __init__(self,name,layer='0',flag=0,base=(0,0,0),entities=[]):
+ self.entities=copy.copy(entities)
+ _Collection.__init__(self,entities)
+ self.layer=layer
+ self.name=name
+ self.flag=0
+ self.base=base
+ def __str__(self): # TODO:
+ e=''.join([str(x)for x in self.entities])
+ return ' 0\nBLOCK\n 8\n%s\n 2\n%s\n 70\n%s\n%s\n 3\n%s\n%s 0\nENDBLK\n'%\
+ (self.layer,self.name.upper(),self.flag,_point(self.base),self.name.upper(),e)
#-----------------------------------------------
class Layer(_Call):
- """Layer"""
- def __init__(self,name='pydxf',color=7,lineType='continuous',flag=64):
- self.name=name
- self.color=color
- self.lineType=lineType
- self.flag=flag
- def __str__(self):
- return ' 0\nLAYER\n 2\n%s\n 70\n%s\n 62\n%s\n 6\n%s\n'%\
- (self.name.upper(),self.flag,self.color,self.lineType)
+ """Layer"""
+ def __init__(self,name='pydxf',color=7,lineType='continuous',flag=64):
+ self.name=name
+ self.color=color
+ self.lineType=lineType
+ self.flag=flag
+ def __str__(self):
+ return ' 0\nLAYER\n 2\n%s\n 70\n%s\n 62\n%s\n 6\n%s\n'%\
+ (self.name.upper(),self.flag,self.color,self.lineType)
#-----------------------------------------------
class LineType(_Call):
- """Custom linetype"""
- def __init__(self,name='CONTINUOUS',description='Solid line',elements=[0.0],flag=0):
- self.name=name
- self.description=description
- self.elements=copy.copy(elements)
- self.flag=flag
- def __str__(self):
- result = ' 0\nLTYPE\n 2\n%s\n 70\n%s\n 3\n%s\n 72\n65\n'%\
- (self.name.upper(),self.flag,self.description)
- if self.elements:
- elements = ' 73\n%s\n' %(len(self.elements)-1)
- elements += ' 40\n%s\n' %(self.elements[0])
- for e in self.elements[1:]:
- elements += ' 49\n%s\n' %e
- result += elements
- return result
+ """Custom linetype"""
+ def __init__(self,name='CONTINUOUS',description='Solid line',elements=[0.0],flag=0):
+ self.name=name
+ self.description=description
+ self.elements=copy.copy(elements)
+ self.flag=flag
+ def __str__(self):
+ result = ' 0\nLTYPE\n 2\n%s\n 70\n%s\n 3\n%s\n 72\n65\n'%\
+ (self.name.upper(),self.flag,self.description)
+ if self.elements:
+ elements = ' 73\n%s\n' %(len(self.elements)-1)
+ elements += ' 40\n%s\n' %(self.elements[0])
+ for e in self.elements[1:]:
+ elements += ' 49\n%s\n' %e
+ result += elements
+ return result
#-----------------------------------------------
class Style(_Call):
- """Text style"""
- def __init__(self,name='standard',flag=0,height=0,widthFactor=1.0,obliqueAngle=0.0,
- mirror=0,lastHeight=1,font='arial.ttf',bigFont=''):
- self.name=name
- self.flag=flag
- self.height=height
- self.widthFactor=widthFactor
- self.obliqueAngle=obliqueAngle
- self.mirror=mirror
- self.lastHeight=lastHeight
- self.font=font
- self.bigFont=bigFont
- def __str__(self):
- return ' 0\nSTYLE\n 2\n%s\n 70\n%s\n 40\n%s\n 41\n%s\n 50\n%s\n 71\n%s\n 42\n%s\n 3\n%s\n 4\n%s\n'%\
- (self.name.upper(),self.flag,self.flag,self.widthFactor,
- self.obliqueAngle,self.mirror,self.lastHeight,
- self.font.upper(),self.bigFont.upper())
+ """Text style"""
+ def __init__(self,name='standard',flag=0,height=0,widthFactor=1.0,obliqueAngle=0.0,
+ mirror=0,lastHeight=1,font='arial.ttf',bigFont=''):
+ self.name=name
+ self.flag=flag
+ self.height=height
+ self.widthFactor=widthFactor
+ self.obliqueAngle=obliqueAngle
+ self.mirror=mirror
+ self.lastHeight=lastHeight
+ self.font=font
+ self.bigFont=bigFont
+ def __str__(self):
+ return ' 0\nSTYLE\n 2\n%s\n 70\n%s\n 40\n%s\n 41\n%s\n 50\n%s\n 71\n%s\n 42\n%s\n 3\n%s\n 4\n%s\n'%\
+ (self.name.upper(),self.flag,self.flag,self.widthFactor,
+ self.obliqueAngle,self.mirror,self.lastHeight,
+ self.font.upper(),self.bigFont.upper())
#-----------------------------------------------
class VPort(_Call):
- def __init__(self,name,flag=0,
- leftBottom=(0.0,0.0),
- rightTop=(1.0,1.0),
- center=(0.5,0.5),
- snap_base=(0.0,0.0),
- snap_spacing=(0.1,0.1),
- grid_spacing=(0.1,0.1),
- direction=(0.0,0.0,1.0),
- target=(0.0,0.0,0.0),
- height=1.0,
- ratio=1.0,
- lens=50.0,
- frontClipping=0.0,
- backClipping=0.0,
- snap_rotation=0.0,
- twist=0.0,
- mode=0,
- circle_zoom=100,
- fast_zoom=1,
- ucsicon=1,
- snap_on=0,
- grid_on=0,
- snap_style=0,
- snap_isopair=0
- ):
- self.name=name
- self.flag=flag
- self.leftBottom=leftBottom
- self.rightTop=rightTop
- self.center=center
- self.snap_base=snap_base
- self.snap_spacing=snap_spacing
- self.grid_spacing=grid_spacing
- self.direction=direction
- self.target=target
- self.height=float(height)
- self.ratio=float(ratio)
- self.lens=float(lens)
- self.frontClipping=float(frontClipping)
- self.backClipping=float(backClipping)
- self.snap_rotation=float(snap_rotation)
- self.twist=float(twist)
- self.mode=mode
- self.circle_zoom=circle_zoom
- self.fast_zoom=fast_zoom
- self.ucsicon=ucsicon
- self.snap_on=snap_on
- self.grid_on=grid_on
- self.snap_style=snap_style
- self.snap_isopair=snap_isopair
- def __str__(self):
- output = [' 0', 'VPORT',
- ' 2', self.name,
- ' 70', self.flag,
- _point(self.leftBottom),
- _point(self.rightTop,1),
- _point(self.center,2), # View center point (in DCS)
- _point(self.snap_base,3),
- _point(self.snap_spacing,4),
- _point(self.grid_spacing,5),
- _point(self.direction,6), #view direction from target (in WCS)
- _point(self.target,7),
- ' 40', self.height,
- ' 41', self.ratio,
- ' 42', self.lens,
- ' 43', self.frontClipping,
- ' 44', self.backClipping,
- ' 50', self.snap_rotation,
- ' 51', self.twist,
- ' 71', self.mode,
- ' 72', self.circle_zoom,
- ' 73', self.fast_zoom,
- ' 74', self.ucsicon,
- ' 75', self.snap_on,
- ' 76', self.grid_on,
- ' 77', self.snap_style,
- ' 78', self.snap_isopair
- ]
-
- output_str = ''
- for s in output:
- output_str += '%s\n' %s
- return output_str
+ def __init__(self,name,flag=0,
+ leftBottom=(0.0,0.0),
+ rightTop=(1.0,1.0),
+ center=(0.5,0.5),
+ snap_base=(0.0,0.0),
+ snap_spacing=(0.1,0.1),
+ grid_spacing=(0.1,0.1),
+ direction=(0.0,0.0,1.0),
+ target=(0.0,0.0,0.0),
+ height=1.0,
+ ratio=1.0,
+ lens=50.0,
+ frontClipping=0.0,
+ backClipping=0.0,
+ snap_rotation=0.0,
+ twist=0.0,
+ mode=0,
+ circle_zoom=100,
+ fast_zoom=1,
+ ucsicon=1,
+ snap_on=0,
+ grid_on=0,
+ snap_style=0,
+ snap_isopair=0
+ ):
+ self.name=name
+ self.flag=flag
+ self.leftBottom=leftBottom
+ self.rightTop=rightTop
+ self.center=center
+ self.snap_base=snap_base
+ self.snap_spacing=snap_spacing
+ self.grid_spacing=grid_spacing
+ self.direction=direction
+ self.target=target
+ self.height=float(height)
+ self.ratio=float(ratio)
+ self.lens=float(lens)
+ self.frontClipping=float(frontClipping)
+ self.backClipping=float(backClipping)
+ self.snap_rotation=float(snap_rotation)
+ self.twist=float(twist)
+ self.mode=mode
+ self.circle_zoom=circle_zoom
+ self.fast_zoom=fast_zoom
+ self.ucsicon=ucsicon
+ self.snap_on=snap_on
+ self.grid_on=grid_on
+ self.snap_style=snap_style
+ self.snap_isopair=snap_isopair
+ def __str__(self):
+ output = [' 0', 'VPORT',
+ ' 2', self.name,
+ ' 70', self.flag,
+ _point(self.leftBottom),
+ _point(self.rightTop,1),
+ _point(self.center,2), # View center point (in DCS)
+ _point(self.snap_base,3),
+ _point(self.snap_spacing,4),
+ _point(self.grid_spacing,5),
+ _point(self.direction,6), #view direction from target (in WCS)
+ _point(self.target,7),
+ ' 40', self.height,
+ ' 41', self.ratio,
+ ' 42', self.lens,
+ ' 43', self.frontClipping,
+ ' 44', self.backClipping,
+ ' 50', self.snap_rotation,
+ ' 51', self.twist,
+ ' 71', self.mode,
+ ' 72', self.circle_zoom,
+ ' 73', self.fast_zoom,
+ ' 74', self.ucsicon,
+ ' 75', self.snap_on,
+ ' 76', self.grid_on,
+ ' 77', self.snap_style,
+ ' 78', self.snap_isopair
+ ]
+
+ output_str = ''
+ for s in output:
+ output_str += '%s\n' %s
+ return output_str
#-----------------------------------------------
class View(_Call):
- def __init__(self,name,flag=0,
- width=1.0,
- height=1.0,
- center=(0.5,0.5),
- direction=(0.0,0.0,1.0),
- target=(0.0,0.0,0.0),
- lens=50.0,
- frontClipping=0.0,
- backClipping=0.0,
- twist=0.0,mode=0
- ):
- self.name=name
- self.flag=flag
- self.width=float(width)
- self.height=float(height)
- self.center=center
- self.direction=direction
- self.target=target
- self.lens=float(lens)
- self.frontClipping=float(frontClipping)
- self.backClipping=float(backClipping)
- self.twist=float(twist)
- self.mode=mode
- def __str__(self):
- output = [' 0', 'VIEW',
- ' 2', self.name,
- ' 70', self.flag,
- ' 40', self.height,
- _point(self.center),
- ' 41', self.width,
- _point(self.direction,1),
- _point(self.target,2),
- ' 42', self.lens,
- ' 43', self.frontClipping,
- ' 44', self.backClipping,
- ' 50', self.twist,
- ' 71', self.mode
- ]
- output_str = ''
- for s in output:
- output_str += '%s\n' %s
- return output_str
+ def __init__(self,name,flag=0,
+ width=1.0,
+ height=1.0,
+ center=(0.5,0.5),
+ direction=(0.0,0.0,1.0),
+ target=(0.0,0.0,0.0),
+ lens=50.0,
+ frontClipping=0.0,
+ backClipping=0.0,
+ twist=0.0,mode=0
+ ):
+ self.name=name
+ self.flag=flag
+ self.width=float(width)
+ self.height=float(height)
+ self.center=center
+ self.direction=direction
+ self.target=target
+ self.lens=float(lens)
+ self.frontClipping=float(frontClipping)
+ self.backClipping=float(backClipping)
+ self.twist=float(twist)
+ self.mode=mode
+ def __str__(self):
+ output = [' 0', 'VIEW',
+ ' 2', self.name,
+ ' 70', self.flag,
+ ' 40', self.height,
+ _point(self.center),
+ ' 41', self.width,
+ _point(self.direction,1),
+ _point(self.target,2),
+ ' 42', self.lens,
+ ' 43', self.frontClipping,
+ ' 44', self.backClipping,
+ ' 50', self.twist,
+ ' 71', self.mode
+ ]
+ output_str = ''
+ for s in output:
+ output_str += '%s\n' %s
+ return output_str
#-----------------------------------------------
def ViewByWindow(name,leftBottom=(0,0),rightTop=(1,1),**options):
- width=abs(rightTop[0]-leftBottom[0])
- height=abs(rightTop[1]-leftBottom[1])
- center=((rightTop[0]+leftBottom[0])*0.5,(rightTop[1]+leftBottom[1])*0.5)
- return View(name=name,width=width,height=height,center=center,**options)
+ width=abs(rightTop[0]-leftBottom[0])
+ height=abs(rightTop[1]-leftBottom[1])
+ center=((rightTop[0]+leftBottom[0])*0.5,(rightTop[1]+leftBottom[1])*0.5)
+ return View(name=name,width=width,height=height,center=center,**options)
#---drawing
#-----------------------------------------------
class Drawing(_Collection):
- """Dxf drawing. Use append or any other list methods to add objects."""
- def __init__(self,insbase=(0.0,0.0,0.0),extmin=(0.0,0.0,0.0),extmax=(0.0,0.0,0.0),
- layers=[Layer()],linetypes=[LineType()],styles=[Style()],blocks=[],
- views=[],vports=[],entities=None,fileName='test.dxf'):
- # TODO: replace list with None,arial
- if not entities:
- entities=[]
- _Collection.__init__(self,entities)
- self.insbase=insbase
- self.extmin=extmin
- self.extmax=extmax
- self.layers=copy.copy(layers)
- self.linetypes=copy.copy(linetypes)
- self.styles=copy.copy(styles)
- self.views=copy.copy(views)
- self.vports=copy.copy(vports)
- self.blocks=copy.copy(blocks)
- self.fileName=fileName
- #print 'deb: blocks=',blocks #----------
- #private
- #self.acadver='9\n$ACADVER\n1\nAC1006\n'
- self.acadver=' 9\n$ACADVER\n 1\nAC1009\n'
- """DXF AutoCAD-Release format codes:
- AC1021 2008, 2007
- AC1018 2006, 2005, 2004
- AC1015 2002, 2000i, 2000
- AC1014 R14,14.01
- AC1012 R13
- AC1009 R12,11
- AC1006 R10
- AC1004 R9
- AC1002 R2.6
- AC1.50 R2.05
- """
-
- def _name(self,x):
- """Helper function for self._point"""
- return ' 9\n$%s\n' %x.upper()
-
- def _point(self,name,x):
- """Point setting from drawing like extmin,extmax,..."""
- return '%s%s' %(self._name(name),_point(x))
-
- def _section(self,name,x):
- """Sections like tables,blocks,entities,..."""
- if x: xstr=''.join(x)
- else: xstr=''
- return ' 0\nSECTION\n 2\n%s\n%s 0\nENDSEC\n'%(name.upper(),xstr)
-
- def _table(self,name,x):
- """Tables like ltype,layer,style,..."""
- if x: xstr=''.join(x)
- else: xstr=''
- return ' 0\nTABLE\n 2\n%s\n 70\n%s\n%s 0\nENDTAB\n'%(name.upper(),len(x),xstr)
-
- def __str__(self):
- """Returns drawing as dxf string."""
- header=[self.acadver]+[self._point(attr,getattr(self,attr))+'\n' for attr in _HEADER_POINTS]
- header=self._section('header',header)
-
- tables=[self._table('vport',[str(x) for x in self.vports]),
- self._table('ltype',[str(x) for x in self.linetypes]),
- self._table('layer',[str(x) for x in self.layers]),
- self._table('style',[str(x) for x in self.styles]),
- self._table('view',[str(x) for x in self.views]),
- ]
- tables=self._section('tables',tables)
- blocks=self._section('blocks',[str(x) for x in self.blocks])
- entities=self._section('entities',[str(x) for x in self.entities])
- all=''.join([header,tables,blocks,entities,' 0\nEOF\n'])
- return all
-
- def _write_section(self,file,name,data):
- file.write(' 0\nSECTION\n 2\n%s\n'%name.upper())
- for x in data:
- file.write(str(x))
- file.write(' 0\nENDSEC\n')
-
- def saveas(self,fileName,buffer=0):
- """Writes DXF file. Needs target file name. If optional parameter buffer>0, then switch to old behavior: store entire output string in RAM.
- """
- self.fileName=fileName
- if buffer: self.save()
- else: self.export()
-
- def save(self):
- outfile=open(self.fileName,'w')
- outfile.write(str(self))
- outfile.close()
-
- def export(self):
- outfile=open(self.fileName,'w')
- header=[self.acadver]+[self._point(attr,getattr(self,attr))+'\n' for attr in _HEADER_POINTS]
- self._write_section(outfile,'header',header)
- tables=[self._table('vport',[str(x) for x in self.vports]),
- self._table('ltype',[str(x) for x in self.linetypes]),
- self._table('layer',[str(x) for x in self.layers]),
- self._table('style',[str(x) for x in self.styles]),
- self._table('view',[str(x) for x in self.views]),
- ]
- self._write_section(outfile,'tables',tables)
- self._write_section(outfile,'blocks',self.blocks)
- self._write_section(outfile,'entities',self.entities)
- outfile.write(' 0\nEOF\n')
- outfile.close()
+ """Dxf drawing. Use append or any other list methods to add objects."""
+ def __init__(self,insbase=(0.0,0.0,0.0),extmin=(0.0,0.0,0.0),extmax=(0.0,0.0,0.0),
+ layers=[Layer()],linetypes=[LineType()],styles=[Style()],blocks=[],
+ views=[],vports=[],entities=None,fileName='test.dxf'):
+ # TODO: replace list with None,arial
+ if not entities:
+ entities=[]
+ _Collection.__init__(self,entities)
+ self.insbase=insbase
+ self.extmin=extmin
+ self.extmax=extmax
+ self.layers=copy.copy(layers)
+ self.linetypes=copy.copy(linetypes)
+ self.styles=copy.copy(styles)
+ self.views=copy.copy(views)
+ self.vports=copy.copy(vports)
+ self.blocks=copy.copy(blocks)
+ self.fileName=fileName
+ #print 'deb: blocks=',blocks #----------
+ #private
+ #self.acadver='9\n$ACADVER\n1\nAC1006\n'
+ self.acadver=' 9\n$ACADVER\n 1\nAC1009\n'
+ """DXF AutoCAD-Release format codes:
+ AC1021 2008, 2007
+ AC1018 2006, 2005, 2004
+ AC1015 2002, 2000i, 2000
+ AC1014 R14,14.01
+ AC1012 R13
+ AC1009 R12,11
+ AC1006 R10
+ AC1004 R9
+ AC1002 R2.6
+ AC1.50 R2.05
+ """
+
+ def _name(self,x):
+ """Helper function for self._point"""
+ return ' 9\n$%s\n' %x.upper()
+
+ def _point(self,name,x):
+ """Point setting from drawing like extmin,extmax,..."""
+ return '%s%s' %(self._name(name),_point(x))
+
+ def _section(self,name,x):
+ """Sections like tables,blocks,entities,..."""
+ if x: xstr=''.join(x)
+ else: xstr=''
+ return ' 0\nSECTION\n 2\n%s\n%s 0\nENDSEC\n'%(name.upper(),xstr)
+
+ def _table(self,name,x):
+ """Tables like ltype,layer,style,..."""
+ if x: xstr=''.join(x)
+ else: xstr=''
+ return ' 0\nTABLE\n 2\n%s\n 70\n%s\n%s 0\nENDTAB\n'%(name.upper(),len(x),xstr)
+
+ def __str__(self):
+ """Returns drawing as dxf string."""
+ header=[self.acadver]+[self._point(attr,getattr(self,attr))+'\n' for attr in _HEADER_POINTS]
+ header=self._section('header',header)
+
+ tables=[self._table('vport',[str(x) for x in self.vports]),
+ self._table('ltype',[str(x) for x in self.linetypes]),
+ self._table('layer',[str(x) for x in self.layers]),
+ self._table('style',[str(x) for x in self.styles]),
+ self._table('view',[str(x) for x in self.views]),
+ ]
+ tables=self._section('tables',tables)
+ blocks=self._section('blocks',[str(x) for x in self.blocks])
+ entities=self._section('entities',[str(x) for x in self.entities])
+ all=''.join([header,tables,blocks,entities,' 0\nEOF\n'])
+ return all
+
+ def _write_section(self,file,name,data):
+ file.write(' 0\nSECTION\n 2\n%s\n'%name.upper())
+ for x in data:
+ file.write(str(x))
+ file.write(' 0\nENDSEC\n')
+
+ def saveas(self,fileName,buffer=0):
+ """Writes DXF file. Needs target file name. If optional parameter buffer>0, then switch to old behavior: store entire output string in RAM.
+ """
+ self.fileName=fileName
+ if buffer: self.save()
+ else: self.export()
+
+ def save(self):
+ outfile=open(self.fileName,'w')
+ outfile.write(str(self))
+ outfile.close()
+
+ def export(self):
+ outfile=open(self.fileName,'w')
+ header=[self.acadver]+[self._point(attr,getattr(self,attr))+'\n' for attr in _HEADER_POINTS]
+ self._write_section(outfile,'header',header)
+ tables=[self._table('vport',[str(x) for x in self.vports]),
+ self._table('ltype',[str(x) for x in self.linetypes]),
+ self._table('layer',[str(x) for x in self.layers]),
+ self._table('style',[str(x) for x in self.styles]),
+ self._table('view',[str(x) for x in self.views]),
+ ]
+ self._write_section(outfile,'tables',tables)
+ self._write_section(outfile,'blocks',self.blocks)
+ self._write_section(outfile,'entities',self.entities)
+ outfile.write(' 0\nEOF\n')
+ outfile.close()
#---extras
#-----------------------------------------------
class Rectangle(_Entity):
- """Rectangle, creates lines."""
- def __init__(self,point=(0,0,0),width=1,height=1,solid=None,line=1,**common):
- _Entity.__init__(self,**common)
- self.point=point
- self.width=width
- self.height=height
- self.solid=solid
- self.line=line
- def __str__(self):
- result=''
- points=[self.point,(self.point[0]+self.width,self.point[1],self.point[2]),
- (self.point[0]+self.width,self.point[1]+self.height,self.point[2]),
- (self.point[0],self.point[1]+self.height,self.point[2]),self.point]
- if self.solid:
- result+= Solid(points=points[:-1],parent=self.solid)
- if self.line:
- for i in range(4):
- result+= Line(points=[points[i],points[i+1]],parent=self)
- return result[1:]
+ """Rectangle, creates lines."""
+ def __init__(self,point=(0,0,0),width=1,height=1,solid=None,line=1,**common):
+ _Entity.__init__(self,**common)
+ self.point=point
+ self.width=width
+ self.height=height
+ self.solid=solid
+ self.line=line
+ def __str__(self):
+ result=''
+ points=[self.point,(self.point[0]+self.width,self.point[1],self.point[2]),
+ (self.point[0]+self.width,self.point[1]+self.height,self.point[2]),
+ (self.point[0],self.point[1]+self.height,self.point[2]),self.point]
+ if self.solid:
+ result+= Solid(points=points[:-1],parent=self.solid)
+ if self.line:
+ for i in range(4):
+ result+= Line(points=[points[i],points[i+1]],parent=self)
+ return result[1:]
#-----------------------------------------------
class LineList(_Entity):
- """Like polyline, but built of individual lines."""
- def __init__(self,points=[],org_point=[0,0,0],closed=0,**common):
- _Entity.__init__(self,**common)
- self.closed=closed
- self.points=copy.copy(points)
- def __str__(self):
- if self.closed:
- points=self.points+[self.points[0]]
- else: points=self.points
- result=''
- for i in range(len(points)-1):
- result+= Line(points=[points[i][0],points[i+1][0]],parent=self)
- return result[1:]
+ """Like polyline, but built of individual lines."""
+ def __init__(self,points=[],org_point=[0,0,0],closed=0,**common):
+ _Entity.__init__(self,**common)
+ self.closed=closed
+ self.points=copy.copy(points)
+ def __str__(self):
+ if self.closed:
+ points=self.points+[self.points[0]]
+ else: points=self.points
+ result=''
+ for i in range(len(points)-1):
+ result+= Line(points=[points[i][0],points[i+1][0]],parent=self)
+ return result[1:]
#-----------------------------------------------------
def test():
- #Blocks
- b=Block('test')
- b.append(Solid(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=1))
- b.append(Arc(center=(1,0,0),color=2))
-
- #Drawing
- d=Drawing()
- #tables
- d.blocks.append(b) #table blocks
- d.styles.append(Style()) #table styles
- d.views.append(View('Normal')) #table view
- d.views.append(ViewByWindow('Window',leftBottom=(1,0),rightTop=(2,1))) #idem
-
- #entities
- d.append(Circle(center=(1,1,0),color=3))
- d.append(Face(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=4))
- d.append(Insert('test',point=(3,3,3),cols=5,colspacing=2))
- d.append(Line(points=[(0,0,0),(1,1,1)]))
- d.append(Mtext('Click on Ads\nmultiple lines with mtext',point=(1,1,1),color=5,rotation=90))
- d.append(Text('Please donate!',point=(3,0,1)))
- #d.append(Rectangle(point=(2,2,2),width=4,height=3,color=6,solid=Solid(color=2)))
- d.append(Solid(points=[(4,4,0),(5,4,0),(7,8,0),(9,9,0)],color=3))
- #d.append(PolyLine(points=[(1,1,1),(2,1,1),(2,2,1),(1,2,1)],flag=1,color=1))
-
- #d.saveas('c:\\test.dxf')
- d.saveas('test.dxf')
+ #Blocks
+ b=Block('test')
+ b.append(Solid(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=1))
+ b.append(Arc(center=(1,0,0),color=2))
+
+ #Drawing
+ d=Drawing()
+ #tables
+ d.blocks.append(b) #table blocks
+ d.styles.append(Style()) #table styles
+ d.views.append(View('Normal')) #table view
+ d.views.append(ViewByWindow('Window',leftBottom=(1,0),rightTop=(2,1))) #idem
+
+ #entities
+ d.append(Circle(center=(1,1,0),color=3))
+ d.append(Face(points=[(0,0,0),(1,0,0),(1,1,0),(0,1,0)],color=4))
+ d.append(Insert('test',point=(3,3,3),cols=5,colspacing=2))
+ d.append(Line(points=[(0,0,0),(1,1,1)]))
+ d.append(Mtext('Click on Ads\nmultiple lines with mtext',point=(1,1,1),color=5,rotation=90))
+ d.append(Text('Please donate!',point=(3,0,1)))
+ #d.append(Rectangle(point=(2,2,2),width=4,height=3,color=6,solid=Solid(color=2)))
+ d.append(Solid(points=[(4,4,0),(5,4,0),(7,8,0),(9,9,0)],color=3))
+ #d.append(PolyLine(points=[(1,1,1),(2,1,1),(2,2,1),(1,2,1)],flag=1,color=1))
+
+ #d.saveas('c:\\test.dxf')
+ d.saveas('test.dxf')
#-----------------------------------------------------
if __name__=='__main__':
- if not copy:
- Draw.PupMenu('Error%t|This script requires a full python install')
- else: test()
+ if not copy:
+ Draw.PupMenu('Error%t|This script requires a full python install')
+ else: test()
diff --git a/io_export_dxf/model/model.py b/io_export_dxf/model/model.py
index 54e12f3a..698f5102 100644
--- a/io_export_dxf/model/model.py
+++ b/io_export_dxf/model/model.py
@@ -1,36 +1,36 @@
class DxfDrawing(object):
- """
- Represents intermediate model of DXF drawing. It is useful in iterating
- through exported object and for easy change the DXF handling library.
- """
- def __init__(self):
- self._entities = {}
- self._layers = {}
- self._views = []
- self._vports = []
- self._blocks = []
-
- def isEmpty(self):
- return len(self._entities) == 0
-
- def addEntity(self, type, **kwargs):
- if type not in self._entities:
- self._entities[type] = []
- self._entities[type].append(kwargs)
-
- def addLayer(self, name, color):
- self._layers[name] = color
-
- def containsLayer(self, name):
- return name in self._layers
-
- def addBlock(self, block):
- self._blocks.append(block)
-
- def containsBlock(self, blockname):
- return blockname in self._blocks
-
- def convert(self, **kwargs):
- """ Converts this drawing into DXF representation object """
- raise NotImplementedError()
+ """
+ Represents intermediate model of DXF drawing. It is useful in iterating
+ through exported object and for easy change the DXF handling library.
+ """
+ def __init__(self):
+ self._entities = {}
+ self._layers = {}
+ self._views = []
+ self._vports = []
+ self._blocks = []
+
+ def isEmpty(self):
+ return len(self._entities) == 0
+
+ def addEntity(self, type, **kwargs):
+ if type not in self._entities:
+ self._entities[type] = []
+ self._entities[type].append(kwargs)
+
+ def addLayer(self, name, color):
+ self._layers[name] = color
+
+ def containsLayer(self, name):
+ return name in self._layers
+
+ def addBlock(self, block):
+ self._blocks.append(block)
+
+ def containsBlock(self, blockname):
+ return blockname in self._blocks
+
+ def convert(self, **kwargs):
+ """ Converts this drawing into DXF representation object """
+ raise NotImplementedError()
diff --git a/io_export_dxf/test2.txt b/io_export_dxf/test2.txt
index fd95ef1c..8ccff989 100644
--- a/io_export_dxf/test2.txt
+++ b/io_export_dxf/test2.txt
@@ -1 +1 @@
-migius commit test 2b \ No newline at end of file
+migius commit test 2b
diff --git a/io_export_paper_model.py b/io_export_paper_model.py
index 083c13d4..1329a304 100644
--- a/io_export_paper_model.py
+++ b/io_export_paper_model.py
@@ -17,9 +17,9 @@ bl_info = {
"location": "File > Export > Paper Model",
"warning": "",
"description": "Export printable net of the active mesh",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/paper_model.html",
"category": "Import-Export",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/paper_model.html",
}
# Task: split into four files (SVG and PDF separately)
diff --git a/io_export_pc2.py b/io_export_pc2.py
index 9cb04769..b40b2a77 100644
--- a/io_export_pc2.py
+++ b/io_export_pc2.py
@@ -24,9 +24,10 @@ bl_info = {
"location": "File > Export > Pointcache (.pc2)",
"description": "Export mesh Pointcache data (.pc2)",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/pc2.html",
- "category": "Import-Export"}
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/pc2.html",
+ "category": "Import-Export",
+}
"""
Related links:
diff --git a/io_import_dxf/__init__.py b/io_import_dxf/__init__.py
index 09f09ea3..bff93e9e 100644
--- a/io_import_dxf/__init__.py
+++ b/io_import_dxf/__init__.py
@@ -38,8 +38,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "File > Import > AutoCAD DXF",
"description": "Import files in the Autocad DXF format (.dxf)",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/scene_dxf.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/scene_dxf.html",
"category": "Import-Export",
}
diff --git a/io_import_images_as_planes.py b/io_import_images_as_planes.py
index 4efe480f..dc25bee0 100644
--- a/io_import_images_as_planes.py
+++ b/io_import_images_as_planes.py
@@ -27,8 +27,8 @@ bl_info = {
"description": "Imports images and creates planes with the appropriate aspect ratio. "
"The images are mapped to the planes.",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/images_as_planes.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/images_as_planes.html",
"support": 'OFFICIAL',
"category": "Import-Export",
}
diff --git a/io_import_palette/__init__.py b/io_import_palette/__init__.py
index f4f1c454..e8f03185 100644
--- a/io_import_palette/__init__.py
+++ b/io_import_palette/__init__.py
@@ -26,9 +26,10 @@ bl_info = {
"location": "File > Import",
"description": "Import Palettes",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/io_palettes.html",
- "category": "Import-Export"}
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/palettes.html",
+ "category": "Import-Export",
+}
import sys
import os
diff --git a/io_mesh_atomic/__init__.py b/io_mesh_atomic/__init__.py
index d9e13c47..fd77c31d 100644
--- a/io_mesh_atomic/__init__.py
+++ b/io_mesh_atomic/__init__.py
@@ -63,8 +63,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "File -> Import -> PDB (.pdb) and File -> Import -> XYZ (.xyz)",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/mesh_atomic.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/mesh_atomic.html",
"category": "Import-Export",
}
diff --git a/io_mesh_atomic/utility_gui.py b/io_mesh_atomic/utility_gui.py
index 97395036..295d1490 100644
--- a/io_mesh_atomic/utility_gui.py
+++ b/io_mesh_atomic/utility_gui.py
@@ -418,4 +418,3 @@ class SticksAllSmallerButton(Operator):
None,
1.0/scn.sticks_all)
return {'FINISHED'}
-
diff --git a/io_mesh_ply/__init__.py b/io_mesh_ply/__init__.py
index f99dbffb..86ab7999 100644
--- a/io_mesh_ply/__init__.py
+++ b/io_mesh_ply/__init__.py
@@ -25,8 +25,8 @@ bl_info = {
"blender": (2, 82, 0),
"location": "File > Import-Export",
"description": "Import-Export PLY mesh data with UVs and vertex colors",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/io_mesh_ply.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/mesh_ply.html",
"support": 'OFFICIAL',
"category": "Import-Export",
}
diff --git a/io_mesh_stl/__init__.py b/io_mesh_stl/__init__.py
index 17ff6dec..17af58f1 100644
--- a/io_mesh_stl/__init__.py
+++ b/io_mesh_stl/__init__.py
@@ -25,8 +25,8 @@ bl_info = {
"blender": (2, 81, 6),
"location": "File > Import-Export",
"description": "Import-Export STL files",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/io_mesh_stl.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/mesh_stl.html",
"support": 'OFFICIAL',
"category": "Import-Export",
}
diff --git a/io_mesh_uv_layout/__init__.py b/io_mesh_uv_layout/__init__.py
index d585c005..b376fda4 100644
--- a/io_mesh_uv_layout/__init__.py
+++ b/io_mesh_uv_layout/__init__.py
@@ -26,8 +26,8 @@ bl_info = {
"location": "Image-Window > UVs > Export UV Layout",
"description": "Export the UV layout as a 2D graphic",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/io_mesh_uv_layout.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/mesh_uv_layout.html",
"support": 'OFFICIAL',
"category": "Import-Export",
}
diff --git a/io_mesh_uv_layout/export_uv_eps.py b/io_mesh_uv_layout/export_uv_eps.py
index 3280cefa..45f64bb7 100644
--- a/io_mesh_uv_layout/export_uv_eps.py
+++ b/io_mesh_uv_layout/export_uv_eps.py
@@ -89,4 +89,4 @@ def draw_polygon_path(uvs, width, height):
def footer():
yield "showpage\n"
- yield "%%EOF\n" \ No newline at end of file
+ yield "%%EOF\n"
diff --git a/io_mesh_uv_layout/export_uv_svg.py b/io_mesh_uv_layout/export_uv_svg.py
index d00f9402..8aba2142 100644
--- a/io_mesh_uv_layout/export_uv_svg.py
+++ b/io_mesh_uv_layout/export_uv_svg.py
@@ -61,4 +61,4 @@ def get_color_string(color):
def footer():
yield '\n'
- yield '</svg>\n' \ No newline at end of file
+ yield '</svg>\n'
diff --git a/io_scene_fbx/__init__.py b/io_scene_fbx/__init__.py
index f14666ed..dcffe3ab 100644
--- a/io_scene_fbx/__init__.py
+++ b/io_scene_fbx/__init__.py
@@ -26,8 +26,8 @@ bl_info = {
"location": "File > Import-Export",
"description": "FBX IO meshes, UV's, vertex colors, materials, textures, cameras, lamps and actions",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/io_scene_fbx.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/scene_fbx.html",
"support": 'OFFICIAL',
"category": "Import-Export",
}
diff --git a/io_scene_gltf2/__init__.py b/io_scene_gltf2/__init__.py
index 2ad36029..de7bbe7a 100755
--- a/io_scene_gltf2/__init__.py
+++ b/io_scene_gltf2/__init__.py
@@ -15,12 +15,12 @@
bl_info = {
'name': 'glTF 2.0 format',
'author': 'Julien Duroure, Norbert Nopper, Urs Hanselmann, Moritz Becher, Benjamin Schmithüsen, Jim Eckerlein, and many external contributors',
- "version": (1, 2, 20),
- 'blender': (2, 81, 6),
+ "version": (1, 2, 35),
+ 'blender': (2, 82, 7),
'location': 'File > Import-Export',
'description': 'Import-Export as glTF 2.0',
'warning': '',
- 'wiki_url': "https://docs.blender.org/manual/en/dev/addons/import_export/scene_gltf2.html",
+ 'doc_url': "https://docs.blender.org/manual/en/dev/addons/import_export/scene_gltf2.html",
'tracker_url': "https://github.com/KhronosGroup/glTF-Blender-IO/issues/",
'support': 'OFFICIAL',
'category': 'Import-Export',
@@ -215,12 +215,19 @@ class ExportGLTF2_Base:
default=False
)
+ # keep it for compatibility (for now)
export_selected: BoolProperty(
name='Selected Objects',
description='Export selected objects only',
default=False
)
+ use_selected: BoolProperty(
+ name='Selected Objects',
+ description='Export selected objects only',
+ default=False
+ )
+
export_extras: BoolProperty(
name='Custom Properties',
description='Export custom properties as glTF extras',
@@ -345,7 +352,13 @@ class ExportGLTF2_Base:
if settings:
try:
for (k, v) in settings.items():
- setattr(self, k, v)
+ if k == "export_selected": # Back compatibility for export_selected --> use_selected
+ setattr(self, "use_selected", v)
+ del settings[k]
+ settings["use_selected"] = v
+ print("export_selected is now renamed use_selected, and will be deleted in a few release")
+ else:
+ setattr(self, k, v)
self.will_save_settings = True
except (AttributeError, TypeError):
@@ -417,7 +430,15 @@ class ExportGLTF2_Base:
export_settings['gltf_materials'] = self.export_materials
export_settings['gltf_colors'] = self.export_colors
export_settings['gltf_cameras'] = self.export_cameras
- export_settings['gltf_selected'] = self.export_selected
+
+ # compatibility after renaming export_selected to use_selected
+ if self.export_selected is True:
+ self.report({"WARNING"}, "export_selected is now renamed use_selected, and will be deleted in a few release")
+ export_settings['gltf_selected'] = self.export_selected
+ else:
+ export_settings['gltf_selected'] = self.use_selected
+
+ # export_settings['gltf_selected'] = self.use_selected This can be uncomment when removing compatibility of export_selected
export_settings['gltf_layers'] = True # self.export_layers
export_settings['gltf_extras'] = self.export_extras
export_settings['gltf_yup'] = self.export_yup
@@ -480,13 +501,8 @@ class ExportGLTF2_Base:
return gltf2_blender_export.save(context, export_settings)
-
-
-
-
-
def draw(self, context):
- pass
+ pass # Is needed to get panels available
class GLTF_PT_export_main(bpy.types.Panel):
@@ -540,7 +556,7 @@ class GLTF_PT_export_include(bpy.types.Panel):
sfile = context.space_data
operator = sfile.active_operator
- layout.prop(operator, 'export_selected')
+ layout.prop(operator, 'use_selected')
layout.prop(operator, 'export_extras')
layout.prop(operator, 'export_cameras')
layout.prop(operator, 'export_lights')
@@ -947,4 +963,3 @@ def unregister():
# remove from the export / import menu
bpy.types.TOPBAR_MT_file_export.remove(menu_func_export)
bpy.types.TOPBAR_MT_file_import.remove(menu_func_import)
-
diff --git a/io_scene_gltf2/blender/com/gltf2_blender_conversion.py b/io_scene_gltf2/blender/com/gltf2_blender_conversion.py
index fccfce95..574e26e5 100755
--- a/io_scene_gltf2/blender/com/gltf2_blender_conversion.py
+++ b/io_scene_gltf2/blender/com/gltf2_blender_conversion.py
@@ -60,4 +60,3 @@ def get_target(property):
"scale": "scale",
"value": "weights"
}.get(property)
-
diff --git a/io_scene_gltf2/blender/com/gltf2_blender_data_path.py b/io_scene_gltf2/blender/com/gltf2_blender_data_path.py
index 6ba77709..a4cb6625 100755
--- a/io_scene_gltf2/blender/com/gltf2_blender_data_path.py
+++ b/io_scene_gltf2/blender/com/gltf2_blender_data_path.py
@@ -36,4 +36,3 @@ def get_rotation_modes(target_property: str) -> str:
return True, ["AXIS_ANGLE"]
else:
return False, []
-
diff --git a/io_scene_gltf2/blender/com/gltf2_blender_extras.py b/io_scene_gltf2/blender/com/gltf2_blender_extras.py
index c67cb903..6cf220e6 100644
--- a/io_scene_gltf2/blender/com/gltf2_blender_extras.py
+++ b/io_scene_gltf2/blender/com/gltf2_blender_extras.py
@@ -91,4 +91,3 @@ def set_extras(blender_element, extras, exclude=[]):
blender_element[custom_property] = value
except TypeError as e:
print('Error setting property %s to value of type %s' % (custom_property, type(value)))
-
diff --git a/io_scene_gltf2/blender/com/gltf2_blender_json.py b/io_scene_gltf2/blender/com/gltf2_blender_json.py
index fbf833c1..e96e58ff 100755
--- a/io_scene_gltf2/blender/com/gltf2_blender_json.py
+++ b/io_scene_gltf2/blender/com/gltf2_blender_json.py
@@ -35,4 +35,3 @@ def is_json_convertible(data):
return True
except:
return False
-
diff --git a/io_scene_gltf2/blender/com/gltf2_blender_material_helpers.py b/io_scene_gltf2/blender/com/gltf2_blender_material_helpers.py
index 2b26350d..349cfda9 100755
--- a/io_scene_gltf2/blender/com/gltf2_blender_material_helpers.py
+++ b/io_scene_gltf2/blender/com/gltf2_blender_material_helpers.py
@@ -15,4 +15,3 @@
def get_gltf_node_name():
return "glTF Settings"
-
diff --git a/io_scene_gltf2/blender/com/gltf2_blender_math.py b/io_scene_gltf2/blender/com/gltf2_blender_math.py
index 9c65b943..fb342bc4 100755
--- a/io_scene_gltf2/blender/com/gltf2_blender_math.py
+++ b/io_scene_gltf2/blender/com/gltf2_blender_math.py
@@ -170,4 +170,3 @@ def transform_value(value: Vector, _: Matrix = Matrix.Identity(4)) -> Vector:
def round_if_near(value: float, target: float) -> float:
"""If value is very close to target, round to target."""
return value if abs(value - target) > 2.0e-6 else target
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_export.py b/io_scene_gltf2/blender/exp/gltf2_blender_export.py
index 94babf78..0e415e7a 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_export.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_export.py
@@ -147,4 +147,3 @@ def __notify_end(context, elapsed):
print_console('INFO', 'Finished glTF 2.0 export in {} s'.format(elapsed))
context.window_manager.progress_end()
print_newline()
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_export_keys.py b/io_scene_gltf2/blender/exp/gltf2_blender_export_keys.py
index 8813337b..ef11459d 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_export_keys.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_export_keys.py
@@ -57,4 +57,3 @@ USE_NO_COLOR = 'gltf_use_no_color'
METALLIC_ROUGHNESS_IMAGE = "metallic_roughness_image"
GROUP_INDEX = 'group_index'
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
index c7758538..762acbf3 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_extract.py
@@ -64,7 +64,7 @@ class ShapeKey:
# Functions
#
-def convert_swizzle_normal_and_tangent(loc, armature, blender_object, export_settings):
+def convert_swizzle_normal(loc, armature, blender_object, export_settings):
"""Convert a normal data from Blender coordinate system to glTF coordinate system."""
if not armature:
# Classic case. Mesh is not skined, no need to apply armature transfoms on vertices / normals / tangents
@@ -74,8 +74,10 @@ def convert_swizzle_normal_and_tangent(loc, armature, blender_object, export_set
return Vector((loc[0], loc[1], loc[2]))
else:
# Mesh is skined, we have to apply armature transforms on data
- apply_matrix = armature.matrix_world.inverted() @ blender_object.matrix_world
- new_loc = apply_matrix.to_quaternion() @ loc
+ apply_matrix = (armature.matrix_world.inverted() @ blender_object.matrix_world).to_3x3().inverted()
+ apply_matrix.transpose()
+ new_loc = ((armature.matrix_world.to_3x3() @ apply_matrix).to_4x4() @ Matrix.Translation(Vector((loc[0], loc[1], loc[2])))).to_translation()
+
if export_settings[gltf2_blender_export_keys.YUP]:
return Vector((new_loc[0], new_loc[2], -new_loc[1]))
else:
@@ -640,14 +642,14 @@ def extract_primitives(glTF, blender_mesh, blender_object, blender_vertex_groups
v = convert_swizzle_location(vertex.co, armature, blender_object, export_settings)
if blender_polygon.use_smooth or blender_mesh.use_auto_smooth:
if blender_mesh.has_custom_normals:
- n = convert_swizzle_normal_and_tangent(blender_mesh.loops[loop_index].normal, armature, blender_object, export_settings)
+ n = convert_swizzle_normal(blender_mesh.loops[loop_index].normal, armature, blender_object, export_settings)
else:
- n = convert_swizzle_normal_and_tangent(vertex.normal, armature, blender_object, export_settings)
+ n = convert_swizzle_normal(vertex.normal, armature, blender_object, export_settings)
if use_tangents:
t = convert_swizzle_tangent(blender_mesh.loops[loop_index].tangent, armature, blender_object, export_settings)
b = convert_swizzle_location(blender_mesh.loops[loop_index].bitangent, armature, blender_object, export_settings)
else:
- n = convert_swizzle_normal_and_tangent(face_normal, armature, blender_object, export_settings)
+ n = convert_swizzle_normal(face_normal, armature, blender_object, export_settings)
if use_tangents:
t = convert_swizzle_tangent(face_tangent, armature, blender_object, export_settings)
b = convert_swizzle_location(face_bitangent, armature, blender_object, export_settings)
@@ -671,20 +673,12 @@ def extract_primitives(glTF, blender_mesh, blender_object, blender_vertex_groups
for color_index in range(0, color_max):
color_name = COLOR_PREFIX + str(color_index)
color = vertex_colors[color_name].data[loop_index].color
- if len(color) == 3:
- colors.append([
- color_srgb_to_scene_linear(color[0]),
- color_srgb_to_scene_linear(color[1]),
- color_srgb_to_scene_linear(color[2]),
- 1.0
- ])
- else:
- colors.append([
- color_srgb_to_scene_linear(color[0]),
- color_srgb_to_scene_linear(color[1]),
- color_srgb_to_scene_linear(color[2]),
- color[3]
- ])
+ colors.append([
+ color_srgb_to_scene_linear(color[0]),
+ color_srgb_to_scene_linear(color[1]),
+ color_srgb_to_scene_linear(color[2]),
+ color[3]
+ ])
#
@@ -774,7 +768,7 @@ def extract_primitives(glTF, blender_mesh, blender_object, blender_vertex_groups
temp_normals[blender_polygon.index * 3 + 0], temp_normals[blender_polygon.index * 3 + 1],
temp_normals[blender_polygon.index * 3 + 2])
- n_morph = convert_swizzle_normal_and_tangent(Vector(n_morph), armature, blender_object, export_settings)
+ n_morph = convert_swizzle_normal(Vector(n_morph), armature, blender_object, export_settings)
# Store delta.
n_morph -= n
@@ -977,4 +971,3 @@ def extract_primitives(glTF, blender_mesh, blender_object, blender_vertex_groups
print_console('INFO', 'Primitives created: ' + str(len(result_primitives)))
return result_primitives
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather.py
index 7bff64d3..02c93b10 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather.py
@@ -84,6 +84,11 @@ def __gather_animations(blender_scene, export_settings):
to_delete_idx = []
for merged_anim_track in merged_tracks.keys():
if len(merged_tracks[merged_anim_track]) < 2:
+
+ # There is only 1 animation in the track
+ # If name of the track is not a default name, use this name for action
+ animations[0].name = merged_anim_track
+
continue
base_animation_idx = None
@@ -137,4 +142,3 @@ def __gather_extras(blender_object, export_settings):
if export_settings[gltf2_blender_export_keys.EXTRAS]:
return generate_extras(blender_object)
return None
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_accessors.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_accessors.py
index 7373a060..2fe992bc 100644
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_accessors.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_accessors.py
@@ -45,4 +45,3 @@ def gather_accessor(buffer_view: gltf2_io_binary_data.BinaryData,
sparse=None,
type=type
)
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py
index 0b23ec85..9dfbea34 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channel_target.py
@@ -119,4 +119,3 @@ def __gather_path(channels: typing.Tuple[bpy.types.FCurve],
raise RuntimeError("Cannot export an animation with {} target".format(target))
return path
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
index 36b850df..99a0ef91 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_channels.py
@@ -21,6 +21,7 @@ from io_scene_gltf2.io.com import gltf2_io_debug
from io_scene_gltf2.blender.exp.gltf2_blender_gather_cache import cached
from io_scene_gltf2.blender.exp import gltf2_blender_gather_animation_samplers
from io_scene_gltf2.blender.exp import gltf2_blender_gather_animation_channel_target
+from io_scene_gltf2.blender.exp import gltf2_blender_gather_animation_sampler_keyframes
from io_scene_gltf2.blender.exp import gltf2_blender_get
from io_scene_gltf2.blender.exp import gltf2_blender_gather_skins
from io_scene_gltf2.blender.exp import gltf2_blender_gather_drivers
@@ -124,6 +125,8 @@ def gather_animation_channels(blender_action: bpy.types.Action,
# resetting driver caches
gltf2_blender_gather_drivers.get_sk_driver_values.reset_cache()
gltf2_blender_gather_drivers.get_sk_drivers.reset_cache()
+ # resetting bone caches
+ gltf2_blender_gather_animation_sampler_keyframes.get_bone_matrix.reset_cache()
return channels
@@ -370,4 +373,3 @@ def __gather_armature_object_channel_groups(blender_action: bpy.types.Action, bl
groups += list(p.values())
return map(tuple, groups)
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py
index bb59b8a9..89559719 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_sampler_keyframes.py
@@ -160,7 +160,7 @@ def get_bone_matrix(blender_object_if_armature: typing.Optional[bpy.types.Object
bpy.context.scene.frame_set(frame)
for pbone in blender_object_if_armature.pose.bones:
if bake_bone is None:
- matrix = pbone.matrix_basis
+ matrix = pbone.matrix_basis.copy()
else:
matrix = pbone.matrix
matrix = blender_object_if_armature.convert_space(pose_bone=pbone, matrix=matrix, from_space='POSE', to_space='LOCAL')
@@ -388,4 +388,3 @@ def needs_baking(blender_object_if_armature: typing.Optional[bpy.types.Object],
return True
return False
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py
index 27750a72..b95b576a 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animation_samplers.py
@@ -410,4 +410,3 @@ def __gather_output(channels: typing.Tuple[bpy.types.FCurve],
sparse=None,
type=data_type
)
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py
index cf106c41..05615053 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_animations.py
@@ -214,9 +214,10 @@ def __get_blender_actions(blender_object: bpy.types.Object,
for track in blender_object.animation_data.nla_tracks:
# Multi-strip tracks do not export correctly yet (they need to be baked),
# so skip them for now and only write single-strip tracks.
- if track.strips is None or len(track.strips) != 1:
+ non_muted_strips = [strip for strip in track.strips if strip.action is not None and strip.mute is False]
+ if track.strips is None or len(non_muted_strips) != 1:
continue
- for strip in [strip for strip in track.strips if strip.action is not None]:
+ for strip in non_muted_strips:
blender_actions.append(strip.action)
blender_tracks[strip.action.name] = track.name # Always set after possible active action -> None will be overwrite
@@ -233,9 +234,10 @@ def __get_blender_actions(blender_object: bpy.types.Object,
for track in blender_object.data.shape_keys.animation_data.nla_tracks:
# Multi-strip tracks do not export correctly yet (they need to be baked),
# so skip them for now and only write single-strip tracks.
- if track.strips is None or len(track.strips) != 1:
+ non_muted_strips = [strip for strip in track.strips if strip.action is not None and strip.mute is False]
+ if track.strips is None or len(non_muted_strips) != 1:
continue
- for strip in track.strips:
+ for strip in non_muted_strips:
blender_actions.append(strip.action)
blender_tracks[strip.action.name] = track.name # Always set after possible active action -> None will be overwrite
@@ -245,4 +247,3 @@ def __get_blender_actions(blender_object: bpy.types.Object,
blender_actions.sort(key = lambda a: a.name.lower())
return [(blender_action, blender_tracks[blender_action.name]) for blender_action in blender_actions]
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_cache.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_cache.py
index 4efd08f3..e82d5929 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_cache.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_cache.py
@@ -69,6 +69,13 @@ def cached(func):
def bonecache(func):
+ def reset_cache_bonecache():
+ func.__current_action_name = None
+ func.__current_armature_name = None
+ func.__bonecache = {}
+
+ func.reset_cache = reset_cache_bonecache
+
@functools.wraps(func)
def wrapper_bonecache(*args, **kwargs):
if args[2] is None:
@@ -78,9 +85,7 @@ def bonecache(func):
pose_bone_if_armature = args[0].pose.bones[args[2]]
if not hasattr(func, "__current_action_name"):
- func.__current_action_name = None
- func.__current_armature_name = None
- func.__bonecache = {}
+ func.reset_cache()
if args[6] != func.__current_action_name or args[0] != func.__current_armature_name:
result = func(*args)
func.__bonecache = result
@@ -106,7 +111,6 @@ def skdriverdiscovercache(func):
@functools.wraps(func)
def wrapper_skdriverdiscover(*args, **kwargs):
if not hasattr(func, "__current_armature_name") or func.__current_armature_name is None:
- func.__current_armature_name = None
func.reset_cache()
if args[0] != func.__current_armature_name:
@@ -139,4 +143,3 @@ def skdrivervalues(func):
else:
return func.__skdrivervalues[args[0].name][args[1]]
return wrapper_skdrivervalues
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_cameras.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_cameras.py
index 6075440c..c9926392 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_cameras.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_cameras.py
@@ -119,4 +119,3 @@ def __gather_type(blender_camera, export_settings):
elif blender_camera.type == 'ORTHO':
return "orthographic"
return None
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py
index a2ab949b..b176ca45 100644
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_drivers.py
@@ -27,6 +27,9 @@ def get_sk_drivers(blender_armature):
for child in blender_armature.children:
if not child.data:
continue
+ # child.data can be an armature - which has no shapekeys
+ if not hasattr(child.data, 'shape_keys'):
+ continue
if not child.data.shape_keys:
continue
if not child.data.shape_keys.animation_data:
@@ -71,4 +74,3 @@ def get_sk_driver_values(blender_object, frame, fcurves):
sk_values.append(blender_object.data.shape_keys.path_resolve(get_target_object_path(f.data_path)).value)
return tuple(sk_values)
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py
index f6a9ef94..c389ba19 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_image.py
@@ -240,4 +240,3 @@ def __get_texname_from_slot(sockets_or_slots, export_settings):
elif isinstance(sockets_or_slots[0], bpy.types.MaterialTextureSlot):
return sockets_or_slots[0].texture.image.name
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py
index dce70c31..6b693575 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_joints.py
@@ -81,4 +81,3 @@ def gather_joint(blender_bone, export_settings):
translation=translation,
weights=None
)
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_light_spots.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_light_spots.py
index b2ab3953..b0b31c1b 100644
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_light_spots.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_light_spots.py
@@ -42,4 +42,3 @@ def __gather_inner_cone_angle(blender_lamp, _) -> Optional[float]:
def __gather_outer_cone_angle(blender_lamp, _) -> Optional[float]:
return blender_lamp.spot_size * 0.5
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py
index 05284163..572533d7 100644
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_lights.py
@@ -133,4 +133,3 @@ def __get_cycles_emission_node(blender_lamp) -> Optional[bpy.types.ShaderNodeEmi
continue
return result[0].shader_node
return None
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_material_normal_texture_info_class.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_material_normal_texture_info_class.py
index 4a46814c..b554717b 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_material_normal_texture_info_class.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_material_normal_texture_info_class.py
@@ -145,4 +145,3 @@ def __get_tex_from_socket(socket):
if result[0].shader_node.image is None:
return None
return result[0]
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_material_occlusion_texture_info_class.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_material_occlusion_texture_info_class.py
index da603bdf..671a41f4 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_material_occlusion_texture_info_class.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_material_occlusion_texture_info_class.py
@@ -135,4 +135,3 @@ def __get_tex_from_socket(socket):
if result[0].shader_node.image is None:
return None
return result[0]
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py
index fceb46f1..35028e5b 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials.py
@@ -217,4 +217,3 @@ def __has_image_node_from_socket(socket):
if not result:
return False
return True
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py
index 3b2c0055..e774bfef 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_materials_pbr_metallic_roughness.py
@@ -173,4 +173,3 @@ def __has_image_node_from_socket(socket):
if not result:
return False
return True
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py
index 6a381c8f..1e155ffd 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_mesh.py
@@ -158,4 +158,3 @@ def __gather_weights(blender_mesh: bpy.types.Mesh,
weights.append(blender_shape_key.value)
return weights
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
index 21b99459..2eaf56f5 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_nodes.py
@@ -29,6 +29,7 @@ from ..com.gltf2_blender_extras import generate_extras
from io_scene_gltf2.io.com import gltf2_io
from io_scene_gltf2.io.com import gltf2_io_extensions
from io_scene_gltf2.io.exp.gltf2_io_user_extensions import export_user_extensions
+from io_scene_gltf2.io.com.gltf2_io_debug import print_console
def gather_node(blender_object, blender_scene, export_settings):
@@ -188,7 +189,10 @@ def __gather_children(blender_object, blender_scene, export_settings):
if trans is None:
trans = [0, 0, 0]
# bones go down their local y axis
- bone_tail = [0, blender_bone.length / blender_bone.matrix.to_scale()[1], 0]
+ if blender_bone.matrix.to_scale()[1] >= 1e-6:
+ bone_tail = [0, blender_bone.length / blender_bone.matrix.to_scale()[1], 0]
+ else:
+ bone_tail = [0,0,0] # If scale is 0, tail == head
child_node.translation = [trans[idx] + bone_tail[idx] for idx in range(3)]
parent_joint.children.append(child_node)
@@ -341,7 +345,19 @@ def __gather_trans_rot_scale(blender_object, export_settings):
else:
# matrix_local = matrix_parent_inverse*location*rotation*scale
# Decomposing matrix_local gives less accuracy, but is needed if matrix_parent_inverse is not the identity.
- trans, rot, sca = gltf2_blender_extract.decompose_transition(blender_object.matrix_local, export_settings)
+
+
+ if blender_object.matrix_local[3][3] != 0.0:
+ trans, rot, sca = gltf2_blender_extract.decompose_transition(blender_object.matrix_local, export_settings)
+ else:
+ # Some really weird cases, scale is null (if parent is null when evaluation is done)
+ print_console('WARNING', 'Some nodes are 0 scaled during evaluation. Result can be wrong')
+ trans = blender_object.location
+ if blender_object.rotation_mode in ['QUATERNION', 'AXIS_ANGLE']:
+ rot = blender_object.rotation_quaternion
+ else:
+ rot = blender_object.rotation_euler.to_quaternion()
+ sca = blender_object.scale
trans = gltf2_blender_extract.convert_swizzle_location(trans, None, None, export_settings)
rot = gltf2_blender_extract.convert_swizzle_rotation(rot, export_settings)
@@ -410,4 +426,3 @@ def __get_correction_node(blender_object, export_settings):
translation=None,
weights=None
)
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py
index 87637b91..f5856257 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitive_attributes.py
@@ -223,4 +223,3 @@ def __gather_skins(blender_primitive, export_settings):
joint_id = 'JOINTS_' + str(bone_set_index)
weight_id = 'WEIGHTS_' + str(bone_set_index)
return attributes
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
index b146928c..db1115d0 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_primitives.py
@@ -232,4 +232,3 @@ def __gather_targets(blender_primitive, blender_mesh, modifiers, export_settings
morph_index += 1
return targets
return None
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_sampler.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_sampler.py
index 80b74e9c..a7d44d71 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_sampler.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_sampler.py
@@ -100,4 +100,3 @@ def gather_sampler_from_texture_slot(blender_texture: bpy.types.TextureSlot, exp
wrap_s=wrap,
wrap_t=wrap
)
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py
index 1ee54b89..2513b073 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_skins.py
@@ -189,4 +189,3 @@ def get_bone_tree(blender_dummy, blender_object):
list_ = list(set(bones))
root_ = list(set(root_bones))
return [blender_object.data.bones[b] for b in list_], children, [blender_object.pose.bones[b] for b in root_]
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_texture.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_texture.py
index b906413f..13292a5a 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_texture.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_texture.py
@@ -106,4 +106,3 @@ def __get_tex_from_socket(socket):
if not result:
return None
return result[0]
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gather_texture_info.py b/io_scene_gltf2/blender/exp/gltf2_blender_gather_texture_info.py
index 66b9b4eb..430dbda8 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gather_texture_info.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gather_texture_info.py
@@ -141,4 +141,3 @@ def __get_tex_from_socket(socket):
if result[0].shader_node.image is None:
return None
return result[0]
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_get.py b/io_scene_gltf2/blender/exp/gltf2_blender_get.py
index fd7d4222..3cee76b4 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_get.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_get.py
@@ -75,10 +75,6 @@ def get_socket_or_texture_slot(blender_material: bpy.types.Material, name: str):
inputs = sum([[input for input in node.inputs if input.name == name] for node in nodes], [])
if inputs:
return inputs[0]
- else:
-
-
- pass
return None
@@ -222,4 +218,3 @@ def get_node(data_path):
return None
return node_name[:(index)]
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_gltf2_exporter.py b/io_scene_gltf2/blender/exp/gltf2_blender_gltf2_exporter.py
index 2c44a018..c94abc5e 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_gltf2_exporter.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_gltf2_exporter.py
@@ -328,4 +328,3 @@ def _path_to_uri(path):
path = os.path.normpath(path)
path = path.replace(os.sep, '/')
return urllib.parse.quote(path)
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_image.py b/io_scene_gltf2/blender/exp/gltf2_blender_image.py
index 30f913f8..145e1ed9 100644
--- a/io_scene_gltf2/blender/exp/gltf2_blender_image.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_image.py
@@ -340,4 +340,3 @@ def _render_temp_scene(
with open(tmpfilename, "rb") as f:
return f.read()
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_search_node_tree.py b/io_scene_gltf2/blender/exp/gltf2_blender_search_node_tree.py
index 6647abec..4edfc918 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_search_node_tree.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_search_node_tree.py
@@ -99,4 +99,3 @@ def from_socket(start_socket: bpy.types.NodeSocket,
return []
return __search_from_socket(start_socket, shader_node_filter, [])
-
diff --git a/io_scene_gltf2/blender/exp/gltf2_blender_utils.py b/io_scene_gltf2/blender/exp/gltf2_blender_utils.py
index c3e0d6ee..8d5baae7 100755
--- a/io_scene_gltf2/blender/exp/gltf2_blender_utils.py
+++ b/io_scene_gltf2/blender/exp/gltf2_blender_utils.py
@@ -65,4 +65,3 @@ def min_components(l: list, data_type: gltf2_io_constants.DataType) -> list:
for i, c in enumerate(components):
result[i] = min(result[i], c)
return result
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py
index f684a641..7669d986 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_pbrSpecularGlossiness.py
@@ -162,4 +162,3 @@ def copy_socket(mh, copy_from, copy_to):
copy_to.default_value = copy_from.default_value
for link in copy_from.links:
mh.node_tree.links.new(copy_to, link.from_socket)
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_unlit.py b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_unlit.py
index 1d3cc0c2..f1a8fefe 100644
--- a/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_unlit.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_KHR_materials_unlit.py
@@ -53,4 +53,3 @@ def unlit(mh):
color_socket=emission_node.inputs['Color'],
alpha_socket=alpha_socket,
)
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_animation.py b/io_scene_gltf2/blender/imp/gltf2_blender_animation.py
index ed1d938d..71f3ec00 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_animation.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_animation.py
@@ -59,4 +59,3 @@ class BlenderAnimation():
for child in gltf.vnodes[vnode_id].children:
BlenderAnimation.restore_animation(gltf, child, animation_name)
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py b/io_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py
index 7e32487c..62c179c1 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_animation_bone.py
@@ -20,8 +20,8 @@ from ...io.imp.gltf2_io_binary import BinaryData
from .gltf2_blender_animation_utils import simulate_stash, make_fcurve
-# The glTF curves store the value of the final transform, but in Blender
-# curves animate a pose bone that is relative to the edit bone
+# In Blender we animate a pose bone. The final TRS of the bone depends on
+# both the edit bone and pose bone
#
# Final = EditBone * PoseBone
# where
@@ -29,7 +29,7 @@ from .gltf2_blender_animation_utils import simulate_stash, make_fcurve
# EditBone = Trans[et] Rot[er] (edit bones have no scale)
# PoseBone = Trans[pt] Rot[pr] Scale[ps]
#
-# Solving for the PoseBone gives the change we need to apply to the curves
+# Given Final we can solve for the PoseBone we need to use with
#
# pt = Rot[er^{-1}] (ft - et)
# pr = er^{-1} fr
@@ -58,18 +58,18 @@ class BlenderBoneAnim():
else:
translation_keyframes = (gltf.loc_gltf_to_blender(vals) for vals in values)
- bind_trans, bind_rot, _ = vnode.trs
- bind_rot_inv = bind_rot.conjugated()
-
- final_translations = [
- bind_rot_inv @ (trans - bind_trans)
+ # Calculate pose bone trans from final bone trans
+ edit_trans, edit_rot = vnode.editbone_trans, vnode.editbone_rot
+ edit_rot_inv = edit_rot.conjugated()
+ pose_translations = [
+ edit_rot_inv @ (trans - edit_trans)
for trans in translation_keyframes
]
BlenderBoneAnim.fill_fcurves(
obj.animation_data.action,
keys,
- final_translations,
+ pose_translations,
group_name,
blender_path,
animation.samplers[channel.sampler].interpolation
@@ -93,24 +93,23 @@ class BlenderBoneAnim():
else:
quat_keyframes = [gltf.quaternion_gltf_to_blender(vals) for vals in values]
- _, bind_rot, _ = vnode.trs
- bind_rot_inv = bind_rot.conjugated()
-
-
- final_rots = [
- bind_rot_inv @ rot
+ # Calculate pose bone rotation from final bone rotation
+ edit_rot = vnode.editbone_rot
+ edit_rot_inv = edit_rot.conjugated()
+ pose_rots = [
+ edit_rot_inv @ rot
for rot in quat_keyframes
]
# Manage antipodal quaternions
- for i in range(1, len(final_rots)):
- if final_rots[i].dot(final_rots[i-1]) < 0:
- final_rots[i] = -final_rots[i]
+ for i in range(1, len(pose_rots)):
+ if pose_rots[i].dot(pose_rots[i-1]) < 0:
+ pose_rots[i] = -pose_rots[i]
BlenderBoneAnim.fill_fcurves(
obj.animation_data.action,
keys,
- final_rots,
+ pose_rots,
group_name,
blender_path,
animation.samplers[channel.sampler].interpolation
@@ -127,17 +126,17 @@ class BlenderBoneAnim():
if animation.samplers[channel.sampler].interpolation == "CUBICSPLINE":
# TODO manage tangent?
- final_scales = [
+ scale_keyframes = [
gltf.scale_gltf_to_blender(values[idx * 3 + 1])
for idx in range(0, len(keys))
]
else:
- final_scales = [gltf.scale_gltf_to_blender(vals) for vals in values]
+ scale_keyframes = [gltf.scale_gltf_to_blender(vals) for vals in values]
BlenderBoneAnim.fill_fcurves(
obj.animation_data.action,
keys,
- final_scales,
+ scale_keyframes,
group_name,
blender_path,
animation.samplers[channel.sampler].interpolation
@@ -179,6 +178,7 @@ class BlenderBoneAnim():
if not action:
name = animation.track_name + "_" + obj.name
action = bpy.data.actions.new(name)
+ action.id_root = 'OBJECT'
gltf.needs_stash.append((obj, animation.track_name, action))
gltf.action_cache[obj.name] = action
@@ -197,4 +197,3 @@ class BlenderBoneAnim():
elif channel.target.path == "scale":
BlenderBoneAnim.parse_scale_channel(gltf, vnode, obj, bone, channel, animation)
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_animation_node.py b/io_scene_gltf2/blender/imp/gltf2_blender_animation_node.py
index 6a0959c2..a0205483 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_animation_node.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_animation_node.py
@@ -49,6 +49,7 @@ class BlenderNodeAnim():
if not action:
name = animation.track_name + "_" + obj.name
action = bpy.data.actions.new(name)
+ action.id_root = 'OBJECT'
gltf.needs_stash.append((obj, animation.track_name, action))
gltf.action_cache[obj.name] = action
@@ -112,4 +113,3 @@ class BlenderNodeAnim():
group_name=group_name,
interpolation=animation.samplers[channel.sampler].interpolation,
)
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_animation_utils.py b/io_scene_gltf2/blender/imp/gltf2_blender_animation_utils.py
index 4feed76a..6c933852 100644
--- a/io_scene_gltf2/blender/imp/gltf2_blender_animation_utils.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_animation_utils.py
@@ -80,4 +80,3 @@ def make_fcurve(action, co, data_path, index=0, group_name=None, interpolation=N
fcurve.update() # force updating tangents (this may change when tangent will be managed)
return fcurve
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_animation_weight.py b/io_scene_gltf2/blender/imp/gltf2_blender_animation_weight.py
index c89e4dfe..1329243d 100644
--- a/io_scene_gltf2/blender/imp/gltf2_blender_animation_weight.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_animation_weight.py
@@ -88,4 +88,3 @@ class BlenderWeightAnim():
group_name="ShapeKeys",
interpolation=animation.samplers[channel.sampler].interpolation,
)
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_camera.py b/io_scene_gltf2/blender/imp/gltf2_blender_camera.py
index 1ed20caf..ffe79b54 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_camera.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_camera.py
@@ -50,4 +50,3 @@ class BlenderCamera():
obj = bpy.data.objects.new(pycamera.name, cam)
return obj
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py b/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py
index 49cbcf64..8e6c1950 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_gltf.py
@@ -96,21 +96,10 @@ class BlenderGlTF():
# Something is wrong in file, there is no nodes
return
- for node_idx, node in enumerate(gltf.data.nodes):
-
+ for node in gltf.data.nodes:
# Weight animation management
node.weight_animation = False
- # skin management
- if node.skin is not None and node.mesh is not None:
- if not hasattr(gltf.data.skins[node.skin], "node_ids"):
- gltf.data.skins[node.skin].node_ids = []
-
- gltf.data.skins[node.skin].node_ids.append(node_idx)
-
- # Lights management
- node.correction_needed = False
-
# Dispatch animation
if gltf.data.animations:
for node_idx, node in enumerate(gltf.data.nodes):
@@ -138,8 +127,7 @@ class BlenderGlTF():
# Meshes
if gltf.data.meshes:
for mesh in gltf.data.meshes:
- mesh.blender_name = {} # cache Blender mesh (keyed by skin_idx)
- mesh.is_weight_animated = False
+ mesh.blender_name = {} # caches Blender mesh name
# Calculate names for each mesh's shapekeys
for mesh in gltf.data.meshes or []:
@@ -191,4 +179,3 @@ class BlenderGlTF():
suffix = '.%03d' % cntr
cntr += 1
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_image.py b/io_scene_gltf2/blender/imp/gltf2_blender_image.py
index c0107c59..0075b7f4 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_image.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_image.py
@@ -74,4 +74,3 @@ class BlenderImage():
def _uri_to_path(uri):
uri = urllib.parse.unquote(uri)
return normpath(uri)
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_light.py b/io_scene_gltf2/blender/imp/gltf2_blender_light.py
index e75864f9..be1c6c40 100644
--- a/io_scene_gltf2/blender/imp/gltf2_blender_light.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_light.py
@@ -90,4 +90,3 @@ class BlenderLight():
spot.spot_blend = 1.0
return obj
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_material.py b/io_scene_gltf2/blender/imp/gltf2_blender_material.py
index c2b48c46..1071f7f1 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_material.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_material.py
@@ -91,4 +91,3 @@ class BlenderMaterial():
color = pbr.base_color_factor or [1, 1, 1, 1]
mat.diffuse_color = color
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_material_utils.py b/io_scene_gltf2/blender/imp/gltf2_blender_material_utils.py
deleted file mode 100644
index 1d2664ef..00000000
--- a/io_scene_gltf2/blender/imp/gltf2_blender_material_utils.py
+++ /dev/null
@@ -1,149 +0,0 @@
-# Copyright 2018-2019 The glTF-Blender-IO authors.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import bpy
-from .gltf2_blender_image import BlenderImage
-from ..com.gltf2_blender_conversion import texture_transform_gltf_to_blender
-from io_scene_gltf2.io.com.gltf2_io import Sampler
-from io_scene_gltf2.io.com.gltf2_io_debug import print_console
-from io_scene_gltf2.io.com.gltf2_io_constants import TextureFilter, TextureWrap
-
-def make_texture_block(gltf, node_tree, tex_info, location, label, name=None, colorspace=None):
- """Creates a block of Shader Nodes for the given TextureInfo.
- Will look like this:
- [UV Map] -> [Mapping] -> [Image Texture]
- The [Image Texture] node is placed at the given location.
- The [Image Texture] node is given the given label.
- The [Image Texture] node is returned.
- """
- # Image Texture (samples image)
-
- tex_img = node_tree.nodes.new('ShaderNodeTexImage')
- if name:
- tex_img.name = name + '.tex_img'
- tex_img.location = location
- tex_img.label = label
-
- pytexture = gltf.data.textures[tex_info.index]
-
- if pytexture.source is not None:
- BlenderImage.create(gltf, pytexture.source)
- pyimg = gltf.data.images[pytexture.source]
- blender_image_name = pyimg.blender_image_name
- if blender_image_name:
- tex_img.image = bpy.data.images[blender_image_name]
-
- if colorspace == 'NONE':
- if tex_img.image:
- tex_img.image.colorspace_settings.is_data = True
-
- if pytexture.sampler is not None:
- pysampler = gltf.data.samplers[pytexture.sampler]
- else:
- pysampler = Sampler.from_dict({})
- set_filtering(tex_img, pysampler)
- set_wrap_mode(tex_img, pysampler)
-
- # Mapping (transforms UVs for KHR_texture_transform)
-
- mapping = node_tree.nodes.new('ShaderNodeMapping')
- if name:
- mapping.name = name + '.mapping'
- mapping.location = location[0] - 500, location[1]
- mapping.vector_type = 'POINT'
-
- if tex_info.extensions and 'KHR_texture_transform' in tex_info.extensions:
- transform = tex_info.extensions['KHR_texture_transform']
- transform = texture_transform_gltf_to_blender(transform)
- mapping.inputs['Location'].default_value[0] = transform['offset'][0]
- mapping.inputs['Location'].default_value[1] = transform['offset'][1]
- mapping.inputs['Rotation'].default_value[2] = transform['rotation']
- mapping.inputs['Scale'].default_value[0] = transform['scale'][0]
- mapping.inputs['Scale'].default_value[1] = transform['scale'][1]
-
- # UV Map (retrieves UV)
-
- uv_map = node_tree.nodes.new('ShaderNodeUVMap')
- if name:
- uv_map.name = name + '.uv_map'
- uv_map.location = location[0] - 1000, location[1]
-
- texcoord_idx = tex_info.tex_coord or 0
- if tex_info.extensions and 'KHR_texture_transform' in tex_info.extensions:
- if 'texCoord' in tex_info.extensions['KHR_texture_transform']:
- texcoord_idx = tex_info.extensions['KHR_texture_transform']['texCoord']
-
- uv_map.uv_map = 'UVMap' if texcoord_idx == 0 else 'UVMap.%03d' % texcoord_idx
-
- # Links
- node_tree.links.new(mapping.inputs[0], uv_map.outputs[0])
- node_tree.links.new(tex_img.inputs[0], mapping.outputs[0])
-
- return tex_img
-
-def set_filtering(tex_img, pysampler):
- """Set the filtering/interpolation on an Image Texture from the glTf sampler."""
- minf = pysampler.min_filter
- magf = pysampler.mag_filter
-
- # Ignore mipmapping
- if minf in [TextureFilter.NearestMipmapNearest, TextureFilter.NearestMipmapLinear]:
- minf = TextureFilter.Nearest
- elif minf in [TextureFilter.LinearMipmapNearest, TextureFilter.LinearMipmapLinear]:
- minf = TextureFilter.Linear
-
- # If both are nearest or the only specified one was nearest, use nearest.
- if (minf, magf) in [
- (TextureFilter.Nearest, TextureFilter.Nearest),
- (TextureFilter.Nearest, None),
- (None, TextureFilter.Nearest),
- ]:
- tex_img.interpolation = 'Closest'
- else:
- tex_img.interpolation = 'Linear'
-
-def set_wrap_mode(tex_img, pysampler):
- """Set the extension on an Image Texture node from the pysampler."""
- wrap_s = pysampler.wrap_s
- wrap_t = pysampler.wrap_t
-
- if wrap_s is None:
- wrap_s = TextureWrap.Repeat
- if wrap_t is None:
- wrap_t = TextureWrap.Repeat
-
- # The extension property on the Image Texture node can only handle the case
- # where both directions are the same and are either REPEAT or CLAMP_TO_EDGE.
- if (wrap_s, wrap_t) == (TextureWrap.Repeat, TextureWrap.Repeat):
- extension = TextureWrap.Repeat
- elif (wrap_s, wrap_t) == (TextureWrap.ClampToEdge, TextureWrap.ClampToEdge):
- extension = TextureWrap.ClampToEdge
- else:
- print_console('WARNING',
- 'texture wrap mode unsupported: (%s, %s)' % (wrap_name(wrap_s), wrap_name(wrap_t)),
- )
- # Default to repeat
- extension = TextureWrap.Repeat
-
- if extension == TextureWrap.Repeat:
- tex_img.extension = 'REPEAT'
- elif extension == TextureWrap.ClampToEdge:
- tex_img.extension = 'EXTEND'
-
-def wrap_name(wrap):
- if wrap == TextureWrap.ClampToEdge: return 'CLAMP_TO_EDGE'
- if wrap == TextureWrap.MirroredRepeat: return 'MIRRORED_REPEAT'
- if wrap == TextureWrap.Repeat: return 'REPEAT'
- return 'UNKNOWN (%s)' % wrap
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py b/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
index 05a443a7..adf05281 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_mesh.py
@@ -75,24 +75,12 @@ class BlenderMesh():
set_extras(mesh, pymesh.extras, exclude=['targetNames'])
- pymesh.blender_name[skin_idx] = mesh.name
-
# Clear accessor cache after all primitives are done
gltf.accessor_cache = {}
return mesh
@staticmethod
- def set_mesh(gltf, pymesh, obj):
- """Sets mesh data after creation."""
- # set default weights for shape keys, and names, if not set by convention on extras data
- if pymesh.weights is not None:
- for i in range(len(pymesh.weights)):
- if pymesh.shapekey_names[i] is None: # No default value if shapekeys was not created
- continue
- obj.data.shape_keys.key_blocks[pymesh.shapekey_names[i]].value = pymesh.weights[i]
-
- @staticmethod
def bmesh_to_mesh(gltf, pymesh, bme, mesh):
bme.to_mesh(mesh)
@@ -157,4 +145,3 @@ class BlenderMesh():
custom_normals = [v.normal for v in bme.verts]
mesh.normals_split_custom_set_from_vertices(custom_normals)
mesh.use_auto_smooth = True
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_node.py b/io_scene_gltf2/blender/imp/gltf2_blender_node.py
index 8f138251..d1ffdbe9 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_node.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_node.py
@@ -134,7 +134,7 @@ class BlenderNode():
editbone.use_connect = False # TODO?
# Give the position of the bone in armature space
- arma_mat = vnode.bone_arma_mat
+ arma_mat = vnode.editbone_arma_mat
editbone.head = arma_mat @ Vector((0, 0, 0))
editbone.tail = arma_mat @ Vector((0, 1, 0))
editbone.align_roll(arma_mat @ Vector((0, 0, 1)) - editbone.head)
@@ -159,8 +159,13 @@ class BlenderNode():
vnode = gltf.vnodes[id]
pose_bone = blender_arma.pose.bones[vnode.blender_bone_name]
- # Put scale on pose bone (edit bones have no scale)
- _, _, s = vnode.trs
+ # BoneTRS = EditBone * PoseBone
+ # Set PoseBone to make BoneTRS = vnode.trs.
+ t, r, s = vnode.trs
+ et, er = vnode.editbone_trans, vnode.editbone_rot
+ pose_bone.location = er.conjugated() @ (t - et)
+ pose_bone.rotation_mode = 'QUATERNION'
+ pose_bone.rotation_quaternion = er.conjugated() @ r
pose_bone.scale = s
if isinstance(id, int):
@@ -169,40 +174,42 @@ class BlenderNode():
@staticmethod
def create_mesh_object(gltf, pynode, name):
- instance = False
- if gltf.data.meshes[pynode.mesh].blender_name.get(pynode.skin) is not None:
- # Mesh is already created, only create instance
- # Except is current node is animated with path weight
- # Or if previous instance is animation at node level
- if pynode.weight_animation is True:
- instance = False
- else:
- if gltf.data.meshes[pynode.mesh].is_weight_animated is True:
- instance = False
- else:
- instance = True
- mesh = bpy.data.meshes[gltf.data.meshes[pynode.mesh].blender_name[pynode.skin]]
-
- if instance is False:
- if pynode.name:
- gltf.log.info("Blender create Mesh node " + pynode.name)
+ pymesh = gltf.data.meshes[pynode.mesh]
+ name = pymesh.name or name
+
+ # Key to cache the Blender mesh by.
+ # Same cache key = instances of the same Blender mesh.
+ cache_key = None
+ if not pymesh.shapekey_names:
+ cache_key = (pynode.skin,)
+ else:
+ # Unlike glTF, all instances of a Blender mesh share shapekeys.
+ # So two instances that might have different morph weights need
+ # different cache keys.
+ if pynode.weight_animation is False:
+ cache_key = (pynode.skin, tuple(pynode.weights or []))
else:
- gltf.log.info("Blender create Mesh node")
+ cache_key = None # don't use the cache at all
+ if cache_key is not None and cache_key in pymesh.blender_name:
+ mesh = bpy.data.meshes[pymesh.blender_name[cache_key]]
+ else:
+ gltf.log.info("Blender create Mesh node %s", name)
mesh = BlenderMesh.create(gltf, pynode.mesh, pynode.skin)
-
- if pynode.weight_animation is True:
- # flag this mesh instance as created only for this node, because of weight animation
- gltf.data.meshes[pynode.mesh].is_weight_animated = True
-
- mesh_name = gltf.data.meshes[pynode.mesh].name
- if not name and mesh_name:
- name = mesh_name
+ if cache_key is not None:
+ pymesh.blender_name[cache_key] = mesh.name
obj = bpy.data.objects.new(name, mesh)
- if instance == False:
- BlenderMesh.set_mesh(gltf, gltf.data.meshes[pynode.mesh], obj)
+ if pymesh.shapekey_names:
+ BlenderNode.set_morph_weights(gltf, pynode, obj)
return obj
+ @staticmethod
+ def set_morph_weights(gltf, pynode, obj):
+ pymesh = gltf.data.meshes[pynode.mesh]
+ weights = pynode.weights or pymesh.weights or []
+ for i, weight in enumerate(weights):
+ if pymesh.shapekey_names[i] is not None:
+ obj.data.shape_keys.key_blocks[pymesh.shapekey_names[i]].value = weight
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_pbrMetallicRoughness.py b/io_scene_gltf2/blender/imp/gltf2_blender_pbrMetallicRoughness.py
index 4ea5f28c..a4910fa0 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_pbrMetallicRoughness.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_pbrMetallicRoughness.py
@@ -46,28 +46,25 @@ def pbr_metallic_roughness(mh: MaterialHelper):
pbr_node = mh.node_tree.nodes.new('ShaderNodeBsdfPrincipled')
pbr_node.location = 10, 300
- # Create material output.
- # TODO: when the exporter can understand them, use the emission/alpha
- # socket on the Principled node instead
- emission_socket, alpha_socket = make_output_nodes(
+ make_output_nodes(
mh,
location=(250, 260),
shader_socket=pbr_node.outputs[0],
- make_emission_socket=mh.needs_emissive(),
- make_alpha_socket=not mh.is_opaque(),
+ make_emission_socket=False,
+ make_alpha_socket=False,
)
emission(
mh,
location=(-200, 860),
- color_socket=emission_socket,
+ color_socket=pbr_node.inputs['Emission'],
)
base_color(
mh,
location=(-200, 380),
color_socket=pbr_node.inputs['Base Color'],
- alpha_socket=alpha_socket,
+ alpha_socket=pbr_node.inputs['Alpha'] if not mh.is_opaque() else None,
)
metallic_roughness(
@@ -487,4 +484,3 @@ def get_settings_group():
gltf_node_group_input = gltf_node_group.nodes.new('NodeGroupInput')
gltf_node_group_input.location = -200, 0
return gltf_node_group
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_primitive.py b/io_scene_gltf2/blender/imp/gltf2_blender_primitive.py
index ff654f18..07030a62 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_primitive.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_primitive.py
@@ -78,8 +78,8 @@ class BlenderPrimitive():
inv_binds = [gltf.matrix_gltf_to_blender(m) for m in inv_binds]
else:
inv_binds = [Matrix.Identity(4) for i in range(len(pyskin.joints))]
- arma_mats = [gltf.vnodes[joint].bone_arma_mat for joint in pyskin.joints]
- joint_mats = [arma_mat @ inv_bind for arma_mat, inv_bind in zip(arma_mats, inv_binds)]
+ bind_mats = [gltf.vnodes[joint].bind_arma_mat for joint in pyskin.joints]
+ joint_mats = [bind_mat @ inv_bind for bind_mat, inv_bind in zip(bind_mats, inv_binds)]
def skin_vert(pos, pidx):
out = Vector((0, 0, 0))
@@ -196,13 +196,7 @@ class BlenderPrimitive():
colors = BinaryData.get_data_from_accessor(gltf, attributes['COLOR_%d' % set_num], cache=True)
- # Check whether Blender takes RGB or RGBA colors (old versions only take RGB)
is_rgba = len(colors[0]) == 4
- blender_num_components = len(bme_verts[0].link_loops[0][layer])
- if is_rgba and blender_num_components == 3:
- gltf2_io_debug.print_console("WARNING",
- "this Blender doesn't support RGBA vertex colors; dropping A"
- )
for bidx, pidx in vert_idxs:
color = colors[pidx]
@@ -211,7 +205,7 @@ class BlenderPrimitive():
color_linear_to_srgb(color[1]),
color_linear_to_srgb(color[2]),
color[3] if is_rgba else 1.0,
- )[:blender_num_components]
+ )
for loop in bme_verts[bidx].link_loops:
loop[layer] = col
@@ -350,4 +344,3 @@ class BlenderPrimitive():
raise Exception('primitive mode unimplemented: %d' % mode)
return es, fs
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_scene.py b/io_scene_gltf2/blender/imp/gltf2_blender_scene.py
index ca2f8052..3c2a8619 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_scene.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_scene.py
@@ -91,4 +91,3 @@ class BlenderScene():
vnode = gltf.vnodes[vnode.children[0]]
bpy.context.view_layer.objects.active = vnode.blender_object
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_skin.py b/io_scene_gltf2/blender/imp/gltf2_blender_skin.py
index a9c50b58..043d8f26 100755
--- a/io_scene_gltf2/blender/imp/gltf2_blender_skin.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_skin.py
@@ -53,4 +53,3 @@ class BlenderSkin():
obj = vnode.blender_object
mod = obj.modifiers.new(name="Armature", type="ARMATURE")
mod.object = arma.blender_object
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_texture.py b/io_scene_gltf2/blender/imp/gltf2_blender_texture.py
index a0f90ddf..678fd2af 100644
--- a/io_scene_gltf2/blender/imp/gltf2_blender_texture.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_texture.py
@@ -64,10 +64,16 @@ def texture(
x -= 340
# UV Transform (for KHR_texture_transform)
- mapping = mh.node_tree.nodes.new('ShaderNodeMapping')
- mapping.location = x - 160, y + 30
- mapping.vector_type = 'POINT'
- if tex_info.extensions and 'KHR_texture_transform' in tex_info.extensions:
+ needs_tex_transform = 'KHR_texture_transform' in (tex_info.extensions or {})
+ if needs_tex_transform:
+ mapping = mh.node_tree.nodes.new('ShaderNodeMapping')
+ mapping.location = x - 160, y + 30
+ mapping.vector_type = 'POINT'
+ # Outputs
+ mh.node_tree.links.new(uv_socket, mapping.outputs[0])
+ # Inputs
+ uv_socket = mapping.inputs[0]
+
transform = tex_info.extensions['KHR_texture_transform']
transform = texture_transform_gltf_to_blender(transform)
mapping.inputs['Location'].default_value[0] = transform['offset'][0]
@@ -75,25 +81,21 @@ def texture(
mapping.inputs['Rotation'].default_value[2] = transform['rotation']
mapping.inputs['Scale'].default_value[0] = transform['scale'][0]
mapping.inputs['Scale'].default_value[1] = transform['scale'][1]
- # Outputs
- mh.node_tree.links.new(uv_socket, mapping.outputs[0])
- # Inputs
- uv_socket = mapping.inputs[0]
- x -= 260
+ x -= 260
# UV Map
- uv_map = mh.node_tree.nodes.new('ShaderNodeUVMap')
- uv_map.location = x - 160, y - 70
- # Get UVMap
uv_idx = tex_info.tex_coord or 0
try:
uv_idx = tex_info.extensions['KHR_texture_transform']['texCoord']
except Exception:
pass
- uv_map.uv_map = 'UVMap' if uv_idx == 0 else 'UVMap.%03d' % uv_idx
- # Outputs
- mh.node_tree.links.new(uv_socket, uv_map.outputs[0])
+ if uv_idx != 0 or needs_tex_transform:
+ uv_map = mh.node_tree.nodes.new('ShaderNodeUVMap')
+ uv_map.location = x - 160, y - 70
+ uv_map.uv_map = 'UVMap' if uv_idx == 0 else 'UVMap.%03d' % uv_idx
+ # Outputs
+ mh.node_tree.links.new(uv_socket, uv_map.outputs[0])
def set_filtering(tex_img, pysampler):
"""Set the filtering/interpolation on an Image Texture from the glTf sampler."""
@@ -149,4 +151,3 @@ def wrap_name(wrap):
if wrap == TextureWrap.MirroredRepeat: return 'MIRRORED_REPEAT'
if wrap == TextureWrap.Repeat: return 'REPEAT'
return 'UNKNOWN (%s)' % wrap
-
diff --git a/io_scene_gltf2/blender/imp/gltf2_blender_vnode.py b/io_scene_gltf2/blender/imp/gltf2_blender_vnode.py
index 4e1c6235..bd5edcd1 100644
--- a/io_scene_gltf2/blender/imp/gltf2_blender_vnode.py
+++ b/io_scene_gltf2/blender/imp/gltf2_blender_vnode.py
@@ -25,6 +25,7 @@ def compute_vnodes(gltf):
move_skinned_meshes(gltf)
fixup_multitype_nodes(gltf)
correct_cameras_and_lights(gltf)
+ pick_bind_pose(gltf)
calc_bone_matrices(gltf)
@@ -181,7 +182,7 @@ def move_skinned_meshes(gltf):
* Move a skinned mesh to become a child of the armature that skins it.
Have to ensure the mesh and arma have the same world transform.
* When we do mesh creation, we will also need to put all the verts in
- their rest pose (ie. the pose the edit bones are in)
+ the bind pose in arma space.
"""
ids = list(gltf.vnodes.keys())
for id in ids:
@@ -334,22 +335,46 @@ def correct_cameras_and_lights(gltf):
vnode.light_node_idx = None
+def pick_bind_pose(gltf):
+ """
+ Pick the bind pose for all bones. Skinned meshes will be retargeted onto
+ this bind pose during mesh creation.
+ """
+ for vnode_id in gltf.vnodes:
+ vnode = gltf.vnodes[vnode_id]
+ if vnode.type == VNode.Bone:
+ # For now, use the node TR for bind pose.
+ # TODO: try calculating from inverseBindMatices?
+ vnode.bind_trans = Vector(vnode.trs[0])
+ vnode.bind_rot = Quaternion(vnode.trs[1])
+
+ # Initialize editbones to match bind pose
+ vnode.editbone_trans = Vector(vnode.bind_trans)
+ vnode.editbone_rot = Quaternion(vnode.bind_rot)
+
+
def calc_bone_matrices(gltf):
"""
- Calculate bone_arma_mat, the transformation from bone space to armature
- space for the edit bone, for each bone.
+ Calculate the transformations from bone space to arma space in the bind
+ pose and in the edit bone pose.
"""
def visit(vnode_id): # Depth-first walk
vnode = gltf.vnodes[vnode_id]
if vnode.type == VNode.Bone:
if gltf.vnodes[vnode.parent].type == VNode.Bone:
- parent_arma_mat = gltf.vnodes[vnode.parent].bone_arma_mat
+ parent_bind_mat = gltf.vnodes[vnode.parent].bind_arma_mat
+ parent_editbone_mat = gltf.vnodes[vnode.parent].editbone_arma_mat
else:
- parent_arma_mat = Matrix.Identity(4)
+ parent_bind_mat = Matrix.Identity(4)
+ parent_editbone_mat = Matrix.Identity(4)
- t, r, _ = vnode.trs
+ t, r = vnode.bind_trans, vnode.bind_rot
local_to_parent = Matrix.Translation(t) @ Quaternion(r).to_matrix().to_4x4()
- vnode.bone_arma_mat = parent_arma_mat @ local_to_parent
+ vnode.bind_arma_mat = parent_bind_mat @ local_to_parent
+
+ t, r = vnode.editbone_trans, vnode.editbone_rot
+ local_to_parent = Matrix.Translation(t) @ Quaternion(r).to_matrix().to_4x4()
+ vnode.editbone_arma_mat = parent_editbone_mat @ local_to_parent
for child in vnode.children:
visit(child)
@@ -358,4 +383,3 @@ def calc_bone_matrices(gltf):
# TODO: add pass to rotate/resize bones so they look pretty
-
diff --git a/io_scene_gltf2/io/__init__.py b/io_scene_gltf2/io/__init__.py
index 10973240..50bfd496 100755
--- a/io_scene_gltf2/io/__init__.py
+++ b/io_scene_gltf2/io/__init__.py
@@ -13,4 +13,3 @@
# limitations under the License.
from .imp import *
-
diff --git a/io_scene_gltf2/io/com/gltf2_io.py b/io_scene_gltf2/io/com/gltf2_io.py
index b8c4b9dd..7d70b5fb 100755
--- a/io_scene_gltf2/io/com/gltf2_io.py
+++ b/io_scene_gltf2/io/com/gltf2_io.py
@@ -1220,4 +1220,3 @@ def gltf_from_dict(s):
def gltf_to_dict(x):
return to_class(Gltf, x)
-
diff --git a/io_scene_gltf2/io/com/gltf2_io_color_management.py b/io_scene_gltf2/io/com/gltf2_io_color_management.py
index b1ebdb4a..56b3a246 100644
--- a/io_scene_gltf2/io/com/gltf2_io_color_management.py
+++ b/io_scene_gltf2/io/com/gltf2_io_color_management.py
@@ -34,4 +34,3 @@ def color_linear_to_srgb(c):
return 0.0 if c < 0.0 else c * 12.92
else:
return 1.055 * pow(c, 1.0 / 2.4) - 0.055
-
diff --git a/io_scene_gltf2/io/com/gltf2_io_constants.py b/io_scene_gltf2/io/com/gltf2_io_constants.py
index 9757a2a7..873e004e 100755
--- a/io_scene_gltf2/io/com/gltf2_io_constants.py
+++ b/io_scene_gltf2/io/com/gltf2_io_constants.py
@@ -144,4 +144,3 @@ GLTF_DATA_TYPE_VEC4 = "VEC4"
GLTF_DATA_TYPE_MAT2 = "MAT2"
GLTF_DATA_TYPE_MAT3 = "MAT3"
GLTF_DATA_TYPE_MAT4 = "MAT4"
-
diff --git a/io_scene_gltf2/io/com/gltf2_io_debug.py b/io_scene_gltf2/io/com/gltf2_io_debug.py
index 7cdf864b..51b825a1 100755
--- a/io_scene_gltf2/io/com/gltf2_io_debug.py
+++ b/io_scene_gltf2/io/com/gltf2_io_debug.py
@@ -124,4 +124,3 @@ class Log:
self.hdlr.setFormatter(formatter)
self.logger.addHandler(self.hdlr)
self.logger.setLevel(int(loglevel))
-
diff --git a/io_scene_gltf2/io/com/gltf2_io_extensions.py b/io_scene_gltf2/io/com/gltf2_io_extensions.py
index 2422d205..c807d9e9 100644
--- a/io_scene_gltf2/io/com/gltf2_io_extensions.py
+++ b/io_scene_gltf2/io/com/gltf2_io_extensions.py
@@ -35,4 +35,3 @@ class ChildOfRootExtension(Extension):
"""
self.path = path
super().__init__(name, extension, required)
-
diff --git a/io_scene_gltf2/io/com/gltf2_io_lights_punctual.py b/io_scene_gltf2/io/com/gltf2_io_lights_punctual.py
index 57679d90..b1c48db0 100644
--- a/io_scene_gltf2/io/com/gltf2_io_lights_punctual.py
+++ b/io_scene_gltf2/io/com/gltf2_io_lights_punctual.py
@@ -74,4 +74,3 @@ class Light:
self.extensions)
result["extras"] = self.extras
return result
-
diff --git a/io_scene_gltf2/io/exp/gltf2_io_binary_data.py b/io_scene_gltf2/io/exp/gltf2_io_binary_data.py
index 5661291c..be1fb8b6 100755
--- a/io_scene_gltf2/io/exp/gltf2_io_binary_data.py
+++ b/io_scene_gltf2/io/exp/gltf2_io_binary_data.py
@@ -39,4 +39,3 @@ class BinaryData:
@property
def byte_length(self):
return len(self.data)
-
diff --git a/io_scene_gltf2/io/exp/gltf2_io_buffer.py b/io_scene_gltf2/io/exp/gltf2_io_buffer.py
index 694be11e..c09bfc39 100755
--- a/io_scene_gltf2/io/exp/gltf2_io_buffer.py
+++ b/io_scene_gltf2/io/exp/gltf2_io_buffer.py
@@ -58,4 +58,3 @@ class Buffer:
def clear(self):
self.__data = b""
-
diff --git a/io_scene_gltf2/io/exp/gltf2_io_draco_compression_extension.py b/io_scene_gltf2/io/exp/gltf2_io_draco_compression_extension.py
index 9189be58..5ece3b13 100644
--- a/io_scene_gltf2/io/exp/gltf2_io_draco_compression_extension.py
+++ b/io_scene_gltf2/io/exp/gltf2_io_draco_compression_extension.py
@@ -343,4 +343,3 @@ def __compress_primitive(primitive, dll, export_settings):
dll.destroy_compressor(compressor)
return
-
diff --git a/io_scene_gltf2/io/exp/gltf2_io_export.py b/io_scene_gltf2/io/exp/gltf2_io_export.py
index dcbdcba8..07cf8820 100755
--- a/io_scene_gltf2/io/exp/gltf2_io_export.py
+++ b/io_scene_gltf2/io/exp/gltf2_io_export.py
@@ -117,4 +117,3 @@ def save_gltf(gltf, export_settings, encoder, glb_buffer):
file.close()
return True
-
diff --git a/io_scene_gltf2/io/exp/gltf2_io_image_data.py b/io_scene_gltf2/io/exp/gltf2_io_image_data.py
index a16207e8..c5a87587 100755
--- a/io_scene_gltf2/io/exp/gltf2_io_image_data.py
+++ b/io_scene_gltf2/io/exp/gltf2_io_image_data.py
@@ -53,4 +53,3 @@ class ImageData:
@property
def byte_length(self):
return len(self._data)
-
diff --git a/io_scene_gltf2/io/exp/gltf2_io_user_extensions.py b/io_scene_gltf2/io/exp/gltf2_io_user_extensions.py
index f8f5e883..424713c3 100644
--- a/io_scene_gltf2/io/exp/gltf2_io_user_extensions.py
+++ b/io_scene_gltf2/io/exp/gltf2_io_user_extensions.py
@@ -20,4 +20,3 @@ def export_user_extensions(hook_name, export_settings, gltf2_object, *args):
hook = getattr(extension, hook_name, None)
if hook is not None:
hook(gltf2_object, *args, export_settings)
-
diff --git a/io_scene_gltf2/io/imp/__init__.py b/io_scene_gltf2/io/imp/__init__.py
index d3c53771..15e503a2 100755
--- a/io_scene_gltf2/io/imp/__init__.py
+++ b/io_scene_gltf2/io/imp/__init__.py
@@ -13,4 +13,3 @@
# limitations under the License.
"""IO imp package."""
-
diff --git a/io_scene_gltf2/io/imp/gltf2_io_binary.py b/io_scene_gltf2/io/imp/gltf2_io_binary.py
index 6969465f..8815ed91 100755
--- a/io_scene_gltf2/io/imp/gltf2_io_binary.py
+++ b/io_scene_gltf2/io/imp/gltf2_io_binary.py
@@ -174,4 +174,3 @@ class BinaryData():
return data, image_name
return None, None
-
diff --git a/io_scene_gltf2/io/imp/gltf2_io_gltf.py b/io_scene_gltf2/io/imp/gltf2_io_gltf.py
index 2248ab64..3224a4a1 100755
--- a/io_scene_gltf2/io/imp/gltf2_io_gltf.py
+++ b/io_scene_gltf2/io/imp/gltf2_io_gltf.py
@@ -202,4 +202,3 @@ class glTFImporter():
except Exception:
self.log.error("Couldn't read file: " + path)
return None, None
-
diff --git a/io_scene_obj/__init__.py b/io_scene_obj/__init__.py
index 9c454851..7cd0f72f 100644
--- a/io_scene_obj/__init__.py
+++ b/io_scene_obj/__init__.py
@@ -26,10 +26,11 @@ bl_info = {
"location": "File > Import-Export",
"description": "Import-Export OBJ, Import OBJ mesh, UV's, materials and textures",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/io_scene_obj.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/scene_obj.html",
"support": 'OFFICIAL',
- "category": "Import-Export"}
+ "category": "Import-Export",
+}
if "bpy" in locals():
import importlib
diff --git a/io_scene_x3d/__init__.py b/io_scene_x3d/__init__.py
index 9c50cbab..232ee479 100644
--- a/io_scene_x3d/__init__.py
+++ b/io_scene_x3d/__init__.py
@@ -26,8 +26,8 @@ bl_info = {
"location": "File > Import-Export",
"description": "Import-Export X3D, Import VRML2",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/io_scene_x3d.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/scene_x3d.html",
"category": "Import-Export",
}
diff --git a/io_shape_mdd/__init__.py b/io_shape_mdd/__init__.py
index f934c197..0078b537 100644
--- a/io_shape_mdd/__init__.py
+++ b/io_shape_mdd/__init__.py
@@ -26,10 +26,11 @@ bl_info = {
"location": "File > Import-Export",
"description": "Import-Export MDD as mesh shape keys",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "import_export/shape_mdd.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "import_export/shape_mdd.html",
"support": 'OFFICIAL',
- "category": "Import-Export"}
+ "category": "Import-Export",
+}
if "bpy" in locals():
import importlib
diff --git a/lighting_dynamic_sky.py b/lighting_dynamic_sky.py
index a61b60e3..86fa6c06 100644
--- a/lighting_dynamic_sky.py
+++ b/lighting_dynamic_sky.py
@@ -27,10 +27,10 @@ bl_info = {
"location": "View3D > Sidebar > Create Tab",
"description": "Creates Dynamic Sky for Cycles",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "lighting/dynamic_sky.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "lighting/dynamic_sky.html",
"category": "Lighting",
- }
+}
import bpy
from bpy.props import StringProperty
diff --git a/lighting_tri_lights.py b/lighting_tri_lights.py
index 44a9c8e6..3e864694 100644
--- a/lighting_tri_lights.py
+++ b/lighting_tri_lights.py
@@ -9,9 +9,9 @@ bl_info = {
"description": "Add 3 Point Lighting to Selected / Active Object",
"warning": "",
"tracker_url": "https://developer.blender.org/maniphest/task/edit/form/2/",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "lighting/trilighting.html",
"category": "Lighting",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "lighting/trilighting.html",
}
import bpy
diff --git a/magic_uv/__init__.py b/magic_uv/__init__.py
index 714f852b..c1b78e40 100644
--- a/magic_uv/__init__.py
+++ b/magic_uv/__init__.py
@@ -35,10 +35,10 @@ bl_info = {
"description": "UV Toolset. See Add-ons Preferences for details",
"warning": "",
"support": "COMMUNITY",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "uv/magic_uv.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "uv/magic_uv.html",
"tracker_url": "https://github.com/nutti/Magic-UV",
- "category": "UV"
+ "category": "UV",
}
diff --git a/magic_uv/lib/bglx.py b/magic_uv/lib/bglx.py
index 24200caf..6bc885c6 100644
--- a/magic_uv/lib/bglx.py
+++ b/magic_uv/lib/bglx.py
@@ -272,4 +272,3 @@ def glTexParameteri(target, pname, param):
def glTexEnvi(target, pname, param):
pass
-
diff --git a/materials_library_vx/__init__.py b/materials_library_vx/__init__.py
index 272bc688..eaed03de 100644
--- a/materials_library_vx/__init__.py
+++ b/materials_library_vx/__init__.py
@@ -26,10 +26,11 @@ bl_info = {
"location": "Properties > Material",
"description": "Material Library VX",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "materials/material_library.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "materials/material_library.html",
"tracker_url": "",
- "category": "Material"}
+ "category": "Material",
+}
import bpy
diff --git a/materials_library_vx/categories.txt b/materials_library_vx/categories.txt
index e5970daf..fce9151e 100644
--- a/materials_library_vx/categories.txt
+++ b/materials_library_vx/categories.txt
@@ -68,4 +68,4 @@
"Metallic Paint Clean"
]
]
-] \ No newline at end of file
+]
diff --git a/materials_utils/__init__.py b/materials_utils/__init__.py
index a542a124..9223ac72 100644
--- a/materials_utils/__init__.py
+++ b/materials_utils/__init__.py
@@ -40,9 +40,9 @@ bl_info = {
"location": "View3D > Shift + Q key",
"description": "Menu of material tools (assign, select..) in the 3D View",
"warning": "Beta",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "materials/material_utils.html",
- "category": "Material"
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "materials/material_utils.html",
+ "category": "Material"
}
"""
diff --git a/measureit/__init__.py b/measureit/__init__.py
index 5f80de87..79e41589 100644
--- a/measureit/__init__.py
+++ b/measureit/__init__.py
@@ -32,8 +32,8 @@ bl_info = {
"version": (1, 8, 1),
"blender": (2, 80, 0),
"description": "Tools for measuring objects.",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons"
- "/3d_view/measureit.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons"
+ "/3d_view/measureit.html",
"category": "3D View"
}
diff --git a/measureit/measureit_geometry.py b/measureit/measureit_geometry.py
index 00d12bee..1f314f7f 100644
--- a/measureit/measureit_geometry.py
+++ b/measureit/measureit_geometry.py
@@ -709,6 +709,9 @@ def get_area_and_paint(myvertices, myobj, obverts, region, rv3d, rgba, ms_scale)
else:
return 0.0
+ # Apply world scale
+ totarea *= bpy.context.scene.unit_settings.scale_length
+
return totarea
diff --git a/mesh_auto_mirror.py b/mesh_auto_mirror.py
index c32d5426..8359e58e 100644
--- a/mesh_auto_mirror.py
+++ b/mesh_auto_mirror.py
@@ -14,9 +14,10 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View 3D > Sidebar > Edit Tab > AutoMirror (panel)",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "mesh/auto_mirror.html",
- "category": "Mesh"}
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "mesh/auto_mirror.html",
+ "category": "Mesh",
+}
import bpy
diff --git a/mesh_bsurfaces.py b/mesh_bsurfaces.py
index 10125a77..f1ae463e 100644
--- a/mesh_bsurfaces.py
+++ b/mesh_bsurfaces.py
@@ -24,8 +24,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D EditMode > Sidebar > Edit Tab",
"description": "Modeling and retopology tool",
- "wiki_url": "https://docs.blender.org/manual/nb/dev/addons/"
- "mesh/bsurfaces.html",
+ "doc_url": "https://docs.blender.org/manual/nb/dev/addons/"
+ "mesh/bsurfaces.html",
"category": "Mesh",
}
diff --git a/mesh_f2.py b/mesh_f2.py
index 1f136619..dcea9d38 100644
--- a/mesh_f2.py
+++ b/mesh_f2.py
@@ -29,8 +29,8 @@ bl_info = {
"location": "Editmode > F",
"warning": "",
"description": "Extends the 'Make Edge/Face' functionality",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "mesh/f2.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "mesh/f2.html",
"category": "Mesh",
}
diff --git a/mesh_inset/__init__.py b/mesh_inset/__init__.py
index e54a91ce..4dbd8472 100644
--- a/mesh_inset/__init__.py
+++ b/mesh_inset/__init__.py
@@ -26,9 +26,10 @@ bl_info = {
"location": "3DView Operator",
"description": "Make an inset inside selection using straight skeleton algorithm.",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "mesh/inset_straight_skeleton.html",
- "category": "Mesh"}
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "mesh/inset_straight_skeleton.html",
+ "category": "Mesh",
+}
if "bpy" in locals():
@@ -199,7 +200,7 @@ class MESH_OT_InsetStraightSkeleton(bpy.types.Operator):
obj = bpy.context.active_object
mesh = obj.data
do_inset(mesh, self.inset_amount, self.inset_height, self.region,
- self.quadrangulate)
+ self.quadrangulate)
bpy.ops.object.editmode_toggle()
bpy.ops.object.editmode_toggle()
@@ -245,7 +246,7 @@ def calc_select_center(context):
center = center / n
world_center = ob.matrix_world @ center
world_center_2d = view3d_utils.location_3d_to_region_2d( \
- context.region, context.region_data, world_center)
+ context.region, context.region_data, world_center)
return (world_center_2d, world_center)
def do_inset(mesh, amount, height, region, quadrangulate):
diff --git a/mesh_looptools.py b/mesh_looptools.py
index 9164a103..3abaacc9 100644
--- a/mesh_looptools.py
+++ b/mesh_looptools.py
@@ -28,8 +28,8 @@ bl_info = {
"location": "View3D > Sidebar > Edit Tab / Edit Mode Context Menu",
"warning": "",
"description": "Mesh modelling toolkit. Several tools to aid modelling",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "mesh/looptools.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "mesh/looptools.html",
"category": "Mesh",
}
diff --git a/mesh_snap_utilities_line/__init__.py b/mesh_snap_utilities_line/__init__.py
index fcdee273..cf620ed8 100644
--- a/mesh_snap_utilities_line/__init__.py
+++ b/mesh_snap_utilities_line/__init__.py
@@ -25,8 +25,9 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D > TOOLS > Line Tool",
"description": "Extends Blender Snap controls",
- "wiki_url" : "https://blenderartists.org/t/cad-snap-utilities",
- "category": "Mesh"}
+ "doc_url" : "https://blenderartists.org/t/cad-snap-utilities",
+ "category": "Mesh",
+}
if "bpy" in locals():
import importlib
diff --git a/mesh_snap_utilities_line/snap_context_l/utils_projection.py b/mesh_snap_utilities_line/snap_context_l/utils_projection.py
index a9b0f021..b941f7db 100644
--- a/mesh_snap_utilities_line/snap_context_l/utils_projection.py
+++ b/mesh_snap_utilities_line/snap_context_l/utils_projection.py
@@ -214,4 +214,3 @@ def intersect_ray_segment_fac(v0, v1, ray_direction, ray_origin):
c = n - t
cray = c.cross(ray_direction)
return cray.dot(n) / nlen
-
diff --git a/mesh_tiny_cad/__init__.py b/mesh_tiny_cad/__init__.py
index ee187180..e6d5d628 100644
--- a/mesh_tiny_cad/__init__.py
+++ b/mesh_tiny_cad/__init__.py
@@ -24,10 +24,10 @@ bl_info = {
"author": "zeffii (aka Dealga McArdle)",
"version": (1, 3, 2),
"blender": (2, 80, 0),
- "category": "Mesh",
"location": "View3D > EditMode Context Menu",
- "wiki_url": "http://zeffii.github.io/mesh_tiny_cad/",
- "tracker_url": "https://github.com/zeffii/mesh_tiny_cad/issues"
+ "doc_url": "http://zeffii.github.io/mesh_tiny_cad/",
+ "tracker_url": "https://github.com/zeffii/mesh_tiny_cad/issues",
+ "category": "Mesh",
}
diff --git a/mesh_tissue/__init__.py b/mesh_tissue/__init__.py
index 90db84d6..34faef58 100644
--- a/mesh_tissue/__init__.py
+++ b/mesh_tissue/__init__.py
@@ -38,9 +38,10 @@ bl_info = {
"location": "Sidebar > Edit Tab",
"description": "Tools for Computational Design",
"warning": "",
- "wiki_url": "https://github.com/alessandro-zomparelli/tissue/wiki",
+ "doc_url": "https://github.com/alessandro-zomparelli/tissue/wiki",
"tracker_url": "https://github.com/alessandro-zomparelli/tissue/issues",
- "category": "Mesh"}
+ "category": "Mesh",
+}
if "bpy" in locals():
diff --git a/mesh_tools/__init__.py b/mesh_tools/__init__.py
index f87b4057..d55ce7e6 100644
--- a/mesh_tools/__init__.py
+++ b/mesh_tools/__init__.py
@@ -29,8 +29,8 @@ bl_info = {
"location": "View3D > Sidebar > Edit Tab / Edit Mode Context Menu",
"warning": "",
"description": "Mesh modelling toolkit. Several tools to aid modelling",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "mesh/edit_mesh_tools.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "mesh/edit_mesh_tools.html",
"category": "Mesh",
}
diff --git a/mesh_tools/mesh_cut_faces.py b/mesh_tools/mesh_cut_faces.py
index a5297c9f..23324f1c 100644
--- a/mesh_tools/mesh_cut_faces.py
+++ b/mesh_tools/mesh_cut_faces.py
@@ -4,7 +4,8 @@ bl_info = {
"version" : (1, 0, 0),
"blender" : (2, 80, 0),
"description" : "Cut Faces and Deselect Boundary operators",
- "category" : "Mesh",}
+ "category" : "Mesh",
+}
import bpy
import bmesh
diff --git a/mesh_tools/mesh_edge_roundifier.py b/mesh_tools/mesh_edge_roundifier.py
index 2d7ed3d3..418d97fd 100644
--- a/mesh_tools/mesh_edge_roundifier.py
+++ b/mesh_tools/mesh_edge_roundifier.py
@@ -18,14 +18,13 @@
bl_info = {
"name": "Edge Roundifier",
- "category": "Mesh",
"author": "Piotr Komisarczyk (komi3D), PKHG",
"version": (1, 0, 2),
"blender": (2, 80, 0),
"location": "SPACE > Edge Roundifier or CTRL-E > "
"Edge Roundifier or Tools > Addons > Edge Roundifier",
"description": "Mesh editing script allowing edge rounding",
- "wiki_url": "",
+ "doc_url": "",
"category": "Mesh"
}
diff --git a/mesh_tools/mesh_edges_floor_plan.py b/mesh_tools/mesh_edges_floor_plan.py
index 1bbd7748..6a303ffb 100644
--- a/mesh_tools/mesh_edges_floor_plan.py
+++ b/mesh_tools/mesh_edges_floor_plan.py
@@ -26,8 +26,9 @@ bl_info = {
"blender": (2, 78, 0),
"location": "View3D > EditMode > Mesh",
"description": "Make a Floor Plan from Edges",
- "wiki_url": "",
- "category": "Mesh"}
+ "doc_url": "",
+ "category": "Mesh",
+}
import bpy
import bmesh
diff --git a/mesh_tools/mesh_edges_length.py b/mesh_tools/mesh_edges_length.py
index 44b415c9..adaee650 100644
--- a/mesh_tools/mesh_edges_length.py
+++ b/mesh_tools/mesh_edges_length.py
@@ -8,9 +8,9 @@ bl_info = {
"blender": (2, 80, 0),
"location": "Toolbar > Tools > Mesh Tools: set Length(Shit+Alt+E)",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Mesh",
- }
+}
import bpy
import bmesh
diff --git a/mesh_tools/mesh_edgetools.py b/mesh_tools/mesh_edgetools.py
index 6fd98b75..b9b61958 100644
--- a/mesh_tools/mesh_edgetools.py
+++ b/mesh_tools/mesh_edgetools.py
@@ -28,9 +28,10 @@ bl_info = {
"location": "View3D > Toolbar and View3D > Specials (W-key)",
"warning": "",
"description": "CAD style edge manipulation tools",
- "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
- "Scripts/Modeling/EdgeTools",
- "category": "Mesh"}
+ "doc_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Modeling/EdgeTools",
+ "category": "Mesh",
+}
import bpy
diff --git a/mesh_tools/mesh_extrude_and_reshape.py b/mesh_tools/mesh_extrude_and_reshape.py
index f4245ac2..ee26cdcd 100644
--- a/mesh_tools/mesh_extrude_and_reshape.py
+++ b/mesh_tools/mesh_extrude_and_reshape.py
@@ -27,9 +27,10 @@ bl_info = {
"location": "View3D > UI > Tools > Mesh Tools > Add: > Extrude Menu (Alt + E)",
"description": "Extrude face and merge edge intersections "
"between the mesh and the new edges",
- "wiki_url": "http://blenderartists.org/forum/"
- "showthread.php?376618-Addon-Push-Pull-Face",
- "category": "Mesh"}
+ "doc_url": "http://blenderartists.org/forum/"
+ "showthread.php?376618-Addon-Push-Pull-Face",
+ "category": "Mesh",
+}
import bpy
import bmesh
diff --git a/mesh_tools/mesh_filletplus.py b/mesh_tools/mesh_filletplus.py
index 01f2f67e..73e62198 100644
--- a/mesh_tools/mesh_filletplus.py
+++ b/mesh_tools/mesh_filletplus.py
@@ -26,8 +26,9 @@ bl_info = {
"location": "View3D > Tool Shelf",
"description": "",
"warning": "",
- "wiki_url": "",
- "category": "Mesh"}
+ "doc_url": "",
+ "category": "Mesh",
+}
import bpy
diff --git a/mesh_tools/mesh_mextrude_plus.py b/mesh_tools/mesh_mextrude_plus.py
index 5fa2aa2b..eea04a51 100644
--- a/mesh_tools/mesh_mextrude_plus.py
+++ b/mesh_tools/mesh_mextrude_plus.py
@@ -30,8 +30,9 @@ bl_info = {
"location": "View3D > Tool Shelf",
"description": "Repeat extrusions from faces to create organic shapes",
"warning": "",
- "wiki_url": "",
- "category": "Mesh"}
+ "doc_url": "",
+ "category": "Mesh",
+}
import bpy
diff --git a/mesh_tools/mesh_offset_edges.py b/mesh_tools/mesh_offset_edges.py
index 5372cb30..1471d256 100644
--- a/mesh_tools/mesh_offset_edges.py
+++ b/mesh_tools/mesh_offset_edges.py
@@ -8,7 +8,7 @@
#
# 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
+# 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
@@ -20,15 +20,16 @@
bl_info = {
"name": "Offset Edges",
"author": "Hidesato Ikeya, Veezen fix 2.8 (temporary)",
- #i tried edit newest version, but got some errors, works only on 0,2,6
+ #i tried edit newest version, but got some errors, works only on 0,2,6
"version": (0, 2, 6),
"blender": (2, 80, 0),
"location": "VIEW3D > Edge menu(CTRL-E) > Offset Edges",
"description": "Offset Edges",
"warning": "",
- "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Modeling/offset_edges",
+ "doc_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Modeling/offset_edges",
"tracker_url": "",
- "category": "Mesh"}
+ "category": "Mesh",
+}
import math
from math import sin, cos, pi, copysign, radians
diff --git a/mesh_tools/mesh_relax.py b/mesh_tools/mesh_relax.py
index 8416ea9a..c646e81b 100644
--- a/mesh_tools/mesh_relax.py
+++ b/mesh_tools/mesh_relax.py
@@ -29,8 +29,8 @@ bl_info = {
"location": "View3D > Edit Mode Context Menu > Relax ",
"description": "Relax the selected verts while retaining the shape",
"warning": "",
- "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
- "Scripts/Modeling/Relax",
+ "doc_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/"
+ "Scripts/Modeling/Relax",
"category": "Mesh",
}
diff --git a/mesh_tools/mesh_vertex_chamfer.py b/mesh_tools/mesh_vertex_chamfer.py
index 9ac3f814..e43d0729 100644
--- a/mesh_tools/mesh_vertex_chamfer.py
+++ b/mesh_tools/mesh_vertex_chamfer.py
@@ -25,8 +25,9 @@ bl_info = {
"blender": (2, 63, 0),
"location": "Spacebar Menu",
"description": "Chamfer vertex",
- "wiki_url": "",
- "category": "Mesh"}
+ "doc_url": "",
+ "category": "Mesh",
+}
import bpy
diff --git a/mesh_tools/pkhg_faces.py b/mesh_tools/pkhg_faces.py
index 2b93d4d7..93a05209 100644
--- a/mesh_tools/pkhg_faces.py
+++ b/mesh_tools/pkhg_faces.py
@@ -8,7 +8,7 @@ bl_info = {
"location": "View3D > Tools > PKHG (tab)",
"description": "Faces selected will become added faces of different style",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Mesh",
}
diff --git a/mesh_tools/random_vertices.py b/mesh_tools/random_vertices.py
index 51f8be24..8025b577 100644
--- a/mesh_tools/random_vertices.py
+++ b/mesh_tools/random_vertices.py
@@ -8,8 +8,9 @@ bl_info = {
"location": "Object > Transform > Random Vertices",
"description": "Randomize selected components of active object",
"warning": "",
- "wiki_url": "",
- "category": "Mesh"}
+ "doc_url": "",
+ "category": "Mesh",
+}
import bpy
diff --git a/mesh_tools/split_solidify.py b/mesh_tools/split_solidify.py
index 690557ed..7158089e 100644
--- a/mesh_tools/split_solidify.py
+++ b/mesh_tools/split_solidify.py
@@ -26,8 +26,9 @@ bl_info = {
"location": "View3D > Tool Shelf",
"description": "",
"warning": "",
- "wiki_url": "",
- "category": "Mesh"}
+ "doc_url": "",
+ "category": "Mesh",
+}
import bpy
import bmesh
diff --git a/mesh_tools/vertex_align.py b/mesh_tools/vertex_align.py
index eb66d747..41d09a71 100644
--- a/mesh_tools/vertex_align.py
+++ b/mesh_tools/vertex_align.py
@@ -28,8 +28,9 @@ bl_info = {
"location": "View3D > Tool Shelf",
"description": "",
"warning": "",
- "wiki_url": "",
- "category": "Mesh"}
+ "doc_url": "",
+ "category": "Mesh",
+}
import bpy
diff --git a/node_arrange.py b/node_arrange.py
index c9c91cda..6d3ed807 100644
--- a/node_arrange.py
+++ b/node_arrange.py
@@ -17,17 +17,17 @@
# ##### END GPL LICENSE BLOCK #####
bl_info = {
- "name": "Node Arrange",
- "author": "JuhaW",
- "version": (0, 2, 2),
- "blender": (2, 80, 4),
- "location": "Node Editor > Properties > Trees",
- "description": "Node Tree Arrangement Tools",
- "warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "node/node_arrange.html",
- "tracker_url": "https://github.com/JuhaW/NodeArrange/issues",
- "category": "Node"
+ "name": "Node Arrange",
+ "author": "JuhaW",
+ "version": (0, 2, 2),
+ "blender": (2, 80, 4),
+ "location": "Node Editor > Properties > Trees",
+ "description": "Node Tree Arrangement Tools",
+ "warning": "",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "node/node_arrange.html",
+ "tracker_url": "https://github.com/JuhaW/NodeArrange/issues",
+ "category": "Node"
}
@@ -129,406 +129,406 @@ class NA_OT_AlignNodes(Operator):
return {'FINISHED'}
class values():
- average_y = 0
- x_last = 0
- margin_x = 100
- mat_name = ""
- margin_y = 20
+ average_y = 0
+ x_last = 0
+ margin_x = 100
+ mat_name = ""
+ margin_y = 20
class NA_PT_NodePanel(Panel):
- bl_label = "Node Arrange"
- bl_space_type = "NODE_EDITOR"
- bl_region_type = "UI"
- bl_category = "Arrange"
-
- def draw(self, context):
- if context.active_node is not None:
- layout = self.layout
- row = layout.row()
- col = layout.column
- row.operator('node.button')
-
- row = layout.row()
- row.prop(bpy.context.scene, 'nodemargin_x', text="Margin x")
- row = layout.row()
- row.prop(bpy.context.scene, 'nodemargin_y', text="Margin y")
- row = layout.row()
- row.prop(context.scene, 'node_center', text="Center nodes")
-
- row = layout.row()
- row.operator('node.na_align_nodes', text="Align to Selected")
-
- row = layout.row()
- node = context.space_data.node_tree.nodes.active
- if node and node.select:
- row.prop(node, 'location', text = "Node X", index = 0)
- row.prop(node, 'location', text = "Node Y", index = 1)
- row = layout.row()
- row.prop(node, 'width', text = "Node width")
-
- row = layout.row()
- row.operator('node.button_odd')
+ bl_label = "Node Arrange"
+ bl_space_type = "NODE_EDITOR"
+ bl_region_type = "UI"
+ bl_category = "Arrange"
+
+ def draw(self, context):
+ if context.active_node is not None:
+ layout = self.layout
+ row = layout.row()
+ col = layout.column
+ row.operator('node.button')
+
+ row = layout.row()
+ row.prop(bpy.context.scene, 'nodemargin_x', text="Margin x")
+ row = layout.row()
+ row.prop(bpy.context.scene, 'nodemargin_y', text="Margin y")
+ row = layout.row()
+ row.prop(context.scene, 'node_center', text="Center nodes")
+
+ row = layout.row()
+ row.operator('node.na_align_nodes', text="Align to Selected")
+
+ row = layout.row()
+ node = context.space_data.node_tree.nodes.active
+ if node and node.select:
+ row.prop(node, 'location', text = "Node X", index = 0)
+ row.prop(node, 'location', text = "Node Y", index = 1)
+ row = layout.row()
+ row.prop(node, 'width', text = "Node width")
+
+ row = layout.row()
+ row.operator('node.button_odd')
class NA_OT_NodeButton(Operator):
- '''Arrange Connected Nodes/Arrange All Nodes'''
- bl_idname = 'node.button'
- bl_label = 'Arrange All Nodes'
+ '''Arrange Connected Nodes/Arrange All Nodes'''
+ bl_idname = 'node.button'
+ bl_label = 'Arrange All Nodes'
- def execute(self, context):
- nodemargin(self, context)
- bpy.context.space_data.node_tree.nodes.update()
- bpy.ops.node.view_all()
+ def execute(self, context):
+ nodemargin(self, context)
+ bpy.context.space_data.node_tree.nodes.update()
+ bpy.ops.node.view_all()
- return {'FINISHED'}
+ return {'FINISHED'}
- # not sure this is doing what you expect.
- # blender.org/api/blender_python_api_current/bpy.types.Operator.html#invoke
- def invoke(self, context, value):
- values.mat_name = bpy.context.space_data.node_tree
- nodemargin(self, context)
- return {'FINISHED'}
+ # not sure this is doing what you expect.
+ # blender.org/api/blender_python_api_current/bpy.types.Operator.html#invoke
+ def invoke(self, context, value):
+ values.mat_name = bpy.context.space_data.node_tree
+ nodemargin(self, context)
+ return {'FINISHED'}
class NA_OT_NodeButtonOdd(Operator):
- 'Show the nodes for this material'
- bl_idname = 'node.button_odd'
- bl_label = 'Select Unlinked'
+ 'Show the nodes for this material'
+ bl_idname = 'node.button_odd'
+ bl_label = 'Select Unlinked'
- def execute(self, context):
- values.mat_name = bpy.context.space_data.node_tree
- #mat = bpy.context.object.active_material
- nodes_iterate(context.space_data.node_tree, False)
- return {'FINISHED'}
+ def execute(self, context):
+ values.mat_name = bpy.context.space_data.node_tree
+ #mat = bpy.context.object.active_material
+ nodes_iterate(context.space_data.node_tree, False)
+ return {'FINISHED'}
class NA_OT_NodeButtonCenter(Operator):
- 'Show the nodes for this material'
- bl_idname = 'node.button_center'
- bl_label = 'Center nodes (0,0)'
+ 'Show the nodes for this material'
+ bl_idname = 'node.button_center'
+ bl_label = 'Center nodes (0,0)'
- def execute(self, context):
- values.mat_name = "" # reset
- mat = bpy.context.object.active_material
- nodes_center(mat)
- return {'FINISHED'}
+ def execute(self, context):
+ values.mat_name = "" # reset
+ mat = bpy.context.object.active_material
+ nodes_center(mat)
+ return {'FINISHED'}
def nodemargin(self, context):
- values.margin_x = context.scene.nodemargin_x
- values.margin_y = context.scene.nodemargin_y
+ values.margin_x = context.scene.nodemargin_x
+ values.margin_y = context.scene.nodemargin_y
- ntree = context.space_data.node_tree
+ ntree = context.space_data.node_tree
- #first arrange nodegroups
- n_groups = []
- for i in ntree.nodes:
- if i.type == 'GROUP':
- n_groups.append(i)
+ #first arrange nodegroups
+ n_groups = []
+ for i in ntree.nodes:
+ if i.type == 'GROUP':
+ n_groups.append(i)
- while n_groups:
- j = n_groups.pop(0)
- nodes_iterate(j.node_tree)
- for i in j.node_tree.nodes:
- if i.type == 'GROUP':
- n_groups.append(i)
+ while n_groups:
+ j = n_groups.pop(0)
+ nodes_iterate(j.node_tree)
+ for i in j.node_tree.nodes:
+ if i.type == 'GROUP':
+ n_groups.append(i)
- nodes_iterate(ntree)
+ nodes_iterate(ntree)
- # arrange nodes + this center nodes together
- if context.scene.node_center:
- nodes_center(ntree)
+ # arrange nodes + this center nodes together
+ if context.scene.node_center:
+ nodes_center(ntree)
class NA_OT_ArrangeNodesOp(bpy.types.Operator):
- bl_idname = 'node.arrange_nodetree'
- bl_label = 'Nodes Private Op'
-
- mat_name : bpy.props.StringProperty()
- margin_x : bpy.props.IntProperty(default=120)
- margin_y : bpy.props.IntProperty(default=120)
-
- def nodemargin2(self, context):
- mat = None
- mat_found = bpy.data.materials.get(self.mat_name)
- if self.mat_name and mat_found:
- mat = mat_found
- #print(mat)
-
- if not mat:
- return
- else:
- values.mat_name = self.mat_name
- scn = context.scene
- scn.nodemargin_x = self.margin_x
- scn.nodemargin_y = self.margin_y
- nodes_iterate(mat)
- if scn.node_center:
- nodes_center(mat)
-
- def execute(self, context):
- self.nodemargin2(context)
- return {'FINISHED'}
-
-
-def outputnode_search(ntree): # return node/None
-
- outputnodes = []
- for node in ntree.nodes:
- if not node.outputs:
- for input in node.inputs:
- if input.is_linked:
- outputnodes.append(node)
- break
-
- if not outputnodes:
- print("No output node found")
- return None
- return outputnodes
-
-
-###############################################################
-def nodes_iterate(ntree, arrange=True):
-
- nodeoutput = outputnode_search(ntree)
- if nodeoutput is None:
- #print ("nodeoutput is None")
- return None
- a = []
- a.append([])
- for i in nodeoutput:
- a[0].append(i)
-
-
- level = 0
-
- while a[level]:
- a.append([])
-
- for node in a[level]:
- inputlist = [i for i in node.inputs if i.is_linked]
-
- if inputlist:
-
- for input in inputlist:
- for nlinks in input.links:
- node1 = nlinks.from_node
- a[level + 1].append(node1)
-
- else:
- pass
+ bl_idname = 'node.arrange_nodetree'
+ bl_label = 'Nodes Private Op'
+
+ mat_name : bpy.props.StringProperty()
+ margin_x : bpy.props.IntProperty(default=120)
+ margin_y : bpy.props.IntProperty(default=120)
+
+ def nodemargin2(self, context):
+ mat = None
+ mat_found = bpy.data.materials.get(self.mat_name)
+ if self.mat_name and mat_found:
+ mat = mat_found
+ #print(mat)
+
+ if not mat:
+ return
+ else:
+ values.mat_name = self.mat_name
+ scn = context.scene
+ scn.nodemargin_x = self.margin_x
+ scn.nodemargin_y = self.margin_y
+ nodes_iterate(mat)
+ if scn.node_center:
+ nodes_center(mat)
- level += 1
+ def execute(self, context):
+ self.nodemargin2(context)
+ return {'FINISHED'}
- del a[level]
- level -= 1
- #remove duplicate nodes at the same level, first wins
- for x, nodes in enumerate(a):
- a[x] = list(OrderedDict(zip(a[x], repeat(None))))
+def outputnode_search(ntree): # return node/None
- #remove duplicate nodes in all levels, last wins
- top = level
- for row1 in range(top, 1, -1):
- for col1 in a[row1]:
- for row2 in range(row1-1, 0, -1):
- for col2 in a[row2]:
- if col1 == col2:
- a[row2].remove(col2)
- break
+ outputnodes = []
+ for node in ntree.nodes:
+ if not node.outputs:
+ for input in node.inputs:
+ if input.is_linked:
+ outputnodes.append(node)
+ break
- """
- for x, i in enumerate(a):
- print (x)
- for j in i:
- print (j)
- #print()
- """
- """
- #add node frames to nodelist
- frames = []
- print ("Frames:")
- print ("level:", level)
- print ("a:",a)
- for row in range(level, 0, -1):
+ if not outputnodes:
+ print("No output node found")
+ return None
+ return outputnodes
- for i, node in enumerate(a[row]):
- if node.parent:
- print ("Frame found:", node.parent, node)
- #if frame already added to the list ?
- frame = node.parent
- #remove node
- del a[row][i]
- if frame not in frames:
- frames.append(frame)
- #add frame to the same place than node was
- a[row].insert(i, frame)
- pprint.pprint(a)
- """
- #return None
- ########################################
+###############################################################
+def nodes_iterate(ntree, arrange=True):
+ nodeoutput = outputnode_search(ntree)
+ if nodeoutput is None:
+ #print ("nodeoutput is None")
+ return None
+ a = []
+ a.append([])
+ for i in nodeoutput:
+ a[0].append(i)
- if not arrange:
- nodelist = [j for i in a for j in i]
- nodes_odd(ntree, nodelist=nodelist)
- return None
+ level = 0
- ########################################
+ while a[level]:
+ a.append([])
- levelmax = level + 1
- level = 0
- values.x_last = 0
+ for node in a[level]:
+ inputlist = [i for i in node.inputs if i.is_linked]
- while level < levelmax:
+ if inputlist:
- values.average_y = 0
- nodes = [x for x in a[level]]
- #print ("level, nodes:", level, nodes)
- nodes_arrange(nodes, level)
+ for input in inputlist:
+ for nlinks in input.links:
+ node1 = nlinks.from_node
+ a[level + 1].append(node1)
- level = level + 1
-
- return None
+ else:
+ pass
+
+ level += 1
+
+ del a[level]
+ level -= 1
+
+ #remove duplicate nodes at the same level, first wins
+ for x, nodes in enumerate(a):
+ a[x] = list(OrderedDict(zip(a[x], repeat(None))))
+
+ #remove duplicate nodes in all levels, last wins
+ top = level
+ for row1 in range(top, 1, -1):
+ for col1 in a[row1]:
+ for row2 in range(row1-1, 0, -1):
+ for col2 in a[row2]:
+ if col1 == col2:
+ a[row2].remove(col2)
+ break
+
+ """
+ for x, i in enumerate(a):
+ print (x)
+ for j in i:
+ print (j)
+ #print()
+ """
+ """
+ #add node frames to nodelist
+ frames = []
+ print ("Frames:")
+ print ("level:", level)
+ print ("a:",a)
+ for row in range(level, 0, -1):
+
+ for i, node in enumerate(a[row]):
+ if node.parent:
+ print ("Frame found:", node.parent, node)
+ #if frame already added to the list ?
+ frame = node.parent
+ #remove node
+ del a[row][i]
+ if frame not in frames:
+ frames.append(frame)
+ #add frame to the same place than node was
+ a[row].insert(i, frame)
+
+ pprint.pprint(a)
+ """
+ #return None
+ ########################################
+
+
+
+ if not arrange:
+ nodelist = [j for i in a for j in i]
+ nodes_odd(ntree, nodelist=nodelist)
+ return None
+
+ ########################################
+
+ levelmax = level + 1
+ level = 0
+ values.x_last = 0
+
+ while level < levelmax:
+
+ values.average_y = 0
+ nodes = [x for x in a[level]]
+ #print ("level, nodes:", level, nodes)
+ nodes_arrange(nodes, level)
+
+ level = level + 1
+
+ return None
###############################################################
def nodes_odd(ntree, nodelist):
- nodes = ntree.nodes
- for i in nodes:
- i.select = False
+ nodes = ntree.nodes
+ for i in nodes:
+ i.select = False
- a = [x for x in nodes if x not in nodelist]
- # print ("odd nodes:",a)
- for i in a:
- i.select = True
+ a = [x for x in nodes if x not in nodelist]
+ # print ("odd nodes:",a)
+ for i in a:
+ i.select = True
def nodes_arrange(nodelist, level):
- parents = []
- for node in nodelist:
- parents.append(node.parent)
- node.parent = None
- bpy.context.space_data.node_tree.nodes.update()
+ parents = []
+ for node in nodelist:
+ parents.append(node.parent)
+ node.parent = None
+ bpy.context.space_data.node_tree.nodes.update()
- #print ("nodes arrange def")
- # node x positions
+ #print ("nodes arrange def")
+ # node x positions
- widthmax = max([x.dimensions.x for x in nodelist])
- xpos = values.x_last - (widthmax + values.margin_x) if level != 0 else 0
- #print ("nodelist, xpos", nodelist,xpos)
- values.x_last = xpos
+ widthmax = max([x.dimensions.x for x in nodelist])
+ xpos = values.x_last - (widthmax + values.margin_x) if level != 0 else 0
+ #print ("nodelist, xpos", nodelist,xpos)
+ values.x_last = xpos
- # node y positions
- x = 0
- y = 0
+ # node y positions
+ x = 0
+ y = 0
- for node in nodelist:
+ for node in nodelist:
- if node.hide:
- hidey = (node.dimensions.y / 2) - 8
- y = y - hidey
- else:
- hidey = 0
+ if node.hide:
+ hidey = (node.dimensions.y / 2) - 8
+ y = y - hidey
+ else:
+ hidey = 0
- node.location.y = y
- y = y - values.margin_y - node.dimensions.y + hidey
+ node.location.y = y
+ y = y - values.margin_y - node.dimensions.y + hidey
- node.location.x = xpos #if node.type != "FRAME" else xpos + 1200
+ node.location.x = xpos #if node.type != "FRAME" else xpos + 1200
- y = y + values.margin_y
+ y = y + values.margin_y
- center = (0 + y) / 2
- values.average_y = center - values.average_y
+ center = (0 + y) / 2
+ values.average_y = center - values.average_y
- #for node in nodelist:
+ #for node in nodelist:
- #node.location.y -= values.average_y
+ #node.location.y -= values.average_y
- for i, node in enumerate(nodelist):
- node.parent = parents[i]
+ for i, node in enumerate(nodelist):
+ node.parent = parents[i]
def nodetree_get(mat):
- return mat.node_tree.nodes
+ return mat.node_tree.nodes
def nodes_center(ntree):
- bboxminx = []
- bboxmaxx = []
- bboxmaxy = []
- bboxminy = []
-
- for node in ntree.nodes:
- if not node.parent:
- bboxminx.append(node.location.x)
- bboxmaxx.append(node.location.x + node.dimensions.x)
- bboxmaxy.append(node.location.y)
- bboxminy.append(node.location.y - node.dimensions.y)
-
- # print ("bboxminy:",bboxminy)
- bboxminx = min(bboxminx)
- bboxmaxx = max(bboxmaxx)
- bboxminy = min(bboxminy)
- bboxmaxy = max(bboxmaxy)
- center_x = (bboxminx + bboxmaxx) / 2
- center_y = (bboxminy + bboxmaxy) / 2
- '''
- print ("minx:",bboxminx)
- print ("maxx:",bboxmaxx)
- print ("miny:",bboxminy)
- print ("maxy:",bboxmaxy)
-
- print ("bboxes:", bboxminx, bboxmaxx, bboxmaxy, bboxminy)
- print ("center x:",center_x)
- print ("center y:",center_y)
- '''
-
- x = 0
- y = 0
-
- for node in ntree.nodes:
-
- if not node.parent:
- node.location.x -= center_x
- node.location.y += -center_y
+ bboxminx = []
+ bboxmaxx = []
+ bboxmaxy = []
+ bboxminy = []
+
+ for node in ntree.nodes:
+ if not node.parent:
+ bboxminx.append(node.location.x)
+ bboxmaxx.append(node.location.x + node.dimensions.x)
+ bboxmaxy.append(node.location.y)
+ bboxminy.append(node.location.y - node.dimensions.y)
+
+ # print ("bboxminy:",bboxminy)
+ bboxminx = min(bboxminx)
+ bboxmaxx = max(bboxmaxx)
+ bboxminy = min(bboxminy)
+ bboxmaxy = max(bboxmaxy)
+ center_x = (bboxminx + bboxmaxx) / 2
+ center_y = (bboxminy + bboxmaxy) / 2
+ '''
+ print ("minx:",bboxminx)
+ print ("maxx:",bboxmaxx)
+ print ("miny:",bboxminy)
+ print ("maxy:",bboxmaxy)
+
+ print ("bboxes:", bboxminx, bboxmaxx, bboxmaxy, bboxminy)
+ print ("center x:",center_x)
+ print ("center y:",center_y)
+ '''
+
+ x = 0
+ y = 0
+
+ for node in ntree.nodes:
+
+ if not node.parent:
+ node.location.x -= center_x
+ node.location.y += -center_y
classes = [
- NA_PT_NodePanel,
- NA_OT_NodeButton,
- NA_OT_NodeButtonOdd,
- NA_OT_NodeButtonCenter,
- NA_OT_ArrangeNodesOp,
+ NA_PT_NodePanel,
+ NA_OT_NodeButton,
+ NA_OT_NodeButtonOdd,
+ NA_OT_NodeButtonCenter,
+ NA_OT_ArrangeNodesOp,
NA_OT_AlignNodes
]
def register():
- for c in classes:
- bpy.utils.register_class(c)
+ for c in classes:
+ bpy.utils.register_class(c)
- bpy.types.Scene.nodemargin_x = bpy.props.IntProperty(default=100, update=nodemargin)
- bpy.types.Scene.nodemargin_y = bpy.props.IntProperty(default=20, update=nodemargin)
- bpy.types.Scene.node_center = bpy.props.BoolProperty(default=True, update=nodemargin)
+ bpy.types.Scene.nodemargin_x = bpy.props.IntProperty(default=100, update=nodemargin)
+ bpy.types.Scene.nodemargin_y = bpy.props.IntProperty(default=20, update=nodemargin)
+ bpy.types.Scene.node_center = bpy.props.BoolProperty(default=True, update=nodemargin)
def unregister():
- for c in classes:
- bpy.utils.unregister_class(c)
+ for c in classes:
+ bpy.utils.unregister_class(c)
- del bpy.types.Scene.nodemargin_x
- del bpy.types.Scene.nodemargin_y
- del bpy.types.Scene.node_center
+ del bpy.types.Scene.nodemargin_x
+ del bpy.types.Scene.nodemargin_y
+ del bpy.types.Scene.node_center
if __name__ == "__main__":
- register()
+ register()
diff --git a/node_presets.py b/node_presets.py
index 2f65dd54..85a262e1 100644
--- a/node_presets.py
+++ b/node_presets.py
@@ -25,8 +25,8 @@ bl_info = {
"location": "Node Editors > Add > Template",
"description": "Add node groups directly to the node editors",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "node/node_presets.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "node/node_presets.html",
"category": "Node",
}
diff --git a/node_wrangler.py b/node_wrangler.py
index 0fad2cca..eba5b60d 100644
--- a/node_wrangler.py
+++ b/node_wrangler.py
@@ -24,8 +24,8 @@ bl_info = {
"location": "Node Editor Toolbar or Shift-W",
"description": "Various tools to enhance and speed up node-based workflow",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "node/node_wrangler.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "node/node_wrangler.html",
"category": "Node",
}
@@ -544,9 +544,6 @@ draw_color_sets = {
}
-def is_cycles_or_eevee(context):
- return context.scene.render.engine in {'CYCLES', 'BLENDER_EEVEE'}
-
def is_visible_socket(socket):
return not socket.hide and socket.enabled
@@ -1583,10 +1580,9 @@ class NWEmissionViewer(Operator, NWBase):
@classmethod
def poll(cls, context):
- is_cycles = is_cycles_or_eevee(context)
if nw_check(context):
space = context.space_data
- if space.tree_type == 'ShaderNodeTree' and is_cycles:
+ if space.tree_type == 'ShaderNodeTree':
if context.active_node:
if context.active_node.type != "OUTPUT_MATERIAL" or context.active_node.type != "OUTPUT_WORLD":
return True
@@ -2583,7 +2579,7 @@ class NWAddTextureSetup(Operator, NWBase):
valid = False
if nw_check(context):
space = context.space_data
- if space.tree_type == 'ShaderNodeTree' and is_cycles_or_eevee(context):
+ if space.tree_type == 'ShaderNodeTree':
valid = True
return valid
@@ -2687,7 +2683,7 @@ class NWAddPrincipledSetup(Operator, NWBase, ImportHelper):
valid = False
if nw_check(context):
space = context.space_data
- if space.tree_type == 'ShaderNodeTree' and is_cycles_or_eevee(context):
+ if space.tree_type == 'ShaderNodeTree':
valid = True
return valid
@@ -3261,10 +3257,7 @@ class NWLinkToOutputNode(Operator, NWBase):
if not output_node:
bpy.ops.node.select_all(action="DESELECT")
if tree_type == 'ShaderNodeTree':
- if is_cycles_or_eevee(context):
- output_node = nodes.new('ShaderNodeOutputMaterial')
- else:
- output_node = nodes.new('ShaderNodeOutput')
+ output_node = nodes.new('ShaderNodeOutputMaterial')
elif tree_type == 'CompositorNodeTree':
output_node = nodes.new('CompositorNodeComposite')
elif tree_type == 'TextureNodeTree':
@@ -3282,7 +3275,7 @@ class NWLinkToOutputNode(Operator, NWBase):
break
out_input_index = 0
- if tree_type == 'ShaderNodeTree' and is_cycles_or_eevee(context):
+ if tree_type == 'ShaderNodeTree':
if active.outputs[output_index].name == 'Volume':
out_input_index = 1
elif active.outputs[output_index].type != 'SHADER': # connect to displacement if not a shader
@@ -3730,7 +3723,7 @@ def drawlayout(context, layout, mode='non-panel'):
col.menu(NWSwitchNodeTypeMenu.bl_idname, text="Switch Node Type")
col.separator()
- if tree_type == 'ShaderNodeTree' and is_cycles_or_eevee(context):
+ if tree_type == 'ShaderNodeTree':
col = layout.column(align=True)
col.operator(NWAddTextureSetup.bl_idname, text="Add Texture Setup", icon='NODE_SEL')
col.operator(NWAddPrincipledSetup.bl_idname, text="Add Principled Setup", icon='NODE_SEL')
@@ -3815,7 +3808,7 @@ class NWMergeNodesMenu(Menu, NWBase):
def draw(self, context):
type = context.space_data.tree_type
layout = self.layout
- if type == 'ShaderNodeTree' and is_cycles_or_eevee(context):
+ if type == 'ShaderNodeTree':
layout.menu(NWMergeShadersMenu.bl_idname, text="Use Shaders")
layout.menu(NWMergeMixMenu.bl_idname, text="Use Mix Nodes")
layout.menu(NWMergeMathMenu.bl_idname, text="Use Math Nodes")
@@ -4039,7 +4032,7 @@ class NWVertColMenu(bpy.types.Menu):
valid = False
if nw_check(context):
snode = context.space_data
- valid = snode.tree_type == 'ShaderNodeTree' and is_cycles_or_eevee(context)
+ valid = snode.tree_type == 'ShaderNodeTree'
return valid
def draw(self, context):
@@ -4074,22 +4067,14 @@ class NWSwitchNodeTypeMenu(Menu, NWBase):
layout = self.layout
tree = context.space_data.node_tree
if tree.type == 'SHADER':
- if is_cycles_or_eevee(context):
- layout.menu(NWSwitchShadersInputSubmenu.bl_idname)
- layout.menu(NWSwitchShadersOutputSubmenu.bl_idname)
- layout.menu(NWSwitchShadersShaderSubmenu.bl_idname)
- layout.menu(NWSwitchShadersTextureSubmenu.bl_idname)
- layout.menu(NWSwitchShadersColorSubmenu.bl_idname)
- layout.menu(NWSwitchShadersVectorSubmenu.bl_idname)
- layout.menu(NWSwitchShadersConverterSubmenu.bl_idname)
- layout.menu(NWSwitchShadersLayoutSubmenu.bl_idname)
- else:
- layout.menu(NWSwitchMatInputSubmenu.bl_idname)
- layout.menu(NWSwitchMatOutputSubmenu.bl_idname)
- layout.menu(NWSwitchMatColorSubmenu.bl_idname)
- layout.menu(NWSwitchMatVectorSubmenu.bl_idname)
- layout.menu(NWSwitchMatConverterSubmenu.bl_idname)
- layout.menu(NWSwitchMatLayoutSubmenu.bl_idname)
+ layout.menu(NWSwitchShadersInputSubmenu.bl_idname)
+ layout.menu(NWSwitchShadersOutputSubmenu.bl_idname)
+ layout.menu(NWSwitchShadersShaderSubmenu.bl_idname)
+ layout.menu(NWSwitchShadersTextureSubmenu.bl_idname)
+ layout.menu(NWSwitchShadersColorSubmenu.bl_idname)
+ layout.menu(NWSwitchShadersVectorSubmenu.bl_idname)
+ layout.menu(NWSwitchShadersConverterSubmenu.bl_idname)
+ layout.menu(NWSwitchShadersLayoutSubmenu.bl_idname)
if tree.type == 'COMPOSITING':
layout.menu(NWSwitchCompoInputSubmenu.bl_idname)
layout.menu(NWSwitchCompoOutputSubmenu.bl_idname)
diff --git a/object_boolean_tools.py b/object_boolean_tools.py
index 7f1c5d33..7ea231e9 100644
--- a/object_boolean_tools.py
+++ b/object_boolean_tools.py
@@ -25,8 +25,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D > Sidebar > Edit Tab",
"description": "Bool Tool Hotkey: Ctrl Shift B",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "object/bool_tools.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "object/bool_tools.html",
"category": "Object",
}
diff --git a/object_carver/__init__.py b/object_carver/__init__.py
index b2a89f28..883d5b76 100644
--- a/object_carver/__init__.py
+++ b/object_carver/__init__.py
@@ -17,18 +17,18 @@
# ##### END GPL LICENSE BLOCK #####
bl_info = {
- "name": "Carver",
- "author": "Pixivore, Cedric LEPILLER, Ted Milker, Clarkx",
- "description": "Multiple tools to carve or to create objects",
- "version": (1, 2, 0),
- "blender": (2, 80, 0),
- "location": "3D View > Ctrl/Shift/x",
- "warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "object/carver.html",
- "support": 'COMMUNITY',
- "category": "Object"
- }
+ "name": "Carver",
+ "author": "Pixivore, Cedric LEPILLER, Ted Milker, Clarkx",
+ "description": "Multiple tools to carve or to create objects",
+ "version": (1, 2, 0),
+ "blender": (2, 80, 0),
+ "location": "3D View > Ctrl/Shift/x",
+ "warning": "",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "object/carver.html",
+ "support": 'COMMUNITY',
+ "category": "Object"
+ }
import bpy
import imp
@@ -61,249 +61,249 @@ imp.reload(carver_operator)
# "or to create objects"
# )
#
-# #Icons : \blender-2.80\2.80\datafiles\icons
-# #Todo: Create a new icon for Carver
+# #Icons : \blender-2.80\2.80\datafiles\icons
+# #Todo: Create a new icon for Carver
# bl_icon = "ops.mesh.knife_tool"
# bl_widget = None
# bl_keymap = (
# ("carver.operator", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
-# )
+# )
#
# def draw_settings(context, layout, tool):
# layout.prop(tool.operator_properties, "carver")
class CarverPreferences(AddonPreferences):
- bl_idname = __name__
+ bl_idname = __name__
- Enable_Tab_01: BoolProperty(
- name="Info",
- description="Some general information and settings about the add-on",
- default=False
- )
- Enable_Tab_02: BoolProperty(
- name="Hotkeys",
- description="List of the shortcuts used during carving",
- default=False
- )
- Key_Create: StringProperty(
- name="Object creation",
- description="Object creation",
- maxlen=1,
- default="C"
- )
- Key_Update: StringProperty(
- name="Auto Bevel Update",
- description="Auto Bevel Update",
- maxlen=1,
- default="A",
- )
- Key_Bool: StringProperty(
- name="Boolean type",
- description="Boolean operation type",
- maxlen=1,
- default="T",
- )
- Key_Brush: StringProperty(
- name="Brush Mode",
- description="Brush Mode",
- maxlen=1,
- default="B",
- )
- Key_Help: StringProperty(
- name="Help display",
- description="Help display",
- maxlen=1,
- default="H",
- )
- Key_Instant: StringProperty(
- name="Instantiate",
- description="Instantiate object",
- maxlen=1,
- default="I",
- )
- Key_Close: StringProperty(
- name="Close polygonal shape",
- description="Close polygonal shape",
- maxlen=1,
- default="X",
- )
- Key_Apply: StringProperty(
- name="Apply operation",
- description="Apply operation",
- maxlen=1,
- default="Q",
- )
- Key_Scale: StringProperty(
- name="Scale object",
- description="Scale object",
- maxlen=1,
- default="S",
- )
- Key_Gapy: StringProperty(
- name="Gap rows",
- description="Scale gap between columns",
- maxlen=1,
- default="J",
- )
- Key_Gapx: StringProperty(
- name="Gap columns",
- description="Scale gap between columns",
- maxlen=1,
- default="U",
- )
- Key_Depth: StringProperty(
- name="Depth",
- description="Cursor depth or solidify pattern",
- maxlen=1,
- default="D",
- )
- Key_BrushDepth: StringProperty(
- name="Brush Depth",
- description="Brush depth",
- maxlen=1,
- default="C",
- )
- Key_Subadd: StringProperty(
- name="Add subdivision",
- description="Add subdivision",
- maxlen=1,
- default="X",
- )
- Key_Subrem: StringProperty(
- name="Remove subdivision",
- description="Remove subdivision",
- maxlen=1,
- default="W",
- )
- Key_Randrot: StringProperty(
- name="Random rotation",
- description="Random rotation",
- maxlen=1,
- default="R",
- )
- ProfilePrefix: StringProperty(
- name="Profile prefix",
- description="Prefix to look for profiles with",
- default="Carver_Profile-",
- )
- LineWidth: IntProperty(
- name="Line Width",
- description="Thickness of the drawing lines",
- default=1,
- )
- Key_Snap: StringProperty(
- name="Grid Snap",
- description="Grid Snap",
- maxlen=1,
- default="G",
- )
+ Enable_Tab_01: BoolProperty(
+ name="Info",
+ description="Some general information and settings about the add-on",
+ default=False
+ )
+ Enable_Tab_02: BoolProperty(
+ name="Hotkeys",
+ description="List of the shortcuts used during carving",
+ default=False
+ )
+ Key_Create: StringProperty(
+ name="Object creation",
+ description="Object creation",
+ maxlen=1,
+ default="C"
+ )
+ Key_Update: StringProperty(
+ name="Auto Bevel Update",
+ description="Auto Bevel Update",
+ maxlen=1,
+ default="A",
+ )
+ Key_Bool: StringProperty(
+ name="Boolean type",
+ description="Boolean operation type",
+ maxlen=1,
+ default="T",
+ )
+ Key_Brush: StringProperty(
+ name="Brush Mode",
+ description="Brush Mode",
+ maxlen=1,
+ default="B",
+ )
+ Key_Help: StringProperty(
+ name="Help display",
+ description="Help display",
+ maxlen=1,
+ default="H",
+ )
+ Key_Instant: StringProperty(
+ name="Instantiate",
+ description="Instantiate object",
+ maxlen=1,
+ default="I",
+ )
+ Key_Close: StringProperty(
+ name="Close polygonal shape",
+ description="Close polygonal shape",
+ maxlen=1,
+ default="X",
+ )
+ Key_Apply: StringProperty(
+ name="Apply operation",
+ description="Apply operation",
+ maxlen=1,
+ default="Q",
+ )
+ Key_Scale: StringProperty(
+ name="Scale object",
+ description="Scale object",
+ maxlen=1,
+ default="S",
+ )
+ Key_Gapy: StringProperty(
+ name="Gap rows",
+ description="Scale gap between columns",
+ maxlen=1,
+ default="J",
+ )
+ Key_Gapx: StringProperty(
+ name="Gap columns",
+ description="Scale gap between columns",
+ maxlen=1,
+ default="U",
+ )
+ Key_Depth: StringProperty(
+ name="Depth",
+ description="Cursor depth or solidify pattern",
+ maxlen=1,
+ default="D",
+ )
+ Key_BrushDepth: StringProperty(
+ name="Brush Depth",
+ description="Brush depth",
+ maxlen=1,
+ default="C",
+ )
+ Key_Subadd: StringProperty(
+ name="Add subdivision",
+ description="Add subdivision",
+ maxlen=1,
+ default="X",
+ )
+ Key_Subrem: StringProperty(
+ name="Remove subdivision",
+ description="Remove subdivision",
+ maxlen=1,
+ default="W",
+ )
+ Key_Randrot: StringProperty(
+ name="Random rotation",
+ description="Random rotation",
+ maxlen=1,
+ default="R",
+ )
+ ProfilePrefix: StringProperty(
+ name="Profile prefix",
+ description="Prefix to look for profiles with",
+ default="Carver_Profile-",
+ )
+ LineWidth: IntProperty(
+ name="Line Width",
+ description="Thickness of the drawing lines",
+ default=1,
+ )
+ Key_Snap: StringProperty(
+ name="Grid Snap",
+ description="Grid Snap",
+ maxlen=1,
+ default="G",
+ )
- def draw(self, context):
- scene = context.scene
- layout = self.layout
+ def draw(self, context):
+ scene = context.scene
+ layout = self.layout
- icon_1 = "TRIA_RIGHT" if not self.Enable_Tab_01 else "TRIA_DOWN"
- box = layout.box()
+ icon_1 = "TRIA_RIGHT" if not self.Enable_Tab_01 else "TRIA_DOWN"
+ box = layout.box()
- box.prop(self, "Enable_Tab_01", text="Info and Settings", emboss=False, icon=icon_1)
- if self.Enable_Tab_01:
- box.label(text="Carver Operator:", icon="LAYER_ACTIVE")
- box.label(text="Select a Mesh Object and press [CTRL]+[SHIFT]+[X] to carve",
- icon="LAYER_USED")
- box.label(text="To finish carving press [ESC] or [RIGHT CLICK]",
- icon="LAYER_USED")
- box.prop(self, "ProfilePrefix", text="Profile prefix")
- row = box.row(align=True)
- row.label(text="Line width:")
- row.prop(self, "LineWidth", text="")
+ box.prop(self, "Enable_Tab_01", text="Info and Settings", emboss=False, icon=icon_1)
+ if self.Enable_Tab_01:
+ box.label(text="Carver Operator:", icon="LAYER_ACTIVE")
+ box.label(text="Select a Mesh Object and press [CTRL]+[SHIFT]+[X] to carve",
+ icon="LAYER_USED")
+ box.label(text="To finish carving press [ESC] or [RIGHT CLICK]",
+ icon="LAYER_USED")
+ box.prop(self, "ProfilePrefix", text="Profile prefix")
+ row = box.row(align=True)
+ row.label(text="Line width:")
+ row.prop(self, "LineWidth", text="")
- icon_2 = "TRIA_RIGHT" if not self.Enable_Tab_02 else "TRIA_DOWN"
- box = layout.box()
- box.prop(self, "Enable_Tab_02", text="Keys", emboss=False, icon=icon_2)
- if self.Enable_Tab_02:
- split = box.split(align=True)
- box = split.box()
- col = box.column(align=True)
- col.label(text="Object Creation:")
- col.prop(self, "Key_Create", text="")
- col.label(text="Auto bevel update:")
- col.prop(self, "Key_Update", text="")
- col.label(text="Boolean operation type:")
- col.prop(self, "Key_Bool", text="")
- col.label(text="Brush Depth:")
- col.prop(self, "Key_BrushDepth", text="")
+ icon_2 = "TRIA_RIGHT" if not self.Enable_Tab_02 else "TRIA_DOWN"
+ box = layout.box()
+ box.prop(self, "Enable_Tab_02", text="Keys", emboss=False, icon=icon_2)
+ if self.Enable_Tab_02:
+ split = box.split(align=True)
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Object Creation:")
+ col.prop(self, "Key_Create", text="")
+ col.label(text="Auto bevel update:")
+ col.prop(self, "Key_Update", text="")
+ col.label(text="Boolean operation type:")
+ col.prop(self, "Key_Bool", text="")
+ col.label(text="Brush Depth:")
+ col.prop(self, "Key_BrushDepth", text="")
- box = split.box()
- col = box.column(align=True)
- col.label(text="Brush Mode:")
- col.prop(self, "Key_Brush", text="")
- col.label(text="Help display:")
- col.prop(self, "Key_Help", text="")
- col.label(text="Instantiate object:")
- col.prop(self, "Key_Instant", text="")
- col.label(text="Random rotation:")
- col.prop(self, "Key_Randrot", text="")
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Brush Mode:")
+ col.prop(self, "Key_Brush", text="")
+ col.label(text="Help display:")
+ col.prop(self, "Key_Help", text="")
+ col.label(text="Instantiate object:")
+ col.prop(self, "Key_Instant", text="")
+ col.label(text="Random rotation:")
+ col.prop(self, "Key_Randrot", text="")
- box = split.box()
- col = box.column(align=True)
- col.label(text="Close polygonal shape:")
- col.prop(self, "Key_Close", text="")
- col.label(text="Apply operation:")
- col.prop(self, "Key_Apply", text="")
- col.label(text="Scale object:")
- col.prop(self, "Key_Scale", text="")
- col.label(text="Subdiv add:")
- col.prop(self, "Key_Subadd", text="")
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Close polygonal shape:")
+ col.prop(self, "Key_Close", text="")
+ col.label(text="Apply operation:")
+ col.prop(self, "Key_Apply", text="")
+ col.label(text="Scale object:")
+ col.prop(self, "Key_Scale", text="")
+ col.label(text="Subdiv add:")
+ col.prop(self, "Key_Subadd", text="")
- box = split.box()
- col = box.column(align=True)
- col.label(text="Gap rows:")
- col.prop(self, "Key_Gapy", text="")
- col.label(text="Gap columns:")
- col.prop(self, "Key_Gapx", text="")
- col.label(text="Depth / Solidify:")
- col.prop(self, "Key_Depth", text="")
- col.label(text="Subdiv Remove:")
- col.prop(self, "Key_Subrem", text="")
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Gap rows:")
+ col.prop(self, "Key_Gapy", text="")
+ col.label(text="Gap columns:")
+ col.prop(self, "Key_Gapx", text="")
+ col.label(text="Depth / Solidify:")
+ col.prop(self, "Key_Depth", text="")
+ col.label(text="Subdiv Remove:")
+ col.prop(self, "Key_Subrem", text="")
- box = split.box()
- col = box.column(align=True)
- col.label(text="Grid Snap:")
- col.prop(self, "Key_Snap", text="")
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Grid Snap:")
+ col.prop(self, "Key_Snap", text="")
addon_keymaps = []
def register():
- print("Registered Carver")
+ print("Registered Carver")
- bpy.utils.register_class(CarverPreferences)
- # Todo : Add an icon in the toolbat
- # bpy.utils.register_tool(CarverTool, separator=True, group=True)
- carver_operator.register()
+ bpy.utils.register_class(CarverPreferences)
+ # Todo : Add an icon in the toolbat
+ # bpy.utils.register_tool(CarverTool, separator=True, group=True)
+ carver_operator.register()
- # add keymap entry
- kcfg = bpy.context.window_manager.keyconfigs.addon
- if kcfg:
- km = kcfg.keymaps.new(name='3D View', space_type='VIEW_3D')
- kmi = km.keymap_items.new("carver.operator", 'X', 'PRESS', shift=True, ctrl=True)
- addon_keymaps.append((km, kmi))
+ # add keymap entry
+ kcfg = bpy.context.window_manager.keyconfigs.addon
+ if kcfg:
+ km = kcfg.keymaps.new(name='3D View', space_type='VIEW_3D')
+ kmi = km.keymap_items.new("carver.operator", 'X', 'PRESS', shift=True, ctrl=True)
+ addon_keymaps.append((km, kmi))
def unregister():
- # Todo : Add an icon in the toolbat
- # bpy.utils.unregister_tool(CarverTool)
- carver_operator.unregister()
- bpy.utils.unregister_class(CarverPreferences)
+ # Todo : Add an icon in the toolbat
+ # bpy.utils.unregister_tool(CarverTool)
+ carver_operator.unregister()
+ bpy.utils.unregister_class(CarverPreferences)
- print("Unregistered Carver")
+ print("Unregistered Carver")
- # remove keymap entry
- for km, kmi in addon_keymaps:
- km.keymap_items.remove(kmi)
- addon_keymaps.clear()
+ # remove keymap entry
+ for km, kmi in addon_keymaps:
+ km.keymap_items.remove(kmi)
+ addon_keymaps.clear()
if __name__ == "__main__":
- register()
+ register()
diff --git a/object_carver/carver_draw.py b/object_carver/carver_draw.py
index 922807ee..f2a3aadc 100644
--- a/object_carver/carver_draw.py
+++ b/object_carver/carver_draw.py
@@ -6,494 +6,494 @@ import numpy as np
import gpu
from gpu_extras.batch import batch_for_shader
from math import(
- cos,
- sin,
- ceil,
- floor,
- )
+ cos,
+ sin,
+ ceil,
+ floor,
+ )
from bpy_extras.view3d_utils import (
- region_2d_to_location_3d,
- location_3d_to_region_2d,
+ region_2d_to_location_3d,
+ location_3d_to_region_2d,
)
from .carver_utils import (
- draw_circle,
- draw_shader,
- objDiagonal,
- mini_grid,
- )
+ draw_circle,
+ draw_shader,
+ objDiagonal,
+ mini_grid,
+ )
from mathutils import (
- Color,
- Euler,
- Vector,
- Quaternion,
+ Color,
+ Euler,
+ Vector,
+ Quaternion,
)
def get_text_info(self, context, help_txt):
- """ Return the dimensions of each part of the text """
+ """ Return the dimensions of each part of the text """
- #Extract the longest first option in sublist
- max_option = max(list(blf.dimensions(0, row[0])[0] for row in help_txt))
+ #Extract the longest first option in sublist
+ max_option = max(list(blf.dimensions(0, row[0])[0] for row in help_txt))
- #Extract the longest key in sublist
- max_key = max(list(blf.dimensions(0, row[1])[0] for row in help_txt))
+ #Extract the longest key in sublist
+ max_key = max(list(blf.dimensions(0, row[1])[0] for row in help_txt))
- #Space between option and key with a comma separator (" : ")
- comma = blf.dimensions(0, "_:_")[0]
+ #Space between option and key with a comma separator (" : ")
+ comma = blf.dimensions(0, "_:_")[0]
- #Get a default height for all the letters
- line_height = (blf.dimensions(0, "gM")[1] * 1.45)
+ #Get a default height for all the letters
+ line_height = (blf.dimensions(0, "gM")[1] * 1.45)
- #Get the total height of the text
- bloc_height = 0
- for row in help_txt:
- bloc_height += line_height
+ #Get the total height of the text
+ bloc_height = 0
+ for row in help_txt:
+ bloc_height += line_height
- return(help_txt, bloc_height, max_option, max_key, comma)
+ return(help_txt, bloc_height, max_option, max_key, comma)
def draw_string(self, color1, color2, left, bottom, text, max_option, divide = 1):
- """ Draw the text like 'option : key' or just 'option' """
-
- font_id = 0
- ui_scale = bpy.context.preferences.system.ui_scale
-
- blf.enable(font_id,blf.SHADOW)
- blf.shadow(font_id, 0, 0.0, 0.0, 0.0, 1.0)
- blf.shadow_offset(font_id,2,-2)
- line_height = (blf.dimensions(font_id, "gM")[1] * 1.45)
- y_offset = 5
-
- # Test if the text is a list formatted like : ('option', 'key')
- if isinstance(text,list):
- spacer_text = " : "
- spacer_width = blf.dimensions(font_id, spacer_text)[0]
- for string in text:
- blf.position(font_id, (left), (bottom + y_offset), 0)
- blf.color(font_id, *color1)
- blf.draw(font_id, string[0])
- blf.position(font_id, (left + max_option), (bottom + y_offset), 0)
- blf.draw(font_id, spacer_text)
- blf.color(font_id, *color2)
- blf.position(font_id, (left + max_option + spacer_width), (bottom + y_offset), 0)
- blf.draw(font_id, string[1])
- y_offset += line_height
- else:
- # The text is formatted like : ('option')
- blf.position(font_id, left, (bottom + y_offset), 0)
- blf.color(font_id, *color1)
- blf.draw(font_id, text)
- y_offset += line_height
-
- blf.disable(font_id,blf.SHADOW)
+ """ Draw the text like 'option : key' or just 'option' """
+
+ font_id = 0
+ ui_scale = bpy.context.preferences.system.ui_scale
+
+ blf.enable(font_id,blf.SHADOW)
+ blf.shadow(font_id, 0, 0.0, 0.0, 0.0, 1.0)
+ blf.shadow_offset(font_id,2,-2)
+ line_height = (blf.dimensions(font_id, "gM")[1] * 1.45)
+ y_offset = 5
+
+ # Test if the text is a list formatted like : ('option', 'key')
+ if isinstance(text,list):
+ spacer_text = " : "
+ spacer_width = blf.dimensions(font_id, spacer_text)[0]
+ for string in text:
+ blf.position(font_id, (left), (bottom + y_offset), 0)
+ blf.color(font_id, *color1)
+ blf.draw(font_id, string[0])
+ blf.position(font_id, (left + max_option), (bottom + y_offset), 0)
+ blf.draw(font_id, spacer_text)
+ blf.color(font_id, *color2)
+ blf.position(font_id, (left + max_option + spacer_width), (bottom + y_offset), 0)
+ blf.draw(font_id, string[1])
+ y_offset += line_height
+ else:
+ # The text is formatted like : ('option')
+ blf.position(font_id, left, (bottom + y_offset), 0)
+ blf.color(font_id, *color1)
+ blf.draw(font_id, text)
+ y_offset += line_height
+
+ blf.disable(font_id,blf.SHADOW)
# Opengl draw on screen
def draw_callback_px(self, context):
- font_id = 0
- region = context.region
- UIColor = (0.992, 0.5518, 0.0, 1.0)
-
- # Cut Type
- RECTANGLE = 0
- LINE = 1
- CIRCLE = 2
- self.carver_prefs = context.preferences.addons[__package__].preferences
-
- # Color
- color1 = (1.0, 1.0, 1.0, 1.0)
- color2 = UIColor
-
- #The mouse is outside the active region
- if not self.in_view_3d:
- color1 = color2 = (1.0, 0.2, 0.1, 1.0)
-
- # Primitives type
- PrimitiveType = "Rectangle"
- if self.CutType == CIRCLE:
- PrimitiveType = "Circle"
- if self.CutType == LINE:
- PrimitiveType = "Line"
-
- # Width screen
- overlap = context.preferences.system.use_region_overlap
-
- t_panel_width = 0
- if overlap:
- for region in context.area.regions:
- if region.type == 'TOOLS':
- t_panel_width = region.width
-
- # Initial position
- region_width = int(region.width / 2.0)
- y_txt = 10
-
-
- # Draw the center command from bottom to top
-
- # Get the size of the text
- text_size = 18 if region.width >= 850 else 12
- ui_scale = bpy.context.preferences.system.ui_scale
- blf.size(0, round(text_size * ui_scale), 72)
-
- # Help Display
- if (self.ObjectMode is False) and (self.ProfileMode is False):
-
- # Depth Cursor
- TypeStr = "Cursor Depth [" + self.carver_prefs.Key_Depth + "]"
- BoolStr = "(ON)" if self.snapCursor else "(OFF)"
- help_txt = [[TypeStr, BoolStr]]
-
- # Close poygonal shape
- if self.CreateMode and self.CutType == LINE:
- TypeStr = "Close [" + self.carver_prefs.Key_Close + "]"
- BoolStr = "(ON)" if self.Closed else "(OFF)"
- help_txt += [[TypeStr, BoolStr]]
-
- if self.CreateMode is False:
- # Apply Booleans
- TypeStr = "Apply Operations [" + self.carver_prefs.Key_Apply + "]"
- BoolStr = "(OFF)" if self.dont_apply_boolean else "(ON)"
- help_txt += [[TypeStr, BoolStr]]
-
- #Auto update for bevel
- TypeStr = "Bevel Update [" + self.carver_prefs.Key_Update + "]"
- BoolStr = "(ON)" if self.Auto_BevelUpdate else "(OFF)"
- help_txt += [[TypeStr, BoolStr]]
-
- # Circle subdivisions
- if self.CutType == CIRCLE:
- TypeStr = "Subdivisions [" + self.carver_prefs.Key_Subrem + "][" + self.carver_prefs.Key_Subadd + "]"
- BoolStr = str((int(360 / self.stepAngle[self.step])))
- help_txt += [[TypeStr, BoolStr]]
-
- if self.CreateMode:
- help_txt += [["Type [Space]", PrimitiveType]]
- else:
- help_txt += [["Cut Type [Space]", PrimitiveType]]
-
- else:
- # Instantiate
- TypeStr = "Instantiate [" + self.carver_prefs.Key_Instant + "]"
- BoolStr = "(ON)" if self.Instantiate else "(OFF)"
- help_txt = [[TypeStr, BoolStr]]
-
- # Random rotation
- if self.alt:
- TypeStr = "Random Rotation [" + self.carver_prefs.Key_Randrot + "]"
- BoolStr = "(ON)" if self.RandomRotation else "(OFF)"
- help_txt += [[TypeStr, BoolStr]]
-
- # Thickness
- if self.BrushSolidify:
- TypeStr = "Thickness [" + self.carver_prefs.Key_Depth + "]"
- if self.ProfileMode:
- BoolStr = str(round(self.ProfileBrush.modifiers["CT_SOLIDIFY"].thickness, 2))
- if self.ObjectMode:
- BoolStr = str(round(self.ObjectBrush.modifiers["CT_SOLIDIFY"].thickness, 2))
- help_txt += [[TypeStr, BoolStr]]
-
- # Brush depth
- if (self.ObjectMode):
- TypeStr = "Carve Depth [" + self.carver_prefs.Key_Depth + "]"
- BoolStr = str(round(self.ObjectBrush.data.vertices[0].co.z, 2))
- help_txt += [[TypeStr, BoolStr]]
-
- TypeStr = "Brush Depth [" + self.carver_prefs.Key_BrushDepth + "]"
- BoolStr = str(round(self.BrushDepthOffset, 2))
- help_txt += [[TypeStr, BoolStr]]
-
- help_txt, bloc_height, max_option, max_key, comma = get_text_info(self, context, help_txt)
- xCmd = region_width - (max_option + max_key + comma) / 2
- draw_string(self, color1, color2, xCmd, y_txt, help_txt, max_option, divide = 2)
-
-
- # Separator (Line)
- LineWidth = (max_option + max_key + comma) / 2
- if region.width >= 850:
- LineWidth = 140
-
- LineWidth = (max_option + max_key + comma)
- coords = [(int(region_width - LineWidth/2), y_txt + bloc_height + 8), \
- (int(region_width + LineWidth/2), y_txt + bloc_height + 8)]
- draw_shader(self, UIColor, 1, 'LINES', coords, self.carver_prefs.LineWidth)
-
- # Command Display
- if self.CreateMode and ((self.ObjectMode is False) and (self.ProfileMode is False)):
- BooleanMode = "Create"
- else:
- if self.ObjectMode or self.ProfileMode:
- BooleanType = "Difference) [T]" if self.BoolOps == self.difference else "Union) [T]"
- BooleanMode = \
- "Object Brush (" + BooleanType if self.ObjectMode else "Profil Brush (" + BooleanType
- else:
- BooleanMode = \
- "Difference" if (self.shift is False) and (self.ForceRebool is False) else "Rebool"
-
- # Display boolean mode
- text_size = 40 if region.width >= 850 else 20
- blf.size(0, round(text_size * ui_scale), 72)
-
- draw_string(self, color2, color2, region_width - (blf.dimensions(0, BooleanMode)[0]) / 2, \
- y_txt + bloc_height + 16, BooleanMode, 0, divide = 2)
-
- if region.width >= 850:
-
- if self.AskHelp is False:
- # "H for Help" text
- blf.size(0, round(13 * ui_scale), 72)
- help_txt = "[" + self.carver_prefs.Key_Help + "] for help"
- txt_width = blf.dimensions(0, help_txt)[0]
- txt_height = (blf.dimensions(0, "gM")[1] * 1.45)
-
- # Draw a rectangle and put the text "H for Help"
- xrect = 40
- yrect = 40
- rect_vertices = [(xrect - 5, yrect - 5), (xrect + txt_width + 5, yrect - 5), \
- (xrect + txt_width + 5, yrect + txt_height + 5), (xrect - 5, yrect + txt_height + 5)]
- draw_shader(self, (0.0, 0.0, 0.0), 0.3, 'TRI_FAN', rect_vertices, self.carver_prefs.LineWidth)
- draw_string(self, color1, color2, xrect, yrect, help_txt, 0)
-
- else:
- #Draw the help text
- xHelp = 30 + t_panel_width
- yHelp = 10
-
- if self.ObjectMode or self.ProfileMode:
- if self.ProfileMode:
- help_txt = [["Object Mode", self.carver_prefs.Key_Brush]]
- else:
- help_txt = [["Cut Mode", self.carver_prefs.Key_Brush]]
-
- else:
- help_txt =[
- ["Profil Brush", self.carver_prefs.Key_Brush],\
- ["Move Cursor", "Ctrl + LMB"]
- ]
-
- if (self.ObjectMode is False) and (self.ProfileMode is False):
- if self.CreateMode is False:
- help_txt +=[
- ["Create geometry", self.carver_prefs.Key_Create],\
- ]
- else:
- help_txt +=[
- ["Cut", self.carver_prefs.Key_Create],\
- ]
- if self.CutMode == RECTANGLE:
- help_txt +=[
- ["Dimension", "MouseMove"],\
- ["Move all", "Alt"],\
- ["Validate", "LMB"],\
- ["Rebool", "Shift"]
- ]
-
- elif self.CutMode == CIRCLE:
- help_txt +=[
- ["Rotation and Radius", "MouseMove"],\
- ["Move all", "Alt"],\
- ["Subdivision", self.carver_prefs.Key_Subrem + " " + self.carver_prefs.Key_Subadd],\
- ["Incremental rotation", "Ctrl"],\
- ["Rebool", "Shift"]
- ]
-
- elif self.CutMode == LINE:
- help_txt +=[
- ["Dimension", "MouseMove"],\
- ["Move all", "Alt"],\
- ["Validate", "Space"],\
- ["Rebool", "Shift"],\
- ["Snap", "Ctrl"],\
- ["Scale Snap", "WheelMouse"],\
- ]
- else:
- # ObjectMode
- help_txt +=[
- ["Difference", "Space"],\
- ["Rebool", "Shift + Space"],\
- ["Duplicate", "Alt + Space"],\
- ["Scale", self.carver_prefs.Key_Scale],\
- ["Rotation", "LMB + Move"],\
- ["Step Angle", "CTRL + LMB + Move"],\
- ]
-
- if self.ProfileMode:
- help_txt +=[["Previous or Next Profile", self.carver_prefs.Key_Subadd + " " + self.carver_prefs.Key_Subrem]]
-
- help_txt +=[
- ["Create / Delete rows", chr(8597)],\
- ["Create / Delete cols", chr(8596)],\
- ["Gap for rows or columns", self.carver_prefs.Key_Gapy + " " + self.carver_prefs.Key_Gapx]
- ]
-
- blf.size(0, round(15 * ui_scale), 72)
- help_txt, bloc_height, max_option, max_key, comma = get_text_info(self, context, help_txt)
- draw_string(self, color1, color2, xHelp, yHelp, help_txt, max_option)
-
- if self.ProfileMode:
- xrect = region.width - t_panel_width - 80
- yrect = 80
- coords = [(xrect, yrect), (xrect+60, yrect), (xrect+60, yrect-60), (xrect, yrect-60)]
-
- # Draw rectangle background in the lower right
- draw_shader(self, (0.0, 0.0, 0.0), 0.3, 'TRI_FAN', coords, size=self.carver_prefs.LineWidth)
-
- # Use numpy to get the vertices and indices of the profile object to draw
- WidthProfil = 50
- location = Vector((region.width - t_panel_width - WidthProfil, 50, 0))
- ProfilScale = 20.0
- coords = []
- mesh = bpy.data.meshes[self.Profils[self.nProfil][0]]
- mesh.calc_loop_triangles()
- vertices = np.empty((len(mesh.vertices), 3), 'f')
- indices = np.empty((len(mesh.loop_triangles), 3), 'i')
- mesh.vertices.foreach_get("co", np.reshape(vertices, len(mesh.vertices) * 3))
- mesh.loop_triangles.foreach_get("vertices", np.reshape(indices, len(mesh.loop_triangles) * 3))
-
- for idx, vals in enumerate(vertices):
- coords.append([
- vals[0] * ProfilScale + location.x,
- vals[1] * ProfilScale + location.y,
- vals[2] * ProfilScale + location.z
- ])
-
- #Draw the silhouette of the mesh
- draw_shader(self, UIColor, 0.5, 'TRIS', coords, size=self.carver_prefs.LineWidth, indices=indices)
-
-
- if self.CutMode:
-
- if len(self.mouse_path) > 1:
- x0 = self.mouse_path[0][0]
- y0 = self.mouse_path[0][1]
- x1 = self.mouse_path[1][0]
- y1 = self.mouse_path[1][1]
-
- # Cut rectangle
- if self.CutType == RECTANGLE:
- coords = [
- (x0 + self.xpos, y0 + self.ypos), (x1 + self.xpos, y0 + self.ypos), \
- (x1 + self.xpos, y1 + self.ypos), (x0 + self.xpos, y1 + self.ypos)
- ]
- indices = ((0, 1, 2), (2, 0, 3))
-
- self.rectangle_coord = coords
-
- draw_shader(self, UIColor, 1, 'LINE_LOOP', coords, size=self.carver_prefs.LineWidth)
-
- #Draw points
- draw_shader(self, UIColor, 1, 'POINTS', coords, size=3)
-
- if self.shift or self.CreateMode:
- draw_shader(self, UIColor, 0.5, 'TRIS', coords, size=self.carver_prefs.LineWidth, indices=indices)
-
- # Draw grid (based on the overlay options) to show the incremental snapping
- if self.ctrl:
- mini_grid(self, context, UIColor)
-
- # Cut Line
- elif self.CutType == LINE:
- coords = []
- indices = []
- top_grid = False
-
- for idx, vals in enumerate(self.mouse_path):
- coords.append([vals[0] + self.xpos, vals[1] + self.ypos])
- indices.append([idx])
-
- # Draw lines
- if self.Closed:
- draw_shader(self, UIColor, 1.0, 'LINE_LOOP', coords, size=self.carver_prefs.LineWidth)
- else:
- draw_shader(self, UIColor, 1.0, 'LINE_STRIP', coords, size=self.carver_prefs.LineWidth)
-
- # Draw points
- draw_shader(self, UIColor, 1.0, 'POINTS', coords, size=3)
-
- # Draw polygon
- if (self.shift) or (self.CreateMode and self.Closed):
- draw_shader(self, UIColor, 0.5, 'TRI_FAN', coords, size=self.carver_prefs.LineWidth)
-
- # Draw grid (based on the overlay options) to show the incremental snapping
- if self.ctrl:
- mini_grid(self, context, UIColor)
-
- # Circle Cut
- elif self.CutType == CIRCLE:
- # Create a circle using a tri fan
- tris_coords, indices = draw_circle(self, x0, y0)
-
- # Remove the vertex in the center to get the outer line of the circle
- line_coords = tris_coords[1:]
- draw_shader(self, UIColor, 1.0, 'LINE_LOOP', line_coords, size=self.carver_prefs.LineWidth)
-
- if self.shift or self.CreateMode:
- draw_shader(self, UIColor, 0.5, 'TRIS', tris_coords, size=self.carver_prefs.LineWidth, indices=indices)
-
- if (self.ObjectMode or self.ProfileMode) and len(self.CurrentSelection) > 0:
- if self.ShowCursor:
- region = context.region
- rv3d = context.space_data.region_3d
-
- if self.ObjectMode:
- ob = self.ObjectBrush
- if self.ProfileMode:
- ob = self.ProfileBrush
- mat = ob.matrix_world
-
- # 50% alpha, 2 pixel width line
- bgl.glEnable(bgl.GL_BLEND)
-
- bbox = [mat @ Vector(b) for b in ob.bound_box]
- objBBDiagonal = objDiagonal(self.CurrentSelection[0])
-
- if self.shift:
- gl_size = 4
- UIColor = (0.5, 1.0, 0.0, 1.0)
- else:
- gl_size = 2
- UIColor = (1.0, 0.8, 0.0, 1.0)
-
- line_coords = []
- idx = 0
- CRadius = ((bbox[7] - bbox[0]).length) / 2
- for i in range(int(len(self.CLR_C) / 3)):
- vector3d = (self.CLR_C[idx * 3] * CRadius + self.CurLoc.x, \
- self.CLR_C[idx * 3 + 1] * CRadius + self.CurLoc.y, \
- self.CLR_C[idx * 3 + 2] * CRadius + self.CurLoc.z)
- vector2d = bpy_extras.view3d_utils.location_3d_to_region_2d(region, rv3d, vector3d)
- if vector2d is not None:
- line_coords.append((vector2d[0], vector2d[1]))
- idx += 1
- if len(line_coords) > 0 :
- draw_shader(self, UIColor, 1.0, 'LINE_LOOP', line_coords, size=gl_size)
-
- # Object display
- if self.quat_rot is not None:
- ob.location = self.CurLoc
- v = Vector()
- v.x = v.y = 0.0
- v.z = self.BrushDepthOffset
- ob.location += self.quat_rot @ v
-
- e = Euler()
- e.x = 0.0
- e.y = 0.0
- e.z = self.aRotZ / 25.0
-
- qe = e.to_quaternion()
- qRot = self.quat_rot @ qe
- ob.rotation_mode = 'QUATERNION'
- ob.rotation_quaternion = qRot
- ob.rotation_mode = 'XYZ'
-
- if self.ProfileMode:
- if self.ProfileBrush is not None:
- self.ProfileBrush.location = self.CurLoc
- self.ProfileBrush.rotation_mode = 'QUATERNION'
- self.ProfileBrush.rotation_quaternion = qRot
- self.ProfileBrush.rotation_mode = 'XYZ'
-
- # Opengl defaults
- bgl.glLineWidth(1)
- bgl.glDisable(bgl.GL_BLEND)
+ font_id = 0
+ region = context.region
+ UIColor = (0.992, 0.5518, 0.0, 1.0)
+
+ # Cut Type
+ RECTANGLE = 0
+ LINE = 1
+ CIRCLE = 2
+ self.carver_prefs = context.preferences.addons[__package__].preferences
+
+ # Color
+ color1 = (1.0, 1.0, 1.0, 1.0)
+ color2 = UIColor
+
+ #The mouse is outside the active region
+ if not self.in_view_3d:
+ color1 = color2 = (1.0, 0.2, 0.1, 1.0)
+
+ # Primitives type
+ PrimitiveType = "Rectangle"
+ if self.CutType == CIRCLE:
+ PrimitiveType = "Circle"
+ if self.CutType == LINE:
+ PrimitiveType = "Line"
+
+ # Width screen
+ overlap = context.preferences.system.use_region_overlap
+
+ t_panel_width = 0
+ if overlap:
+ for region in context.area.regions:
+ if region.type == 'TOOLS':
+ t_panel_width = region.width
+
+ # Initial position
+ region_width = int(region.width / 2.0)
+ y_txt = 10
+
+
+ # Draw the center command from bottom to top
+
+ # Get the size of the text
+ text_size = 18 if region.width >= 850 else 12
+ ui_scale = bpy.context.preferences.system.ui_scale
+ blf.size(0, round(text_size * ui_scale), 72)
+
+ # Help Display
+ if (self.ObjectMode is False) and (self.ProfileMode is False):
+
+ # Depth Cursor
+ TypeStr = "Cursor Depth [" + self.carver_prefs.Key_Depth + "]"
+ BoolStr = "(ON)" if self.snapCursor else "(OFF)"
+ help_txt = [[TypeStr, BoolStr]]
+
+ # Close poygonal shape
+ if self.CreateMode and self.CutType == LINE:
+ TypeStr = "Close [" + self.carver_prefs.Key_Close + "]"
+ BoolStr = "(ON)" if self.Closed else "(OFF)"
+ help_txt += [[TypeStr, BoolStr]]
+
+ if self.CreateMode is False:
+ # Apply Booleans
+ TypeStr = "Apply Operations [" + self.carver_prefs.Key_Apply + "]"
+ BoolStr = "(OFF)" if self.dont_apply_boolean else "(ON)"
+ help_txt += [[TypeStr, BoolStr]]
+
+ #Auto update for bevel
+ TypeStr = "Bevel Update [" + self.carver_prefs.Key_Update + "]"
+ BoolStr = "(ON)" if self.Auto_BevelUpdate else "(OFF)"
+ help_txt += [[TypeStr, BoolStr]]
+
+ # Circle subdivisions
+ if self.CutType == CIRCLE:
+ TypeStr = "Subdivisions [" + self.carver_prefs.Key_Subrem + "][" + self.carver_prefs.Key_Subadd + "]"
+ BoolStr = str((int(360 / self.stepAngle[self.step])))
+ help_txt += [[TypeStr, BoolStr]]
+
+ if self.CreateMode:
+ help_txt += [["Type [Space]", PrimitiveType]]
+ else:
+ help_txt += [["Cut Type [Space]", PrimitiveType]]
+
+ else:
+ # Instantiate
+ TypeStr = "Instantiate [" + self.carver_prefs.Key_Instant + "]"
+ BoolStr = "(ON)" if self.Instantiate else "(OFF)"
+ help_txt = [[TypeStr, BoolStr]]
+
+ # Random rotation
+ if self.alt:
+ TypeStr = "Random Rotation [" + self.carver_prefs.Key_Randrot + "]"
+ BoolStr = "(ON)" if self.RandomRotation else "(OFF)"
+ help_txt += [[TypeStr, BoolStr]]
+
+ # Thickness
+ if self.BrushSolidify:
+ TypeStr = "Thickness [" + self.carver_prefs.Key_Depth + "]"
+ if self.ProfileMode:
+ BoolStr = str(round(self.ProfileBrush.modifiers["CT_SOLIDIFY"].thickness, 2))
+ if self.ObjectMode:
+ BoolStr = str(round(self.ObjectBrush.modifiers["CT_SOLIDIFY"].thickness, 2))
+ help_txt += [[TypeStr, BoolStr]]
+
+ # Brush depth
+ if (self.ObjectMode):
+ TypeStr = "Carve Depth [" + self.carver_prefs.Key_Depth + "]"
+ BoolStr = str(round(self.ObjectBrush.data.vertices[0].co.z, 2))
+ help_txt += [[TypeStr, BoolStr]]
+
+ TypeStr = "Brush Depth [" + self.carver_prefs.Key_BrushDepth + "]"
+ BoolStr = str(round(self.BrushDepthOffset, 2))
+ help_txt += [[TypeStr, BoolStr]]
+
+ help_txt, bloc_height, max_option, max_key, comma = get_text_info(self, context, help_txt)
+ xCmd = region_width - (max_option + max_key + comma) / 2
+ draw_string(self, color1, color2, xCmd, y_txt, help_txt, max_option, divide = 2)
+
+
+ # Separator (Line)
+ LineWidth = (max_option + max_key + comma) / 2
+ if region.width >= 850:
+ LineWidth = 140
+
+ LineWidth = (max_option + max_key + comma)
+ coords = [(int(region_width - LineWidth/2), y_txt + bloc_height + 8), \
+ (int(region_width + LineWidth/2), y_txt + bloc_height + 8)]
+ draw_shader(self, UIColor, 1, 'LINES', coords, self.carver_prefs.LineWidth)
+
+ # Command Display
+ if self.CreateMode and ((self.ObjectMode is False) and (self.ProfileMode is False)):
+ BooleanMode = "Create"
+ else:
+ if self.ObjectMode or self.ProfileMode:
+ BooleanType = "Difference) [T]" if self.BoolOps == self.difference else "Union) [T]"
+ BooleanMode = \
+ "Object Brush (" + BooleanType if self.ObjectMode else "Profil Brush (" + BooleanType
+ else:
+ BooleanMode = \
+ "Difference" if (self.shift is False) and (self.ForceRebool is False) else "Rebool"
+
+ # Display boolean mode
+ text_size = 40 if region.width >= 850 else 20
+ blf.size(0, round(text_size * ui_scale), 72)
+
+ draw_string(self, color2, color2, region_width - (blf.dimensions(0, BooleanMode)[0]) / 2, \
+ y_txt + bloc_height + 16, BooleanMode, 0, divide = 2)
+
+ if region.width >= 850:
+
+ if self.AskHelp is False:
+ # "H for Help" text
+ blf.size(0, round(13 * ui_scale), 72)
+ help_txt = "[" + self.carver_prefs.Key_Help + "] for help"
+ txt_width = blf.dimensions(0, help_txt)[0]
+ txt_height = (blf.dimensions(0, "gM")[1] * 1.45)
+
+ # Draw a rectangle and put the text "H for Help"
+ xrect = 40
+ yrect = 40
+ rect_vertices = [(xrect - 5, yrect - 5), (xrect + txt_width + 5, yrect - 5), \
+ (xrect + txt_width + 5, yrect + txt_height + 5), (xrect - 5, yrect + txt_height + 5)]
+ draw_shader(self, (0.0, 0.0, 0.0), 0.3, 'TRI_FAN', rect_vertices, self.carver_prefs.LineWidth)
+ draw_string(self, color1, color2, xrect, yrect, help_txt, 0)
+
+ else:
+ #Draw the help text
+ xHelp = 30 + t_panel_width
+ yHelp = 10
+
+ if self.ObjectMode or self.ProfileMode:
+ if self.ProfileMode:
+ help_txt = [["Object Mode", self.carver_prefs.Key_Brush]]
+ else:
+ help_txt = [["Cut Mode", self.carver_prefs.Key_Brush]]
+
+ else:
+ help_txt =[
+ ["Profil Brush", self.carver_prefs.Key_Brush],\
+ ["Move Cursor", "Ctrl + LMB"]
+ ]
+
+ if (self.ObjectMode is False) and (self.ProfileMode is False):
+ if self.CreateMode is False:
+ help_txt +=[
+ ["Create geometry", self.carver_prefs.Key_Create],\
+ ]
+ else:
+ help_txt +=[
+ ["Cut", self.carver_prefs.Key_Create],\
+ ]
+ if self.CutMode == RECTANGLE:
+ help_txt +=[
+ ["Dimension", "MouseMove"],\
+ ["Move all", "Alt"],\
+ ["Validate", "LMB"],\
+ ["Rebool", "Shift"]
+ ]
+
+ elif self.CutMode == CIRCLE:
+ help_txt +=[
+ ["Rotation and Radius", "MouseMove"],\
+ ["Move all", "Alt"],\
+ ["Subdivision", self.carver_prefs.Key_Subrem + " " + self.carver_prefs.Key_Subadd],\
+ ["Incremental rotation", "Ctrl"],\
+ ["Rebool", "Shift"]
+ ]
+
+ elif self.CutMode == LINE:
+ help_txt +=[
+ ["Dimension", "MouseMove"],\
+ ["Move all", "Alt"],\
+ ["Validate", "Space"],\
+ ["Rebool", "Shift"],\
+ ["Snap", "Ctrl"],\
+ ["Scale Snap", "WheelMouse"],\
+ ]
+ else:
+ # ObjectMode
+ help_txt +=[
+ ["Difference", "Space"],\
+ ["Rebool", "Shift + Space"],\
+ ["Duplicate", "Alt + Space"],\
+ ["Scale", self.carver_prefs.Key_Scale],\
+ ["Rotation", "LMB + Move"],\
+ ["Step Angle", "CTRL + LMB + Move"],\
+ ]
+
+ if self.ProfileMode:
+ help_txt +=[["Previous or Next Profile", self.carver_prefs.Key_Subadd + " " + self.carver_prefs.Key_Subrem]]
+
+ help_txt +=[
+ ["Create / Delete rows", chr(8597)],\
+ ["Create / Delete cols", chr(8596)],\
+ ["Gap for rows or columns", self.carver_prefs.Key_Gapy + " " + self.carver_prefs.Key_Gapx]
+ ]
+
+ blf.size(0, round(15 * ui_scale), 72)
+ help_txt, bloc_height, max_option, max_key, comma = get_text_info(self, context, help_txt)
+ draw_string(self, color1, color2, xHelp, yHelp, help_txt, max_option)
+
+ if self.ProfileMode:
+ xrect = region.width - t_panel_width - 80
+ yrect = 80
+ coords = [(xrect, yrect), (xrect+60, yrect), (xrect+60, yrect-60), (xrect, yrect-60)]
+
+ # Draw rectangle background in the lower right
+ draw_shader(self, (0.0, 0.0, 0.0), 0.3, 'TRI_FAN', coords, size=self.carver_prefs.LineWidth)
+
+ # Use numpy to get the vertices and indices of the profile object to draw
+ WidthProfil = 50
+ location = Vector((region.width - t_panel_width - WidthProfil, 50, 0))
+ ProfilScale = 20.0
+ coords = []
+ mesh = bpy.data.meshes[self.Profils[self.nProfil][0]]
+ mesh.calc_loop_triangles()
+ vertices = np.empty((len(mesh.vertices), 3), 'f')
+ indices = np.empty((len(mesh.loop_triangles), 3), 'i')
+ mesh.vertices.foreach_get("co", np.reshape(vertices, len(mesh.vertices) * 3))
+ mesh.loop_triangles.foreach_get("vertices", np.reshape(indices, len(mesh.loop_triangles) * 3))
+
+ for idx, vals in enumerate(vertices):
+ coords.append([
+ vals[0] * ProfilScale + location.x,
+ vals[1] * ProfilScale + location.y,
+ vals[2] * ProfilScale + location.z
+ ])
+
+ #Draw the silhouette of the mesh
+ draw_shader(self, UIColor, 0.5, 'TRIS', coords, size=self.carver_prefs.LineWidth, indices=indices)
+
+
+ if self.CutMode:
+
+ if len(self.mouse_path) > 1:
+ x0 = self.mouse_path[0][0]
+ y0 = self.mouse_path[0][1]
+ x1 = self.mouse_path[1][0]
+ y1 = self.mouse_path[1][1]
+
+ # Cut rectangle
+ if self.CutType == RECTANGLE:
+ coords = [
+ (x0 + self.xpos, y0 + self.ypos), (x1 + self.xpos, y0 + self.ypos), \
+ (x1 + self.xpos, y1 + self.ypos), (x0 + self.xpos, y1 + self.ypos)
+ ]
+ indices = ((0, 1, 2), (2, 0, 3))
+
+ self.rectangle_coord = coords
+
+ draw_shader(self, UIColor, 1, 'LINE_LOOP', coords, size=self.carver_prefs.LineWidth)
+
+ #Draw points
+ draw_shader(self, UIColor, 1, 'POINTS', coords, size=3)
+
+ if self.shift or self.CreateMode:
+ draw_shader(self, UIColor, 0.5, 'TRIS', coords, size=self.carver_prefs.LineWidth, indices=indices)
+
+ # Draw grid (based on the overlay options) to show the incremental snapping
+ if self.ctrl:
+ mini_grid(self, context, UIColor)
+
+ # Cut Line
+ elif self.CutType == LINE:
+ coords = []
+ indices = []
+ top_grid = False
+
+ for idx, vals in enumerate(self.mouse_path):
+ coords.append([vals[0] + self.xpos, vals[1] + self.ypos])
+ indices.append([idx])
+
+ # Draw lines
+ if self.Closed:
+ draw_shader(self, UIColor, 1.0, 'LINE_LOOP', coords, size=self.carver_prefs.LineWidth)
+ else:
+ draw_shader(self, UIColor, 1.0, 'LINE_STRIP', coords, size=self.carver_prefs.LineWidth)
+
+ # Draw points
+ draw_shader(self, UIColor, 1.0, 'POINTS', coords, size=3)
+
+ # Draw polygon
+ if (self.shift) or (self.CreateMode and self.Closed):
+ draw_shader(self, UIColor, 0.5, 'TRI_FAN', coords, size=self.carver_prefs.LineWidth)
+
+ # Draw grid (based on the overlay options) to show the incremental snapping
+ if self.ctrl:
+ mini_grid(self, context, UIColor)
+
+ # Circle Cut
+ elif self.CutType == CIRCLE:
+ # Create a circle using a tri fan
+ tris_coords, indices = draw_circle(self, x0, y0)
+
+ # Remove the vertex in the center to get the outer line of the circle
+ line_coords = tris_coords[1:]
+ draw_shader(self, UIColor, 1.0, 'LINE_LOOP', line_coords, size=self.carver_prefs.LineWidth)
+
+ if self.shift or self.CreateMode:
+ draw_shader(self, UIColor, 0.5, 'TRIS', tris_coords, size=self.carver_prefs.LineWidth, indices=indices)
+
+ if (self.ObjectMode or self.ProfileMode) and len(self.CurrentSelection) > 0:
+ if self.ShowCursor:
+ region = context.region
+ rv3d = context.space_data.region_3d
+
+ if self.ObjectMode:
+ ob = self.ObjectBrush
+ if self.ProfileMode:
+ ob = self.ProfileBrush
+ mat = ob.matrix_world
+
+ # 50% alpha, 2 pixel width line
+ bgl.glEnable(bgl.GL_BLEND)
+
+ bbox = [mat @ Vector(b) for b in ob.bound_box]
+ objBBDiagonal = objDiagonal(self.CurrentSelection[0])
+
+ if self.shift:
+ gl_size = 4
+ UIColor = (0.5, 1.0, 0.0, 1.0)
+ else:
+ gl_size = 2
+ UIColor = (1.0, 0.8, 0.0, 1.0)
+
+ line_coords = []
+ idx = 0
+ CRadius = ((bbox[7] - bbox[0]).length) / 2
+ for i in range(int(len(self.CLR_C) / 3)):
+ vector3d = (self.CLR_C[idx * 3] * CRadius + self.CurLoc.x, \
+ self.CLR_C[idx * 3 + 1] * CRadius + self.CurLoc.y, \
+ self.CLR_C[idx * 3 + 2] * CRadius + self.CurLoc.z)
+ vector2d = bpy_extras.view3d_utils.location_3d_to_region_2d(region, rv3d, vector3d)
+ if vector2d is not None:
+ line_coords.append((vector2d[0], vector2d[1]))
+ idx += 1
+ if len(line_coords) > 0 :
+ draw_shader(self, UIColor, 1.0, 'LINE_LOOP', line_coords, size=gl_size)
+
+ # Object display
+ if self.quat_rot is not None:
+ ob.location = self.CurLoc
+ v = Vector()
+ v.x = v.y = 0.0
+ v.z = self.BrushDepthOffset
+ ob.location += self.quat_rot @ v
+
+ e = Euler()
+ e.x = 0.0
+ e.y = 0.0
+ e.z = self.aRotZ / 25.0
+
+ qe = e.to_quaternion()
+ qRot = self.quat_rot @ qe
+ ob.rotation_mode = 'QUATERNION'
+ ob.rotation_quaternion = qRot
+ ob.rotation_mode = 'XYZ'
+
+ if self.ProfileMode:
+ if self.ProfileBrush is not None:
+ self.ProfileBrush.location = self.CurLoc
+ self.ProfileBrush.rotation_mode = 'QUATERNION'
+ self.ProfileBrush.rotation_quaternion = qRot
+ self.ProfileBrush.rotation_mode = 'XYZ'
+
+ # Opengl defaults
+ bgl.glLineWidth(1)
+ bgl.glDisable(bgl.GL_BLEND)
diff --git a/object_carver/carver_operator.py b/object_carver/carver_operator.py
index c75a5ab7..95fa4af0 100644
--- a/object_carver/carver_operator.py
+++ b/object_carver/carver_operator.py
@@ -2,340 +2,340 @@ import bpy
import bpy_extras
import sys
from bpy.props import (
- BoolProperty,
- IntProperty,
- PointerProperty,
- StringProperty,
- EnumProperty,
- )
+ BoolProperty,
+ IntProperty,
+ PointerProperty,
+ StringProperty,
+ EnumProperty,
+ )
from mathutils import (
- Vector,
- )
+ Vector,
+ )
from bpy_extras.view3d_utils import (
- region_2d_to_vector_3d,
- region_2d_to_origin_3d,
- region_2d_to_location_3d,
- location_3d_to_region_2d,
+ region_2d_to_vector_3d,
+ region_2d_to_origin_3d,
+ region_2d_to_location_3d,
+ location_3d_to_region_2d,
)
from .carver_profils import (
- Profils
- )
+ Profils
+ )
from .carver_utils import (
- duplicateObject,
- UndoListUpdate,
- createMeshFromData,
- SelectObject,
- Selection_Save_Restore,
- Selection_Save,
- Selection_Restore,
- update_grid,
- objDiagonal,
- Undo,
- UndoAdd,
- Pick,
- rot_axis_quat,
- MoveCursor,
- Picking,
- CreateCutSquare,
- CreateCutCircle,
- CreateCutLine,
- boolean_operation,
- update_bevel,
- CreateBevel,
- Rebool,
- Snap_Cursor,
- )
+ duplicateObject,
+ UndoListUpdate,
+ createMeshFromData,
+ SelectObject,
+ Selection_Save_Restore,
+ Selection_Save,
+ Selection_Restore,
+ update_grid,
+ objDiagonal,
+ Undo,
+ UndoAdd,
+ Pick,
+ rot_axis_quat,
+ MoveCursor,
+ Picking,
+ CreateCutSquare,
+ CreateCutCircle,
+ CreateCutLine,
+ boolean_operation,
+ update_bevel,
+ CreateBevel,
+ Rebool,
+ Snap_Cursor,
+ )
from .carver_draw import draw_callback_px
# Modal Operator
class CARVER_OT_operator(bpy.types.Operator):
- bl_idname = "carver.operator"
- bl_label = "Carver"
- bl_description = "Cut or create Meshes in Object mode"
- bl_options = {'REGISTER', 'UNDO'}
+ bl_idname = "carver.operator"
+ bl_label = "Carver"
+ bl_description = "Cut or create Meshes in Object mode"
+ bl_options = {'REGISTER', 'UNDO'}
- def __init__(self):
- context = bpy.context
- # Carve mode: Cut, Object, Profile
- self.CutMode = False
- self.CreateMode = False
- self.ObjectMode = False
- self.ProfileMode = False
+ def __init__(self):
+ context = bpy.context
+ # Carve mode: Cut, Object, Profile
+ self.CutMode = False
+ self.CreateMode = False
+ self.ObjectMode = False
+ self.ProfileMode = False
- # Create mode
- self.ExclusiveCreateMode = False
- if len(context.selected_objects) == 0:
- self.ExclusiveCreateMode = True
- self.CreateMode = True
+ # Create mode
+ self.ExclusiveCreateMode = False
+ if len(context.selected_objects) == 0:
+ self.ExclusiveCreateMode = True
+ self.CreateMode = True
- # Cut type (Rectangle, Circle, Line)
- self.rectangle = 0
- self.line = 1
- self.circle = 2
+ # Cut type (Rectangle, Circle, Line)
+ self.rectangle = 0
+ self.line = 1
+ self.circle = 2
- # Cut Rectangle coordinates
- self.rectangle_coord = []
+ # Cut Rectangle coordinates
+ self.rectangle_coord = []
- # Selected type of cut
- self.CutType = 0
+ # Selected type of cut
+ self.CutType = 0
- # Boolean operation
- self.difference = 0
- self.union = 1
-
- self.BoolOps = self.difference
-
- self.CurrentSelection = context.selected_objects.copy()
- self.CurrentActive = context.active_object
- self.all_sel_obj_list = context.selected_objects.copy()
- self.save_active_obj = None
-
- args = (self, context)
- self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
-
- self.mouse_path = [(0, 0), (0, 0)]
-
- # Keyboard event
- self.shift = False
- self.ctrl = False
- self.alt = False
-
- self.dont_apply_boolean = context.scene.mesh_carver.DontApply
- self.Auto_BevelUpdate = True
-
- # Circle variables
- self.stepAngle = [2, 4, 5, 6, 9, 10, 15, 20, 30, 40, 45, 60, 72, 90]
- self.step = 4
-
- # Primitives Position
- self.xpos = 0
- self.ypos = 0
- self.InitPosition = False
-
- # Close polygonal shape
- self.Closed = False
-
- # Depth Cursor
- self.snapCursor = context.scene.mesh_carver.DepthCursor
-
- # Help
- self.AskHelp = False
-
- # Working object
- self.OpsObj = context.active_object
-
- # Rebool forced (cut line)
- self.ForceRebool = False
-
- self.ViewVector = Vector()
- self.CurrentObj = None
-
- # Brush
- self.BrushSolidify = False
- self.WidthSolidify = False
- self.CarveDepth = False
- self.BrushDepth = False
- self.BrushDepthOffset = 0.0
- self.snap = False
-
- self.ObjectScale = False
-
- #Init create circle primitive
- self.CLR_C = []
-
- # Cursor location
- self.CurLoc = Vector((0.0, 0.0, 0.0))
- self.SavCurLoc = Vector((0.0, 0.0, 0.0))
-
- # Mouse region
- self.mouse_region = -1, -1
- self.SavMousePos = None
- self.xSavMouse = 0
-
- # Scale, rotate object
- self.ascale = 0
- self.aRotZ = 0
- self.nRotZ = 0
- self.quat_rot_axis = None
- self.quat_rot = None
-
- self.RandomRotation = context.scene.mesh_carver.ORandom
-
- self.ShowCursor = True
-
- self.Instantiate = context.scene.mesh_carver.OInstanciate
-
- self.ProfileBrush = None
- self.ObjectBrush = None
-
- self.InitBrush = {
- 'location' : None,
- 'scale' : None,
- 'rotation_quaternion' : None,
- 'rotation_euler' : None,
- 'display_type' : 'WIRE',
- 'show_in_front' : False
- }
-
- # Array variables
- self.nbcol = 1
- self.nbrow = 1
- self.gapx = 0
- self.gapy = 0
- self.scale_x = 1
- self.scale_y = 1
- self.GridScaleX = False
- self.GridScaleY = False
-
- @classmethod
- def poll(cls, context):
- ob = None
- if len(context.selected_objects) > 0:
- ob = context.selected_objects[0]
- # Test if selected object or none (for create mode)
- return (
- (ob and ob.type == 'MESH' and context.mode == 'OBJECT') or
- (context.mode == 'OBJECT' and ob is None) or
- (context.mode == 'EDIT_MESH'))
-
- def modal(self, context, event):
- PI = 3.14156
- region_types = {'WINDOW', 'UI'}
- win = context.window
-
- # Find the limit of the view3d region
- self.check_region(context,event)
-
- for area in win.screen.areas:
- if area.type == 'VIEW_3D':
- for region in area.regions:
- if not region_types or region.type in region_types:
- region.tag_redraw()
-
- # Change the snap increment value using the wheel mouse
- if self.CutMode:
- if self.alt is False:
- if self.ctrl and (self.CutType in (self.line, self.rectangle)):
- # Get the VIEW3D area
- for i, a in enumerate(context.screen.areas):
- if a.type == 'VIEW_3D':
- space = context.screen.areas[i].spaces.active
- grid_scale = space.overlay.grid_scale
- grid_subdivisions = space.overlay.grid_subdivisions
-
- if event.type == 'WHEELUPMOUSE':
- space.overlay.grid_subdivisions += 1
- elif event.type == 'WHEELDOWNMOUSE':
- space.overlay.grid_subdivisions -= 1
-
- if event.type in {
- 'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE',
- 'NUMPAD_1', 'NUMPAD_2', 'NUMPAD_3', 'NUMPAD_4', 'NUMPAD_6',
- 'NUMPAD_7', 'NUMPAD_8', 'NUMPAD_9', 'NUMPAD_5'}:
- return {'PASS_THROUGH'}
-
- try:
- # [Shift]
- self.shift = True if event.shift else False
-
- # [Ctrl]
- self.ctrl = True if event.ctrl else False
-
- # [Alt]
- self.alt = False
-
- # [Alt] press : Init position variable before moving the cut brush with LMB
- if event.alt:
- if self.InitPosition is False:
- self.xpos = 0
- self.ypos = 0
- self.last_mouse_region_x = event.mouse_region_x
- self.last_mouse_region_y = event.mouse_region_y
- self.InitPosition = True
- self.alt = True
-
- # [Alt] release : update the coordinates
- if self.InitPosition and self.alt is False:
- for i in range(0, len(self.mouse_path)):
- l = list(self.mouse_path[i])
- l[0] += self.xpos
- l[1] += self.ypos
- self.mouse_path[i] = tuple(l)
-
- self.xpos = self.ypos = 0
- self.InitPosition = False
-
- if event.type == 'SPACE' and event.value == 'PRESS':
- # If object or profile mode is TRUE : Confirm the cut
- if self.ObjectMode or self.ProfileMode:
- # If array, remove double with intersect meshes
- if ((self.nbcol + self.nbrow) > 3):
- # Go in edit mode mode
- bpy.ops.object.mode_set(mode='EDIT')
- # Remove duplicate vertices
- bpy.ops.mesh.remove_doubles()
- # Return in object mode
- bpy.ops.object.mode_set(mode='OBJECT')
-
- if self.alt:
- # Save selected objects
- self.all_sel_obj_list = context.selected_objects.copy()
- if len(context.selected_objects) > 0:
- bpy.ops.object.select_all(action='TOGGLE')
-
- if self.ObjectMode:
- SelectObject(self, self.ObjectBrush)
- else:
- SelectObject(self, self.ProfileBrush)
- duplicateObject(self)
- else:
- # Brush Cut
- self.Cut()
- # Save selected objects
- if self.ObjectMode:
- if len(self.ObjectBrush.children) > 0:
- self.all_sel_obj_list = context.selected_objects.copy()
- if len(context.selected_objects) > 0:
- bpy.ops.object.select_all(action='TOGGLE')
-
- if self.ObjectMode:
- SelectObject(self, self.ObjectBrush)
- else:
- SelectObject(self, self.ProfileBrush)
- duplicateObject(self)
-
- UndoListUpdate(self)
-
- # Save cursor position
- self.SavMousePos = self.CurLoc
- else:
- if self.CutMode is False:
- # Cut Mode
- self.CutType += 1
- if self.CutType > 2:
- self.CutType = 0
- else:
- if self.CutType == self.line:
- # Cuts creation
- CreateCutLine(self, context)
- if self.CreateMode:
- # Object creation
- self.CreateGeometry()
- bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
- # Cursor Snap
- context.scene.mesh_carver.DepthCursor = self.snapCursor
- # Object Instantiate
- context.scene.mesh_carver.OInstanciate = self.Instantiate
- # Random rotation
- context.scene.mesh_carver.ORandom = self.RandomRotation
-
- return {'FINISHED'}
- else:
- self.Cut()
- UndoListUpdate(self)
+ # Boolean operation
+ self.difference = 0
+ self.union = 1
+
+ self.BoolOps = self.difference
+
+ self.CurrentSelection = context.selected_objects.copy()
+ self.CurrentActive = context.active_object
+ self.all_sel_obj_list = context.selected_objects.copy()
+ self.save_active_obj = None
+
+ args = (self, context)
+ self._handle = bpy.types.SpaceView3D.draw_handler_add(draw_callback_px, args, 'WINDOW', 'POST_PIXEL')
+
+ self.mouse_path = [(0, 0), (0, 0)]
+
+ # Keyboard event
+ self.shift = False
+ self.ctrl = False
+ self.alt = False
+
+ self.dont_apply_boolean = context.scene.mesh_carver.DontApply
+ self.Auto_BevelUpdate = True
+
+ # Circle variables
+ self.stepAngle = [2, 4, 5, 6, 9, 10, 15, 20, 30, 40, 45, 60, 72, 90]
+ self.step = 4
+
+ # Primitives Position
+ self.xpos = 0
+ self.ypos = 0
+ self.InitPosition = False
+
+ # Close polygonal shape
+ self.Closed = False
+
+ # Depth Cursor
+ self.snapCursor = context.scene.mesh_carver.DepthCursor
+
+ # Help
+ self.AskHelp = False
+
+ # Working object
+ self.OpsObj = context.active_object
+
+ # Rebool forced (cut line)
+ self.ForceRebool = False
+
+ self.ViewVector = Vector()
+ self.CurrentObj = None
+
+ # Brush
+ self.BrushSolidify = False
+ self.WidthSolidify = False
+ self.CarveDepth = False
+ self.BrushDepth = False
+ self.BrushDepthOffset = 0.0
+ self.snap = False
+
+ self.ObjectScale = False
+
+ #Init create circle primitive
+ self.CLR_C = []
+
+ # Cursor location
+ self.CurLoc = Vector((0.0, 0.0, 0.0))
+ self.SavCurLoc = Vector((0.0, 0.0, 0.0))
+
+ # Mouse region
+ self.mouse_region = -1, -1
+ self.SavMousePos = None
+ self.xSavMouse = 0
+
+ # Scale, rotate object
+ self.ascale = 0
+ self.aRotZ = 0
+ self.nRotZ = 0
+ self.quat_rot_axis = None
+ self.quat_rot = None
+
+ self.RandomRotation = context.scene.mesh_carver.ORandom
+
+ self.ShowCursor = True
+
+ self.Instantiate = context.scene.mesh_carver.OInstanciate
+
+ self.ProfileBrush = None
+ self.ObjectBrush = None
+
+ self.InitBrush = {
+ 'location' : None,
+ 'scale' : None,
+ 'rotation_quaternion' : None,
+ 'rotation_euler' : None,
+ 'display_type' : 'WIRE',
+ 'show_in_front' : False
+ }
+
+ # Array variables
+ self.nbcol = 1
+ self.nbrow = 1
+ self.gapx = 0
+ self.gapy = 0
+ self.scale_x = 1
+ self.scale_y = 1
+ self.GridScaleX = False
+ self.GridScaleY = False
+
+ @classmethod
+ def poll(cls, context):
+ ob = None
+ if len(context.selected_objects) > 0:
+ ob = context.selected_objects[0]
+ # Test if selected object or none (for create mode)
+ return (
+ (ob and ob.type == 'MESH' and context.mode == 'OBJECT') or
+ (context.mode == 'OBJECT' and ob is None) or
+ (context.mode == 'EDIT_MESH'))
+
+ def modal(self, context, event):
+ PI = 3.14156
+ region_types = {'WINDOW', 'UI'}
+ win = context.window
+
+ # Find the limit of the view3d region
+ self.check_region(context,event)
+
+ for area in win.screen.areas:
+ if area.type == 'VIEW_3D':
+ for region in area.regions:
+ if not region_types or region.type in region_types:
+ region.tag_redraw()
+
+ # Change the snap increment value using the wheel mouse
+ if self.CutMode:
+ if self.alt is False:
+ if self.ctrl and (self.CutType in (self.line, self.rectangle)):
+ # Get the VIEW3D area
+ for i, a in enumerate(context.screen.areas):
+ if a.type == 'VIEW_3D':
+ space = context.screen.areas[i].spaces.active
+ grid_scale = space.overlay.grid_scale
+ grid_subdivisions = space.overlay.grid_subdivisions
+
+ if event.type == 'WHEELUPMOUSE':
+ space.overlay.grid_subdivisions += 1
+ elif event.type == 'WHEELDOWNMOUSE':
+ space.overlay.grid_subdivisions -= 1
+
+ if event.type in {
+ 'MIDDLEMOUSE', 'WHEELUPMOUSE', 'WHEELDOWNMOUSE',
+ 'NUMPAD_1', 'NUMPAD_2', 'NUMPAD_3', 'NUMPAD_4', 'NUMPAD_6',
+ 'NUMPAD_7', 'NUMPAD_8', 'NUMPAD_9', 'NUMPAD_5'}:
+ return {'PASS_THROUGH'}
+
+ try:
+ # [Shift]
+ self.shift = True if event.shift else False
+
+ # [Ctrl]
+ self.ctrl = True if event.ctrl else False
+
+ # [Alt]
+ self.alt = False
+
+ # [Alt] press : Init position variable before moving the cut brush with LMB
+ if event.alt:
+ if self.InitPosition is False:
+ self.xpos = 0
+ self.ypos = 0
+ self.last_mouse_region_x = event.mouse_region_x
+ self.last_mouse_region_y = event.mouse_region_y
+ self.InitPosition = True
+ self.alt = True
+
+ # [Alt] release : update the coordinates
+ if self.InitPosition and self.alt is False:
+ for i in range(0, len(self.mouse_path)):
+ l = list(self.mouse_path[i])
+ l[0] += self.xpos
+ l[1] += self.ypos
+ self.mouse_path[i] = tuple(l)
+
+ self.xpos = self.ypos = 0
+ self.InitPosition = False
+
+ if event.type == 'SPACE' and event.value == 'PRESS':
+ # If object or profile mode is TRUE : Confirm the cut
+ if self.ObjectMode or self.ProfileMode:
+ # If array, remove double with intersect meshes
+ if ((self.nbcol + self.nbrow) > 3):
+ # Go in edit mode mode
+ bpy.ops.object.mode_set(mode='EDIT')
+ # Remove duplicate vertices
+ bpy.ops.mesh.remove_doubles()
+ # Return in object mode
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ if self.alt:
+ # Save selected objects
+ self.all_sel_obj_list = context.selected_objects.copy()
+ if len(context.selected_objects) > 0:
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ if self.ObjectMode:
+ SelectObject(self, self.ObjectBrush)
+ else:
+ SelectObject(self, self.ProfileBrush)
+ duplicateObject(self)
+ else:
+ # Brush Cut
+ self.Cut()
+ # Save selected objects
+ if self.ObjectMode:
+ if len(self.ObjectBrush.children) > 0:
+ self.all_sel_obj_list = context.selected_objects.copy()
+ if len(context.selected_objects) > 0:
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ if self.ObjectMode:
+ SelectObject(self, self.ObjectBrush)
+ else:
+ SelectObject(self, self.ProfileBrush)
+ duplicateObject(self)
+
+ UndoListUpdate(self)
+
+ # Save cursor position
+ self.SavMousePos = self.CurLoc
+ else:
+ if self.CutMode is False:
+ # Cut Mode
+ self.CutType += 1
+ if self.CutType > 2:
+ self.CutType = 0
+ else:
+ if self.CutType == self.line:
+ # Cuts creation
+ CreateCutLine(self, context)
+ if self.CreateMode:
+ # Object creation
+ self.CreateGeometry()
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+ # Cursor Snap
+ context.scene.mesh_carver.DepthCursor = self.snapCursor
+ # Object Instantiate
+ context.scene.mesh_carver.OInstanciate = self.Instantiate
+ # Random rotation
+ context.scene.mesh_carver.ORandom = self.RandomRotation
+
+ return {'FINISHED'}
+ else:
+ self.Cut()
+ UndoListUpdate(self)
#-----------------------------------------------------
@@ -343,1005 +343,1005 @@ class CARVER_OT_operator(bpy.types.Operator):
#-----------------------------------------------------
- # Object creation
- if event.type == self.carver_prefs.Key_Create and event.value == 'PRESS':
- if self.ExclusiveCreateMode is False:
- self.CreateMode = not self.CreateMode
-
- # Auto Bevel Update
- if event.type == self.carver_prefs.Key_Update and event.value == 'PRESS':
- self.Auto_BevelUpdate = not self.Auto_BevelUpdate
-
- # Boolean operation type
- if event.type == self.carver_prefs.Key_Bool and event.value == 'PRESS':
- if (self.ProfileMode is True) or (self.ObjectMode is True):
- if self.BoolOps == self.difference:
- self.BoolOps = self.union
- else:
- self.BoolOps = self.difference
-
- # Brush Mode
- if event.type == self.carver_prefs.Key_Brush and event.value == 'PRESS':
- self.dont_apply_boolean = False
- if (self.ProfileMode is False) and (self.ObjectMode is False):
- self.ProfileMode = True
- else:
- self.ProfileMode = False
- if self.ObjectBrush is not None:
- if self.ObjectMode is False:
- self.ObjectMode = True
- self.BrushSolidify = False
- self.CList = self.OB_List
-
- Selection_Save_Restore(self)
- context.scene.mesh_carver.nProfile = self.nProfil
- else:
- self.ObjectMode = False
- else:
- self.BrushSolidify = False
- Selection_Save_Restore(self)
-
- if self.ProfileMode:
- createMeshFromData(self)
- self.ProfileBrush = bpy.data.objects["CT_Profil"]
- Selection_Save(self)
- self.BrushSolidify = True
-
- bpy.ops.object.select_all(action='TOGGLE')
- self.ProfileBrush.select_set(True)
- context.view_layer.objects.active = self.ProfileBrush
- # Set xRay
- self.ProfileBrush.show_in_front = True
-
- bpy.ops.object.modifier_add(type='SOLIDIFY')
- context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
- context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
-
- Selection_Restore(self)
-
- self.CList = self.CurrentSelection
- else:
- if self.ObjectBrush is not None:
- if self.ObjectMode is False:
- if self.ObjectBrush is not None:
- self.ObjectBrush.location = self.InitBrush['location']
- self.ObjectBrush.scale = self.InitBrush['scale']
- self.ObjectBrush.rotation_quaternion = self.InitBrush['rotation_quaternion']
- self.ObjectBrush.rotation_euler = self.InitBrush['rotation_euler']
- self.ObjectBrush.display_type = self.InitBrush['display_type']
- self.ObjectBrush.show_in_front = self.InitBrush['show_in_front']
-
- #Store active and selected objects
- Selection_Save(self)
-
- #Remove Carver modifier
- self.BrushSolidify = False
- bpy.ops.object.select_all(action='TOGGLE')
- self.ObjectBrush.select_set(True)
- context.view_layer.objects.active = self.ObjectBrush
- bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
-
- #Restore selected and active object
- Selection_Restore(self)
- else:
- if self.SolidifyPossible:
- #Store active and selected objects
- Selection_Save(self)
- self.BrushSolidify = True
- bpy.ops.object.select_all(action='TOGGLE')
- self.ObjectBrush.select_set(True)
- context.view_layer.objects.active = self.ObjectBrush
- # Set xRay
- self.ObjectBrush.show_in_front = True
- bpy.ops.object.modifier_add(type='SOLIDIFY')
- context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
- context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
-
- #Restore selected and active object
- Selection_Restore(self)
-
- # Help display
- if event.type == self.carver_prefs.Key_Help and event.value == 'PRESS':
- self.AskHelp = not self.AskHelp
-
- # Instantiate object
- if event.type == self.carver_prefs.Key_Instant and event.value == 'PRESS':
- self.Instantiate = not self.Instantiate
-
- # Close polygonal shape
- if event.type == self.carver_prefs.Key_Close and event.value == 'PRESS':
- if self.CreateMode:
- self.Closed = not self.Closed
-
- if event.type == self.carver_prefs.Key_Apply and event.value == 'PRESS':
- self.dont_apply_boolean = not self.dont_apply_boolean
-
- # Scale object
- if event.type == self.carver_prefs.Key_Scale and event.value == 'PRESS':
- if self.ObjectScale is False:
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- self.ObjectScale = True
-
- # Grid : Snap on grid
- if event.type == self.carver_prefs.Key_Snap and event.value == 'PRESS':
- self.snap = not self.snap
-
- # Array : Add column
- if event.type == 'UP_ARROW' and event.value == 'PRESS':
- self.nbrow += 1
- update_grid(self, context)
-
- # Array : Delete column
- elif event.type == 'DOWN_ARROW' and event.value == 'PRESS':
- self.nbrow -= 1
- update_grid(self, context)
-
- # Array : Add row
- elif event.type == 'RIGHT_ARROW' and event.value == 'PRESS':
- self.nbcol += 1
- update_grid(self, context)
-
- # Array : Delete row
- elif event.type == 'LEFT_ARROW' and event.value == 'PRESS':
- self.nbcol -= 1
- update_grid(self, context)
-
- # Array : Scale gap between columns
- if event.type == self.carver_prefs.Key_Gapy and event.value == 'PRESS':
- if self.GridScaleX is False:
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- self.GridScaleX = True
-
- # Array : Scale gap between rows
- if event.type == self.carver_prefs.Key_Gapx and event.value == 'PRESS':
- if self.GridScaleY is False:
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- self.GridScaleY = True
-
- # Cursor depth or solidify pattern
- if event.type == self.carver_prefs.Key_Depth and event.value == 'PRESS':
- if (self.ObjectMode is False) and (self.ProfileMode is False):
- self.snapCursor = not self.snapCursor
- else:
- # Solidify
-
- if (self.ObjectMode or self.ProfileMode) and (self.SolidifyPossible):
- solidify = True
-
- if self.ObjectMode:
- z = self.ObjectBrush.data.vertices[0].co.z
- ErrorMarge = 0.01
- for v in self.ObjectBrush.data.vertices:
- if abs(v.co.z - z) > ErrorMarge:
- solidify = False
- self.CarveDepth = True
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- break
-
- if solidify:
- if self.ObjectMode:
- for mb in self.ObjectBrush.modifiers:
- if mb.type == 'SOLIDIFY':
- AlreadySoldify = True
- else:
- for mb in self.ProfileBrush.modifiers:
- if mb.type == 'SOLIDIFY':
- AlreadySoldify = True
-
- if AlreadySoldify is False:
- Selection_Save(self)
- self.BrushSolidify = True
-
- bpy.ops.object.select_all(action='TOGGLE')
- if self.ObjectMode:
- self.ObjectBrush.select_set(True)
- context.view_layer.objects.active = self.ObjectBrush
- # Active le xray
- self.ObjectBrush.show_in_front = True
- else:
- self.ProfileBrush.select_set(True)
- context.view_layer.objects.active = self.ProfileBrush
- # Active le xray
- self.ProfileBrush.show_in_front = True
-
- bpy.ops.object.modifier_add(type='SOLIDIFY')
- context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
-
- context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
-
- Selection_Restore(self)
-
- self.WidthSolidify = not self.WidthSolidify
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
-
- if event.type == self.carver_prefs.Key_BrushDepth and event.value == 'PRESS':
- if self.ObjectMode:
- self.CarveDepth = False
-
- self.BrushDepth = True
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
-
- # Random rotation
- if event.type == 'R' and event.value == 'PRESS':
- self.RandomRotation = not self.RandomRotation
-
- # Undo
- if event.type == 'Z' and event.value == 'PRESS':
- if self.ctrl:
- if (self.CutType == self.line) and (self.CutMode):
- if len(self.mouse_path) > 1:
- self.mouse_path[len(self.mouse_path) - 1:] = []
- else:
- Undo(self)
-
- # Mouse move
- if event.type == 'MOUSEMOVE' :
- if self.ObjectMode or self.ProfileMode:
- fac = 50.0
- if self.shift:
- fac = 500.0
- if self.WidthSolidify:
- if self.ObjectMode:
- bpy.data.objects[self.ObjectBrush.name].modifiers[
- "CT_SOLIDIFY"].thickness += (event.mouse_region_x - self.mouse_region[0]) / fac
- elif self.ProfileMode:
- bpy.data.objects[self.ProfileBrush.name].modifiers[
- "CT_SOLIDIFY"].thickness += (event.mouse_region_x - self.mouse_region[0]) / fac
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- elif self.CarveDepth:
- for v in self.ObjectBrush.data.vertices:
- v.co.z += (event.mouse_region_x - self.mouse_region[0]) / fac
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- elif self.BrushDepth:
- self.BrushDepthOffset += (event.mouse_region_x - self.mouse_region[0]) / fac
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- else:
- if (self.GridScaleX):
- self.gapx += (event.mouse_region_x - self.mouse_region[0]) / 50
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- update_grid(self, context)
- return {'RUNNING_MODAL'}
-
- elif (self.GridScaleY):
- self.gapy += (event.mouse_region_x - self.mouse_region[0]) / 50
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- update_grid(self, context)
- return {'RUNNING_MODAL'}
-
- elif self.ObjectScale:
- self.ascale = -(event.mouse_region_x - self.mouse_region[0])
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
-
- if self.ObjectMode:
- self.ObjectBrush.scale.x -= float(self.ascale) / 150.0
- if self.ObjectBrush.scale.x <= 0.0:
- self.ObjectBrush.scale.x = 0.0
- self.ObjectBrush.scale.y -= float(self.ascale) / 150.0
- if self.ObjectBrush.scale.y <= 0.0:
- self.ObjectBrush.scale.y = 0.0
- self.ObjectBrush.scale.z -= float(self.ascale) / 150.0
- if self.ObjectBrush.scale.z <= 0.0:
- self.ObjectBrush.scale.z = 0.0
-
- elif self.ProfileMode:
- if self.ProfileBrush is not None:
- self.ProfileBrush.scale.x -= float(self.ascale) / 150.0
- self.ProfileBrush.scale.y -= float(self.ascale) / 150.0
- self.ProfileBrush.scale.z -= float(self.ascale) / 150.0
- else:
- if self.LMB:
- if self.ctrl:
- self.aRotZ = - \
- ((int((event.mouse_region_x - self.xSavMouse) / 10.0) * PI / 4.0) * 25.0)
- else:
- self.aRotZ -= event.mouse_region_x - self.mouse_region[0]
- self.ascale = 0.0
-
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- else:
- target_hit, target_normal, target_eul_rotation = Pick(context, event, self)
- if target_hit is not None:
- self.ShowCursor = True
- up_vector = Vector((0.0, 0.0, 1.0))
- quat_rot_axis = rot_axis_quat(up_vector, target_normal)
- self.quat_rot = target_eul_rotation @ quat_rot_axis
- MoveCursor(quat_rot_axis, target_hit, self)
- self.SavCurLoc = target_hit
- if self.ctrl:
- if self.SavMousePos is not None:
- xEcart = abs(self.SavMousePos.x - self.SavCurLoc.x)
- yEcart = abs(self.SavMousePos.y - self.SavCurLoc.y)
- zEcart = abs(self.SavMousePos.z - self.SavCurLoc.z)
- if (xEcart > yEcart) and (xEcart > zEcart):
- self.CurLoc = Vector(
- (target_hit.x, self.SavMousePos.y, self.SavMousePos.z))
- if (yEcart > xEcart) and (yEcart > zEcart):
- self.CurLoc = Vector(
- (self.SavMousePos.x, target_hit.y, self.SavMousePos.z))
- if (zEcart > xEcart) and (zEcart > yEcart):
- self.CurLoc = Vector(
- (self.SavMousePos.x, self.SavMousePos.y, target_hit.z))
- else:
- self.CurLoc = target_hit
- else:
- self.CurLoc = target_hit
- else:
- if self.CutMode:
- if self.alt is False:
- if self.ctrl :
- # Find the closest position on the overlay grid and snap the mouse on it
- # Draw a mini grid around the cursor
- mouse_pos = [[event.mouse_region_x, event.mouse_region_y]]
- Snap_Cursor(self, context, event, mouse_pos)
-
- else:
- if len(self.mouse_path) > 0:
- self.mouse_path[len(self.mouse_path) -
- 1] = (event.mouse_region_x, event.mouse_region_y)
- else:
- # [ALT] press, update position
- self.xpos += (event.mouse_region_x - self.last_mouse_region_x)
- self.ypos += (event.mouse_region_y - self.last_mouse_region_y)
-
- self.last_mouse_region_x = event.mouse_region_x
- self.last_mouse_region_y = event.mouse_region_y
-
- elif event.type == 'LEFTMOUSE' and event.value == 'PRESS':
- if self.ObjectMode or self.ProfileMode:
- if self.LMB is False:
- target_hit, target_normal, target_eul_rotation = Pick(context, event, self)
- if target_hit is not None:
- up_vector = Vector((0.0, 0.0, 1.0))
- self.quat_rot_axis = rot_axis_quat(up_vector, target_normal)
- self.quat_rot = target_eul_rotation @ self.quat_rot_axis
- self.mouse_region = event.mouse_region_x, event.mouse_region_y
- self.xSavMouse = event.mouse_region_x
-
- if self.ctrl:
- self.nRotZ = int((self.aRotZ / 25.0) / (PI / 4.0))
- self.aRotZ = self.nRotZ * (PI / 4.0) * 25.0
-
- self.LMB = True
-
- # LEFTMOUSE
- elif event.type == 'LEFTMOUSE' and event.value == 'RELEASE' and self.in_view_3d:
- if self.ObjectMode or self.ProfileMode:
- # Rotation and scale
- self.LMB = False
- if self.ObjectScale is True:
- self.ObjectScale = False
-
- if self.GridScaleX is True:
- self.GridScaleX = False
-
- if self.GridScaleY is True:
- self.GridScaleY = False
-
- if self.WidthSolidify:
- self.WidthSolidify = False
-
- if self.CarveDepth is True:
- self.CarveDepth = False
-
- if self.BrushDepth is True:
- self.BrushDepth = False
-
- else:
- if self.CutMode is False:
- if self.ctrl:
- Picking(context, event)
-
- else:
-
- if self.CutType == self.line:
- if self.CutMode is False:
- self.mouse_path.clear()
- self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
- self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
- else:
- self.mouse_path[0] = (event.mouse_region_x, event.mouse_region_y)
- self.mouse_path[1] = (event.mouse_region_x, event.mouse_region_y)
- self.CutMode = True
- else:
- if self.CutType != self.line:
- # Cut creation
- if self.CutType == self.rectangle:
- CreateCutSquare(self, context)
- if self.CutType == self.circle:
- CreateCutCircle(self, context)
- if self.CutType == self.line:
- CreateCutLine(self, context)
-
- if self.CreateMode:
- # Object creation
- self.CreateGeometry()
- bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
- # Depth Cursor
- context.scene.mesh_carver.DepthCursor = self.snapCursor
- # Instantiate object
- context.scene.mesh_carver.OInstanciate = self.Instantiate
- # Random rotation
- context.scene.mesh_carver.ORandom = self.RandomRotation
- # Apply operation
- context.scene.mesh_carver.DontApply = self.dont_apply_boolean
-
- # if Object mode, set initiale state
- if self.ObjectBrush is not None:
- self.ObjectBrush.location = self.InitBrush['location']
- self.ObjectBrush.scale = self.InitBrush['scale']
- self.ObjectBrush.rotation_quaternion = self.InitBrush['rotation_quaternion']
- self.ObjectBrush.rotation_euler = self.InitBrush['rotation_euler']
- self.ObjectBrush.display_type = self.InitBrush['display_type']
- self.ObjectBrush.show_in_front = self.InitBrush['show_in_front']
-
- # remove solidify
- Selection_Save(self)
- self.BrushSolidify = False
-
- bpy.ops.object.select_all(action='TOGGLE')
- self.ObjectBrush.select_set(True)
- context.view_layer.objects.active = self.ObjectBrush
-
- bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
-
- Selection_Restore(self)
-
- context.scene.mesh_carver.nProfile = self.nProfil
-
- return {'FINISHED'}
- else:
- self.Cut()
- UndoListUpdate(self)
- else:
- # Line
- self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
-
- # Change brush profil or circle subdivisions
- elif (event.type == 'COMMA' and event.value == 'PRESS') or \
- (event.type == self.carver_prefs.Key_Subrem and event.value == 'PRESS'):
- # Brush profil
- if self.ProfileMode:
- self.nProfil += 1
- if self.nProfil >= self.MaxProfil:
- self.nProfil = 0
- createMeshFromData(self)
- # Circle subdivisions
- if self.CutType == self.circle:
- self.step += 1
- if self.step >= len(self.stepAngle):
- self.step = len(self.stepAngle) - 1
- # Change brush profil or circle subdivisions
- elif (event.type == 'PERIOD' and event.value == 'PRESS') or \
- (event.type == self.carver_prefs.Key_Subadd and event.value == 'PRESS'):
- # Brush profil
- if self.ProfileMode:
- self.nProfil -= 1
- if self.nProfil < 0:
- self.nProfil = self.MaxProfil - 1
- createMeshFromData(self)
- # Circle subdivisions
- if self.CutType == self.circle:
- if self.step > 0:
- self.step -= 1
- # Quit
- elif event.type in {'RIGHTMOUSE', 'ESC'}:
- # Depth Cursor
- context.scene.mesh_carver.DepthCursor = self.snapCursor
- # Instantiate object
- context.scene.mesh_carver.OInstanciate = self.Instantiate
- # Random Rotation
- context.scene.mesh_carver.ORandom = self.RandomRotation
- # Apply boolean operation
- context.scene.mesh_carver.DontApply = self.dont_apply_boolean
-
- # Reset Object
- if self.ObjectBrush is not None:
- self.ObjectBrush.location = self.InitBrush['location']
- self.ObjectBrush.scale = self.InitBrush['scale']
- self.ObjectBrush.rotation_quaternion = self.InitBrush['rotation_quaternion']
- self.ObjectBrush.rotation_euler = self.InitBrush['rotation_euler']
- self.ObjectBrush.display_type = self.InitBrush['display_type']
- self.ObjectBrush.show_in_front = self.InitBrush['show_in_front']
-
- # Remove solidify modifier
- Selection_Save(self)
- self.BrushSolidify = False
-
- bpy.ops.object.select_all(action='TOGGLE')
- self.ObjectBrush.select_set(True)
- context.view_layer.objects.active = self.ObjectBrush
-
- bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
- bpy.ops.object.select_all(action='TOGGLE')
-
- Selection_Restore(self)
-
- Selection_Save_Restore(self)
- context.view_layer.objects.active = self.CurrentActive
- context.scene.mesh_carver.nProfile = self.nProfil
-
- bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
-
- # Remove Copy Object Brush
- if bpy.data.objects.get("CarverBrushCopy") is not None:
- brush = bpy.data.objects["CarverBrushCopy"]
- self.ObjectBrush.data = bpy.data.meshes[brush.data.name]
- bpy.ops.object.select_all(action='DESELECT')
- bpy.data.objects["CarverBrushCopy"].select_set(True)
- bpy.ops.object.delete()
-
- return {'FINISHED'}
-
- return {'RUNNING_MODAL'}
-
- except:
- print("\n[Carver MT ERROR]\n")
- import traceback
- traceback.print_exc()
-
- context.window.cursor_modal_set("DEFAULT")
- context.area.header_text_set(None)
- bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
-
- self.report({'WARNING'},
- "Operation finished. Failure during Carving (Check the console for more info)")
-
- return {'FINISHED'}
-
- def cancel(self, context):
- # Note: used to prevent memory leaks on quitting Blender while the modal operator
- # is still running, gets called on return {"CANCELLED"}
- bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
-
- def invoke(self, context, event):
- if context.area.type != 'VIEW_3D':
- self.report({'WARNING'},
- "View3D not found or not currently active. Operation Cancelled")
- self.cancel(context)
- return {'CANCELLED'}
-
- # test if some other object types are selected that are not meshes
- for obj in context.selected_objects:
- if obj.type != "MESH":
- self.report({'WARNING'},
- "Some selected objects are not of the Mesh type. Operation Cancelled")
- self.cancel(context)
- return {'CANCELLED'}
-
- if context.mode == 'EDIT_MESH':
- bpy.ops.object.mode_set(mode='OBJECT')
-
- #Load the Carver preferences
- self.carver_prefs = bpy.context.preferences.addons[__package__].preferences
-
- # Get default patterns
- self.Profils = []
- for p in Profils:
- self.Profils.append((p[0], p[1], p[2], p[3]))
-
- for o in context.scene.objects:
- if not o.name.startswith(self.carver_prefs.ProfilePrefix):
- continue
- # In-scene profiles may have changed, remove them to refresh
- for m in bpy.data.meshes:
- if m.name.startswith(self.carver_prefs.ProfilePrefix):
- bpy.data.meshes.remove(m)
-
- vertices = []
- for v in o.data.vertices:
- vertices.append((v.co.x, v.co.y, v.co.z))
-
- faces = []
- for f in o.data.polygons:
- face = []
- for v in f.vertices:
- face.append(v)
-
- faces.append(face)
-
- self.Profils.append(
- (o.name,
- Vector((o.location.x, o.location.y, o.location.z)),
- vertices, faces)
- )
-
- self.nProfil = context.scene.mesh_carver.nProfile
- self.MaxProfil = len(self.Profils)
-
-
- # reset selected profile if last profile exceeds length of array
- if self.nProfil >= self.MaxProfil:
- self.nProfil = context.scene.mesh_carver.nProfile = 0
-
- if len(context.selected_objects) > 1:
- self.ObjectBrush = context.active_object
-
- # Copy the brush object
- ob = bpy.data.objects.new("CarverBrushCopy", context.object.data.copy())
- ob.location = self.ObjectBrush.location
- context.collection.objects.link(ob)
- context.view_layer.update()
-
- # Save default variables
- self.InitBrush['location'] = self.ObjectBrush.location.copy()
- self.InitBrush['scale'] = self.ObjectBrush.scale.copy()
- self.InitBrush['rotation_quaternion'] = self.ObjectBrush.rotation_quaternion.copy()
- self.InitBrush['rotation_euler'] = self.ObjectBrush.rotation_euler.copy()
- self.InitBrush['display_type'] = self.ObjectBrush.display_type
- self.InitBrush['show_in_front'] = self.ObjectBrush.show_in_front
-
- # Test if flat object
- z = self.ObjectBrush.data.vertices[0].co.z
- ErrorMarge = 0.01
- self.SolidifyPossible = True
- for v in self.ObjectBrush.data.vertices:
- if abs(v.co.z - z) > ErrorMarge:
- self.SolidifyPossible = False
- break
-
- self.CList = []
- self.OPList = []
- self.RList = []
- self.OB_List = []
-
- for obj in context.selected_objects:
- if obj != self.ObjectBrush:
- self.OB_List.append(obj)
-
- # Left button
- self.LMB = False
-
- # Undo Variables
- self.undo_index = 0
- self.undo_limit = context.preferences.edit.undo_steps
- self.undo_list = []
-
- # Boolean operations type
- self.BooleanType = 0
-
- self.UList = []
- self.UList_Index = -1
- self.UndoOps = []
-
- context.window_manager.modal_handler_add(self)
- return {'RUNNING_MODAL'}
-
- #Get the region area where the operator is used
- def check_region(self,context,event):
- if context.area != None:
- if context.area.type == "VIEW_3D" :
- for region in context.area.regions:
- if region.type == "TOOLS":
- t_panel = region
- elif region.type == "UI":
- ui_panel = region
-
- view_3d_region_x = Vector((context.area.x + t_panel.width, context.area.x + context.area.width - ui_panel.width))
- view_3d_region_y = Vector((context.region.y, context.region.y+context.region.height))
-
- if (event.mouse_x > view_3d_region_x[0] and event.mouse_x < view_3d_region_x[1] \
- and event.mouse_y > view_3d_region_y[0] and event.mouse_y < view_3d_region_y[1]):
- self.in_view_3d = True
- else:
- self.in_view_3d = False
- else:
- self.in_view_3d = False
-
- def CreateGeometry(self):
- context = bpy.context
- in_local_view = False
-
- for area in context.screen.areas:
- if area.type == 'VIEW_3D':
- if area.spaces[0].local_view is not None:
- in_local_view = True
-
- if in_local_view:
- bpy.ops.view3d.localview()
-
- if self.ExclusiveCreateMode:
- # Default width
- objBBDiagonal = 0.5
- else:
- ActiveObj = self.CurrentSelection[0]
- if ActiveObj is not None:
- # Object dimensions
- objBBDiagonal = objDiagonal(ActiveObj) / 4
- subdivisions = 2
-
- if len(context.selected_objects) > 0:
- bpy.ops.object.select_all(action='TOGGLE')
-
- context.view_layer.objects.active = self.CurrentObj
-
- bpy.data.objects[self.CurrentObj.name].select_set(True)
- bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
-
- bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.mesh.select_all(action='SELECT')
- bpy.ops.mesh.select_mode(type="EDGE")
- if self.snapCursor is False:
- bpy.ops.transform.translate(value=self.ViewVector * objBBDiagonal * subdivisions)
- bpy.ops.mesh.extrude_region_move(
- TRANSFORM_OT_translate={"value": -self.ViewVector * objBBDiagonal * subdivisions * 2})
-
- bpy.ops.mesh.select_all(action='SELECT')
- bpy.ops.mesh.normals_make_consistent()
- bpy.ops.object.mode_set(mode='OBJECT')
-
- saved_location_0 = context.scene.cursor.location.copy()
- bpy.ops.view3d.snap_cursor_to_active()
- saved_location = context.scene.cursor.location.copy()
- bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
- context.scene.cursor.location = saved_location
- bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
- context.scene.cursor.location = saved_location_0
-
- bpy.data.objects[self.CurrentObj.name].select_set(True)
- bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
-
- for o in self.all_sel_obj_list:
- bpy.data.objects[o.name].select_set(True)
-
- if in_local_view:
- bpy.ops.view3d.localview()
-
- self.CutMode = False
- self.mouse_path.clear()
- self.mouse_path = [(0, 0), (0, 0)]
-
- def Cut(self):
- context = bpy.context
-
- # Local view ?
- in_local_view = False
- for area in context.screen.areas:
- if area.type == 'VIEW_3D':
- if area.spaces[0].local_view is not None:
- in_local_view = True
-
- if in_local_view:
- bpy.ops.view3d.localview()
-
- # Save cursor position
- CursorLocation = context.scene.cursor.location.copy()
-
- #List of selected objects
- selected_obj_list = []
-
- #Cut Mode with line
- if (self.ObjectMode is False) and (self.ProfileMode is False):
-
- #Compute the bounding Box
- objBBDiagonal = objDiagonal(self.CurrentSelection[0])
- if self.dont_apply_boolean:
- subdivisions = 1
- else:
- subdivisions = 32
-
- # Get selected objects
- selected_obj_list = context.selected_objects.copy()
-
- bpy.ops.object.select_all(action='TOGGLE')
-
- context.view_layer.objects.active = self.CurrentObj
-
- bpy.data.objects[self.CurrentObj.name].select_set(True)
- bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
-
- bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.mesh.select_all(action='SELECT')
- bpy.ops.mesh.select_mode(type="EDGE")
- #Translate the created mesh away from the view
- if (self.snapCursor is False) or (self.ForceRebool):
- bpy.ops.transform.translate(value=self.ViewVector * objBBDiagonal * subdivisions)
- #Extrude the mesh region and move the result
- bpy.ops.mesh.extrude_region_move(
- TRANSFORM_OT_translate={"value": -self.ViewVector * objBBDiagonal * subdivisions * 2})
- bpy.ops.mesh.select_all(action='SELECT')
- bpy.ops.mesh.normals_make_consistent()
- bpy.ops.object.mode_set(mode='OBJECT')
- else:
- # Create list
- if self.ObjectMode:
- for o in self.CurrentSelection:
- if o != self.ObjectBrush:
- selected_obj_list.append(o)
- self.CurrentObj = self.ObjectBrush
- else:
- selected_obj_list = self.CurrentSelection
- self.CurrentObj = self.ProfileBrush
-
- for obj in self.CurrentSelection:
- UndoAdd(self, "MESH", obj)
-
- # List objects create with rebool
- lastSelected = []
-
- for ActiveObj in selected_obj_list:
- context.scene.cursor.location = CursorLocation
-
- if len(context.selected_objects) > 0:
- bpy.ops.object.select_all(action='TOGGLE')
-
- # Select cut object
- bpy.data.objects[self.CurrentObj.name].select_set(True)
- context.view_layer.objects.active = self.CurrentObj
-
- bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.mesh.select_all(action='SELECT')
- bpy.ops.object.mode_set(mode='OBJECT')
-
- # Select object to cut
- bpy.data.objects[ActiveObj.name].select_set(True)
- context.view_layer.objects.active = ActiveObj
-
- bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.mesh.select_all(action='DESELECT')
- bpy.ops.object.mode_set(mode='OBJECT')
-
- # Boolean operation
- if (self.shift is False) and (self.ForceRebool is False):
- if self.ObjectMode or self.ProfileMode:
- if self.BoolOps == self.union:
- boolean_operation(bool_type="UNION")
- else:
- boolean_operation(bool_type="DIFFERENCE")
- else:
- boolean_operation(bool_type="DIFFERENCE")
-
- # Apply booleans
- if self.dont_apply_boolean is False:
- BMname = "CT_" + self.CurrentObj.name
- for mb in ActiveObj.modifiers:
- if (mb.type == 'BOOLEAN') and (mb.name == BMname):
- try:
- bpy.ops.object.modifier_apply(apply_as='DATA', modifier=BMname)
- except:
- bpy.ops.object.modifier_remove(modifier=BMname)
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.report({'ERROR'}, str(exc_value))
-
- bpy.ops.object.select_all(action='TOGGLE')
- else:
- if self.ObjectMode or self.ProfileMode:
- for mb in self.CurrentObj.modifiers:
- if (mb.type == 'SOLIDIFY') and (mb.name == "CT_SOLIDIFY"):
- try:
- bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
- except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.report({'ERROR'}, str(exc_value))
-
- # Rebool
- Rebool(context, self)
-
- # Test if not empty object
- if context.selected_objects[0]:
- rebool_RT = context.selected_objects[0]
- if len(rebool_RT.data.vertices) > 0:
- # Create Bevel for new objects
- CreateBevel(context, context.selected_objects[0])
-
- UndoAdd(self, "REBOOL", context.selected_objects[0])
-
- context.scene.cursor.location = ActiveObj.location
- bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
- else:
- bpy.ops.object.delete(use_global=False)
-
- context.scene.cursor.location = CursorLocation
-
- if self.ObjectMode:
- context.view_layer.objects.active = self.ObjectBrush
- if self.ProfileMode:
- context.view_layer.objects.active = self.ProfileBrush
-
- if self.dont_apply_boolean is False:
- # Apply booleans
- BMname = "CT_" + self.CurrentObj.name
- for mb in ActiveObj.modifiers:
- if (mb.type == 'BOOLEAN') and (mb.name == BMname):
- try:
- bpy.ops.object.modifier_apply(apply_as='DATA', modifier=BMname)
- except:
- bpy.ops.object.modifier_remove(modifier=BMname)
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.report({'ERROR'}, str(exc_value))
- # Get new objects created with rebool operations
- if len(context.selected_objects) > 0:
- if self.shift is True:
- # Get the last object selected
- lastSelected.append(context.selected_objects[0])
-
- context.scene.cursor.location = CursorLocation
-
- if self.dont_apply_boolean is False:
- # Remove cut object
- if (self.ObjectMode is False) and (self.ProfileMode is False):
- if len(context.selected_objects) > 0:
- bpy.ops.object.select_all(action='TOGGLE')
- bpy.data.objects[self.CurrentObj.name].select_set(True)
- bpy.ops.object.delete(use_global=False)
- else:
- if self.ObjectMode:
- self.ObjectBrush.display_type = self.InitBrush['display_type']
-
- if len(context.selected_objects) > 0:
- bpy.ops.object.select_all(action='TOGGLE')
-
- # Select cut objects
- for obj in lastSelected:
- bpy.data.objects[obj.name].select_set(True)
-
- for ActiveObj in selected_obj_list:
- bpy.data.objects[ActiveObj.name].select_set(True)
- context.view_layer.objects.active = ActiveObj
- # Update bevel
- list_act_obj = context.selected_objects.copy()
- if self.Auto_BevelUpdate:
- update_bevel(context)
-
- # Re-select initial objects
- bpy.ops.object.select_all(action='TOGGLE')
- if self.ObjectMode:
- # Re-select brush
- self.ObjectBrush.select_set(True)
- for ActiveObj in selected_obj_list:
- bpy.data.objects[ActiveObj.name].select_set(True)
- context.view_layer.objects.active = ActiveObj
-
- # If object has children, set "Wire" draw type
- if self.ObjectBrush is not None:
- if len(self.ObjectBrush.children) > 0:
- self.ObjectBrush.display_type = "WIRE"
- if self.ProfileMode:
- self.ProfileBrush.display_type = "WIRE"
-
- if in_local_view:
- bpy.ops.view3d.localview()
-
- # Reset variables
- self.CutMode = False
- self.mouse_path.clear()
- self.mouse_path = [(0, 0), (0, 0)]
-
- self.ForceRebool = False
-
- # bpy.ops.mesh.customdata_custom_splitnormals_clear()
+ # Object creation
+ if event.type == self.carver_prefs.Key_Create and event.value == 'PRESS':
+ if self.ExclusiveCreateMode is False:
+ self.CreateMode = not self.CreateMode
+
+ # Auto Bevel Update
+ if event.type == self.carver_prefs.Key_Update and event.value == 'PRESS':
+ self.Auto_BevelUpdate = not self.Auto_BevelUpdate
+
+ # Boolean operation type
+ if event.type == self.carver_prefs.Key_Bool and event.value == 'PRESS':
+ if (self.ProfileMode is True) or (self.ObjectMode is True):
+ if self.BoolOps == self.difference:
+ self.BoolOps = self.union
+ else:
+ self.BoolOps = self.difference
+
+ # Brush Mode
+ if event.type == self.carver_prefs.Key_Brush and event.value == 'PRESS':
+ self.dont_apply_boolean = False
+ if (self.ProfileMode is False) and (self.ObjectMode is False):
+ self.ProfileMode = True
+ else:
+ self.ProfileMode = False
+ if self.ObjectBrush is not None:
+ if self.ObjectMode is False:
+ self.ObjectMode = True
+ self.BrushSolidify = False
+ self.CList = self.OB_List
+
+ Selection_Save_Restore(self)
+ context.scene.mesh_carver.nProfile = self.nProfil
+ else:
+ self.ObjectMode = False
+ else:
+ self.BrushSolidify = False
+ Selection_Save_Restore(self)
+
+ if self.ProfileMode:
+ createMeshFromData(self)
+ self.ProfileBrush = bpy.data.objects["CT_Profil"]
+ Selection_Save(self)
+ self.BrushSolidify = True
+
+ bpy.ops.object.select_all(action='TOGGLE')
+ self.ProfileBrush.select_set(True)
+ context.view_layer.objects.active = self.ProfileBrush
+ # Set xRay
+ self.ProfileBrush.show_in_front = True
+
+ bpy.ops.object.modifier_add(type='SOLIDIFY')
+ context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
+ context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
+
+ Selection_Restore(self)
+
+ self.CList = self.CurrentSelection
+ else:
+ if self.ObjectBrush is not None:
+ if self.ObjectMode is False:
+ if self.ObjectBrush is not None:
+ self.ObjectBrush.location = self.InitBrush['location']
+ self.ObjectBrush.scale = self.InitBrush['scale']
+ self.ObjectBrush.rotation_quaternion = self.InitBrush['rotation_quaternion']
+ self.ObjectBrush.rotation_euler = self.InitBrush['rotation_euler']
+ self.ObjectBrush.display_type = self.InitBrush['display_type']
+ self.ObjectBrush.show_in_front = self.InitBrush['show_in_front']
+
+ #Store active and selected objects
+ Selection_Save(self)
+
+ #Remove Carver modifier
+ self.BrushSolidify = False
+ bpy.ops.object.select_all(action='TOGGLE')
+ self.ObjectBrush.select_set(True)
+ context.view_layer.objects.active = self.ObjectBrush
+ bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
+
+ #Restore selected and active object
+ Selection_Restore(self)
+ else:
+ if self.SolidifyPossible:
+ #Store active and selected objects
+ Selection_Save(self)
+ self.BrushSolidify = True
+ bpy.ops.object.select_all(action='TOGGLE')
+ self.ObjectBrush.select_set(True)
+ context.view_layer.objects.active = self.ObjectBrush
+ # Set xRay
+ self.ObjectBrush.show_in_front = True
+ bpy.ops.object.modifier_add(type='SOLIDIFY')
+ context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
+ context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
+
+ #Restore selected and active object
+ Selection_Restore(self)
+
+ # Help display
+ if event.type == self.carver_prefs.Key_Help and event.value == 'PRESS':
+ self.AskHelp = not self.AskHelp
+
+ # Instantiate object
+ if event.type == self.carver_prefs.Key_Instant and event.value == 'PRESS':
+ self.Instantiate = not self.Instantiate
+
+ # Close polygonal shape
+ if event.type == self.carver_prefs.Key_Close and event.value == 'PRESS':
+ if self.CreateMode:
+ self.Closed = not self.Closed
+
+ if event.type == self.carver_prefs.Key_Apply and event.value == 'PRESS':
+ self.dont_apply_boolean = not self.dont_apply_boolean
+
+ # Scale object
+ if event.type == self.carver_prefs.Key_Scale and event.value == 'PRESS':
+ if self.ObjectScale is False:
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ self.ObjectScale = True
+
+ # Grid : Snap on grid
+ if event.type == self.carver_prefs.Key_Snap and event.value == 'PRESS':
+ self.snap = not self.snap
+
+ # Array : Add column
+ if event.type == 'UP_ARROW' and event.value == 'PRESS':
+ self.nbrow += 1
+ update_grid(self, context)
+
+ # Array : Delete column
+ elif event.type == 'DOWN_ARROW' and event.value == 'PRESS':
+ self.nbrow -= 1
+ update_grid(self, context)
+
+ # Array : Add row
+ elif event.type == 'RIGHT_ARROW' and event.value == 'PRESS':
+ self.nbcol += 1
+ update_grid(self, context)
+
+ # Array : Delete row
+ elif event.type == 'LEFT_ARROW' and event.value == 'PRESS':
+ self.nbcol -= 1
+ update_grid(self, context)
+
+ # Array : Scale gap between columns
+ if event.type == self.carver_prefs.Key_Gapy and event.value == 'PRESS':
+ if self.GridScaleX is False:
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ self.GridScaleX = True
+
+ # Array : Scale gap between rows
+ if event.type == self.carver_prefs.Key_Gapx and event.value == 'PRESS':
+ if self.GridScaleY is False:
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ self.GridScaleY = True
+
+ # Cursor depth or solidify pattern
+ if event.type == self.carver_prefs.Key_Depth and event.value == 'PRESS':
+ if (self.ObjectMode is False) and (self.ProfileMode is False):
+ self.snapCursor = not self.snapCursor
+ else:
+ # Solidify
+
+ if (self.ObjectMode or self.ProfileMode) and (self.SolidifyPossible):
+ solidify = True
+
+ if self.ObjectMode:
+ z = self.ObjectBrush.data.vertices[0].co.z
+ ErrorMarge = 0.01
+ for v in self.ObjectBrush.data.vertices:
+ if abs(v.co.z - z) > ErrorMarge:
+ solidify = False
+ self.CarveDepth = True
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ break
+
+ if solidify:
+ if self.ObjectMode:
+ for mb in self.ObjectBrush.modifiers:
+ if mb.type == 'SOLIDIFY':
+ AlreadySoldify = True
+ else:
+ for mb in self.ProfileBrush.modifiers:
+ if mb.type == 'SOLIDIFY':
+ AlreadySoldify = True
+
+ if AlreadySoldify is False:
+ Selection_Save(self)
+ self.BrushSolidify = True
+
+ bpy.ops.object.select_all(action='TOGGLE')
+ if self.ObjectMode:
+ self.ObjectBrush.select_set(True)
+ context.view_layer.objects.active = self.ObjectBrush
+ # Active le xray
+ self.ObjectBrush.show_in_front = True
+ else:
+ self.ProfileBrush.select_set(True)
+ context.view_layer.objects.active = self.ProfileBrush
+ # Active le xray
+ self.ProfileBrush.show_in_front = True
+
+ bpy.ops.object.modifier_add(type='SOLIDIFY')
+ context.object.modifiers["Solidify"].name = "CT_SOLIDIFY"
+
+ context.object.modifiers["CT_SOLIDIFY"].thickness = 0.1
+
+ Selection_Restore(self)
+
+ self.WidthSolidify = not self.WidthSolidify
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+
+ if event.type == self.carver_prefs.Key_BrushDepth and event.value == 'PRESS':
+ if self.ObjectMode:
+ self.CarveDepth = False
+
+ self.BrushDepth = True
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+
+ # Random rotation
+ if event.type == 'R' and event.value == 'PRESS':
+ self.RandomRotation = not self.RandomRotation
+
+ # Undo
+ if event.type == 'Z' and event.value == 'PRESS':
+ if self.ctrl:
+ if (self.CutType == self.line) and (self.CutMode):
+ if len(self.mouse_path) > 1:
+ self.mouse_path[len(self.mouse_path) - 1:] = []
+ else:
+ Undo(self)
+
+ # Mouse move
+ if event.type == 'MOUSEMOVE' :
+ if self.ObjectMode or self.ProfileMode:
+ fac = 50.0
+ if self.shift:
+ fac = 500.0
+ if self.WidthSolidify:
+ if self.ObjectMode:
+ bpy.data.objects[self.ObjectBrush.name].modifiers[
+ "CT_SOLIDIFY"].thickness += (event.mouse_region_x - self.mouse_region[0]) / fac
+ elif self.ProfileMode:
+ bpy.data.objects[self.ProfileBrush.name].modifiers[
+ "CT_SOLIDIFY"].thickness += (event.mouse_region_x - self.mouse_region[0]) / fac
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ elif self.CarveDepth:
+ for v in self.ObjectBrush.data.vertices:
+ v.co.z += (event.mouse_region_x - self.mouse_region[0]) / fac
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ elif self.BrushDepth:
+ self.BrushDepthOffset += (event.mouse_region_x - self.mouse_region[0]) / fac
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ else:
+ if (self.GridScaleX):
+ self.gapx += (event.mouse_region_x - self.mouse_region[0]) / 50
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ update_grid(self, context)
+ return {'RUNNING_MODAL'}
+
+ elif (self.GridScaleY):
+ self.gapy += (event.mouse_region_x - self.mouse_region[0]) / 50
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ update_grid(self, context)
+ return {'RUNNING_MODAL'}
+
+ elif self.ObjectScale:
+ self.ascale = -(event.mouse_region_x - self.mouse_region[0])
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+
+ if self.ObjectMode:
+ self.ObjectBrush.scale.x -= float(self.ascale) / 150.0
+ if self.ObjectBrush.scale.x <= 0.0:
+ self.ObjectBrush.scale.x = 0.0
+ self.ObjectBrush.scale.y -= float(self.ascale) / 150.0
+ if self.ObjectBrush.scale.y <= 0.0:
+ self.ObjectBrush.scale.y = 0.0
+ self.ObjectBrush.scale.z -= float(self.ascale) / 150.0
+ if self.ObjectBrush.scale.z <= 0.0:
+ self.ObjectBrush.scale.z = 0.0
+
+ elif self.ProfileMode:
+ if self.ProfileBrush is not None:
+ self.ProfileBrush.scale.x -= float(self.ascale) / 150.0
+ self.ProfileBrush.scale.y -= float(self.ascale) / 150.0
+ self.ProfileBrush.scale.z -= float(self.ascale) / 150.0
+ else:
+ if self.LMB:
+ if self.ctrl:
+ self.aRotZ = - \
+ ((int((event.mouse_region_x - self.xSavMouse) / 10.0) * PI / 4.0) * 25.0)
+ else:
+ self.aRotZ -= event.mouse_region_x - self.mouse_region[0]
+ self.ascale = 0.0
+
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ else:
+ target_hit, target_normal, target_eul_rotation = Pick(context, event, self)
+ if target_hit is not None:
+ self.ShowCursor = True
+ up_vector = Vector((0.0, 0.0, 1.0))
+ quat_rot_axis = rot_axis_quat(up_vector, target_normal)
+ self.quat_rot = target_eul_rotation @ quat_rot_axis
+ MoveCursor(quat_rot_axis, target_hit, self)
+ self.SavCurLoc = target_hit
+ if self.ctrl:
+ if self.SavMousePos is not None:
+ xEcart = abs(self.SavMousePos.x - self.SavCurLoc.x)
+ yEcart = abs(self.SavMousePos.y - self.SavCurLoc.y)
+ zEcart = abs(self.SavMousePos.z - self.SavCurLoc.z)
+ if (xEcart > yEcart) and (xEcart > zEcart):
+ self.CurLoc = Vector(
+ (target_hit.x, self.SavMousePos.y, self.SavMousePos.z))
+ if (yEcart > xEcart) and (yEcart > zEcart):
+ self.CurLoc = Vector(
+ (self.SavMousePos.x, target_hit.y, self.SavMousePos.z))
+ if (zEcart > xEcart) and (zEcart > yEcart):
+ self.CurLoc = Vector(
+ (self.SavMousePos.x, self.SavMousePos.y, target_hit.z))
+ else:
+ self.CurLoc = target_hit
+ else:
+ self.CurLoc = target_hit
+ else:
+ if self.CutMode:
+ if self.alt is False:
+ if self.ctrl :
+ # Find the closest position on the overlay grid and snap the mouse on it
+ # Draw a mini grid around the cursor
+ mouse_pos = [[event.mouse_region_x, event.mouse_region_y]]
+ Snap_Cursor(self, context, event, mouse_pos)
+
+ else:
+ if len(self.mouse_path) > 0:
+ self.mouse_path[len(self.mouse_path) -
+ 1] = (event.mouse_region_x, event.mouse_region_y)
+ else:
+ # [ALT] press, update position
+ self.xpos += (event.mouse_region_x - self.last_mouse_region_x)
+ self.ypos += (event.mouse_region_y - self.last_mouse_region_y)
+
+ self.last_mouse_region_x = event.mouse_region_x
+ self.last_mouse_region_y = event.mouse_region_y
+
+ elif event.type == 'LEFTMOUSE' and event.value == 'PRESS':
+ if self.ObjectMode or self.ProfileMode:
+ if self.LMB is False:
+ target_hit, target_normal, target_eul_rotation = Pick(context, event, self)
+ if target_hit is not None:
+ up_vector = Vector((0.0, 0.0, 1.0))
+ self.quat_rot_axis = rot_axis_quat(up_vector, target_normal)
+ self.quat_rot = target_eul_rotation @ self.quat_rot_axis
+ self.mouse_region = event.mouse_region_x, event.mouse_region_y
+ self.xSavMouse = event.mouse_region_x
+
+ if self.ctrl:
+ self.nRotZ = int((self.aRotZ / 25.0) / (PI / 4.0))
+ self.aRotZ = self.nRotZ * (PI / 4.0) * 25.0
+
+ self.LMB = True
+
+ # LEFTMOUSE
+ elif event.type == 'LEFTMOUSE' and event.value == 'RELEASE' and self.in_view_3d:
+ if self.ObjectMode or self.ProfileMode:
+ # Rotation and scale
+ self.LMB = False
+ if self.ObjectScale is True:
+ self.ObjectScale = False
+
+ if self.GridScaleX is True:
+ self.GridScaleX = False
+
+ if self.GridScaleY is True:
+ self.GridScaleY = False
+
+ if self.WidthSolidify:
+ self.WidthSolidify = False
+
+ if self.CarveDepth is True:
+ self.CarveDepth = False
+
+ if self.BrushDepth is True:
+ self.BrushDepth = False
+
+ else:
+ if self.CutMode is False:
+ if self.ctrl:
+ Picking(context, event)
+
+ else:
+
+ if self.CutType == self.line:
+ if self.CutMode is False:
+ self.mouse_path.clear()
+ self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
+ self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
+ else:
+ self.mouse_path[0] = (event.mouse_region_x, event.mouse_region_y)
+ self.mouse_path[1] = (event.mouse_region_x, event.mouse_region_y)
+ self.CutMode = True
+ else:
+ if self.CutType != self.line:
+ # Cut creation
+ if self.CutType == self.rectangle:
+ CreateCutSquare(self, context)
+ if self.CutType == self.circle:
+ CreateCutCircle(self, context)
+ if self.CutType == self.line:
+ CreateCutLine(self, context)
+
+ if self.CreateMode:
+ # Object creation
+ self.CreateGeometry()
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+ # Depth Cursor
+ context.scene.mesh_carver.DepthCursor = self.snapCursor
+ # Instantiate object
+ context.scene.mesh_carver.OInstanciate = self.Instantiate
+ # Random rotation
+ context.scene.mesh_carver.ORandom = self.RandomRotation
+ # Apply operation
+ context.scene.mesh_carver.DontApply = self.dont_apply_boolean
+
+ # if Object mode, set initiale state
+ if self.ObjectBrush is not None:
+ self.ObjectBrush.location = self.InitBrush['location']
+ self.ObjectBrush.scale = self.InitBrush['scale']
+ self.ObjectBrush.rotation_quaternion = self.InitBrush['rotation_quaternion']
+ self.ObjectBrush.rotation_euler = self.InitBrush['rotation_euler']
+ self.ObjectBrush.display_type = self.InitBrush['display_type']
+ self.ObjectBrush.show_in_front = self.InitBrush['show_in_front']
+
+ # remove solidify
+ Selection_Save(self)
+ self.BrushSolidify = False
+
+ bpy.ops.object.select_all(action='TOGGLE')
+ self.ObjectBrush.select_set(True)
+ context.view_layer.objects.active = self.ObjectBrush
+
+ bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
+
+ Selection_Restore(self)
+
+ context.scene.mesh_carver.nProfile = self.nProfil
+
+ return {'FINISHED'}
+ else:
+ self.Cut()
+ UndoListUpdate(self)
+ else:
+ # Line
+ self.mouse_path.append((event.mouse_region_x, event.mouse_region_y))
+
+ # Change brush profil or circle subdivisions
+ elif (event.type == 'COMMA' and event.value == 'PRESS') or \
+ (event.type == self.carver_prefs.Key_Subrem and event.value == 'PRESS'):
+ # Brush profil
+ if self.ProfileMode:
+ self.nProfil += 1
+ if self.nProfil >= self.MaxProfil:
+ self.nProfil = 0
+ createMeshFromData(self)
+ # Circle subdivisions
+ if self.CutType == self.circle:
+ self.step += 1
+ if self.step >= len(self.stepAngle):
+ self.step = len(self.stepAngle) - 1
+ # Change brush profil or circle subdivisions
+ elif (event.type == 'PERIOD' and event.value == 'PRESS') or \
+ (event.type == self.carver_prefs.Key_Subadd and event.value == 'PRESS'):
+ # Brush profil
+ if self.ProfileMode:
+ self.nProfil -= 1
+ if self.nProfil < 0:
+ self.nProfil = self.MaxProfil - 1
+ createMeshFromData(self)
+ # Circle subdivisions
+ if self.CutType == self.circle:
+ if self.step > 0:
+ self.step -= 1
+ # Quit
+ elif event.type in {'RIGHTMOUSE', 'ESC'}:
+ # Depth Cursor
+ context.scene.mesh_carver.DepthCursor = self.snapCursor
+ # Instantiate object
+ context.scene.mesh_carver.OInstanciate = self.Instantiate
+ # Random Rotation
+ context.scene.mesh_carver.ORandom = self.RandomRotation
+ # Apply boolean operation
+ context.scene.mesh_carver.DontApply = self.dont_apply_boolean
+
+ # Reset Object
+ if self.ObjectBrush is not None:
+ self.ObjectBrush.location = self.InitBrush['location']
+ self.ObjectBrush.scale = self.InitBrush['scale']
+ self.ObjectBrush.rotation_quaternion = self.InitBrush['rotation_quaternion']
+ self.ObjectBrush.rotation_euler = self.InitBrush['rotation_euler']
+ self.ObjectBrush.display_type = self.InitBrush['display_type']
+ self.ObjectBrush.show_in_front = self.InitBrush['show_in_front']
+
+ # Remove solidify modifier
+ Selection_Save(self)
+ self.BrushSolidify = False
+
+ bpy.ops.object.select_all(action='TOGGLE')
+ self.ObjectBrush.select_set(True)
+ context.view_layer.objects.active = self.ObjectBrush
+
+ bpy.ops.object.modifier_remove(modifier="CT_SOLIDIFY")
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ Selection_Restore(self)
+
+ Selection_Save_Restore(self)
+ context.view_layer.objects.active = self.CurrentActive
+ context.scene.mesh_carver.nProfile = self.nProfil
+
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+
+ # Remove Copy Object Brush
+ if bpy.data.objects.get("CarverBrushCopy") is not None:
+ brush = bpy.data.objects["CarverBrushCopy"]
+ self.ObjectBrush.data = bpy.data.meshes[brush.data.name]
+ bpy.ops.object.select_all(action='DESELECT')
+ bpy.data.objects["CarverBrushCopy"].select_set(True)
+ bpy.ops.object.delete()
+
+ return {'FINISHED'}
+
+ return {'RUNNING_MODAL'}
+
+ except:
+ print("\n[Carver MT ERROR]\n")
+ import traceback
+ traceback.print_exc()
+
+ context.window.cursor_modal_set("DEFAULT")
+ context.area.header_text_set(None)
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+
+ self.report({'WARNING'},
+ "Operation finished. Failure during Carving (Check the console for more info)")
+
+ return {'FINISHED'}
+
+ def cancel(self, context):
+ # Note: used to prevent memory leaks on quitting Blender while the modal operator
+ # is still running, gets called on return {"CANCELLED"}
+ bpy.types.SpaceView3D.draw_handler_remove(self._handle, 'WINDOW')
+
+ def invoke(self, context, event):
+ if context.area.type != 'VIEW_3D':
+ self.report({'WARNING'},
+ "View3D not found or not currently active. Operation Cancelled")
+ self.cancel(context)
+ return {'CANCELLED'}
+
+ # test if some other object types are selected that are not meshes
+ for obj in context.selected_objects:
+ if obj.type != "MESH":
+ self.report({'WARNING'},
+ "Some selected objects are not of the Mesh type. Operation Cancelled")
+ self.cancel(context)
+ return {'CANCELLED'}
+
+ if context.mode == 'EDIT_MESH':
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ #Load the Carver preferences
+ self.carver_prefs = bpy.context.preferences.addons[__package__].preferences
+
+ # Get default patterns
+ self.Profils = []
+ for p in Profils:
+ self.Profils.append((p[0], p[1], p[2], p[3]))
+
+ for o in context.scene.objects:
+ if not o.name.startswith(self.carver_prefs.ProfilePrefix):
+ continue
+ # In-scene profiles may have changed, remove them to refresh
+ for m in bpy.data.meshes:
+ if m.name.startswith(self.carver_prefs.ProfilePrefix):
+ bpy.data.meshes.remove(m)
+
+ vertices = []
+ for v in o.data.vertices:
+ vertices.append((v.co.x, v.co.y, v.co.z))
+
+ faces = []
+ for f in o.data.polygons:
+ face = []
+ for v in f.vertices:
+ face.append(v)
+
+ faces.append(face)
+
+ self.Profils.append(
+ (o.name,
+ Vector((o.location.x, o.location.y, o.location.z)),
+ vertices, faces)
+ )
+
+ self.nProfil = context.scene.mesh_carver.nProfile
+ self.MaxProfil = len(self.Profils)
+
+
+ # reset selected profile if last profile exceeds length of array
+ if self.nProfil >= self.MaxProfil:
+ self.nProfil = context.scene.mesh_carver.nProfile = 0
+
+ if len(context.selected_objects) > 1:
+ self.ObjectBrush = context.active_object
+
+ # Copy the brush object
+ ob = bpy.data.objects.new("CarverBrushCopy", context.object.data.copy())
+ ob.location = self.ObjectBrush.location
+ context.collection.objects.link(ob)
+ context.view_layer.update()
+
+ # Save default variables
+ self.InitBrush['location'] = self.ObjectBrush.location.copy()
+ self.InitBrush['scale'] = self.ObjectBrush.scale.copy()
+ self.InitBrush['rotation_quaternion'] = self.ObjectBrush.rotation_quaternion.copy()
+ self.InitBrush['rotation_euler'] = self.ObjectBrush.rotation_euler.copy()
+ self.InitBrush['display_type'] = self.ObjectBrush.display_type
+ self.InitBrush['show_in_front'] = self.ObjectBrush.show_in_front
+
+ # Test if flat object
+ z = self.ObjectBrush.data.vertices[0].co.z
+ ErrorMarge = 0.01
+ self.SolidifyPossible = True
+ for v in self.ObjectBrush.data.vertices:
+ if abs(v.co.z - z) > ErrorMarge:
+ self.SolidifyPossible = False
+ break
+
+ self.CList = []
+ self.OPList = []
+ self.RList = []
+ self.OB_List = []
+
+ for obj in context.selected_objects:
+ if obj != self.ObjectBrush:
+ self.OB_List.append(obj)
+
+ # Left button
+ self.LMB = False
+
+ # Undo Variables
+ self.undo_index = 0
+ self.undo_limit = context.preferences.edit.undo_steps
+ self.undo_list = []
+
+ # Boolean operations type
+ self.BooleanType = 0
+
+ self.UList = []
+ self.UList_Index = -1
+ self.UndoOps = []
+
+ context.window_manager.modal_handler_add(self)
+ return {'RUNNING_MODAL'}
+
+ #Get the region area where the operator is used
+ def check_region(self,context,event):
+ if context.area != None:
+ if context.area.type == "VIEW_3D" :
+ for region in context.area.regions:
+ if region.type == "TOOLS":
+ t_panel = region
+ elif region.type == "UI":
+ ui_panel = region
+
+ view_3d_region_x = Vector((context.area.x + t_panel.width, context.area.x + context.area.width - ui_panel.width))
+ view_3d_region_y = Vector((context.region.y, context.region.y+context.region.height))
+
+ if (event.mouse_x > view_3d_region_x[0] and event.mouse_x < view_3d_region_x[1] \
+ and event.mouse_y > view_3d_region_y[0] and event.mouse_y < view_3d_region_y[1]):
+ self.in_view_3d = True
+ else:
+ self.in_view_3d = False
+ else:
+ self.in_view_3d = False
+
+ def CreateGeometry(self):
+ context = bpy.context
+ in_local_view = False
+
+ for area in context.screen.areas:
+ if area.type == 'VIEW_3D':
+ if area.spaces[0].local_view is not None:
+ in_local_view = True
+
+ if in_local_view:
+ bpy.ops.view3d.localview()
+
+ if self.ExclusiveCreateMode:
+ # Default width
+ objBBDiagonal = 0.5
+ else:
+ ActiveObj = self.CurrentSelection[0]
+ if ActiveObj is not None:
+ # Object dimensions
+ objBBDiagonal = objDiagonal(ActiveObj) / 4
+ subdivisions = 2
+
+ if len(context.selected_objects) > 0:
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ context.view_layer.objects.active = self.CurrentObj
+
+ bpy.data.objects[self.CurrentObj.name].select_set(True)
+ bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.mesh.select_mode(type="EDGE")
+ if self.snapCursor is False:
+ bpy.ops.transform.translate(value=self.ViewVector * objBBDiagonal * subdivisions)
+ bpy.ops.mesh.extrude_region_move(
+ TRANSFORM_OT_translate={"value": -self.ViewVector * objBBDiagonal * subdivisions * 2})
+
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.mesh.normals_make_consistent()
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ saved_location_0 = context.scene.cursor.location.copy()
+ bpy.ops.view3d.snap_cursor_to_active()
+ saved_location = context.scene.cursor.location.copy()
+ bpy.ops.object.transform_apply(location=True, rotation=True, scale=True)
+ context.scene.cursor.location = saved_location
+ bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
+ context.scene.cursor.location = saved_location_0
+
+ bpy.data.objects[self.CurrentObj.name].select_set(True)
+ bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
+
+ for o in self.all_sel_obj_list:
+ bpy.data.objects[o.name].select_set(True)
+
+ if in_local_view:
+ bpy.ops.view3d.localview()
+
+ self.CutMode = False
+ self.mouse_path.clear()
+ self.mouse_path = [(0, 0), (0, 0)]
+
+ def Cut(self):
+ context = bpy.context
+
+ # Local view ?
+ in_local_view = False
+ for area in context.screen.areas:
+ if area.type == 'VIEW_3D':
+ if area.spaces[0].local_view is not None:
+ in_local_view = True
+
+ if in_local_view:
+ bpy.ops.view3d.localview()
+
+ # Save cursor position
+ CursorLocation = context.scene.cursor.location.copy()
+
+ #List of selected objects
+ selected_obj_list = []
+
+ #Cut Mode with line
+ if (self.ObjectMode is False) and (self.ProfileMode is False):
+
+ #Compute the bounding Box
+ objBBDiagonal = objDiagonal(self.CurrentSelection[0])
+ if self.dont_apply_boolean:
+ subdivisions = 1
+ else:
+ subdivisions = 32
+
+ # Get selected objects
+ selected_obj_list = context.selected_objects.copy()
+
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ context.view_layer.objects.active = self.CurrentObj
+
+ bpy.data.objects[self.CurrentObj.name].select_set(True)
+ bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY')
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.mesh.select_mode(type="EDGE")
+ #Translate the created mesh away from the view
+ if (self.snapCursor is False) or (self.ForceRebool):
+ bpy.ops.transform.translate(value=self.ViewVector * objBBDiagonal * subdivisions)
+ #Extrude the mesh region and move the result
+ bpy.ops.mesh.extrude_region_move(
+ TRANSFORM_OT_translate={"value": -self.ViewVector * objBBDiagonal * subdivisions * 2})
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.mesh.normals_make_consistent()
+ bpy.ops.object.mode_set(mode='OBJECT')
+ else:
+ # Create list
+ if self.ObjectMode:
+ for o in self.CurrentSelection:
+ if o != self.ObjectBrush:
+ selected_obj_list.append(o)
+ self.CurrentObj = self.ObjectBrush
+ else:
+ selected_obj_list = self.CurrentSelection
+ self.CurrentObj = self.ProfileBrush
+
+ for obj in self.CurrentSelection:
+ UndoAdd(self, "MESH", obj)
+
+ # List objects create with rebool
+ lastSelected = []
+
+ for ActiveObj in selected_obj_list:
+ context.scene.cursor.location = CursorLocation
+
+ if len(context.selected_objects) > 0:
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ # Select cut object
+ bpy.data.objects[self.CurrentObj.name].select_set(True)
+ context.view_layer.objects.active = self.CurrentObj
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Select object to cut
+ bpy.data.objects[ActiveObj.name].select_set(True)
+ context.view_layer.objects.active = ActiveObj
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ # Boolean operation
+ if (self.shift is False) and (self.ForceRebool is False):
+ if self.ObjectMode or self.ProfileMode:
+ if self.BoolOps == self.union:
+ boolean_operation(bool_type="UNION")
+ else:
+ boolean_operation(bool_type="DIFFERENCE")
+ else:
+ boolean_operation(bool_type="DIFFERENCE")
+
+ # Apply booleans
+ if self.dont_apply_boolean is False:
+ BMname = "CT_" + self.CurrentObj.name
+ for mb in ActiveObj.modifiers:
+ if (mb.type == 'BOOLEAN') and (mb.name == BMname):
+ try:
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier=BMname)
+ except:
+ bpy.ops.object.modifier_remove(modifier=BMname)
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.report({'ERROR'}, str(exc_value))
+
+ bpy.ops.object.select_all(action='TOGGLE')
+ else:
+ if self.ObjectMode or self.ProfileMode:
+ for mb in self.CurrentObj.modifiers:
+ if (mb.type == 'SOLIDIFY') and (mb.name == "CT_SOLIDIFY"):
+ try:
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
+ except:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.report({'ERROR'}, str(exc_value))
+
+ # Rebool
+ Rebool(context, self)
+
+ # Test if not empty object
+ if context.selected_objects[0]:
+ rebool_RT = context.selected_objects[0]
+ if len(rebool_RT.data.vertices) > 0:
+ # Create Bevel for new objects
+ CreateBevel(context, context.selected_objects[0])
+
+ UndoAdd(self, "REBOOL", context.selected_objects[0])
+
+ context.scene.cursor.location = ActiveObj.location
+ bpy.ops.object.origin_set(type='ORIGIN_CURSOR')
+ else:
+ bpy.ops.object.delete(use_global=False)
+
+ context.scene.cursor.location = CursorLocation
+
+ if self.ObjectMode:
+ context.view_layer.objects.active = self.ObjectBrush
+ if self.ProfileMode:
+ context.view_layer.objects.active = self.ProfileBrush
+
+ if self.dont_apply_boolean is False:
+ # Apply booleans
+ BMname = "CT_" + self.CurrentObj.name
+ for mb in ActiveObj.modifiers:
+ if (mb.type == 'BOOLEAN') and (mb.name == BMname):
+ try:
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier=BMname)
+ except:
+ bpy.ops.object.modifier_remove(modifier=BMname)
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.report({'ERROR'}, str(exc_value))
+ # Get new objects created with rebool operations
+ if len(context.selected_objects) > 0:
+ if self.shift is True:
+ # Get the last object selected
+ lastSelected.append(context.selected_objects[0])
+
+ context.scene.cursor.location = CursorLocation
+
+ if self.dont_apply_boolean is False:
+ # Remove cut object
+ if (self.ObjectMode is False) and (self.ProfileMode is False):
+ if len(context.selected_objects) > 0:
+ bpy.ops.object.select_all(action='TOGGLE')
+ bpy.data.objects[self.CurrentObj.name].select_set(True)
+ bpy.ops.object.delete(use_global=False)
+ else:
+ if self.ObjectMode:
+ self.ObjectBrush.display_type = self.InitBrush['display_type']
+
+ if len(context.selected_objects) > 0:
+ bpy.ops.object.select_all(action='TOGGLE')
+
+ # Select cut objects
+ for obj in lastSelected:
+ bpy.data.objects[obj.name].select_set(True)
+
+ for ActiveObj in selected_obj_list:
+ bpy.data.objects[ActiveObj.name].select_set(True)
+ context.view_layer.objects.active = ActiveObj
+ # Update bevel
+ list_act_obj = context.selected_objects.copy()
+ if self.Auto_BevelUpdate:
+ update_bevel(context)
+
+ # Re-select initial objects
+ bpy.ops.object.select_all(action='TOGGLE')
+ if self.ObjectMode:
+ # Re-select brush
+ self.ObjectBrush.select_set(True)
+ for ActiveObj in selected_obj_list:
+ bpy.data.objects[ActiveObj.name].select_set(True)
+ context.view_layer.objects.active = ActiveObj
+
+ # If object has children, set "Wire" draw type
+ if self.ObjectBrush is not None:
+ if len(self.ObjectBrush.children) > 0:
+ self.ObjectBrush.display_type = "WIRE"
+ if self.ProfileMode:
+ self.ProfileBrush.display_type = "WIRE"
+
+ if in_local_view:
+ bpy.ops.view3d.localview()
+
+ # Reset variables
+ self.CutMode = False
+ self.mouse_path.clear()
+ self.mouse_path = [(0, 0), (0, 0)]
+
+ self.ForceRebool = False
+
+ # bpy.ops.mesh.customdata_custom_splitnormals_clear()
class CarverProperties(bpy.types.PropertyGroup):
- DepthCursor: BoolProperty(
- name="DepthCursor",
- default=False
- )
- OInstanciate: BoolProperty(
- name="Obj_Instantiate",
- default=False
- )
- ORandom: BoolProperty(
- name="Random_Rotation",
- default=False
- )
- DontApply: BoolProperty(
- name="Dont_Apply",
- default=False
- )
- nProfile: IntProperty(
- name="Num_Profile",
- default=0
- )
+ DepthCursor: BoolProperty(
+ name="DepthCursor",
+ default=False
+ )
+ OInstanciate: BoolProperty(
+ name="Obj_Instantiate",
+ default=False
+ )
+ ORandom: BoolProperty(
+ name="Random_Rotation",
+ default=False
+ )
+ DontApply: BoolProperty(
+ name="Dont_Apply",
+ default=False
+ )
+ nProfile: IntProperty(
+ name="Num_Profile",
+ default=0
+ )
def register():
- from bpy.utils import register_class
- bpy.utils.register_class(CARVER_OT_operator)
- bpy.utils.register_class(CarverProperties)
- bpy.types.Scene.mesh_carver = bpy.props.PointerProperty(type=CarverProperties)
+ from bpy.utils import register_class
+ bpy.utils.register_class(CARVER_OT_operator)
+ bpy.utils.register_class(CarverProperties)
+ bpy.types.Scene.mesh_carver = bpy.props.PointerProperty(type=CarverProperties)
def unregister():
- from bpy.utils import unregister_class
- bpy.utils.unregister_class(CarverProperties)
- bpy.utils.unregister_class(CARVER_OT_operator)
- del bpy.types.Scene.mesh_carver
+ from bpy.utils import unregister_class
+ bpy.utils.unregister_class(CarverProperties)
+ bpy.utils.unregister_class(CARVER_OT_operator)
+ del bpy.types.Scene.mesh_carver
diff --git a/object_carver/carver_preferences.py b/object_carver/carver_preferences.py
index b7131193..1e6bc7ab 100644
--- a/object_carver/carver_preferences.py
+++ b/object_carver/carver_preferences.py
@@ -1,194 +1,194 @@
import bpy
from bpy.props import (
- BoolProperty,
- IntProperty,
- PointerProperty,
- StringProperty,
+ BoolProperty,
+ IntProperty,
+ PointerProperty,
+ StringProperty,
)
class CarverPrefs(bpy.types.AddonPreferences):
- bl_idname = __name__
+ bl_idname = __name__
- Enable_Tab_01: BoolProperty(
- name="Info",
- description="Some general information and settings about the add-on",
- default=False
- )
- Enable_Tab_02: BoolProperty(
- name="Hotkeys",
- description="List of the shortcuts used during carving",
- default=False
- )
- bpy.types.Scene.Key_Create: StringProperty(
- name="Object creation",
- description="Object creation",
- maxlen=1,
- default="C"
- )
- bpy.types.Scene.Key_Update: StringProperty(
- name="Auto Bevel Update",
- description="Auto Bevel Update",
- maxlen=1,
- default="A",
- )
- bpy.types.Scene.Key_Bool: StringProperty(
- name="Boolean type",
- description="Boolean operation type",
- maxlen=1,
- default="T",
- )
- bpy.types.Scene.Key_Brush: StringProperty(
- name="Brush Mode",
- description="Brush Mode",
- maxlen=1,
- default="B",
- )
- bpy.types.Scene.Key_Help: StringProperty(
- name="Help display",
- description="Help display",
- maxlen=1,
- default="H",
- )
- bpy.types.Scene.Key_Instant: StringProperty(
- name="Instantiate",
- description="Instantiate object",
- maxlen=1,
- default="I",
- )
- bpy.types.Scene.Key_Close: StringProperty(
- name="Close polygonal shape",
- description="Close polygonal shape",
- maxlen=1,
- default="X",
- )
- bpy.types.Scene.Key_Apply: StringProperty(
- name="Apply operation",
- description="Apply operation",
- maxlen=1,
- default="Q",
- )
- bpy.types.Scene.Key_Scale: StringProperty(
- name="Scale object",
- description="Scale object",
- maxlen=1,
- default="S",
- )
- bpy.types.Scene.Key_Gapy: StringProperty(
- name="Gap rows",
- description="Scale gap between columns",
- maxlen=1,
- default="J",
- )
- bpy.types.Scene.Key_Gapx: StringProperty(
- name="Gap columns",
- description="Scale gap between columns",
- maxlen=1,
- default="U",
- )
- bpy.types.Scene.Key_Depth: StringProperty(
- name="Depth",
- description="Cursor depth or solidify pattern",
- maxlen=1,
- default="D",
- )
- bpy.types.Scene.Key_BrushDepth: StringProperty(
- name="Brush Depth",
- description="Brush depth",
- maxlen=1,
- default="C",
- )
- bpy.types.Scene.Key_Subadd: StringProperty(
- name="Add subdivision",
- description="Add subdivision",
- maxlen=1,
- default="X",
- )
- bpy.types.Scene.Key_Subrem: StringProperty(
- name="Remove subdivision",
- description="Remove subdivision",
- maxlen=1,
- default="W",
- )
- bpy.types.Scene.Key_Randrot: StringProperty(
- name="Random rotation",
- description="Random rotation",
- maxlen=1,
- default="R",
- )
- bpy.types.Scene.ProfilePrefix: StringProperty(
- name="Profile prefix",
- description="Prefix to look for profiles with",
- default="Carver_Profile-"
- )
+ Enable_Tab_01: BoolProperty(
+ name="Info",
+ description="Some general information and settings about the add-on",
+ default=False
+ )
+ Enable_Tab_02: BoolProperty(
+ name="Hotkeys",
+ description="List of the shortcuts used during carving",
+ default=False
+ )
+ bpy.types.Scene.Key_Create: StringProperty(
+ name="Object creation",
+ description="Object creation",
+ maxlen=1,
+ default="C"
+ )
+ bpy.types.Scene.Key_Update: StringProperty(
+ name="Auto Bevel Update",
+ description="Auto Bevel Update",
+ maxlen=1,
+ default="A",
+ )
+ bpy.types.Scene.Key_Bool: StringProperty(
+ name="Boolean type",
+ description="Boolean operation type",
+ maxlen=1,
+ default="T",
+ )
+ bpy.types.Scene.Key_Brush: StringProperty(
+ name="Brush Mode",
+ description="Brush Mode",
+ maxlen=1,
+ default="B",
+ )
+ bpy.types.Scene.Key_Help: StringProperty(
+ name="Help display",
+ description="Help display",
+ maxlen=1,
+ default="H",
+ )
+ bpy.types.Scene.Key_Instant: StringProperty(
+ name="Instantiate",
+ description="Instantiate object",
+ maxlen=1,
+ default="I",
+ )
+ bpy.types.Scene.Key_Close: StringProperty(
+ name="Close polygonal shape",
+ description="Close polygonal shape",
+ maxlen=1,
+ default="X",
+ )
+ bpy.types.Scene.Key_Apply: StringProperty(
+ name="Apply operation",
+ description="Apply operation",
+ maxlen=1,
+ default="Q",
+ )
+ bpy.types.Scene.Key_Scale: StringProperty(
+ name="Scale object",
+ description="Scale object",
+ maxlen=1,
+ default="S",
+ )
+ bpy.types.Scene.Key_Gapy: StringProperty(
+ name="Gap rows",
+ description="Scale gap between columns",
+ maxlen=1,
+ default="J",
+ )
+ bpy.types.Scene.Key_Gapx: StringProperty(
+ name="Gap columns",
+ description="Scale gap between columns",
+ maxlen=1,
+ default="U",
+ )
+ bpy.types.Scene.Key_Depth: StringProperty(
+ name="Depth",
+ description="Cursor depth or solidify pattern",
+ maxlen=1,
+ default="D",
+ )
+ bpy.types.Scene.Key_BrushDepth: StringProperty(
+ name="Brush Depth",
+ description="Brush depth",
+ maxlen=1,
+ default="C",
+ )
+ bpy.types.Scene.Key_Subadd: StringProperty(
+ name="Add subdivision",
+ description="Add subdivision",
+ maxlen=1,
+ default="X",
+ )
+ bpy.types.Scene.Key_Subrem: StringProperty(
+ name="Remove subdivision",
+ description="Remove subdivision",
+ maxlen=1,
+ default="W",
+ )
+ bpy.types.Scene.Key_Randrot: StringProperty(
+ name="Random rotation",
+ description="Random rotation",
+ maxlen=1,
+ default="R",
+ )
+ bpy.types.Scene.ProfilePrefix: StringProperty(
+ name="Profile prefix",
+ description="Prefix to look for profiles with",
+ default="Carver_Profile-"
+ )
- def draw(self, context):
- scene = context.scene
- layout = self.layout
- print("DRAW !")
+ def draw(self, context):
+ scene = context.scene
+ layout = self.layout
+ print("DRAW !")
- icon_1 = "TRIA_RIGHT" if not self.Enable_Tab_01 else "TRIA_DOWN"
- box = layout.box()
+ icon_1 = "TRIA_RIGHT" if not self.Enable_Tab_01 else "TRIA_DOWN"
+ box = layout.box()
- box.prop(self, "Enable_Tab_01", text="Info and Settings", emboss=False, icon=icon_1)
- if self.Enable_Tab_01:
- box.label(text="Carver Operator:", icon="LAYER_ACTIVE")
- box.label(text="Select a Mesh Object and press [CTRL]+[SHIFT]+[X] to carve",
- icon="LAYER_USED")
- box.label(text="To finish carving press [ESC] or [RIGHT CLICK]",
- icon="LAYER_USED")
- box.prop(scene, "ProfilePrefix", text="Profile prefix")
+ box.prop(self, "Enable_Tab_01", text="Info and Settings", emboss=False, icon=icon_1)
+ if self.Enable_Tab_01:
+ box.label(text="Carver Operator:", icon="LAYER_ACTIVE")
+ box.label(text="Select a Mesh Object and press [CTRL]+[SHIFT]+[X] to carve",
+ icon="LAYER_USED")
+ box.label(text="To finish carving press [ESC] or [RIGHT CLICK]",
+ icon="LAYER_USED")
+ box.prop(scene, "ProfilePrefix", text="Profile prefix")
- icon_2 = "TRIA_RIGHT" if not self.Enable_Tab_02 else "TRIA_DOWN"
- box = layout.box()
- box.prop(self, "Enable_Tab_02", text="Keys", emboss=False, icon=icon_2)
- if self.Enable_Tab_02:
- split = box.split(align=True)
- box = split.box()
- col = box.column(align=True)
- col.label(text="Object Creation:")
- col.prop(scene, "Key_Create", text="")
- col.label(text="Auto bevel update:")
- col.prop(scene, "Key_Update", text="")
- col.label(text="Boolean operation type:")
- col.prop(scene, "Key_Bool", text="")
- col.label(text="Brush Depth:")
- col.prop(scene, "Key_BrushDepth", text="")
+ icon_2 = "TRIA_RIGHT" if not self.Enable_Tab_02 else "TRIA_DOWN"
+ box = layout.box()
+ box.prop(self, "Enable_Tab_02", text="Keys", emboss=False, icon=icon_2)
+ if self.Enable_Tab_02:
+ split = box.split(align=True)
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Object Creation:")
+ col.prop(scene, "Key_Create", text="")
+ col.label(text="Auto bevel update:")
+ col.prop(scene, "Key_Update", text="")
+ col.label(text="Boolean operation type:")
+ col.prop(scene, "Key_Bool", text="")
+ col.label(text="Brush Depth:")
+ col.prop(scene, "Key_BrushDepth", text="")
- box = split.box()
- col = box.column(align=True)
- col.label(text="Brush Mode:")
- col.prop(scene, "Key_Brush", text="")
- col.label(text="Help display:")
- col.prop(scene, "Key_Help", text="")
- col.label(text="Instantiate object:")
- col.prop(scene, "Key_Instant", text="")
- col.label(text="Random rotation:")
- col.prop(scene, "Key_Randrot", text="")
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Brush Mode:")
+ col.prop(scene, "Key_Brush", text="")
+ col.label(text="Help display:")
+ col.prop(scene, "Key_Help", text="")
+ col.label(text="Instantiate object:")
+ col.prop(scene, "Key_Instant", text="")
+ col.label(text="Random rotation:")
+ col.prop(scene, "Key_Randrot", text="")
- box = split.box()
- col = box.column(align=True)
- col.label(text="Close polygonal shape:")
- col.prop(scene, "Key_Close", text="")
- col.label(text="Apply operation:")
- col.prop(scene, "Key_Apply", text="")
- col.label(text="Scale object:")
- col.prop(scene, "Key_Scale", text="")
- col.label(text="Subdiv add:")
- col.prop(scene, "Key_Subadd", text="")
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Close polygonal shape:")
+ col.prop(scene, "Key_Close", text="")
+ col.label(text="Apply operation:")
+ col.prop(scene, "Key_Apply", text="")
+ col.label(text="Scale object:")
+ col.prop(scene, "Key_Scale", text="")
+ col.label(text="Subdiv add:")
+ col.prop(scene, "Key_Subadd", text="")
- box = split.box()
- col = box.column(align=True)
- col.label(text="Gap rows:")
- col.prop(scene, "Key_Gapy", text="")
- col.label(text="Gap columns:")
- col.prop(scene, "Key_Gapx", text="")
- col.label(text="Depth / Solidify:")
- col.prop(scene, "Key_Depth", text="")
- col.label(text="Subdiv Remove:")
- col.prop(scene, "Key_Subrem", text="")
+ box = split.box()
+ col = box.column(align=True)
+ col.label(text="Gap rows:")
+ col.prop(scene, "Key_Gapy", text="")
+ col.label(text="Gap columns:")
+ col.prop(scene, "Key_Gapx", text="")
+ col.label(text="Depth / Solidify:")
+ col.prop(scene, "Key_Depth", text="")
+ col.label(text="Subdiv Remove:")
+ col.prop(scene, "Key_Subrem", text="")
def register():
- bpy.utils.register_class(CarverPrefs)
+ bpy.utils.register_class(CarverPrefs)
def unregister():
- bpy.utils.unregister_class(CarverPrefs)
+ bpy.utils.unregister_class(CarverPrefs)
diff --git a/object_carver/carver_profils.py b/object_carver/carver_profils.py
index d19478c9..9c99bf97 100644
--- a/object_carver/carver_profils.py
+++ b/object_carver/carver_profils.py
@@ -1,409 +1,409 @@
from mathutils import (
- Vector,
+ Vector,
)
Profils = [
- ("TEST",
- Vector((0,0,1)),
- [(-1, 1, 0.032334), (1, 1, 0.032334),(-1, -1, 0.032334), (1, -1, 0.01032334)],
- [(0, 1, 2), (2,1,3)]),
- ("CTP_4882",
- Vector((2.61824, -5.56469, 0)),
- [(-1.156501, 0.799282, 0.032334),
- (-0.967583, 0.838861, 0.032334),
- (-1.10386, 0.846403, 0.032334),
- (-1.034712, 0.86089, 0.032334),
- (-1.88472, -0.564419, 0.032334),
- (-1.924299, -0.375502, 0.032334),
- (-1.93184, -0.511778, 0.032334),
- (-1.946327, -0.44263, 0.032334),
- (-0.219065, -0.869195, 0.032334),
- (-0.149916, -0.854708, 0.032334),
- (-0.286193, -0.847167, 0.032334),
- (-0.097275, -0.807588, 0.032334),
- (0.692551, 0.434324, 0.032334),
- (0.678064, 0.503472, 0.032334),
- (0.670523, 0.367196, 0.032334),
- (0.630943, 0.556113, 0.032334),
- (-0.780424, -0.44263, 0.032334),
- (-0.765937, -0.511778, 0.032334),
- (-0.758396, -0.375502, 0.032334),
- (-0.718817, -0.564419, 0.032334),
- (-0.53496, 0.556113, 0.032334),
- (-0.49538, 0.367196, 0.032334),
- (-0.487839, 0.503472, 0.032334),
- (-0.473352, 0.434324, 0.032334),
- (-1.263178, -0.807588, 0.032334),
- (-1.452096, -0.847167, 0.032334),
- (-1.315819, -0.854708, 0.032334),
- (-1.384968, -0.869195, 0.032334),
- (0.131191, 0.86089, 0.032334),
- (0.062043, 0.846403, 0.032334),
- (0.19832, 0.838861, 0.032334),
- (0.009402, 0.799282, 0.032334),
- (0.946838, -0.869195, 0.032334),
- (1.015987, -0.854708, 0.032334),
- (0.87971, -0.847167, 0.032334),
- (1.068628, -0.807588, 0.032334),
- (1.858454, 0.434324, 0.032334),
- (1.843967, 0.503472, 0.032334),
- (1.836426, 0.367196, 0.032334),
- (1.796846, 0.556113, 0.032334),
- (0.385479, -0.44263, 0.032334),
- (0.399966, -0.511778, 0.032334),
- (0.407507, -0.375502, 0.032334),
- (0.447086, -0.564419, 0.032334),
- (1.297095, 0.86089, 0.032334),
- (1.227946, 0.846403, 0.032334),
- (1.364223, 0.838861, 0.032334),
- (1.175305, 0.799282, 0.032334),
- ],
- [[16, 17, 19], [5, 4, 24], [14, 12, 15], [14, 15, 31], [10, 8, 11], [15, 30, 31], [19, 10, 11],
- [11, 14, 31], [31, 18, 11], [8, 9, 11], [18, 16, 19], [12, 13, 15], [18, 19, 11], [28, 29, 31],
- [30, 28, 31], [24, 21, 0], [23, 22, 20], [20, 1, 0], [3, 2, 0], [0, 5, 24], [7, 6, 4], [4, 25, 24],
- [27, 26, 24], [21, 23, 20], [1, 3, 0], [5, 7, 4], [25, 27, 24], [21, 20, 0], [40, 41, 43], [38, 36, 39],
- [38, 39, 47], [34, 32, 35], [39, 46, 47], [43, 34, 35], [35, 38, 47], [47, 42, 35], [32, 33, 35],
- [42, 40, 43], [36, 37, 39], [42, 43, 35], [44, 45, 47], [46, 44, 47]]),
- ("CTP_8354",
- Vector((-0.06267, -2.43829, -0.0)),
- [(-0.534254, -1.0, 0.032334),
- (-1.0, -0.534254, 0.032334),
- (-0.654798, -0.98413, 0.032334),
- (-0.767127, -0.937602, 0.032334),
- (-0.863586, -0.863586, 0.032334),
- (-0.937602, -0.767127, 0.032334),
- (-0.98413, -0.654798, 0.032334),
- (1.0, -0.534254, 0.032334),
- (0.534254, -1.0, 0.032334),
- (0.98413, -0.654798, 0.032334),
- (0.937602, -0.767127, 0.032334),
- (0.863586, -0.863586, 0.032334),
- (0.767127, -0.937602, 0.032334),
- (0.654798, -0.98413, 0.032334),
- (-1.0, 0.534254, 0.032334),
- (-0.534254, 1.0, 0.032334),
- (-0.98413, 0.654798, 0.032334),
- (-0.937602, 0.767127, 0.032334),
- (-0.863586, 0.863586, 0.032334),
- (-0.767127, 0.937602, 0.032334),
- (-0.654798, 0.98413, 0.032334),
- (0.534254, 1.0, 0.032334),
- (1.0, 0.534254, 0.032334),
- (0.654798, 0.98413, 0.032334),
- (0.767127, 0.937602, 0.032334),
- (0.863586, 0.863586, 0.032334),
- (0.937602, 0.767127, 0.032334),
- (0.98413, 0.654798, 0.032334),
- (-0.763998, 0.518786, 0.032334),
- (-0.763998, -0.518786, 0.032334),
- (-0.754202, -0.593189, 0.032334),
- (-0.731454, -0.648108, 0.032334),
- (-0.695267, -0.695267, 0.032334),
- (-0.648108, -0.731454, 0.032334),
- (-0.593189, -0.754202, 0.032334),
- (-0.518786, -0.763998, 0.032334),
- (0.518786, -0.763998, 0.032334),
- (0.593189, -0.754202, 0.032334),
- (0.648108, -0.731454, 0.032334),
- (0.695267, -0.695267, 0.032334),
- (0.731454, -0.648108, 0.032334),
- (0.754202, -0.593189, 0.032334),
- (0.763998, -0.518786, 0.032334),
- (0.763998, 0.518786, 0.032334),
- (0.754202, 0.593189, 0.032334),
- (0.731454, 0.648108, 0.032334),
- (0.695267, 0.695267, 0.032334),
- (0.648108, 0.731454, 0.032334),
- (0.593189, 0.754202, 0.032334),
- (0.518786, 0.763998, 0.032334),
- (-0.518786, 0.763998, 0.032334),
- (-0.593189, 0.754202, 0.032334),
- (-0.648108, 0.731454, 0.032334),
- (-0.695267, 0.695267, 0.032334),
- (-0.731454, 0.648108, 0.032334),
- (-0.754202, 0.593189, 0.032334),
- (0.518786, 0.518786, 0.032334),
- (-0.518786, 0.518786, 0.032334),
- (0.518786, -0.518786, 0.032334),
- (-0.518786, -0.518786, 0.032334),
- (-0.593189, 0.518786, 0.032334),
- (-0.593189, -0.518786, 0.032334),
- (0.518786, -0.593189, 0.032334),
- (-0.518786, -0.593189, 0.032334),
- (-0.593189, -0.593189, 0.032334),
- (0.593189, 0.518786, 0.032334),
- (0.593189, -0.518786, 0.032334),
- (0.593189, -0.593189, 0.032334),
- (-0.593189, 0.593189, 0.032334),
- (-0.518786, 0.593189, 0.032334),
- (0.518786, 0.593189, 0.032334),
- (0.593189, 0.593189, 0.032334),
- (-0.648108, 0.593189, 0.032334),
- (-0.648108, 0.518786, 0.032334),
- (-0.648108, -0.518786, 0.032334),
- (-0.648108, -0.593189, 0.032334),
- (-0.695267, 0.593189, 0.032334),
- (-0.695267, 0.518786, 0.032334),
- (-0.695267, -0.518786, 0.032334),
- (-0.695267, -0.593189, 0.032334),
- (0.648108, 0.593189, 0.032334),
- (0.648108, 0.518786, 0.032334),
- (0.648108, -0.518786, 0.032334),
- (0.648108, -0.593189, 0.032334),
- (0.695267, 0.593189, 0.032334),
- (0.695267, 0.518786, 0.032334),
- (0.695267, -0.518786, 0.032334),
- (0.695267, -0.593189, 0.032334),
- ],
- [[87, 39, 40, 41], [29, 28, 14, 1], [30, 29, 1, 6], [31, 30, 6, 5], [32, 31, 5, 4], [33, 32, 4, 3],
- [34, 33, 3, 2], [35, 34, 2, 0], [36, 35, 0, 8], [37, 36, 8, 13], [38, 37, 13, 12], [39, 38, 12, 11],
- [40, 39, 11, 10], [41, 40, 10, 9], [42, 41, 9, 7], [43, 42, 7, 22], [44, 43, 22, 27], [45, 44, 27, 26],
- [46, 45, 26, 25], [47, 46, 25, 24], [48, 47, 24, 23], [49, 48, 23, 21], [50, 49, 21, 15], [51, 50, 15, 20],
- [52, 51, 20, 19], [53, 52, 19, 18], [54, 53, 18, 17], [55, 54, 17, 16], [28, 55, 16, 14], [68, 69, 50, 51],
- [63, 35, 36, 62], [69, 57, 56, 70], [84, 85, 43, 44], [64, 34, 35, 63], [57, 59, 58, 56], [85, 86, 42, 43],
- [60, 61, 59, 57], [73, 74, 61, 60], [72, 68, 51, 52], [75, 33, 34, 64], [61, 64, 63, 59], [59, 63, 62, 58],
- [86, 87, 41, 42], [74, 75, 64, 61], [58, 62, 67, 66], [56, 58, 66, 65], [70, 56, 65, 71], [62, 36, 37, 67],
- [49, 70, 71, 48], [50, 69, 70, 49], [60, 57, 69, 68], [73, 60, 68, 72], [46, 84, 44, 45], [78, 79, 75, 74],
- [77, 78, 74, 73], [77, 73, 72, 76], [76, 72, 52, 53], [79, 32, 33, 75], [29, 30, 79, 78], [28, 29, 78, 77],
- [28, 77, 76, 55], [55, 76, 53, 54], [30, 31, 32, 79], [66, 67, 83, 82], [65, 66, 82, 81], [71, 65, 81, 80],
- [48, 71, 80, 47], [67, 37, 38, 83], [82, 83, 87, 86], [81, 82, 86, 85], [80, 81, 85, 84], [47, 80, 84, 46],
- [83, 38, 39, 87]]),
- ("CTP_5585",
- Vector((5.0114, -2.4281, 0.0)),
- [(-0.490711, -1.0, 0.032334),
- (-1.0, -0.490711, 0.032334),
- (1.0, -0.490711, 0.032334),
- (0.490711, -1.0, 0.032334),
- (-1.0, 0.490711, 0.032334),
- (-0.490711, 1.0, 0.032334),
- (0.490711, 1.0, 0.032334),
- (1.0, 0.490711, 0.032334),
- (-0.51852, 0.291276, 0.032334),
- (-0.51852, -0.291276, 0.032334),
- (-0.291276, -0.51852, 0.032334),
- (0.291276, -0.51852, 0.032334),
- (0.51852, -0.291276, 0.032334),
- (0.51852, 0.291276, 0.032334),
- (0.291276, 0.51852, 0.032334),
- (-0.291276, 0.51852, 0.032334),
- ],
- [[11, 12, 13, 14], [9, 8, 4, 1], [10, 9, 1, 0], [11, 10, 0, 3], [12, 11, 3, 2], [13, 12, 2, 7],
- [14, 13, 7, 6], [15, 14, 6, 5], [8, 15, 5, 4], [9, 10, 15, 8], [10, 11, 14, 15]]),
- ("CTP_6960",
- Vector((-0.11417, 2.48371, -0.0)),
- [(0.0, 1.0, 0.016827),
- (-0.382683, 0.92388, 0.016827),
- (-0.707107, 0.707107, 0.016827),
- (-0.92388, 0.382683, 0.016827),
- (-1.0, -0.0, 0.016827),
- (-0.92388, -0.382684, 0.016827),
- (-0.707107, -0.707107, 0.016827),
- (-0.382683, -0.92388, 0.016827),
- (-0.0, -1.0, 0.016827),
- (0.382683, -0.92388, 0.016827),
- (0.707107, -0.707107, 0.016827),
- (0.92388, -0.382684, 0.016827),
- (1.0, 0.0, 0.016827),
- (0.923879, 0.382684, 0.016827),
- (0.707107, 0.707107, 0.016827),
- (0.382683, 0.92388, 0.016827),
- (-0.0, 0.546859, 0.016827),
- (-0.209274, 0.505231, 0.016827),
- (-0.386687, 0.386687, 0.016827),
- (-0.505231, 0.209274, 0.016827),
- (-0.546859, -0.0, 0.016827),
- (-0.505231, -0.209274, 0.016827),
- (-0.386687, -0.386687, 0.016827),
- (-0.209274, -0.505231, 0.016827),
- (-0.0, -0.546859, 0.016827),
- (0.209274, -0.505231, 0.016827),
- (0.386687, -0.386688, 0.016827),
- (0.505231, -0.209274, 0.016827),
- (0.546858, 0.0, 0.016827),
- (0.505231, 0.209274, 0.016827),
- (0.386687, 0.386688, 0.016827),
- (0.209273, 0.505232, 0.016827),
- ],
- [[3, 19, 18, 2], [11, 27, 26, 10], [4, 20, 19, 3], [12, 28, 27, 11], [5, 21, 20, 4], [13, 29, 28, 12],
- [6, 22, 21, 5], [14, 30, 29, 13], [7, 23, 22, 6], [15, 31, 30, 14], [8, 24, 23, 7], [1, 17, 16, 0],
- [0, 16, 31, 15], [9, 25, 24, 8], [2, 18, 17, 1], [10, 26, 25, 9]]),
- ("CTP_5359",
- Vector((5.50446, 2.41669, -0.0)),
- [(0.0, 0.714247, 0.023261),
- (-0.382683, 0.659879, 0.023261),
- (-0.707107, 0.505049, 0.023261),
- (-0.92388, 0.273331, 0.023261),
- (-1.0, -0.0, 0.023261),
- (-0.92388, -0.273331, 0.023261),
- (-0.707107, -0.505049, 0.023261),
- (-0.382683, -0.659879, 0.023261),
- (-0.0, -0.714247, 0.023261),
- (0.382683, -0.659879, 0.023261),
- (0.707107, -0.505049, 0.023261),
- (0.92388, -0.273331, 0.023261),
- (1.0, 0.0, 0.023261),
- (0.923879, 0.273331, 0.023261),
- (0.707107, 0.505049, 0.023261),
- (0.382683, 0.659879, 0.023261),
- (-0.0, 0.303676, 0.023261),
- (-0.162705, 0.28056, 0.023261),
- (-0.30064, 0.214731, 0.023261),
- (-0.392805, 0.116212, 0.023261),
- (-0.425169, -0.0, 0.023261),
- (-0.392805, -0.116212, 0.023261),
- (-0.30064, -0.214731, 0.023261),
- (-0.162705, -0.28056, 0.023261),
- (-0.0, -0.303676, 0.023261),
- (0.162705, -0.28056, 0.023261),
- (0.30064, -0.214731, 0.023261),
- (0.392805, -0.116212, 0.023261),
- (0.425169, 0.0, 0.023261),
- (0.392805, 0.116212, 0.023261),
- (0.30064, 0.214731, 0.023261),
- (0.162705, 0.28056, 0.023261),
- ],
- [[3, 19, 18, 2], [11, 27, 26, 10], [4, 20, 19, 3], [12, 28, 27, 11], [5, 21, 20, 4], [13, 29, 28, 12],
- [6, 22, 21, 5], [14, 30, 29, 13], [7, 23, 22, 6], [15, 31, 30, 14], [8, 24, 23, 7], [1, 17, 16, 0],
- [0, 16, 31, 15], [9, 25, 24, 8], [2, 18, 17, 1], [10, 26, 25, 9]]),
- ("CTP_5424",
- Vector((2.61824, 2.34147, 0.0)),
- [(1.0, -1.0, 0.032334),
- (-1.0, 1.0, 0.032334),
- (1.0, 1.0, 0.032334),
- (0.783867, -0.259989, 0.032334),
- (-0.393641, 0.857073, 0.032334),
- (0.73142, -0.116299, 0.032334),
- (0.657754, 0.02916, 0.032334),
- (0.564682, 0.172804, 0.032334),
- (0.454497, 0.311098, 0.032334),
- (0.329912, 0.440635, 0.032334),
- (0.193995, 0.558227, 0.032334),
- (0.050092, 0.660978, 0.032334),
- (-0.098254, 0.746358, 0.032334),
- (-0.247389, 0.812263, 0.032334),
- ],
- [[3, 0, 2], [10, 9, 2], [2, 1, 4], [2, 4, 13], [5, 3, 2], [6, 5, 2], [2, 13, 12], [2, 12, 11], [7, 6, 2],
- [8, 7, 2], [2, 11, 10], [9, 8, 2]]),
- ("CTP_3774",
- Vector((2.61824, -2.52425, 0.0)),
- [(1.0, 0.0, 0.020045),
- (-1.0, 0.0, 0.020045),
- (0.31903, -0.664947, 0.020045),
- (-0.31903, -0.664947, 0.020045),
- (-0.31903, 1.0, 0.020045),
- (0.31903, 1.0, 0.020045),
- (0.31903, 0.0, 0.020045),
- (-0.31903, 0.0, 0.020045),
- (-1.0, 0.614333, 0.020045),
- (-0.614333, 1.0, 0.020045),
- (-0.970643, 0.761921, 0.020045),
- (-0.887041, 0.887041, 0.020045),
- (-0.761921, 0.970643, 0.020045),
- (0.614333, 1.0, 0.020045),
- (1.0, 0.614333, 0.020045),
- (0.761921, 0.970643, 0.020045),
- (0.887041, 0.887041, 0.020045),
- (0.970643, 0.761921, 0.020045),
- (-0.31903, 0.614333, 0.020045),
- (0.31903, 0.614333, 0.020045),
- (0.31903, 0.761921, 0.020045),
- (-0.31903, 0.761921, 0.020045),
- (0.31903, 0.887041, 0.020045),
- (-0.31903, 0.887041, 0.020045),
- (0.614333, 0.614333, 0.020045),
- (0.614333, 0.0, 0.020045),
- (0.614333, 0.761921, 0.020045),
- (0.614333, 0.887041, 0.020045),
- (-0.614333, 0.761921, 0.020045),
- (-0.614333, 0.0, 0.020045),
- (-0.614333, 0.887041, 0.020045),
- (-0.614333, 0.614333, 0.020045),
- ],
- [[6, 25, 24, 19], [6, 19, 18, 7], [2, 6, 7, 3], [1, 29, 31, 8], [8, 31, 28, 10], [19, 24, 26, 20],
- [18, 19, 20, 21], [21, 20, 22, 23], [10, 28, 30, 11], [20, 26, 27, 22], [22, 27, 13, 5], [23, 22, 5, 4],
- [11, 30, 9, 12], [17, 16, 27, 26], [14, 17, 26, 24], [24, 25, 0, 14], [15, 13, 27, 16], [9, 30, 23, 4],
- [31, 29, 7, 18], [28, 31, 18, 21], [30, 28, 21, 23]]),
- ("CTP_4473",
- Vector((7.31539, 0.0, 0.0)),
- [(0.24549, -1.0, 0.022454),
- (-0.24549, -1.0, 0.022454),
- (-0.24549, 1.0, 0.022454),
- (0.24549, 1.0, 0.022454),
- (1.0, 0.267452, 0.022454),
- (1.0, -0.267452, 0.022454),
- (-1.0, -0.267452, 0.022454),
- (-1.0, 0.267452, 0.022454),
- (0.24549, 0.267452, 0.022454),
- (0.24549, -0.267452, 0.022454),
- (-0.24549, 0.267452, 0.022454),
- (-0.24549, -0.267452, 0.022454),
- ],
- [[8, 3, 2, 10], [0, 9, 11, 1], [4, 8, 9, 5], [8, 10, 11, 9], [10, 7, 6, 11]]),
- ("CTP_4003",
- Vector((4.91276, 0.0, 0.0)),
- [(-1.0, -1.0, 0.026945),
- (1.0, -1.0, 0.026945),
- (-1.0, 1.0, 0.026945),
- (-0.026763, -1.0, 0.026945),
- (-0.026763, 1.0, 0.026945),
- (1.0, -0.026763, 0.026945),
- (0.238983, 0.965014, 0.026945),
- (0.486619, 0.86244, 0.026945),
- (0.699268, 0.699268, 0.026945),
- (0.86244, 0.486619, 0.026945),
- (0.965014, 0.238983, 0.026945),
- (0.238983, -1.0, 0.026945),
- (0.486619, -1.0, 0.026945),
- (0.699268, -1.0, 0.026945),
- (0.86244, -1.0, 0.026945),
- (-0.026763, 0.479676, 0.026945),
- (0.486619, 0.479676, 0.026945),
- (0.699268, 0.479676, 0.026945),
- (0.238983, 0.479676, 0.026945),
- (0.865316, 0.479676, 0.026945),
- (-1.0, 0.479676, 0.026945),
- (0.86244, 0.479676, 0.026945),
- (-0.026763, 0.238983, 0.026945),
- (0.486619, 0.238983, 0.026945),
- (0.699268, 0.238983, 0.026945),
- (0.238983, 0.238983, 0.026945),
- (-1.0, 0.238983, 0.026945),
- (0.86244, 0.238983, 0.026945),
- (-0.026763, -0.026763, 0.026945),
- (0.486619, -0.026763, 0.026945),
- (0.699268, -0.026763, 0.026945),
- (0.238983, -0.026763, 0.026945),
- (-1.0, -0.026763, 0.026945),
- (0.86244, -0.026763, 0.026945),
- ],
- [[0, 3, 28, 32], [4, 15, 18, 6], [6, 18, 16, 7], [7, 16, 17, 8], [8, 17, 21, 9], [9, 21, 19], [18, 15, 22, 25],
- [19, 21, 27, 10], [16, 18, 25, 23], [17, 16, 23, 24], [20, 15, 4, 2], [21, 17, 24, 27], [27, 24, 30, 33],
- [23, 25, 31, 29], [24, 23, 29, 30], [25, 22, 28, 31], [26, 22, 15, 20], [10, 27, 33, 5], [31, 28, 3, 11],
- [33, 30, 13, 14], [29, 31, 11, 12], [5, 33, 14, 1], [30, 29, 12, 13], [32, 28, 22, 26]]),
- ("CTP_3430",
- Vector((2.61824, 0.0, 0.0)),
- [(-1.0, -1.0, 0.032334),
- (1.0, -1.0, 0.032334),
- (-1.0, 1.0, 0.032334),
- (1.0, 1.0, 0.032334),
- ],
- [[0, 1, 3, 2]]),
- ("CTP_7175",
- Vector((0.0, 0.0, 0.0)),
- [(-1.0, -1.0, 0.032334),
- (1.0, -1.0, 0.032334),
- (-1.0, 1.0, 0.032334),
- (1.0, 1.0, 0.032334),
- (0.0, 0.0, 0.032334),
- (0.0, 0.0, 0.032334),
- (0.0, 0.0, 0.032334),
- (0.0, 0.0, 0.032334),
- (0.0, 0.0, 0.032334),
- (-0.636126, 0.636126, 0.032334),
- (-0.636126, -0.636126, 0.032334),
- (0.636126, -0.636126, 0.032334),
- (0.636126, 0.636126, 0.032334),
- ],
- [[10, 9, 2, 0], [11, 10, 0, 1], [12, 11, 1, 3], [9, 12, 3, 2]]),
+ ("TEST",
+ Vector((0,0,1)),
+ [(-1, 1, 0.032334), (1, 1, 0.032334),(-1, -1, 0.032334), (1, -1, 0.01032334)],
+ [(0, 1, 2), (2,1,3)]),
+ ("CTP_4882",
+ Vector((2.61824, -5.56469, 0)),
+ [(-1.156501, 0.799282, 0.032334),
+ (-0.967583, 0.838861, 0.032334),
+ (-1.10386, 0.846403, 0.032334),
+ (-1.034712, 0.86089, 0.032334),
+ (-1.88472, -0.564419, 0.032334),
+ (-1.924299, -0.375502, 0.032334),
+ (-1.93184, -0.511778, 0.032334),
+ (-1.946327, -0.44263, 0.032334),
+ (-0.219065, -0.869195, 0.032334),
+ (-0.149916, -0.854708, 0.032334),
+ (-0.286193, -0.847167, 0.032334),
+ (-0.097275, -0.807588, 0.032334),
+ (0.692551, 0.434324, 0.032334),
+ (0.678064, 0.503472, 0.032334),
+ (0.670523, 0.367196, 0.032334),
+ (0.630943, 0.556113, 0.032334),
+ (-0.780424, -0.44263, 0.032334),
+ (-0.765937, -0.511778, 0.032334),
+ (-0.758396, -0.375502, 0.032334),
+ (-0.718817, -0.564419, 0.032334),
+ (-0.53496, 0.556113, 0.032334),
+ (-0.49538, 0.367196, 0.032334),
+ (-0.487839, 0.503472, 0.032334),
+ (-0.473352, 0.434324, 0.032334),
+ (-1.263178, -0.807588, 0.032334),
+ (-1.452096, -0.847167, 0.032334),
+ (-1.315819, -0.854708, 0.032334),
+ (-1.384968, -0.869195, 0.032334),
+ (0.131191, 0.86089, 0.032334),
+ (0.062043, 0.846403, 0.032334),
+ (0.19832, 0.838861, 0.032334),
+ (0.009402, 0.799282, 0.032334),
+ (0.946838, -0.869195, 0.032334),
+ (1.015987, -0.854708, 0.032334),
+ (0.87971, -0.847167, 0.032334),
+ (1.068628, -0.807588, 0.032334),
+ (1.858454, 0.434324, 0.032334),
+ (1.843967, 0.503472, 0.032334),
+ (1.836426, 0.367196, 0.032334),
+ (1.796846, 0.556113, 0.032334),
+ (0.385479, -0.44263, 0.032334),
+ (0.399966, -0.511778, 0.032334),
+ (0.407507, -0.375502, 0.032334),
+ (0.447086, -0.564419, 0.032334),
+ (1.297095, 0.86089, 0.032334),
+ (1.227946, 0.846403, 0.032334),
+ (1.364223, 0.838861, 0.032334),
+ (1.175305, 0.799282, 0.032334),
+ ],
+ [[16, 17, 19], [5, 4, 24], [14, 12, 15], [14, 15, 31], [10, 8, 11], [15, 30, 31], [19, 10, 11],
+ [11, 14, 31], [31, 18, 11], [8, 9, 11], [18, 16, 19], [12, 13, 15], [18, 19, 11], [28, 29, 31],
+ [30, 28, 31], [24, 21, 0], [23, 22, 20], [20, 1, 0], [3, 2, 0], [0, 5, 24], [7, 6, 4], [4, 25, 24],
+ [27, 26, 24], [21, 23, 20], [1, 3, 0], [5, 7, 4], [25, 27, 24], [21, 20, 0], [40, 41, 43], [38, 36, 39],
+ [38, 39, 47], [34, 32, 35], [39, 46, 47], [43, 34, 35], [35, 38, 47], [47, 42, 35], [32, 33, 35],
+ [42, 40, 43], [36, 37, 39], [42, 43, 35], [44, 45, 47], [46, 44, 47]]),
+ ("CTP_8354",
+ Vector((-0.06267, -2.43829, -0.0)),
+ [(-0.534254, -1.0, 0.032334),
+ (-1.0, -0.534254, 0.032334),
+ (-0.654798, -0.98413, 0.032334),
+ (-0.767127, -0.937602, 0.032334),
+ (-0.863586, -0.863586, 0.032334),
+ (-0.937602, -0.767127, 0.032334),
+ (-0.98413, -0.654798, 0.032334),
+ (1.0, -0.534254, 0.032334),
+ (0.534254, -1.0, 0.032334),
+ (0.98413, -0.654798, 0.032334),
+ (0.937602, -0.767127, 0.032334),
+ (0.863586, -0.863586, 0.032334),
+ (0.767127, -0.937602, 0.032334),
+ (0.654798, -0.98413, 0.032334),
+ (-1.0, 0.534254, 0.032334),
+ (-0.534254, 1.0, 0.032334),
+ (-0.98413, 0.654798, 0.032334),
+ (-0.937602, 0.767127, 0.032334),
+ (-0.863586, 0.863586, 0.032334),
+ (-0.767127, 0.937602, 0.032334),
+ (-0.654798, 0.98413, 0.032334),
+ (0.534254, 1.0, 0.032334),
+ (1.0, 0.534254, 0.032334),
+ (0.654798, 0.98413, 0.032334),
+ (0.767127, 0.937602, 0.032334),
+ (0.863586, 0.863586, 0.032334),
+ (0.937602, 0.767127, 0.032334),
+ (0.98413, 0.654798, 0.032334),
+ (-0.763998, 0.518786, 0.032334),
+ (-0.763998, -0.518786, 0.032334),
+ (-0.754202, -0.593189, 0.032334),
+ (-0.731454, -0.648108, 0.032334),
+ (-0.695267, -0.695267, 0.032334),
+ (-0.648108, -0.731454, 0.032334),
+ (-0.593189, -0.754202, 0.032334),
+ (-0.518786, -0.763998, 0.032334),
+ (0.518786, -0.763998, 0.032334),
+ (0.593189, -0.754202, 0.032334),
+ (0.648108, -0.731454, 0.032334),
+ (0.695267, -0.695267, 0.032334),
+ (0.731454, -0.648108, 0.032334),
+ (0.754202, -0.593189, 0.032334),
+ (0.763998, -0.518786, 0.032334),
+ (0.763998, 0.518786, 0.032334),
+ (0.754202, 0.593189, 0.032334),
+ (0.731454, 0.648108, 0.032334),
+ (0.695267, 0.695267, 0.032334),
+ (0.648108, 0.731454, 0.032334),
+ (0.593189, 0.754202, 0.032334),
+ (0.518786, 0.763998, 0.032334),
+ (-0.518786, 0.763998, 0.032334),
+ (-0.593189, 0.754202, 0.032334),
+ (-0.648108, 0.731454, 0.032334),
+ (-0.695267, 0.695267, 0.032334),
+ (-0.731454, 0.648108, 0.032334),
+ (-0.754202, 0.593189, 0.032334),
+ (0.518786, 0.518786, 0.032334),
+ (-0.518786, 0.518786, 0.032334),
+ (0.518786, -0.518786, 0.032334),
+ (-0.518786, -0.518786, 0.032334),
+ (-0.593189, 0.518786, 0.032334),
+ (-0.593189, -0.518786, 0.032334),
+ (0.518786, -0.593189, 0.032334),
+ (-0.518786, -0.593189, 0.032334),
+ (-0.593189, -0.593189, 0.032334),
+ (0.593189, 0.518786, 0.032334),
+ (0.593189, -0.518786, 0.032334),
+ (0.593189, -0.593189, 0.032334),
+ (-0.593189, 0.593189, 0.032334),
+ (-0.518786, 0.593189, 0.032334),
+ (0.518786, 0.593189, 0.032334),
+ (0.593189, 0.593189, 0.032334),
+ (-0.648108, 0.593189, 0.032334),
+ (-0.648108, 0.518786, 0.032334),
+ (-0.648108, -0.518786, 0.032334),
+ (-0.648108, -0.593189, 0.032334),
+ (-0.695267, 0.593189, 0.032334),
+ (-0.695267, 0.518786, 0.032334),
+ (-0.695267, -0.518786, 0.032334),
+ (-0.695267, -0.593189, 0.032334),
+ (0.648108, 0.593189, 0.032334),
+ (0.648108, 0.518786, 0.032334),
+ (0.648108, -0.518786, 0.032334),
+ (0.648108, -0.593189, 0.032334),
+ (0.695267, 0.593189, 0.032334),
+ (0.695267, 0.518786, 0.032334),
+ (0.695267, -0.518786, 0.032334),
+ (0.695267, -0.593189, 0.032334),
+ ],
+ [[87, 39, 40, 41], [29, 28, 14, 1], [30, 29, 1, 6], [31, 30, 6, 5], [32, 31, 5, 4], [33, 32, 4, 3],
+ [34, 33, 3, 2], [35, 34, 2, 0], [36, 35, 0, 8], [37, 36, 8, 13], [38, 37, 13, 12], [39, 38, 12, 11],
+ [40, 39, 11, 10], [41, 40, 10, 9], [42, 41, 9, 7], [43, 42, 7, 22], [44, 43, 22, 27], [45, 44, 27, 26],
+ [46, 45, 26, 25], [47, 46, 25, 24], [48, 47, 24, 23], [49, 48, 23, 21], [50, 49, 21, 15], [51, 50, 15, 20],
+ [52, 51, 20, 19], [53, 52, 19, 18], [54, 53, 18, 17], [55, 54, 17, 16], [28, 55, 16, 14], [68, 69, 50, 51],
+ [63, 35, 36, 62], [69, 57, 56, 70], [84, 85, 43, 44], [64, 34, 35, 63], [57, 59, 58, 56], [85, 86, 42, 43],
+ [60, 61, 59, 57], [73, 74, 61, 60], [72, 68, 51, 52], [75, 33, 34, 64], [61, 64, 63, 59], [59, 63, 62, 58],
+ [86, 87, 41, 42], [74, 75, 64, 61], [58, 62, 67, 66], [56, 58, 66, 65], [70, 56, 65, 71], [62, 36, 37, 67],
+ [49, 70, 71, 48], [50, 69, 70, 49], [60, 57, 69, 68], [73, 60, 68, 72], [46, 84, 44, 45], [78, 79, 75, 74],
+ [77, 78, 74, 73], [77, 73, 72, 76], [76, 72, 52, 53], [79, 32, 33, 75], [29, 30, 79, 78], [28, 29, 78, 77],
+ [28, 77, 76, 55], [55, 76, 53, 54], [30, 31, 32, 79], [66, 67, 83, 82], [65, 66, 82, 81], [71, 65, 81, 80],
+ [48, 71, 80, 47], [67, 37, 38, 83], [82, 83, 87, 86], [81, 82, 86, 85], [80, 81, 85, 84], [47, 80, 84, 46],
+ [83, 38, 39, 87]]),
+ ("CTP_5585",
+ Vector((5.0114, -2.4281, 0.0)),
+ [(-0.490711, -1.0, 0.032334),
+ (-1.0, -0.490711, 0.032334),
+ (1.0, -0.490711, 0.032334),
+ (0.490711, -1.0, 0.032334),
+ (-1.0, 0.490711, 0.032334),
+ (-0.490711, 1.0, 0.032334),
+ (0.490711, 1.0, 0.032334),
+ (1.0, 0.490711, 0.032334),
+ (-0.51852, 0.291276, 0.032334),
+ (-0.51852, -0.291276, 0.032334),
+ (-0.291276, -0.51852, 0.032334),
+ (0.291276, -0.51852, 0.032334),
+ (0.51852, -0.291276, 0.032334),
+ (0.51852, 0.291276, 0.032334),
+ (0.291276, 0.51852, 0.032334),
+ (-0.291276, 0.51852, 0.032334),
+ ],
+ [[11, 12, 13, 14], [9, 8, 4, 1], [10, 9, 1, 0], [11, 10, 0, 3], [12, 11, 3, 2], [13, 12, 2, 7],
+ [14, 13, 7, 6], [15, 14, 6, 5], [8, 15, 5, 4], [9, 10, 15, 8], [10, 11, 14, 15]]),
+ ("CTP_6960",
+ Vector((-0.11417, 2.48371, -0.0)),
+ [(0.0, 1.0, 0.016827),
+ (-0.382683, 0.92388, 0.016827),
+ (-0.707107, 0.707107, 0.016827),
+ (-0.92388, 0.382683, 0.016827),
+ (-1.0, -0.0, 0.016827),
+ (-0.92388, -0.382684, 0.016827),
+ (-0.707107, -0.707107, 0.016827),
+ (-0.382683, -0.92388, 0.016827),
+ (-0.0, -1.0, 0.016827),
+ (0.382683, -0.92388, 0.016827),
+ (0.707107, -0.707107, 0.016827),
+ (0.92388, -0.382684, 0.016827),
+ (1.0, 0.0, 0.016827),
+ (0.923879, 0.382684, 0.016827),
+ (0.707107, 0.707107, 0.016827),
+ (0.382683, 0.92388, 0.016827),
+ (-0.0, 0.546859, 0.016827),
+ (-0.209274, 0.505231, 0.016827),
+ (-0.386687, 0.386687, 0.016827),
+ (-0.505231, 0.209274, 0.016827),
+ (-0.546859, -0.0, 0.016827),
+ (-0.505231, -0.209274, 0.016827),
+ (-0.386687, -0.386687, 0.016827),
+ (-0.209274, -0.505231, 0.016827),
+ (-0.0, -0.546859, 0.016827),
+ (0.209274, -0.505231, 0.016827),
+ (0.386687, -0.386688, 0.016827),
+ (0.505231, -0.209274, 0.016827),
+ (0.546858, 0.0, 0.016827),
+ (0.505231, 0.209274, 0.016827),
+ (0.386687, 0.386688, 0.016827),
+ (0.209273, 0.505232, 0.016827),
+ ],
+ [[3, 19, 18, 2], [11, 27, 26, 10], [4, 20, 19, 3], [12, 28, 27, 11], [5, 21, 20, 4], [13, 29, 28, 12],
+ [6, 22, 21, 5], [14, 30, 29, 13], [7, 23, 22, 6], [15, 31, 30, 14], [8, 24, 23, 7], [1, 17, 16, 0],
+ [0, 16, 31, 15], [9, 25, 24, 8], [2, 18, 17, 1], [10, 26, 25, 9]]),
+ ("CTP_5359",
+ Vector((5.50446, 2.41669, -0.0)),
+ [(0.0, 0.714247, 0.023261),
+ (-0.382683, 0.659879, 0.023261),
+ (-0.707107, 0.505049, 0.023261),
+ (-0.92388, 0.273331, 0.023261),
+ (-1.0, -0.0, 0.023261),
+ (-0.92388, -0.273331, 0.023261),
+ (-0.707107, -0.505049, 0.023261),
+ (-0.382683, -0.659879, 0.023261),
+ (-0.0, -0.714247, 0.023261),
+ (0.382683, -0.659879, 0.023261),
+ (0.707107, -0.505049, 0.023261),
+ (0.92388, -0.273331, 0.023261),
+ (1.0, 0.0, 0.023261),
+ (0.923879, 0.273331, 0.023261),
+ (0.707107, 0.505049, 0.023261),
+ (0.382683, 0.659879, 0.023261),
+ (-0.0, 0.303676, 0.023261),
+ (-0.162705, 0.28056, 0.023261),
+ (-0.30064, 0.214731, 0.023261),
+ (-0.392805, 0.116212, 0.023261),
+ (-0.425169, -0.0, 0.023261),
+ (-0.392805, -0.116212, 0.023261),
+ (-0.30064, -0.214731, 0.023261),
+ (-0.162705, -0.28056, 0.023261),
+ (-0.0, -0.303676, 0.023261),
+ (0.162705, -0.28056, 0.023261),
+ (0.30064, -0.214731, 0.023261),
+ (0.392805, -0.116212, 0.023261),
+ (0.425169, 0.0, 0.023261),
+ (0.392805, 0.116212, 0.023261),
+ (0.30064, 0.214731, 0.023261),
+ (0.162705, 0.28056, 0.023261),
+ ],
+ [[3, 19, 18, 2], [11, 27, 26, 10], [4, 20, 19, 3], [12, 28, 27, 11], [5, 21, 20, 4], [13, 29, 28, 12],
+ [6, 22, 21, 5], [14, 30, 29, 13], [7, 23, 22, 6], [15, 31, 30, 14], [8, 24, 23, 7], [1, 17, 16, 0],
+ [0, 16, 31, 15], [9, 25, 24, 8], [2, 18, 17, 1], [10, 26, 25, 9]]),
+ ("CTP_5424",
+ Vector((2.61824, 2.34147, 0.0)),
+ [(1.0, -1.0, 0.032334),
+ (-1.0, 1.0, 0.032334),
+ (1.0, 1.0, 0.032334),
+ (0.783867, -0.259989, 0.032334),
+ (-0.393641, 0.857073, 0.032334),
+ (0.73142, -0.116299, 0.032334),
+ (0.657754, 0.02916, 0.032334),
+ (0.564682, 0.172804, 0.032334),
+ (0.454497, 0.311098, 0.032334),
+ (0.329912, 0.440635, 0.032334),
+ (0.193995, 0.558227, 0.032334),
+ (0.050092, 0.660978, 0.032334),
+ (-0.098254, 0.746358, 0.032334),
+ (-0.247389, 0.812263, 0.032334),
+ ],
+ [[3, 0, 2], [10, 9, 2], [2, 1, 4], [2, 4, 13], [5, 3, 2], [6, 5, 2], [2, 13, 12], [2, 12, 11], [7, 6, 2],
+ [8, 7, 2], [2, 11, 10], [9, 8, 2]]),
+ ("CTP_3774",
+ Vector((2.61824, -2.52425, 0.0)),
+ [(1.0, 0.0, 0.020045),
+ (-1.0, 0.0, 0.020045),
+ (0.31903, -0.664947, 0.020045),
+ (-0.31903, -0.664947, 0.020045),
+ (-0.31903, 1.0, 0.020045),
+ (0.31903, 1.0, 0.020045),
+ (0.31903, 0.0, 0.020045),
+ (-0.31903, 0.0, 0.020045),
+ (-1.0, 0.614333, 0.020045),
+ (-0.614333, 1.0, 0.020045),
+ (-0.970643, 0.761921, 0.020045),
+ (-0.887041, 0.887041, 0.020045),
+ (-0.761921, 0.970643, 0.020045),
+ (0.614333, 1.0, 0.020045),
+ (1.0, 0.614333, 0.020045),
+ (0.761921, 0.970643, 0.020045),
+ (0.887041, 0.887041, 0.020045),
+ (0.970643, 0.761921, 0.020045),
+ (-0.31903, 0.614333, 0.020045),
+ (0.31903, 0.614333, 0.020045),
+ (0.31903, 0.761921, 0.020045),
+ (-0.31903, 0.761921, 0.020045),
+ (0.31903, 0.887041, 0.020045),
+ (-0.31903, 0.887041, 0.020045),
+ (0.614333, 0.614333, 0.020045),
+ (0.614333, 0.0, 0.020045),
+ (0.614333, 0.761921, 0.020045),
+ (0.614333, 0.887041, 0.020045),
+ (-0.614333, 0.761921, 0.020045),
+ (-0.614333, 0.0, 0.020045),
+ (-0.614333, 0.887041, 0.020045),
+ (-0.614333, 0.614333, 0.020045),
+ ],
+ [[6, 25, 24, 19], [6, 19, 18, 7], [2, 6, 7, 3], [1, 29, 31, 8], [8, 31, 28, 10], [19, 24, 26, 20],
+ [18, 19, 20, 21], [21, 20, 22, 23], [10, 28, 30, 11], [20, 26, 27, 22], [22, 27, 13, 5], [23, 22, 5, 4],
+ [11, 30, 9, 12], [17, 16, 27, 26], [14, 17, 26, 24], [24, 25, 0, 14], [15, 13, 27, 16], [9, 30, 23, 4],
+ [31, 29, 7, 18], [28, 31, 18, 21], [30, 28, 21, 23]]),
+ ("CTP_4473",
+ Vector((7.31539, 0.0, 0.0)),
+ [(0.24549, -1.0, 0.022454),
+ (-0.24549, -1.0, 0.022454),
+ (-0.24549, 1.0, 0.022454),
+ (0.24549, 1.0, 0.022454),
+ (1.0, 0.267452, 0.022454),
+ (1.0, -0.267452, 0.022454),
+ (-1.0, -0.267452, 0.022454),
+ (-1.0, 0.267452, 0.022454),
+ (0.24549, 0.267452, 0.022454),
+ (0.24549, -0.267452, 0.022454),
+ (-0.24549, 0.267452, 0.022454),
+ (-0.24549, -0.267452, 0.022454),
+ ],
+ [[8, 3, 2, 10], [0, 9, 11, 1], [4, 8, 9, 5], [8, 10, 11, 9], [10, 7, 6, 11]]),
+ ("CTP_4003",
+ Vector((4.91276, 0.0, 0.0)),
+ [(-1.0, -1.0, 0.026945),
+ (1.0, -1.0, 0.026945),
+ (-1.0, 1.0, 0.026945),
+ (-0.026763, -1.0, 0.026945),
+ (-0.026763, 1.0, 0.026945),
+ (1.0, -0.026763, 0.026945),
+ (0.238983, 0.965014, 0.026945),
+ (0.486619, 0.86244, 0.026945),
+ (0.699268, 0.699268, 0.026945),
+ (0.86244, 0.486619, 0.026945),
+ (0.965014, 0.238983, 0.026945),
+ (0.238983, -1.0, 0.026945),
+ (0.486619, -1.0, 0.026945),
+ (0.699268, -1.0, 0.026945),
+ (0.86244, -1.0, 0.026945),
+ (-0.026763, 0.479676, 0.026945),
+ (0.486619, 0.479676, 0.026945),
+ (0.699268, 0.479676, 0.026945),
+ (0.238983, 0.479676, 0.026945),
+ (0.865316, 0.479676, 0.026945),
+ (-1.0, 0.479676, 0.026945),
+ (0.86244, 0.479676, 0.026945),
+ (-0.026763, 0.238983, 0.026945),
+ (0.486619, 0.238983, 0.026945),
+ (0.699268, 0.238983, 0.026945),
+ (0.238983, 0.238983, 0.026945),
+ (-1.0, 0.238983, 0.026945),
+ (0.86244, 0.238983, 0.026945),
+ (-0.026763, -0.026763, 0.026945),
+ (0.486619, -0.026763, 0.026945),
+ (0.699268, -0.026763, 0.026945),
+ (0.238983, -0.026763, 0.026945),
+ (-1.0, -0.026763, 0.026945),
+ (0.86244, -0.026763, 0.026945),
+ ],
+ [[0, 3, 28, 32], [4, 15, 18, 6], [6, 18, 16, 7], [7, 16, 17, 8], [8, 17, 21, 9], [9, 21, 19], [18, 15, 22, 25],
+ [19, 21, 27, 10], [16, 18, 25, 23], [17, 16, 23, 24], [20, 15, 4, 2], [21, 17, 24, 27], [27, 24, 30, 33],
+ [23, 25, 31, 29], [24, 23, 29, 30], [25, 22, 28, 31], [26, 22, 15, 20], [10, 27, 33, 5], [31, 28, 3, 11],
+ [33, 30, 13, 14], [29, 31, 11, 12], [5, 33, 14, 1], [30, 29, 12, 13], [32, 28, 22, 26]]),
+ ("CTP_3430",
+ Vector((2.61824, 0.0, 0.0)),
+ [(-1.0, -1.0, 0.032334),
+ (1.0, -1.0, 0.032334),
+ (-1.0, 1.0, 0.032334),
+ (1.0, 1.0, 0.032334),
+ ],
+ [[0, 1, 3, 2]]),
+ ("CTP_7175",
+ Vector((0.0, 0.0, 0.0)),
+ [(-1.0, -1.0, 0.032334),
+ (1.0, -1.0, 0.032334),
+ (-1.0, 1.0, 0.032334),
+ (1.0, 1.0, 0.032334),
+ (0.0, 0.0, 0.032334),
+ (0.0, 0.0, 0.032334),
+ (0.0, 0.0, 0.032334),
+ (0.0, 0.0, 0.032334),
+ (0.0, 0.0, 0.032334),
+ (-0.636126, 0.636126, 0.032334),
+ (-0.636126, -0.636126, 0.032334),
+ (0.636126, -0.636126, 0.032334),
+ (0.636126, 0.636126, 0.032334),
+ ],
+ [[10, 9, 2, 0], [11, 10, 0, 1], [12, 11, 1, 3], [9, 12, 3, 2]]),
]
diff --git a/object_carver/carver_utils.py b/object_carver/carver_utils.py
index ce66052f..495aa1ce 100644
--- a/object_carver/carver_utils.py
+++ b/object_carver/carver_utils.py
@@ -8,934 +8,934 @@ import sys
import random
import bmesh
from mathutils import (
- Euler,
- Matrix,
- Vector,
- Quaternion,
+ Euler,
+ Matrix,
+ Vector,
+ Quaternion,
)
from mathutils.geometry import (
- intersect_line_plane,
+ intersect_line_plane,
)
from math import (
- sin,
- cos,
- pi,
- )
+ sin,
+ cos,
+ pi,
+ )
import bpy_extras
from bpy_extras import view3d_utils
from bpy_extras.view3d_utils import (
- region_2d_to_vector_3d,
- region_2d_to_location_3d,
- location_3d_to_region_2d,
+ region_2d_to_vector_3d,
+ region_2d_to_location_3d,
+ location_3d_to_region_2d,
)
# Cut Square
def CreateCutSquare(self, context):
- """ Create a rectangle mesh """
- far_limit = 10000.0
- faces=[]
-
- # Get the mouse coordinates
- coord = self.mouse_path[0][0], self.mouse_path[0][1]
-
- # New mesh
- me = bpy.data.meshes.new('CMT_Square')
- bm = bmesh.new()
- bm.from_mesh(me)
-
- # New object and link it to the scene
- ob = bpy.data.objects.new('CMT_Square', me)
- self.CurrentObj = ob
- context.collection.objects.link(ob)
-
- # Scene information
- region = context.region
- rv3d = context.region_data
- depth_location = region_2d_to_vector_3d(region, rv3d, coord)
- self.ViewVector = depth_location
-
- # Get a point on a infinite plane and its direction
- plane_normal = depth_location
- plane_direction = plane_normal.normalized()
-
- if self.snapCursor:
- plane_point = context.scene.cursor.location
- else:
- plane_point = self.OpsObj.location if self.OpsObj is not None else Vector((0.0, 0.0, 0.0))
-
- # Find the intersection of a line going thru each vertex and the infinite plane
- for v_co in self.rectangle_coord:
- vec = region_2d_to_vector_3d(region, rv3d, v_co)
- p0 = region_2d_to_location_3d(region, rv3d,v_co, vec)
- p1 = region_2d_to_location_3d(region, rv3d,v_co, vec) + plane_direction * far_limit
- faces.append(bm.verts.new(intersect_line_plane(p0, p1, plane_point, plane_direction)))
-
- # Update vertices index
- bm.verts.index_update()
- # New faces
- t_face = bm.faces.new(faces)
- # Set mesh
- bm.to_mesh(me)
+ """ Create a rectangle mesh """
+ far_limit = 10000.0
+ faces=[]
+
+ # Get the mouse coordinates
+ coord = self.mouse_path[0][0], self.mouse_path[0][1]
+
+ # New mesh
+ me = bpy.data.meshes.new('CMT_Square')
+ bm = bmesh.new()
+ bm.from_mesh(me)
+
+ # New object and link it to the scene
+ ob = bpy.data.objects.new('CMT_Square', me)
+ self.CurrentObj = ob
+ context.collection.objects.link(ob)
+
+ # Scene information
+ region = context.region
+ rv3d = context.region_data
+ depth_location = region_2d_to_vector_3d(region, rv3d, coord)
+ self.ViewVector = depth_location
+
+ # Get a point on a infinite plane and its direction
+ plane_normal = depth_location
+ plane_direction = plane_normal.normalized()
+
+ if self.snapCursor:
+ plane_point = context.scene.cursor.location
+ else:
+ plane_point = self.OpsObj.location if self.OpsObj is not None else Vector((0.0, 0.0, 0.0))
+
+ # Find the intersection of a line going thru each vertex and the infinite plane
+ for v_co in self.rectangle_coord:
+ vec = region_2d_to_vector_3d(region, rv3d, v_co)
+ p0 = region_2d_to_location_3d(region, rv3d,v_co, vec)
+ p1 = region_2d_to_location_3d(region, rv3d,v_co, vec) + plane_direction * far_limit
+ faces.append(bm.verts.new(intersect_line_plane(p0, p1, plane_point, plane_direction)))
+
+ # Update vertices index
+ bm.verts.index_update()
+ # New faces
+ t_face = bm.faces.new(faces)
+ # Set mesh
+ bm.to_mesh(me)
# Cut Line
def CreateCutLine(self, context):
- """ Create a polygon mesh """
- far_limit = 10000.0
- vertices = []
- faces = []
- loc = []
-
- # Get the mouse coordinates
- coord = self.mouse_path[0][0], self.mouse_path[0][1]
-
- # New mesh
- me = bpy.data.meshes.new('CMT_Line')
- bm = bmesh.new()
- bm.from_mesh(me)
-
- # New object and link it to the scene
- ob = bpy.data.objects.new('CMT_Line', me)
- self.CurrentObj = ob
- context.collection.objects.link(ob)
-
- # Scene information
- region = context.region
- rv3d = context.region_data
- depth_location = region_2d_to_vector_3d(region, rv3d, coord)
- self.ViewVector = depth_location
-
- # Get a point on a infinite plane and its direction
- plane_normal = depth_location
- plane_direction = plane_normal.normalized()
-
- if self.snapCursor:
- plane_point = context.scene.cursor.location
- else:
- plane_point = self.OpsObj.location if self.OpsObj is not None else Vector((0.0, 0.0, 0.0))
-
- # Use dict to remove doubles
- # Find the intersection of a line going thru each vertex and the infinite plane
- for idx, v_co in enumerate(list(dict.fromkeys(self.mouse_path))):
- vec = region_2d_to_vector_3d(region, rv3d, v_co)
- p0 = region_2d_to_location_3d(region, rv3d,v_co, vec)
- p1 = region_2d_to_location_3d(region, rv3d,v_co, vec) + plane_direction * far_limit
- loc.append(intersect_line_plane(p0, p1, plane_point, plane_direction))
- vertices.append(bm.verts.new(loc[idx]))
-
- if idx > 0:
- bm.edges.new([vertices[idx-1],vertices[idx]])
-
- faces.append(vertices[idx])
-
- # Update vertices index
- bm.verts.index_update()
-
- # Nothing is selected, create close geometry
- if self.CreateMode:
- if self.Closed and len(vertices) > 1:
- bm.edges.new([vertices[-1], vertices[0]])
- bm.faces.new(faces)
- else:
- # Create faces if more than 2 vertices
- if len(vertices) > 1 :
- bm.edges.new([vertices[-1], vertices[0]])
- bm.faces.new(faces)
-
- bm.to_mesh(me)
+ """ Create a polygon mesh """
+ far_limit = 10000.0
+ vertices = []
+ faces = []
+ loc = []
+
+ # Get the mouse coordinates
+ coord = self.mouse_path[0][0], self.mouse_path[0][1]
+
+ # New mesh
+ me = bpy.data.meshes.new('CMT_Line')
+ bm = bmesh.new()
+ bm.from_mesh(me)
+
+ # New object and link it to the scene
+ ob = bpy.data.objects.new('CMT_Line', me)
+ self.CurrentObj = ob
+ context.collection.objects.link(ob)
+
+ # Scene information
+ region = context.region
+ rv3d = context.region_data
+ depth_location = region_2d_to_vector_3d(region, rv3d, coord)
+ self.ViewVector = depth_location
+
+ # Get a point on a infinite plane and its direction
+ plane_normal = depth_location
+ plane_direction = plane_normal.normalized()
+
+ if self.snapCursor:
+ plane_point = context.scene.cursor.location
+ else:
+ plane_point = self.OpsObj.location if self.OpsObj is not None else Vector((0.0, 0.0, 0.0))
+
+ # Use dict to remove doubles
+ # Find the intersection of a line going thru each vertex and the infinite plane
+ for idx, v_co in enumerate(list(dict.fromkeys(self.mouse_path))):
+ vec = region_2d_to_vector_3d(region, rv3d, v_co)
+ p0 = region_2d_to_location_3d(region, rv3d,v_co, vec)
+ p1 = region_2d_to_location_3d(region, rv3d,v_co, vec) + plane_direction * far_limit
+ loc.append(intersect_line_plane(p0, p1, plane_point, plane_direction))
+ vertices.append(bm.verts.new(loc[idx]))
+
+ if idx > 0:
+ bm.edges.new([vertices[idx-1],vertices[idx]])
+
+ faces.append(vertices[idx])
+
+ # Update vertices index
+ bm.verts.index_update()
+
+ # Nothing is selected, create close geometry
+ if self.CreateMode:
+ if self.Closed and len(vertices) > 1:
+ bm.edges.new([vertices[-1], vertices[0]])
+ bm.faces.new(faces)
+ else:
+ # Create faces if more than 2 vertices
+ if len(vertices) > 1 :
+ bm.edges.new([vertices[-1], vertices[0]])
+ bm.faces.new(faces)
+
+ bm.to_mesh(me)
# Cut Circle
def CreateCutCircle(self, context):
- """ Create a circle mesh """
- far_limit = 10000.0
- FacesList = []
-
- # Get the mouse coordinates
- mouse_pos_x = self.mouse_path[0][0]
- mouse_pos_y = self.mouse_path[0][1]
- coord = self.mouse_path[0][0], self.mouse_path[0][1]
-
- # Scene information
- region = context.region
- rv3d = context.region_data
- depth_location = region_2d_to_vector_3d(region, rv3d, coord)
- self.ViewVector = depth_location
-
- # Get a point on a infinite plane and its direction
- plane_point = context.scene.cursor.location if self.snapCursor else Vector((0.0, 0.0, 0.0))
- plane_normal = depth_location
- plane_direction = plane_normal.normalized()
-
- # New mesh
- me = bpy.data.meshes.new('CMT_Circle')
- bm = bmesh.new()
- bm.from_mesh(me)
-
- # New object and link it to the scene
- ob = bpy.data.objects.new('CMT_Circle', me)
- self.CurrentObj = ob
- context.collection.objects.link(ob)
-
- # Create a circle using a tri fan
- tris_fan, indices = draw_circle(self, mouse_pos_x, mouse_pos_y)
-
- # Remove the vertex in the center to get the outer line of the circle
- verts = tris_fan[1:]
-
- # Find the intersection of a line going thru each vertex and the infinite plane
- for vert in verts:
- vec = region_2d_to_vector_3d(region, rv3d, vert)
- p0 = region_2d_to_location_3d(region, rv3d, vert, vec)
- p1 = p0 + plane_direction * far_limit
- loc0 = intersect_line_plane(p0, p1, plane_point, plane_direction)
- t_v0 = bm.verts.new(loc0)
- FacesList.append(t_v0)
-
- bm.verts.index_update()
- bm.faces.new(FacesList)
- bm.to_mesh(me)
+ """ Create a circle mesh """
+ far_limit = 10000.0
+ FacesList = []
+
+ # Get the mouse coordinates
+ mouse_pos_x = self.mouse_path[0][0]
+ mouse_pos_y = self.mouse_path[0][1]
+ coord = self.mouse_path[0][0], self.mouse_path[0][1]
+
+ # Scene information
+ region = context.region
+ rv3d = context.region_data
+ depth_location = region_2d_to_vector_3d(region, rv3d, coord)
+ self.ViewVector = depth_location
+
+ # Get a point on a infinite plane and its direction
+ plane_point = context.scene.cursor.location if self.snapCursor else Vector((0.0, 0.0, 0.0))
+ plane_normal = depth_location
+ plane_direction = plane_normal.normalized()
+
+ # New mesh
+ me = bpy.data.meshes.new('CMT_Circle')
+ bm = bmesh.new()
+ bm.from_mesh(me)
+
+ # New object and link it to the scene
+ ob = bpy.data.objects.new('CMT_Circle', me)
+ self.CurrentObj = ob
+ context.collection.objects.link(ob)
+
+ # Create a circle using a tri fan
+ tris_fan, indices = draw_circle(self, mouse_pos_x, mouse_pos_y)
+
+ # Remove the vertex in the center to get the outer line of the circle
+ verts = tris_fan[1:]
+
+ # Find the intersection of a line going thru each vertex and the infinite plane
+ for vert in verts:
+ vec = region_2d_to_vector_3d(region, rv3d, vert)
+ p0 = region_2d_to_location_3d(region, rv3d, vert, vec)
+ p1 = p0 + plane_direction * far_limit
+ loc0 = intersect_line_plane(p0, p1, plane_point, plane_direction)
+ t_v0 = bm.verts.new(loc0)
+ FacesList.append(t_v0)
+
+ bm.verts.index_update()
+ bm.faces.new(FacesList)
+ bm.to_mesh(me)
def create_2d_circle(self, step, radius, rotation = 0):
- """ Create the vertices of a 2d circle at (0,0) """
- verts = []
- for angle in range(0, 360, step):
- verts.append(math.cos(math.radians(angle + rotation)) * radius)
- verts.append(math.sin(math.radians(angle + rotation)) * radius)
- verts.append(0.0)
- verts.append(math.cos(math.radians(0.0 + rotation)) * radius)
- verts.append(math.sin(math.radians(0.0 + rotation)) * radius)
- verts.append(0.0)
- return(verts)
+ """ Create the vertices of a 2d circle at (0,0) """
+ verts = []
+ for angle in range(0, 360, step):
+ verts.append(math.cos(math.radians(angle + rotation)) * radius)
+ verts.append(math.sin(math.radians(angle + rotation)) * radius)
+ verts.append(0.0)
+ verts.append(math.cos(math.radians(0.0 + rotation)) * radius)
+ verts.append(math.sin(math.radians(0.0 + rotation)) * radius)
+ verts.append(0.0)
+ return(verts)
def draw_circle(self, mouse_pos_x, mouse_pos_y):
- """ Return the coordinates + indices of a circle using a triangle fan """
- tris_verts = []
- indices = []
- segments = int(360 / self.stepAngle[self.step])
- radius = self.mouse_path[1][0] - self.mouse_path[0][0]
- rotation = (self.mouse_path[1][1] - self.mouse_path[0][1]) / 2
+ """ Return the coordinates + indices of a circle using a triangle fan """
+ tris_verts = []
+ indices = []
+ segments = int(360 / self.stepAngle[self.step])
+ radius = self.mouse_path[1][0] - self.mouse_path[0][0]
+ rotation = (self.mouse_path[1][1] - self.mouse_path[0][1]) / 2
- # Get the vertices of a 2d circle
- verts = create_2d_circle(self, self.stepAngle[self.step], radius, rotation)
+ # Get the vertices of a 2d circle
+ verts = create_2d_circle(self, self.stepAngle[self.step], radius, rotation)
- # Create the first vertex at mouse position for the center of the circle
- tris_verts.append(Vector((mouse_pos_x + self.xpos , mouse_pos_y + self.ypos)))
+ # Create the first vertex at mouse position for the center of the circle
+ tris_verts.append(Vector((mouse_pos_x + self.xpos , mouse_pos_y + self.ypos)))
- # For each vertex of the circle, add the mouse position and the translation
- for idx in range(int(len(verts) / 3) - 1):
- tris_verts.append(Vector((verts[idx * 3] + mouse_pos_x + self.xpos, \
- verts[idx * 3 + 1] + mouse_pos_y + self.ypos)))
- i1 = idx+1
- i2 = idx+2 if idx+2 <= segments else 1
- indices.append((0,i1,i2))
+ # For each vertex of the circle, add the mouse position and the translation
+ for idx in range(int(len(verts) / 3) - 1):
+ tris_verts.append(Vector((verts[idx * 3] + mouse_pos_x + self.xpos, \
+ verts[idx * 3 + 1] + mouse_pos_y + self.ypos)))
+ i1 = idx+1
+ i2 = idx+2 if idx+2 <= segments else 1
+ indices.append((0,i1,i2))
- return(tris_verts, indices)
+ return(tris_verts, indices)
# Object dimensions (SCULPT Tools tips)
def objDiagonal(obj):
- return ((obj.dimensions[0]**2) + (obj.dimensions[1]**2) + (obj.dimensions[2]**2))**0.5
+ return ((obj.dimensions[0]**2) + (obj.dimensions[1]**2) + (obj.dimensions[2]**2))**0.5
# Bevel Update
def update_bevel(context):
- selection = context.selected_objects.copy()
- active = context.active_object
+ selection = context.selected_objects.copy()
+ active = context.active_object
- if len(selection) > 0:
- for obj in selection:
- bpy.ops.object.select_all(action='DESELECT')
- obj.select_set(True)
- context.view_layer.objects.active = obj
+ if len(selection) > 0:
+ for obj in selection:
+ bpy.ops.object.select_all(action='DESELECT')
+ obj.select_set(True)
+ context.view_layer.objects.active = obj
- # Test object name
- # Subdive mode : Only bevel weight
- if obj.data.name.startswith("S_") or obj.data.name.startswith("S "):
- bpy.ops.object.mode_set(mode='EDIT')
- bpy.ops.mesh.region_to_loop()
- bpy.ops.transform.edge_bevelweight(value=1)
- bpy.ops.object.mode_set(mode='OBJECT')
+ # Test object name
+ # Subdive mode : Only bevel weight
+ if obj.data.name.startswith("S_") or obj.data.name.startswith("S "):
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.region_to_loop()
+ bpy.ops.transform.edge_bevelweight(value=1)
+ bpy.ops.object.mode_set(mode='OBJECT')
- else:
- # No subdiv mode : bevel weight + Crease + Sharp
- CreateBevel(context, obj)
+ else:
+ # No subdiv mode : bevel weight + Crease + Sharp
+ CreateBevel(context, obj)
- bpy.ops.object.select_all(action='DESELECT')
+ bpy.ops.object.select_all(action='DESELECT')
- for obj in selection:
- obj.select_set(True)
- context.view_layer.objects.active = active
+ for obj in selection:
+ obj.select_set(True)
+ context.view_layer.objects.active = active
# Create bevel
def CreateBevel(context, CurrentObject):
- # Save active object
- SavActive = context.active_object
+ # Save active object
+ SavActive = context.active_object
- # Test if initial object has bevel
- bevel_modifier = False
- for modifier in SavActive.modifiers:
- if modifier.name == 'Bevel':
- bevel_modifier = True
+ # Test if initial object has bevel
+ bevel_modifier = False
+ for modifier in SavActive.modifiers:
+ if modifier.name == 'Bevel':
+ bevel_modifier = True
- if bevel_modifier:
- # Active "CurrentObject"
- context.view_layer.objects.active = CurrentObject
+ if bevel_modifier:
+ # Active "CurrentObject"
+ context.view_layer.objects.active = CurrentObject
- bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.object.mode_set(mode='EDIT')
- # Edge mode
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
- # Clear all
- bpy.ops.mesh.select_all(action='SELECT')
- bpy.ops.mesh.mark_sharp(clear=True)
- bpy.ops.transform.edge_crease(value=-1)
- bpy.ops.transform.edge_bevelweight(value=-1)
+ # Edge mode
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
+ # Clear all
+ bpy.ops.mesh.select_all(action='SELECT')
+ bpy.ops.mesh.mark_sharp(clear=True)
+ bpy.ops.transform.edge_crease(value=-1)
+ bpy.ops.transform.edge_bevelweight(value=-1)
- bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.mesh.select_all(action='DESELECT')
- # Select (in radians) all 30° sharp edges
- bpy.ops.mesh.edges_select_sharp(sharpness=0.523599)
- # Apply bevel weight + Crease + Sharp to the selected edges
- bpy.ops.mesh.mark_sharp()
- bpy.ops.transform.edge_crease(value=1)
- bpy.ops.transform.edge_bevelweight(value=1)
+ # Select (in radians) all 30° sharp edges
+ bpy.ops.mesh.edges_select_sharp(sharpness=0.523599)
+ # Apply bevel weight + Crease + Sharp to the selected edges
+ bpy.ops.mesh.mark_sharp()
+ bpy.ops.transform.edge_crease(value=1)
+ bpy.ops.transform.edge_bevelweight(value=1)
- bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.mesh.select_all(action='DESELECT')
- bpy.ops.object.mode_set(mode='OBJECT')
+ bpy.ops.object.mode_set(mode='OBJECT')
- CurrentObject.data.use_customdata_edge_bevel = True
+ CurrentObject.data.use_customdata_edge_bevel = True
- for i in range(len(CurrentObject.data.edges)):
- if CurrentObject.data.edges[i].select is True:
- CurrentObject.data.edges[i].bevel_weight = 1.0
- CurrentObject.data.edges[i].use_edge_sharp = True
+ for i in range(len(CurrentObject.data.edges)):
+ if CurrentObject.data.edges[i].select is True:
+ CurrentObject.data.edges[i].bevel_weight = 1.0
+ CurrentObject.data.edges[i].use_edge_sharp = True
- bevel_modifier = False
- for m in CurrentObject.modifiers:
- if m.name == 'Bevel':
- bevel_modifier = True
+ bevel_modifier = False
+ for m in CurrentObject.modifiers:
+ if m.name == 'Bevel':
+ bevel_modifier = True
- if bevel_modifier is False:
- bpy.ops.object.modifier_add(type='BEVEL')
- mod = context.object.modifiers[-1]
- mod.limit_method = 'WEIGHT'
- mod.width = 0.01
- mod.profile = 0.699099
- mod.use_clight_overlap = False
- mod.segments = 3
- mod.loop_slide = False
+ if bevel_modifier is False:
+ bpy.ops.object.modifier_add(type='BEVEL')
+ mod = context.object.modifiers[-1]
+ mod.limit_method = 'WEIGHT'
+ mod.width = 0.01
+ mod.profile = 0.699099
+ mod.use_clight_overlap = False
+ mod.segments = 3
+ mod.loop_slide = False
- bpy.ops.object.shade_smooth()
+ bpy.ops.object.shade_smooth()
- context.object.data.use_auto_smooth = True
- context.object.data.auto_smooth_angle = 1.0471975
+ context.object.data.use_auto_smooth = True
+ context.object.data.auto_smooth_angle = 1.0471975
- # Restore the active object
- context.view_layer.objects.active = SavActive
+ # Restore the active object
+ context.view_layer.objects.active = SavActive
def MoveCursor(qRot, location, self):
- """ In brush mode : Draw a circle around the brush """
- if qRot is not None:
- verts = create_2d_circle(self, 10, 1)
- self.CLR_C.clear()
- vc = Vector()
- for idx in range(int(len(verts) / 3)):
- vc.x = verts[idx * 3]
- vc.y = verts[idx * 3 + 1]
- vc.z = verts[idx * 3 + 2]
- vc = qRot @ vc
- self.CLR_C.append(vc.x)
- self.CLR_C.append(vc.y)
- self.CLR_C.append(vc.z)
+ """ In brush mode : Draw a circle around the brush """
+ if qRot is not None:
+ verts = create_2d_circle(self, 10, 1)
+ self.CLR_C.clear()
+ vc = Vector()
+ for idx in range(int(len(verts) / 3)):
+ vc.x = verts[idx * 3]
+ vc.y = verts[idx * 3 + 1]
+ vc.z = verts[idx * 3 + 2]
+ vc = qRot @ vc
+ self.CLR_C.append(vc.x)
+ self.CLR_C.append(vc.y)
+ self.CLR_C.append(vc.z)
def rot_axis_quat(vector1, vector2):
- """ Find the rotation (quaternion) from vector 1 to vector 2"""
- vector1 = vector1.normalized()
- vector2 = vector2.normalized()
- cosTheta = vector1.dot(vector2)
- rotationAxis = Vector((0.0, 0.0, 0.0))
- if (cosTheta < -1 + 0.001):
- v = Vector((0.0, 1.0, 0.0))
- #Get the vector at the right angles to both
- rotationAxis = vector1.cross(v)
- rotationAxis = rotationAxis.normalized()
- q = Quaternion()
- q.w = 0.0
- q.x = rotationAxis.x
- q.y = rotationAxis.y
- q.z = rotationAxis.z
- else:
- rotationAxis = vector1.cross(vector2)
- s = math.sqrt((1.0 + cosTheta) * 2.0)
- invs = 1 / s
- q = Quaternion()
- q.w = s * 0.5
- q.x = rotationAxis.x * invs
- q.y = rotationAxis.y * invs
- q.z = rotationAxis.z * invs
- return q
+ """ Find the rotation (quaternion) from vector 1 to vector 2"""
+ vector1 = vector1.normalized()
+ vector2 = vector2.normalized()
+ cosTheta = vector1.dot(vector2)
+ rotationAxis = Vector((0.0, 0.0, 0.0))
+ if (cosTheta < -1 + 0.001):
+ v = Vector((0.0, 1.0, 0.0))
+ #Get the vector at the right angles to both
+ rotationAxis = vector1.cross(v)
+ rotationAxis = rotationAxis.normalized()
+ q = Quaternion()
+ q.w = 0.0
+ q.x = rotationAxis.x
+ q.y = rotationAxis.y
+ q.z = rotationAxis.z
+ else:
+ rotationAxis = vector1.cross(vector2)
+ s = math.sqrt((1.0 + cosTheta) * 2.0)
+ invs = 1 / s
+ q = Quaternion()
+ q.w = s * 0.5
+ q.x = rotationAxis.x * invs
+ q.y = rotationAxis.y * invs
+ q.z = rotationAxis.z * invs
+ return q
# Picking (template)
def Picking(context, event):
- """ Put the 3d cursor on the closest object"""
-
- # get the context arguments
- scene = context.scene
- region = context.region
- rv3d = context.region_data
- coord = event.mouse_region_x, event.mouse_region_y
-
- # get the ray from the viewport and mouse
- view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
- ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
- ray_target = ray_origin + view_vector
-
- def visible_objects_and_duplis():
- depsgraph = context.evaluated_depsgraph_get()
- for dup in depsgraph.object_instances:
- if dup.is_instance: # Real dupli instance
- obj = dup.instance_object.original
- yield (obj, dup.matrix.copy())
- else: # Usual object
- obj = dup.object.original
- yield (obj, obj.matrix_world.copy())
-
- def obj_ray_cast(obj, matrix):
- # get the ray relative to the object
- matrix_inv = matrix.inverted()
- ray_origin_obj = matrix_inv @ ray_origin
- ray_target_obj = matrix_inv @ ray_target
- ray_direction_obj = ray_target_obj - ray_origin_obj
- # cast the ray
- success, location, normal, face_index = obj.ray_cast(ray_origin_obj, ray_direction_obj)
- if success:
- return location, normal, face_index
- return None, None, None
-
- # cast rays and find the closest object
- best_length_squared = -1.0
- best_obj = None
-
- # cast rays and find the closest object
- for obj, matrix in visible_objects_and_duplis():
- if obj.type == 'MESH':
- hit, normal, face_index = obj_ray_cast(obj, matrix)
- if hit is not None:
- hit_world = matrix @ hit
- length_squared = (hit_world - ray_origin).length_squared
- if best_obj is None or length_squared < best_length_squared:
- scene.cursor.location = hit_world
- best_length_squared = length_squared
- best_obj = obj
- else:
- if best_obj is None:
- depth_location = region_2d_to_vector_3d(region, rv3d, coord)
- loc = region_2d_to_location_3d(region, rv3d, coord, depth_location)
- scene.cursor.location = loc
+ """ Put the 3d cursor on the closest object"""
+
+ # get the context arguments
+ scene = context.scene
+ region = context.region
+ rv3d = context.region_data
+ coord = event.mouse_region_x, event.mouse_region_y
+
+ # get the ray from the viewport and mouse
+ view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
+ ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
+ ray_target = ray_origin + view_vector
+
+ def visible_objects_and_duplis():
+ depsgraph = context.evaluated_depsgraph_get()
+ for dup in depsgraph.object_instances:
+ if dup.is_instance: # Real dupli instance
+ obj = dup.instance_object.original
+ yield (obj, dup.matrix.copy())
+ else: # Usual object
+ obj = dup.object.original
+ yield (obj, obj.matrix_world.copy())
+
+ def obj_ray_cast(obj, matrix):
+ # get the ray relative to the object
+ matrix_inv = matrix.inverted()
+ ray_origin_obj = matrix_inv @ ray_origin
+ ray_target_obj = matrix_inv @ ray_target
+ ray_direction_obj = ray_target_obj - ray_origin_obj
+ # cast the ray
+ success, location, normal, face_index = obj.ray_cast(ray_origin_obj, ray_direction_obj)
+ if success:
+ return location, normal, face_index
+ return None, None, None
+
+ # cast rays and find the closest object
+ best_length_squared = -1.0
+ best_obj = None
+
+ # cast rays and find the closest object
+ for obj, matrix in visible_objects_and_duplis():
+ if obj.type == 'MESH':
+ hit, normal, face_index = obj_ray_cast(obj, matrix)
+ if hit is not None:
+ hit_world = matrix @ hit
+ length_squared = (hit_world - ray_origin).length_squared
+ if best_obj is None or length_squared < best_length_squared:
+ scene.cursor.location = hit_world
+ best_length_squared = length_squared
+ best_obj = obj
+ else:
+ if best_obj is None:
+ depth_location = region_2d_to_vector_3d(region, rv3d, coord)
+ loc = region_2d_to_location_3d(region, rv3d, coord, depth_location)
+ scene.cursor.location = loc
def Pick(context, event, self, ray_max=10000.0):
- region = context.region
- rv3d = context.region_data
- coord = event.mouse_region_x, event.mouse_region_y
- view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
- ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
- ray_target = ray_origin + (view_vector * ray_max)
-
- def obj_ray_cast(obj, matrix):
- matrix_inv = matrix.inverted()
- ray_origin_obj = matrix_inv @ ray_origin
- ray_target_obj = matrix_inv @ ray_target
- success, hit, normal, face_index = obj.ray_cast(ray_origin_obj, ray_target_obj)
- if success:
- return hit, normal, face_index
- return None, None, None
-
- best_length_squared = ray_max * ray_max
- best_obj = None
- for obj in self.CList:
- matrix = obj.matrix_world
- hit, normal, face_index = obj_ray_cast(obj, matrix)
- rotation = obj.rotation_euler.to_quaternion()
- if hit is not None:
- hit_world = matrix @ hit
- length_squared = (hit_world - ray_origin).length_squared
- if length_squared < best_length_squared:
- best_length_squared = length_squared
- best_obj = obj
- hits = hit_world
- ns = normal
- fs = face_index
-
- if best_obj is not None:
- return hits, ns, rotation
-
- return None, None, None
+ region = context.region
+ rv3d = context.region_data
+ coord = event.mouse_region_x, event.mouse_region_y
+ view_vector = view3d_utils.region_2d_to_vector_3d(region, rv3d, coord)
+ ray_origin = view3d_utils.region_2d_to_origin_3d(region, rv3d, coord)
+ ray_target = ray_origin + (view_vector * ray_max)
+
+ def obj_ray_cast(obj, matrix):
+ matrix_inv = matrix.inverted()
+ ray_origin_obj = matrix_inv @ ray_origin
+ ray_target_obj = matrix_inv @ ray_target
+ success, hit, normal, face_index = obj.ray_cast(ray_origin_obj, ray_target_obj)
+ if success:
+ return hit, normal, face_index
+ return None, None, None
+
+ best_length_squared = ray_max * ray_max
+ best_obj = None
+ for obj in self.CList:
+ matrix = obj.matrix_world
+ hit, normal, face_index = obj_ray_cast(obj, matrix)
+ rotation = obj.rotation_euler.to_quaternion()
+ if hit is not None:
+ hit_world = matrix @ hit
+ length_squared = (hit_world - ray_origin).length_squared
+ if length_squared < best_length_squared:
+ best_length_squared = length_squared
+ best_obj = obj
+ hits = hit_world
+ ns = normal
+ fs = face_index
+
+ if best_obj is not None:
+ return hits, ns, rotation
+
+ return None, None, None
def SelectObject(self, copyobj):
- copyobj.select_set(True)
+ copyobj.select_set(True)
- for child in copyobj.children:
- SelectObject(self, child)
+ for child in copyobj.children:
+ SelectObject(self, child)
- if copyobj.parent is None:
- bpy.context.view_layer.objects.active = copyobj
+ if copyobj.parent is None:
+ bpy.context.view_layer.objects.active = copyobj
# Undo
def printUndo(self):
- for l in self.UList:
- print(l)
+ for l in self.UList:
+ print(l)
def UndoAdd(self, type, obj):
- """ Create a backup mesh before apply the action to the object """
- if obj is None:
- return
+ """ Create a backup mesh before apply the action to the object """
+ if obj is None:
+ return
- if type != "DUPLICATE":
- bm = bmesh.new()
- bm.from_mesh(obj.data)
- self.UndoOps.append((obj, type, bm))
- else:
- self.UndoOps.append((obj, type, None))
+ if type != "DUPLICATE":
+ bm = bmesh.new()
+ bm.from_mesh(obj.data)
+ self.UndoOps.append((obj, type, bm))
+ else:
+ self.UndoOps.append((obj, type, None))
def UndoListUpdate(self):
- self.UList.append((self.UndoOps.copy()))
- self.UList_Index += 1
- self.UndoOps.clear()
+ self.UList.append((self.UndoOps.copy()))
+ self.UList_Index += 1
+ self.UndoOps.clear()
def Undo(self):
- if self.UList_Index < 0:
- return
- # get previous mesh
- for o in self.UList[self.UList_Index]:
- if o[1] == "MESH":
- bm = o[2]
- bm.to_mesh(o[0].data)
+ if self.UList_Index < 0:
+ return
+ # get previous mesh
+ for o in self.UList[self.UList_Index]:
+ if o[1] == "MESH":
+ bm = o[2]
+ bm.to_mesh(o[0].data)
- SelectObjList = bpy.context.selected_objects.copy()
- Active_Obj = bpy.context.active_object
- bpy.ops.object.select_all(action='TOGGLE')
+ SelectObjList = bpy.context.selected_objects.copy()
+ Active_Obj = bpy.context.active_object
+ bpy.ops.object.select_all(action='TOGGLE')
- for o in self.UList[self.UList_Index]:
- if o[1] == "REBOOL":
- o[0].select_set(True)
- o[0].hide_viewport = False
+ for o in self.UList[self.UList_Index]:
+ if o[1] == "REBOOL":
+ o[0].select_set(True)
+ o[0].hide_viewport = False
- if o[1] == "DUPLICATE":
- o[0].select_set(True)
- o[0].hide_viewport = False
+ if o[1] == "DUPLICATE":
+ o[0].select_set(True)
+ o[0].hide_viewport = False
- bpy.ops.object.delete(use_global=False)
+ bpy.ops.object.delete(use_global=False)
- for so in SelectObjList:
- bpy.data.objects[so.name].select_set(True)
- bpy.context.view_layer.objects.active = Active_Obj
+ for so in SelectObjList:
+ bpy.data.objects[so.name].select_set(True)
+ bpy.context.view_layer.objects.active = Active_Obj
- self.UList_Index -= 1
- self.UList[self.UList_Index + 1:] = []
+ self.UList_Index -= 1
+ self.UList[self.UList_Index + 1:] = []
def duplicateObject(self):
- if self.Instantiate:
- bpy.ops.object.duplicate_move_linked(
- OBJECT_OT_duplicate={
- "linked": True,
- "mode": 'TRANSLATION',
- },
- TRANSFORM_OT_translate={
- "value": (0, 0, 0),
- },
- )
- else:
- bpy.ops.object.duplicate_move(
- OBJECT_OT_duplicate={
- "linked": False,
- "mode": 'TRANSLATION',
- },
- TRANSFORM_OT_translate={
- "value": (0, 0, 0),
- },
- )
-
- ob_new = bpy.context.active_object
-
- ob_new.location = self.CurLoc
- v = Vector()
- v.x = v.y = 0.0
- v.z = self.BrushDepthOffset
- ob_new.location += self.qRot * v
-
- if self.ObjectMode:
- ob_new.scale = self.ObjectBrush.scale
- if self.ProfileMode:
- ob_new.scale = self.ProfileBrush.scale
-
- e = Euler()
- e.x = e.y = 0.0
- e.z = self.aRotZ / 25.0
-
- # If duplicate with a grid, no random rotation (each mesh in the grid is already rotated randomly)
- if (self.alt is True) and ((self.nbcol + self.nbrow) < 3):
- if self.RandomRotation:
- e.z += random.random()
-
- qe = e.to_quaternion()
- qRot = self.qRot * qe
- ob_new.rotation_mode = 'QUATERNION'
- ob_new.rotation_quaternion = qRot
- ob_new.rotation_mode = 'XYZ'
-
- if (ob_new.display_type == "WIRE") and (self.BrushSolidify is False):
- ob_new.hide_viewport = True
-
- if self.BrushSolidify:
- ob_new.display_type = "SOLID"
- ob_new.show_in_front = False
-
- for o in bpy.context.selected_objects:
- UndoAdd(self, "DUPLICATE", o)
-
- if len(bpy.context.selected_objects) > 0:
- bpy.ops.object.select_all(action='TOGGLE')
- for o in self.all_sel_obj_list:
- o.select_set(True)
-
- bpy.context.view_layer.objects.active = self.OpsObj
+ if self.Instantiate:
+ bpy.ops.object.duplicate_move_linked(
+ OBJECT_OT_duplicate={
+ "linked": True,
+ "mode": 'TRANSLATION',
+ },
+ TRANSFORM_OT_translate={
+ "value": (0, 0, 0),
+ },
+ )
+ else:
+ bpy.ops.object.duplicate_move(
+ OBJECT_OT_duplicate={
+ "linked": False,
+ "mode": 'TRANSLATION',
+ },
+ TRANSFORM_OT_translate={
+ "value": (0, 0, 0),
+ },
+ )
+
+ ob_new = bpy.context.active_object
+
+ ob_new.location = self.CurLoc
+ v = Vector()
+ v.x = v.y = 0.0
+ v.z = self.BrushDepthOffset
+ ob_new.location += self.qRot * v
+
+ if self.ObjectMode:
+ ob_new.scale = self.ObjectBrush.scale
+ if self.ProfileMode:
+ ob_new.scale = self.ProfileBrush.scale
+
+ e = Euler()
+ e.x = e.y = 0.0
+ e.z = self.aRotZ / 25.0
+
+ # If duplicate with a grid, no random rotation (each mesh in the grid is already rotated randomly)
+ if (self.alt is True) and ((self.nbcol + self.nbrow) < 3):
+ if self.RandomRotation:
+ e.z += random.random()
+
+ qe = e.to_quaternion()
+ qRot = self.qRot * qe
+ ob_new.rotation_mode = 'QUATERNION'
+ ob_new.rotation_quaternion = qRot
+ ob_new.rotation_mode = 'XYZ'
+
+ if (ob_new.display_type == "WIRE") and (self.BrushSolidify is False):
+ ob_new.hide_viewport = True
+
+ if self.BrushSolidify:
+ ob_new.display_type = "SOLID"
+ ob_new.show_in_front = False
+
+ for o in bpy.context.selected_objects:
+ UndoAdd(self, "DUPLICATE", o)
+
+ if len(bpy.context.selected_objects) > 0:
+ bpy.ops.object.select_all(action='TOGGLE')
+ for o in self.all_sel_obj_list:
+ o.select_set(True)
+
+ bpy.context.view_layer.objects.active = self.OpsObj
def update_grid(self, context):
- """
- Thanks to batFINGER for his help :
- source : http://blender.stackexchange.com/questions/55864/multiple-meshes-not-welded-with-pydata
- """
- verts = []
- edges = []
- faces = []
- numface = 0
-
- if self.nbcol < 1:
- self.nbcol = 1
- if self.nbrow < 1:
- self.nbrow = 1
- if self.gapx < 0:
- self.gapx = 0
- if self.gapy < 0:
- self.gapy = 0
-
- # Get the data from the profils or the object
- if self.ProfileMode:
- brush = bpy.data.objects.new(
- self.Profils[self.nProfil][0],
- bpy.data.meshes[self.Profils[self.nProfil][0]]
- )
- obj = bpy.data.objects["CT_Profil"]
- obfaces = brush.data.polygons
- obverts = brush.data.vertices
- lenverts = len(obverts)
- else:
- brush = bpy.data.objects["CarverBrushCopy"]
- obj = context.selected_objects[0]
- obverts = brush.data.vertices
- obfaces = brush.data.polygons
- lenverts = len(brush.data.vertices)
-
- # Gap between each row / column
- gapx = self.gapx
- gapy = self.gapy
-
- # Width of each row / column
- widthx = brush.dimensions.x * self.scale_x
- widthy = brush.dimensions.y * self.scale_y
-
- # Compute the corners so the new object will be always at the center
- left = -((self.nbcol - 1) * (widthx + gapx)) / 2
- start = -((self.nbrow - 1) * (widthy + gapy)) / 2
-
- for i in range(self.nbrow * self.nbcol):
- row = i % self.nbrow
- col = i // self.nbrow
- startx = left + ((widthx + gapx) * col)
- starty = start + ((widthy + gapy) * row)
-
- # Add random rotation
- if (self.RandomRotation) and not (self.GridScaleX or self.GridScaleY):
- rotmat = Matrix.Rotation(math.radians(360 * random.random()), 4, 'Z')
- for v in obverts:
- v.co = v.co @ rotmat
-
- verts.extend([((v.co.x - startx, v.co.y - starty, v.co.z)) for v in obverts])
- faces.extend([[v + numface * lenverts for v in p.vertices] for p in obfaces])
- numface += 1
-
- # Update the mesh
- # Create mesh data
- mymesh = bpy.data.meshes.new("CT_Profil")
- # Generate mesh data
- mymesh.from_pydata(verts, edges, faces)
- # Calculate the edges
- mymesh.update(calc_edges=True)
- # Update data
- obj.data = mymesh
- # Make the object active to remove doubles
- context.view_layer.objects.active = obj
+ """
+ Thanks to batFINGER for his help :
+ source : http://blender.stackexchange.com/questions/55864/multiple-meshes-not-welded-with-pydata
+ """
+ verts = []
+ edges = []
+ faces = []
+ numface = 0
+
+ if self.nbcol < 1:
+ self.nbcol = 1
+ if self.nbrow < 1:
+ self.nbrow = 1
+ if self.gapx < 0:
+ self.gapx = 0
+ if self.gapy < 0:
+ self.gapy = 0
+
+ # Get the data from the profils or the object
+ if self.ProfileMode:
+ brush = bpy.data.objects.new(
+ self.Profils[self.nProfil][0],
+ bpy.data.meshes[self.Profils[self.nProfil][0]]
+ )
+ obj = bpy.data.objects["CT_Profil"]
+ obfaces = brush.data.polygons
+ obverts = brush.data.vertices
+ lenverts = len(obverts)
+ else:
+ brush = bpy.data.objects["CarverBrushCopy"]
+ obj = context.selected_objects[0]
+ obverts = brush.data.vertices
+ obfaces = brush.data.polygons
+ lenverts = len(brush.data.vertices)
+
+ # Gap between each row / column
+ gapx = self.gapx
+ gapy = self.gapy
+
+ # Width of each row / column
+ widthx = brush.dimensions.x * self.scale_x
+ widthy = brush.dimensions.y * self.scale_y
+
+ # Compute the corners so the new object will be always at the center
+ left = -((self.nbcol - 1) * (widthx + gapx)) / 2
+ start = -((self.nbrow - 1) * (widthy + gapy)) / 2
+
+ for i in range(self.nbrow * self.nbcol):
+ row = i % self.nbrow
+ col = i // self.nbrow
+ startx = left + ((widthx + gapx) * col)
+ starty = start + ((widthy + gapy) * row)
+
+ # Add random rotation
+ if (self.RandomRotation) and not (self.GridScaleX or self.GridScaleY):
+ rotmat = Matrix.Rotation(math.radians(360 * random.random()), 4, 'Z')
+ for v in obverts:
+ v.co = v.co @ rotmat
+
+ verts.extend([((v.co.x - startx, v.co.y - starty, v.co.z)) for v in obverts])
+ faces.extend([[v + numface * lenverts for v in p.vertices] for p in obfaces])
+ numface += 1
+
+ # Update the mesh
+ # Create mesh data
+ mymesh = bpy.data.meshes.new("CT_Profil")
+ # Generate mesh data
+ mymesh.from_pydata(verts, edges, faces)
+ # Calculate the edges
+ mymesh.update(calc_edges=True)
+ # Update data
+ obj.data = mymesh
+ # Make the object active to remove doubles
+ context.view_layer.objects.active = obj
def boolean_operation(bool_type="DIFFERENCE"):
- ActiveObj = bpy.context.active_object
- sel_index = 0 if bpy.context.selected_objects[0] != bpy.context.active_object else 1
+ ActiveObj = bpy.context.active_object
+ sel_index = 0 if bpy.context.selected_objects[0] != bpy.context.active_object else 1
- # bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
- bool_name = "CT_" + bpy.context.selected_objects[sel_index].name
- BoolMod = ActiveObj.modifiers.new(bool_name, "BOOLEAN")
- BoolMod.object = bpy.context.selected_objects[sel_index]
- BoolMod.operation = bool_type
- bpy.context.selected_objects[sel_index].display_type = 'WIRE'
- while ActiveObj.modifiers.find(bool_name) > 0:
- bpy.ops.object.modifier_move_up(modifier=bool_name)
+ # bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
+ bool_name = "CT_" + bpy.context.selected_objects[sel_index].name
+ BoolMod = ActiveObj.modifiers.new(bool_name, "BOOLEAN")
+ BoolMod.object = bpy.context.selected_objects[sel_index]
+ BoolMod.operation = bool_type
+ bpy.context.selected_objects[sel_index].display_type = 'WIRE'
+ while ActiveObj.modifiers.find(bool_name) > 0:
+ bpy.ops.object.modifier_move_up(modifier=bool_name)
def Rebool(context, self):
- target_obj = context.active_object
+ target_obj = context.active_object
- Brush = context.selected_objects[1]
- Brush.display_type = "WIRE"
+ Brush = context.selected_objects[1]
+ Brush.display_type = "WIRE"
- #Deselect all
- bpy.ops.object.select_all(action='TOGGLE')
+ #Deselect all
+ bpy.ops.object.select_all(action='TOGGLE')
- target_obj.display_type = "SOLID"
- target_obj.select_set(True)
- bpy.ops.object.duplicate()
+ target_obj.display_type = "SOLID"
+ target_obj.select_set(True)
+ bpy.ops.object.duplicate()
- rebool_obj = context.active_object
+ rebool_obj = context.active_object
- m = rebool_obj.modifiers.new("CT_INTERSECT", "BOOLEAN")
- m.operation = "INTERSECT"
- m.object = Brush
+ m = rebool_obj.modifiers.new("CT_INTERSECT", "BOOLEAN")
+ m.operation = "INTERSECT"
+ m.object = Brush
- m = target_obj.modifiers.new("CT_DIFFERENCE", "BOOLEAN")
- m.operation = "DIFFERENCE"
- m.object = Brush
+ m = target_obj.modifiers.new("CT_DIFFERENCE", "BOOLEAN")
+ m.operation = "DIFFERENCE"
+ m.object = Brush
- for mb in target_obj.modifiers:
- if mb.type == 'BEVEL':
- mb.show_viewport = False
+ for mb in target_obj.modifiers:
+ if mb.type == 'BEVEL':
+ mb.show_viewport = False
- if self.ObjectBrush or self.ProfileBrush:
- rebool_obj.show_in_front = False
- try:
- bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
- except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.report({'ERROR'}, str(exc_value))
+ if self.ObjectBrush or self.ProfileBrush:
+ rebool_obj.show_in_front = False
+ try:
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_SOLIDIFY")
+ except:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.report({'ERROR'}, str(exc_value))
- if self.dont_apply_boolean is False:
- try:
- bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_INTERSECT")
- except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.report({'ERROR'}, str(exc_value))
+ if self.dont_apply_boolean is False:
+ try:
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_INTERSECT")
+ except:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.report({'ERROR'}, str(exc_value))
- bpy.ops.object.select_all(action='TOGGLE')
+ bpy.ops.object.select_all(action='TOGGLE')
- for mb in target_obj.modifiers:
- if mb.type == 'BEVEL':
- mb.show_viewport = True
+ for mb in target_obj.modifiers:
+ if mb.type == 'BEVEL':
+ mb.show_viewport = True
- context.view_layer.objects.active = target_obj
- target_obj.select_set(True)
- if self.dont_apply_boolean is False:
- try:
- bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_DIFFERENCE")
- except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.report({'ERROR'}, str(exc_value))
+ context.view_layer.objects.active = target_obj
+ target_obj.select_set(True)
+ if self.dont_apply_boolean is False:
+ try:
+ bpy.ops.object.modifier_apply(apply_as='DATA', modifier="CT_DIFFERENCE")
+ except:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.report({'ERROR'}, str(exc_value))
- bpy.ops.object.select_all(action='TOGGLE')
+ bpy.ops.object.select_all(action='TOGGLE')
- rebool_obj.select_set(True)
+ rebool_obj.select_set(True)
def createMeshFromData(self):
- if self.Profils[self.nProfil][0] not in bpy.data.meshes:
- # Create mesh and object
- me = bpy.data.meshes.new(self.Profils[self.nProfil][0])
- # Create mesh from given verts, faces.
- me.from_pydata(self.Profils[self.nProfil][2], [], self.Profils[self.nProfil][3])
- me.validate(verbose=True, clean_customdata=True)
- # Update mesh with new data
- me.update()
-
- if "CT_Profil" not in bpy.data.objects:
- ob = bpy.data.objects.new("CT_Profil", bpy.data.meshes[self.Profils[self.nProfil][0]])
- ob.location = Vector((0.0, 0.0, 0.0))
-
- # Link object to scene and make active
- bpy.context.collection.objects.link(ob)
- bpy.context.view_layer.update()
- bpy.context.view_layer.objects.active = ob
- ob.select_set(True)
- ob.location = Vector((10000.0, 0.0, 0.0))
- ob.display_type = "WIRE"
-
- self.SolidifyPossible = True
- else:
- bpy.data.objects["CT_Profil"].data = bpy.data.meshes[self.Profils[self.nProfil][0]]
+ if self.Profils[self.nProfil][0] not in bpy.data.meshes:
+ # Create mesh and object
+ me = bpy.data.meshes.new(self.Profils[self.nProfil][0])
+ # Create mesh from given verts, faces.
+ me.from_pydata(self.Profils[self.nProfil][2], [], self.Profils[self.nProfil][3])
+ me.validate(verbose=True, clean_customdata=True)
+ # Update mesh with new data
+ me.update()
+
+ if "CT_Profil" not in bpy.data.objects:
+ ob = bpy.data.objects.new("CT_Profil", bpy.data.meshes[self.Profils[self.nProfil][0]])
+ ob.location = Vector((0.0, 0.0, 0.0))
+
+ # Link object to scene and make active
+ bpy.context.collection.objects.link(ob)
+ bpy.context.view_layer.update()
+ bpy.context.view_layer.objects.active = ob
+ ob.select_set(True)
+ ob.location = Vector((10000.0, 0.0, 0.0))
+ ob.display_type = "WIRE"
+
+ self.SolidifyPossible = True
+ else:
+ bpy.data.objects["CT_Profil"].data = bpy.data.meshes[self.Profils[self.nProfil][0]]
def Selection_Save_Restore(self):
- if "CT_Profil" in bpy.data.objects:
- Selection_Save(self)
- bpy.ops.object.select_all(action='DESELECT')
- bpy.data.objects["CT_Profil"].select_set(True)
- bpy.context.view_layer.objects.active = bpy.data.objects["CT_Profil"]
- if bpy.data.objects["CT_Profil"] in self.all_sel_obj_list:
- self.all_sel_obj_list.remove(bpy.data.objects["CT_Profil"])
- bpy.ops.object.delete(use_global=False)
- Selection_Restore(self)
+ if "CT_Profil" in bpy.data.objects:
+ Selection_Save(self)
+ bpy.ops.object.select_all(action='DESELECT')
+ bpy.data.objects["CT_Profil"].select_set(True)
+ bpy.context.view_layer.objects.active = bpy.data.objects["CT_Profil"]
+ if bpy.data.objects["CT_Profil"] in self.all_sel_obj_list:
+ self.all_sel_obj_list.remove(bpy.data.objects["CT_Profil"])
+ bpy.ops.object.delete(use_global=False)
+ Selection_Restore(self)
def Selection_Save(self):
- obj_name = getattr(bpy.context.active_object, "name", None)
- self.all_sel_obj_list = bpy.context.selected_objects.copy()
- self.save_active_obj = obj_name
+ obj_name = getattr(bpy.context.active_object, "name", None)
+ self.all_sel_obj_list = bpy.context.selected_objects.copy()
+ self.save_active_obj = obj_name
def Selection_Restore(self):
- for o in self.all_sel_obj_list:
- o.select_set(True)
- if self.save_active_obj:
- bpy.context.view_layer.objects.active = bpy.data.objects.get(self.save_active_obj, None)
+ for o in self.all_sel_obj_list:
+ o.select_set(True)
+ if self.save_active_obj:
+ bpy.context.view_layer.objects.active = bpy.data.objects.get(self.save_active_obj, None)
def Snap_Cursor(self, context, event, mouse_pos):
- """ Find the closest position on the overlay grid and snap the mouse on it """
- # Get the context arguments
- region = context.region
- rv3d = context.region_data
-
- # Get the VIEW3D area
- for i, a in enumerate(context.screen.areas):
- if a.type == 'VIEW_3D':
- space = context.screen.areas[i].spaces.active
-
- # Get the grid overlay for the VIEW_3D
- grid_scale = space.overlay.grid_scale
- grid_subdivisions = space.overlay.grid_subdivisions
-
- # Use the grid scale and subdivision to get the increment
- increment = (grid_scale / grid_subdivisions)
- half_increment = increment / 2
-
- # Convert the 2d location of the mouse in 3d
- for index, loc in enumerate(reversed(mouse_pos)):
- mouse_loc_3d = region_2d_to_location_3d(region, rv3d, loc, (0, 0, 0))
-
- # Get the remainder from the mouse location and the ratio
- # Test if the remainder > to the half of the increment
- for i in range(3):
- modulo = mouse_loc_3d[i] % increment
- if modulo < half_increment:
- modulo = - modulo
- else:
- modulo = increment - modulo
-
- # Add the remainder to get the closest location on the grid
- mouse_loc_3d[i] = mouse_loc_3d[i] + modulo
-
- # Get the snapped 2d location
- snap_loc_2d = location_3d_to_region_2d(region, rv3d, mouse_loc_3d)
-
- # Replace the last mouse location by the snapped location
- if len(self.mouse_path) > 0:
- self.mouse_path[len(self.mouse_path) - (index + 1) ] = tuple(snap_loc_2d)
+ """ Find the closest position on the overlay grid and snap the mouse on it """
+ # Get the context arguments
+ region = context.region
+ rv3d = context.region_data
+
+ # Get the VIEW3D area
+ for i, a in enumerate(context.screen.areas):
+ if a.type == 'VIEW_3D':
+ space = context.screen.areas[i].spaces.active
+
+ # Get the grid overlay for the VIEW_3D
+ grid_scale = space.overlay.grid_scale
+ grid_subdivisions = space.overlay.grid_subdivisions
+
+ # Use the grid scale and subdivision to get the increment
+ increment = (grid_scale / grid_subdivisions)
+ half_increment = increment / 2
+
+ # Convert the 2d location of the mouse in 3d
+ for index, loc in enumerate(reversed(mouse_pos)):
+ mouse_loc_3d = region_2d_to_location_3d(region, rv3d, loc, (0, 0, 0))
+
+ # Get the remainder from the mouse location and the ratio
+ # Test if the remainder > to the half of the increment
+ for i in range(3):
+ modulo = mouse_loc_3d[i] % increment
+ if modulo < half_increment:
+ modulo = - modulo
+ else:
+ modulo = increment - modulo
+
+ # Add the remainder to get the closest location on the grid
+ mouse_loc_3d[i] = mouse_loc_3d[i] + modulo
+
+ # Get the snapped 2d location
+ snap_loc_2d = location_3d_to_region_2d(region, rv3d, mouse_loc_3d)
+
+ # Replace the last mouse location by the snapped location
+ if len(self.mouse_path) > 0:
+ self.mouse_path[len(self.mouse_path) - (index + 1) ] = tuple(snap_loc_2d)
def mini_grid(self, context, color):
- """ Draw a snap mini grid around the cursor based on the overlay grid"""
- # Get the context arguments
- region = context.region
- rv3d = context.region_data
-
- # Get the VIEW3D area
- for i, a in enumerate(context.screen.areas):
- if a.type == 'VIEW_3D':
- space = context.screen.areas[i].spaces.active
- screen_height = context.screen.areas[i].height
- screen_width = context.screen.areas[i].width
-
- #Draw the snap grid, only in ortho view
- if not space.region_3d.is_perspective :
- grid_scale = space.overlay.grid_scale
- grid_subdivisions = space.overlay.grid_subdivisions
- increment = (grid_scale / grid_subdivisions)
-
- # Get the 3d location of the mouse forced to a snap value in the operator
- mouse_coord = self.mouse_path[len(self.mouse_path) - 1]
-
- snap_loc = region_2d_to_location_3d(region, rv3d, mouse_coord, (0, 0, 0))
-
- # Add the increment to get the closest location on the grid
- snap_loc[0] += increment
- snap_loc[1] += increment
-
- # Get the 2d location of the snap location
- snap_loc = location_3d_to_region_2d(region, rv3d, snap_loc)
- origin = location_3d_to_region_2d(region, rv3d, (0,0,0))
-
- # Get the increment value
- snap_value = snap_loc[0] - mouse_coord[0]
-
- grid_coords = []
-
- # Draw lines on X and Z axis from the cursor through the screen
- grid_coords = [
- (0, mouse_coord[1]), (screen_width, mouse_coord[1]),
- (mouse_coord[0], 0), (mouse_coord[0], screen_height)
- ]
-
- # Draw a mlini grid around the cursor to show the snap options
- grid_coords += [
- (mouse_coord[0] + snap_value, mouse_coord[1] + 25 + snap_value),
- (mouse_coord[0] + snap_value, mouse_coord[1] - 25 - snap_value),
- (mouse_coord[0] + 25 + snap_value, mouse_coord[1] + snap_value),
- (mouse_coord[0] - 25 - snap_value, mouse_coord[1] + snap_value),
- (mouse_coord[0] - snap_value, mouse_coord[1] + 25 + snap_value),
- (mouse_coord[0] - snap_value, mouse_coord[1] - 25 - snap_value),
- (mouse_coord[0] + 25 + snap_value, mouse_coord[1] - snap_value),
- (mouse_coord[0] - 25 - snap_value, mouse_coord[1] - snap_value),
- ]
- draw_shader(self, color, 0.3, 'LINES', grid_coords, size=2)
+ """ Draw a snap mini grid around the cursor based on the overlay grid"""
+ # Get the context arguments
+ region = context.region
+ rv3d = context.region_data
+
+ # Get the VIEW3D area
+ for i, a in enumerate(context.screen.areas):
+ if a.type == 'VIEW_3D':
+ space = context.screen.areas[i].spaces.active
+ screen_height = context.screen.areas[i].height
+ screen_width = context.screen.areas[i].width
+
+ #Draw the snap grid, only in ortho view
+ if not space.region_3d.is_perspective :
+ grid_scale = space.overlay.grid_scale
+ grid_subdivisions = space.overlay.grid_subdivisions
+ increment = (grid_scale / grid_subdivisions)
+
+ # Get the 3d location of the mouse forced to a snap value in the operator
+ mouse_coord = self.mouse_path[len(self.mouse_path) - 1]
+
+ snap_loc = region_2d_to_location_3d(region, rv3d, mouse_coord, (0, 0, 0))
+
+ # Add the increment to get the closest location on the grid
+ snap_loc[0] += increment
+ snap_loc[1] += increment
+
+ # Get the 2d location of the snap location
+ snap_loc = location_3d_to_region_2d(region, rv3d, snap_loc)
+ origin = location_3d_to_region_2d(region, rv3d, (0,0,0))
+
+ # Get the increment value
+ snap_value = snap_loc[0] - mouse_coord[0]
+
+ grid_coords = []
+
+ # Draw lines on X and Z axis from the cursor through the screen
+ grid_coords = [
+ (0, mouse_coord[1]), (screen_width, mouse_coord[1]),
+ (mouse_coord[0], 0), (mouse_coord[0], screen_height)
+ ]
+
+ # Draw a mlini grid around the cursor to show the snap options
+ grid_coords += [
+ (mouse_coord[0] + snap_value, mouse_coord[1] + 25 + snap_value),
+ (mouse_coord[0] + snap_value, mouse_coord[1] - 25 - snap_value),
+ (mouse_coord[0] + 25 + snap_value, mouse_coord[1] + snap_value),
+ (mouse_coord[0] - 25 - snap_value, mouse_coord[1] + snap_value),
+ (mouse_coord[0] - snap_value, mouse_coord[1] + 25 + snap_value),
+ (mouse_coord[0] - snap_value, mouse_coord[1] - 25 - snap_value),
+ (mouse_coord[0] + 25 + snap_value, mouse_coord[1] - snap_value),
+ (mouse_coord[0] - 25 - snap_value, mouse_coord[1] - snap_value),
+ ]
+ draw_shader(self, color, 0.3, 'LINES', grid_coords, size=2)
def draw_shader(self, color, alpha, type, coords, size=1, indices=None):
- """ Create a batch for a draw type """
- bgl.glEnable(bgl.GL_BLEND)
- bgl.glEnable(bgl.GL_LINE_SMOOTH)
- if type =='POINTS':
- bgl.glPointSize(size)
- else:
- bgl.glLineWidth(size)
- try:
- if len(coords[0])>2:
- shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
- else:
- shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
- batch = batch_for_shader(shader, type, {"pos": coords}, indices=indices)
- shader.bind()
- shader.uniform_float("color", (color[0], color[1], color[2], alpha))
- batch.draw(shader)
- bgl.glLineWidth(1)
- bgl.glPointSize(1)
- bgl.glDisable(bgl.GL_LINE_SMOOTH)
- bgl.glDisable(bgl.GL_BLEND)
- except:
- exc_type, exc_value, exc_traceback = sys.exc_info()
- self.report({'ERROR'}, str(exc_value))
+ """ Create a batch for a draw type """
+ bgl.glEnable(bgl.GL_BLEND)
+ bgl.glEnable(bgl.GL_LINE_SMOOTH)
+ if type =='POINTS':
+ bgl.glPointSize(size)
+ else:
+ bgl.glLineWidth(size)
+ try:
+ if len(coords[0])>2:
+ shader = gpu.shader.from_builtin('3D_UNIFORM_COLOR')
+ else:
+ shader = gpu.shader.from_builtin('2D_UNIFORM_COLOR')
+ batch = batch_for_shader(shader, type, {"pos": coords}, indices=indices)
+ shader.bind()
+ shader.uniform_float("color", (color[0], color[1], color[2], alpha))
+ batch.draw(shader)
+ bgl.glLineWidth(1)
+ bgl.glPointSize(1)
+ bgl.glDisable(bgl.GL_LINE_SMOOTH)
+ bgl.glDisable(bgl.GL_BLEND)
+ except:
+ exc_type, exc_value, exc_traceback = sys.exc_info()
+ self.report({'ERROR'}, str(exc_value))
diff --git a/object_collection_manager/__init__.py b/object_collection_manager/__init__.py
index 5c751fce..580a46e0 100644
--- a/object_collection_manager/__init__.py
+++ b/object_collection_manager/__init__.py
@@ -26,8 +26,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D - Object Mode (Shortcut - M)",
"warning": '', # used for warning icon and text in addons panel
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "interface/collection_manager.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "interface/collection_manager.html",
"category": "Interface",
}
diff --git a/object_collection_manager/internals.py b/object_collection_manager/internals.py
index e2e6a64b..64c48150 100644
--- a/object_collection_manager/internals.py
+++ b/object_collection_manager/internals.py
@@ -214,4 +214,3 @@ def send_report(message):
bpy.ops.view3d.cm_send_report(ctx, 'INVOKE_DEFAULT', message=message)
bpy.app.timers.register(report)
-
diff --git a/object_color_rules.py b/object_color_rules.py
index b877caec..ff1b1ab2 100644
--- a/object_color_rules.py
+++ b/object_color_rules.py
@@ -23,8 +23,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "Properties > Object Buttons",
"description": "Rules for assigning object color (for object & wireframe colors).",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "object/color_rules.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "object/color_rules.html",
"category": "Object",
}
diff --git a/object_edit_linked.py b/object_edit_linked.py
index e4428e14..88ea91cb 100644
--- a/object_edit_linked.py
+++ b/object_edit_linked.py
@@ -24,8 +24,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "File > External Data / View3D > Sidebar > Item Tab",
"description": "Allows editing of objects linked from a .blend library.",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "object/edit_linked_library.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "object/edit_linked_library.html",
"category": "Object",
}
diff --git a/object_fracture_cell/__init__.py b/object_fracture_cell/__init__.py
index ae404fcd..04b47706 100644
--- a/object_fracture_cell/__init__.py
+++ b/object_fracture_cell/__init__.py
@@ -24,8 +24,8 @@ bl_info = {
"location": "Viewport Object Menu -> Quick Effects",
"description": "Fractured Object Creation",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "object/cell_fracture.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "object/cell_fracture.html",
"category": "Object",
}
diff --git a/object_print3d_utils/__init__.py b/object_print3d_utils/__init__.py
index d567bd77..04b03a7e 100644
--- a/object_print3d_utils/__init__.py
+++ b/object_print3d_utils/__init__.py
@@ -24,7 +24,7 @@ bl_info = {
"blender": (2, 82, 0),
"location": "3D View > Sidebar",
"description": "Utilities for 3D printing",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/mesh/3d_print_toolbox.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/mesh/3d_print_toolbox.html",
"support": 'OFFICIAL',
"category": "Mesh",
}
diff --git a/object_scatter/__init__.py b/object_scatter/__init__.py
index 98579d81..ecf634d4 100644
--- a/object_scatter/__init__.py
+++ b/object_scatter/__init__.py
@@ -24,7 +24,7 @@ bl_info = {
"location": "3D View",
"description": "Distribute object instances on another object.",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"support": 'OFFICIAL',
"category": "Object",
}
diff --git a/object_skinify.py b/object_skinify.py
index 594d6183..58263c9f 100644
--- a/object_skinify.py
+++ b/object_skinify.py
@@ -24,9 +24,10 @@ bl_info = {
"location": "Pose Mode > Sidebar > Create Tab",
"description": "Creates a mesh object from selected bones",
"warning": "Work in progress",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "object/skinify.html",
- "category": "Object"}
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "object/skinify.html",
+ "category": "Object",
+}
import bpy
from bpy.props import (
diff --git a/oscurart_tools/__init__.py b/oscurart_tools/__init__.py
index 93eacd55..26c07c2d 100644
--- a/oscurart_tools/__init__.py
+++ b/oscurart_tools/__init__.py
@@ -26,9 +26,9 @@ bl_info = {
"location": "View3D > Context Menu > Object/Edit Modes",
"description": "Tools for objects, render, shapes, and files.",
"warning": "",
- "wiki_url": "https://www.oscurart.com.ar",
+ "doc_url": "https://www.oscurart.com.ar",
"category": "Object",
- }
+}
import bpy
diff --git a/oscurart_tools/files/reload_images.py b/oscurart_tools/files/reload_images.py
index 68b5c61b..8461e26d 100644
--- a/oscurart_tools/files/reload_images.py
+++ b/oscurart_tools/files/reload_images.py
@@ -33,5 +33,3 @@ class reloadImages (Operator):
for imgs in bpy.data.images:
imgs.reload()
return {'FINISHED'}
-
-
diff --git a/oscurart_tools/files/save_incremental.py b/oscurart_tools/files/save_incremental.py
index b10db327..d7eb4652 100644
--- a/oscurart_tools/files/save_incremental.py
+++ b/oscurart_tools/files/save_incremental.py
@@ -66,5 +66,3 @@ class saveIncrementalBackup (bpy.types.Operator):
def execute(self, context):
saveBkp(self, context)
return {'FINISHED'}
-
-
diff --git a/oscurart_tools/mesh/apply_linked_meshes.py b/oscurart_tools/mesh/apply_linked_meshes.py
index 0bd7bf47..63e7f907 100644
--- a/oscurart_tools/mesh/apply_linked_meshes.py
+++ b/oscurart_tools/mesh/apply_linked_meshes.py
@@ -53,8 +53,3 @@ class ApplyLRT(bpy.types.Operator):
def execute(self, context):
applyLRTEx(self, context)
return {'FINISHED'}
-
-
-
-
-
diff --git a/oscurart_tools/mesh/flipped_uvs.py b/oscurart_tools/mesh/flipped_uvs.py
index 14d1be4c..13d837f1 100644
--- a/oscurart_tools/mesh/flipped_uvs.py
+++ b/oscurart_tools/mesh/flipped_uvs.py
@@ -57,4 +57,4 @@ class selectFlippedUvs(bpy.types.Operator):
def execute(self, context):
defSelectFlippedUvs(self, context)
- return {'FINISHED'} \ No newline at end of file
+ return {'FINISHED'}
diff --git a/oscurart_tools/mesh/overlap_island.py b/oscurart_tools/mesh/overlap_island.py
index 68b3d339..c6b70cd2 100644
--- a/oscurart_tools/mesh/overlap_island.py
+++ b/oscurart_tools/mesh/overlap_island.py
@@ -95,6 +95,3 @@ class OscOverlapUv(Operator):
def execute(self, context):
DefOscOverlapUv(self,self.offset,self.rotate)
return {'FINISHED'}
-
-
-
diff --git a/oscurart_tools/mesh/overlap_uvs.py b/oscurart_tools/mesh/overlap_uvs.py
index 2960bb3d..d0d13752 100644
--- a/oscurart_tools/mesh/overlap_uvs.py
+++ b/oscurart_tools/mesh/overlap_uvs.py
@@ -128,4 +128,3 @@ class PasteUvIsland(Operator):
def execute(self, context):
defPasteUvsIsland(self, self.uvOffset, self.rotateUv, context)
return {'FINISHED'}
-
diff --git a/oscurart_tools/mesh/remove_modifiers.py b/oscurart_tools/mesh/remove_modifiers.py
index 186588ce..db015200 100644
--- a/oscurart_tools/mesh/remove_modifiers.py
+++ b/oscurart_tools/mesh/remove_modifiers.py
@@ -42,6 +42,3 @@ class RemoveModifiers(bpy.types.Operator):
def execute(self, context):
funcRemoveModifiers(self,context)
return {'FINISHED'}
-
-
-
diff --git a/oscurart_tools/mesh/select_doubles.py b/oscurart_tools/mesh/select_doubles.py
index b2a7d434..6551824a 100644
--- a/oscurart_tools/mesh/select_doubles.py
+++ b/oscurart_tools/mesh/select_doubles.py
@@ -72,6 +72,3 @@ class SelectDoubles(Operator):
def execute(self, context):
SelDoubles(self, context,self.distance)
return {'FINISHED'}
-
-
-
diff --git a/oscurart_tools/mesh/vertex_color_id.py b/oscurart_tools/mesh/vertex_color_id.py
index 2eb9790d..6c68938a 100644
--- a/oscurart_tools/mesh/vertex_color_id.py
+++ b/oscurart_tools/mesh/vertex_color_id.py
@@ -65,6 +65,3 @@ class createVCMask(bpy.types.Operator):
def execute(self, context):
vertexColorMask(self, context)
return {'FINISHED'}
-
-
-
diff --git a/oscurart_tools/object/distribute.py b/oscurart_tools/object/distribute.py
index 991d664b..a0fb6263 100644
--- a/oscurart_tools/object/distribute.py
+++ b/oscurart_tools/object/distribute.py
@@ -67,4 +67,3 @@ class DistributeOsc(Operator):
self.Booly = True
self.Boolz = True
return context.window_manager.invoke_props_dialog(self)
-
diff --git a/oscurart_tools/object/search_and_select.py b/oscurart_tools/object/search_and_select.py
index 707c7188..63787af4 100644
--- a/oscurart_tools/object/search_and_select.py
+++ b/oscurart_tools/object/search_and_select.py
@@ -57,6 +57,3 @@ class SearchAndSelectOt(bpy.types.Operator):
self.count = True
self.end = True
return context.window_manager.invoke_props_dialog(self)
-
-
-
diff --git a/oscurart_tools/render/batch_maker.py b/oscurart_tools/render/batch_maker.py
index fed15dcc..ca386546 100644
--- a/oscurart_tools/render/batch_maker.py
+++ b/oscurart_tools/render/batch_maker.py
@@ -48,4 +48,3 @@ class oscBatchMaker (bpy.types.Operator):
def execute(self, context):
batchMaker(self.bin)
return {'FINISHED'}
-
diff --git a/oscurart_tools/render/material_overrides.py b/oscurart_tools/render/material_overrides.py
index 5720d293..faa9be63 100644
--- a/oscurart_tools/render/material_overrides.py
+++ b/oscurart_tools/render/material_overrides.py
@@ -175,4 +175,3 @@ class OscOverridesKill(bpy.types.Operator):
ovlist = context.scene.ovlist
ovlist.remove(self.index)
return {'FINISHED'}
-
diff --git a/paint_palette.py b/paint_palette.py
index 067beb4f..54b6eb17 100644
--- a/paint_palette.py
+++ b/paint_palette.py
@@ -27,8 +27,8 @@ bl_info = {
"location": "Image Editor and 3D View > Any Paint mode > Color Palette or Weight Palette panel",
"description": "Palettes for color and weight paint modes",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "paint/paint_palettes.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "paint/paint_palettes.html",
"category": "Paint",
}
diff --git a/power_sequencer/__init__.py b/power_sequencer/__init__.py
index 670bcf41..3ec6999f 100755
--- a/power_sequencer/__init__.py
+++ b/power_sequencer/__init__.py
@@ -42,7 +42,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "Sequencer",
"tracker_url": "https://github.com/GDquest/Blender-power-sequencer/issues",
- "wiki_url": "https://www.gdquest.com/docs/documentation/power-sequencer/",
+ "doc_url": "https://www.gdquest.com/docs/documentation/power-sequencer/",
"support": "COMMUNITY",
"category": "Sequencer",
}
diff --git a/power_sequencer/scripts/BPSProxy/bpsproxy/commands.py b/power_sequencer/scripts/BPSProxy/bpsproxy/commands.py
index 72c81ccf..fd41619d 100644
--- a/power_sequencer/scripts/BPSProxy/bpsproxy/commands.py
+++ b/power_sequencer/scripts/BPSProxy/bpsproxy/commands.py
@@ -186,5 +186,5 @@ def get_commands_vi(cfg, clargs, **kwargs):
An iterator with the 1st element as a tag (the `what` parameter) and the 2nd
element as the iterator of the actual commands.
"""
- ws = filter(lambda x: x is not "all", cfg["extensions"])
+ ws = filter(lambda x: x != "all", cfg["extensions"])
return chain.from_iterable(map(lambda w: get_commands(cfg, clargs, what=w, **kwargs), ws))
diff --git a/power_sequencer/scripts/BPSProxy/bpsproxy/utils.py b/power_sequencer/scripts/BPSProxy/bpsproxy/utils.py
index 832a0beb..2f5b7c5e 100644
--- a/power_sequencer/scripts/BPSProxy/bpsproxy/utils.py
+++ b/power_sequencer/scripts/BPSProxy/bpsproxy/utils.py
@@ -36,7 +36,7 @@ def checktools(tools):
msg = ["BPSProxy couldn't find external dependencies:"]
msg += [
"[{check}] {tool}: {path}".format(
- check="v" if path is not "" else "X", tool=tool, path=path or "NOT FOUND"
+ check="v" if path != "" else "X", tool=tool, path=path or "NOT FOUND"
)
for tool, path in check["tools"]
]
diff --git a/power_sequencer/scripts/BPSRender/bpsrender/__init__.py b/power_sequencer/scripts/BPSRender/bpsrender/__init__.py
index 35a40273..f14cfb6a 100644
--- a/power_sequencer/scripts/BPSRender/bpsrender/__init__.py
+++ b/power_sequencer/scripts/BPSRender/bpsrender/__init__.py
@@ -14,4 +14,3 @@
# You should have received a copy of the GNU General Public License along with Power Sequencer. If
# not, see <https://www.gnu.org/licenses/>.
#
-
diff --git a/power_sequencer/scripts/BPSRender/bpsrender/helpers.py b/power_sequencer/scripts/BPSRender/bpsrender/helpers.py
index 9ebcf2b0..58f79775 100644
--- a/power_sequencer/scripts/BPSRender/bpsrender/helpers.py
+++ b/power_sequencer/scripts/BPSRender/bpsrender/helpers.py
@@ -41,7 +41,7 @@ def checktools(tools):
msg = ["BPSRender couldn't find external dependencies:"]
msg += [
"[{check}] {tool}: {path}".format(
- check="v" if path is not "" else "X", tool=tool, path=path or "NOT FOUND"
+ check="v" if path != "" else "X", tool=tool, path=path or "NOT FOUND"
)
for tool, path in check["tools"]
]
diff --git a/precision_drawing_tools/__init__.py b/precision_drawing_tools/__init__.py
index 14545104..b64a164c 100644
--- a/precision_drawing_tools/__init__.py
+++ b/precision_drawing_tools/__init__.py
@@ -34,7 +34,7 @@ bl_info = {
"location": "View3D > UI > PDT",
"description": "Precision Drawing Tools for Acccurate Modelling",
"warning": "",
- "wiki_url": "https://github.com/Clockmender/Precision-Drawing-Tools/wiki",
+ "doc_url": "https://github.com/Clockmender/Precision-Drawing-Tools/wiki",
"category": "3D View",
}
diff --git a/presets/pov/light/17_(1700K)_135W_Low_Pressure_Sodium.py b/presets/pov/light/17_(1700K)_135W_Low_Pressure_Sodium.py
index a6486c01..fc40d772 100644
--- a/presets/pov/light/17_(1700K)_135W_Low_Pressure_Sodium.py
+++ b/presets/pov/light/17_(1700K)_135W_Low_Pressure_Sodium.py
@@ -8,4 +8,4 @@ lampdata = bpy.context.object.data
lampdata.color = (1.0, 0.5764706134796143, 0.16078431904315948)
lampdata.energy = 8.43048#22600lm/21.446(=lux)*0.004(distance) *2 for distance is the point of half strength
lampdata.distance = 1.0
-lampdata.falloff_type = 'INVERSE_SQUARE' \ No newline at end of file
+lampdata.falloff_type = 'INVERSE_SQUARE'
diff --git a/presets/pov/world/4_Cartoony_Sky.py b/presets/pov/world/4_Cartoony_Sky.py
index 90b87bf5..c2410a35 100644
--- a/presets/pov/world/4_Cartoony_Sky.py
+++ b/presets/pov/world/4_Cartoony_Sky.py
@@ -16,4 +16,4 @@ scene.pov.media_scattering_type = '4'
scene.pov.media_samples = 35
scene.pov.media_diffusion_color = (0.20000000298023224, 0.4000000059604645, 1.0)
scene.pov.media_absorption_color = (0.0, 0.0, 0.0)
-scene.pov.media_eccentricity = 0.0 \ No newline at end of file
+scene.pov.media_eccentricity = 0.0
diff --git a/presets/pov/world/5_Under_Water.py b/presets/pov/world/5_Under_Water.py
index 36af4196..5dfd9c59 100644
--- a/presets/pov/world/5_Under_Water.py
+++ b/presets/pov/world/5_Under_Water.py
@@ -16,4 +16,4 @@ scene.pov.media_scattering_type = '5'
scene.pov.media_samples = 35
scene.pov.media_diffusion_color = (0.000034, 0.000034, 0.000017)
scene.pov.media_absorption_color = (0.00000455, 0.00000165, 0.00000031)
-scene.pov.media_eccentricity = 0.7 \ No newline at end of file
+scene.pov.media_eccentricity = 0.7
diff --git a/render_auto_tile_size.py b/render_auto_tile_size.py
index d39f72d6..b1cac20b 100644
--- a/render_auto_tile_size.py
+++ b/render_auto_tile_size.py
@@ -24,8 +24,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "Render Settings > Performance",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "render/auto_tile_size.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "render/auto_tile_size.html",
"category": "Render",
}
diff --git a/render_copy_settings/__init__.py b/render_copy_settings/__init__.py
index c40f41b7..32a5fb0c 100644
--- a/render_copy_settings/__init__.py
+++ b/render_copy_settings/__init__.py
@@ -26,8 +26,8 @@ bl_info = {
"location": "Render buttons (Properties window)",
"description": "Allows to copy a selection of render settings "
"from current scene to others.",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "render/copy_settings.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "render/copy_settings.html",
"category": "Render",
}
diff --git a/render_freestyle_svg.py b/render_freestyle_svg.py
index d0d6a479..a6936bff 100644
--- a/render_freestyle_svg.py
+++ b/render_freestyle_svg.py
@@ -26,10 +26,10 @@ bl_info = {
"location": "Properties > Render > Freestyle SVG Export",
"description": "Exports Freestyle's stylized edges in SVG format",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/render/render_freestyle_svg.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/render/render_freestyle_svg.html",
"support": 'OFFICIAL',
"category": "Render",
- }
+}
import bpy
import parameter_editor
diff --git a/render_povray/__init__.py b/render_povray/__init__.py
index 99c854a4..8d6b7540 100644
--- a/render_povray/__init__.py
+++ b/render_povray/__init__.py
@@ -102,7 +102,7 @@ bl_info = {
"blender": (2, 81, 0),
"location": "Render Properties > Render Engine > Persistence of Vision",
"description": "Persistence of Vision integration for blender",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/render/povray.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/render/povray.html",
"category": "Render",
}
diff --git a/rigify/__init__.py b/rigify/__init__.py
index 25c164ab..a6e7fa87 100644
--- a/rigify/__init__.py
+++ b/rigify/__init__.py
@@ -25,9 +25,10 @@ bl_info = {
"blender": (2, 81, 0),
"description": "Automatic rigging from building-block components",
"location": "Armature properties, Bone properties, View3d tools panel, Armature Add menu",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "rigging/rigify/index.html",
- "category": "Rigging"}
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "rigging/rigify/index.html",
+ "category": "Rigging",
+}
import importlib
import sys
diff --git a/rigify/base_generate.py b/rigify/base_generate.py
index ea1415c9..7141d77e 100644
--- a/rigify/base_generate.py
+++ b/rigify/base_generate.py
@@ -465,4 +465,3 @@ class BaseGenerator:
for bone in self.obj.data.bones:
if bone.parent is None:
self.__build_rig_tree_rec(bone, None, handled)
-
diff --git a/rigify/legacy/__init__.py b/rigify/legacy/__init__.py
index 029d877e..76c3a72f 100644
--- a/rigify/legacy/__init__.py
+++ b/rigify/legacy/__init__.py
@@ -25,10 +25,11 @@ bl_info = {
"blender": (2, 66, 0),
"description": "Automatic rigging from building-block components",
"location": "Armature properties, Bone properties, View3d tools panel, Armature Add menu",
- "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"
- "Scripts/Rigging/Rigify",
+ "doc_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/"
+ "Scripts/Rigging/Rigify",
"tracker_url": "http://github.com/cessen/rigify/issues",
- "category": "Rigging"}
+ "category": "Rigging",
+}
if "bpy" in locals():
diff --git a/rigify/rigs/experimental/super_chain.py b/rigify/rigs/experimental/super_chain.py
index 3f7ca5d6..346c16b8 100644
--- a/rigify/rigs/experimental/super_chain.py
+++ b/rigify/rigs/experimental/super_chain.py
@@ -558,7 +558,7 @@ class Rig:
)
invert_last = True
- if self.params.wgt_align_axis is not 'y' or '-y':
+ if self.params.wgt_align_axis not in {'y' or '-y'}:
invert_last = False
create_chain_widget(
diff --git a/rigify/rot_mode.py b/rigify/rot_mode.py
index 50e79877..6ea9f241 100644
--- a/rigify/rot_mode.py
+++ b/rigify/rot_mode.py
@@ -11,7 +11,7 @@ This script/addon:
TO-DO:
- To convert object's rotation mode (already done in Mutant Bob script,
- but not done in this one.
+ but not done in this one.
- To understand "EnumProperty" and write it well.
- Code clean
- ...
@@ -33,9 +33,10 @@ blender.stackexchange.com/questions/40711/how-to-convert-quaternions-keyframes-t
# 'location': '',
# "description": "Converts bones rotation mode",
# "warning": "",
-# "wiki_url": "",
+# "doc_url": "",
# "tracker_url": "https://github.com/MarioMey/rotation_mode_addon/",
-# "category": "Animation"}
+# "category": "Animation",
+# }
import bpy
from bpy.props import (
diff --git a/rigify/utils/metaclass.py b/rigify/utils/metaclass.py
index 77ce4b6b..9e169e05 100644
--- a/rigify/utils/metaclass.py
+++ b/rigify/utils/metaclass.py
@@ -168,4 +168,3 @@ class SingletonPluginMetaclass(StagedMetaclass):
owner.plugin_list.append(new_obj)
owner.plugin_list.sort(key=lambda obj: obj.priority, reverse=True)
return new_obj
-
diff --git a/space_clip_editor_refine_solution.py b/space_clip_editor_refine_solution.py
index 7e3e8cac..13985c2a 100644
--- a/space_clip_editor_refine_solution.py
+++ b/space_clip_editor_refine_solution.py
@@ -30,8 +30,8 @@ bl_info = {
"description": "Refine motion solution by setting track weight according"
" to reprojection error",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "video_tools/refine_tracking.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "video_tools/refine_tracking.html",
"category": "Video Tools",
}
diff --git a/space_view3d_3d_navigation.py b/space_view3d_3d_navigation.py
index 34074ad0..c8b27323 100644
--- a/space_view3d_3d_navigation.py
+++ b/space_view3d_3d_navigation.py
@@ -30,8 +30,8 @@ bl_info = {
"location": "View3D > Sidebar > View Tab",
"description": "Navigate the Camera & 3D View from the Toolshelf",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "3d_view/3d_navigation.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "3d_view/3d_navigation.html",
"category": "3D View",
}
diff --git a/space_view3d_align_tools.py b/space_view3d_align_tools.py
index 6ae21e0b..c021ff06 100644
--- a/space_view3d_align_tools.py
+++ b/space_view3d_align_tools.py
@@ -26,8 +26,8 @@ bl_info = {
"location": "View3D > Sidebar > Item Tab",
"description": "Align Selected Objects to Active Object",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "object/align_tools.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "object/align_tools.html",
"category": "Object",
}
diff --git a/space_view3d_brush_menus/__init__.py b/space_view3d_brush_menus/__init__.py
index dbc16a5e..3607630a 100644
--- a/space_view3d_brush_menus/__init__.py
+++ b/space_view3d_brush_menus/__init__.py
@@ -27,8 +27,9 @@ bl_info = {
"blender": (2, 80, 0),
"location": "Spacebar in Sculpt/Paint Modes",
"warning": '',
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/interface/brush_menus.html",
- "category": "Interface"}
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/interface/brush_menus.html",
+ "category": "Interface",
+}
if "bpy" in locals():
diff --git a/space_view3d_copy_attributes.py b/space_view3d_copy_attributes.py
index f06ec3d1..c4bf4c42 100644
--- a/space_view3d_copy_attributes.py
+++ b/space_view3d_copy_attributes.py
@@ -25,8 +25,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D > Ctrl-C",
"description": "Copy Attributes Menu from Blender 2.4",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "interface/copy_attributes.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "interface/copy_attributes.html",
"category": "Interface",
}
diff --git a/space_view3d_math_vis/__init__.py b/space_view3d_math_vis/__init__.py
index 129a0618..23995374 100644
--- a/space_view3d_math_vis/__init__.py
+++ b/space_view3d_math_vis/__init__.py
@@ -25,8 +25,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "Properties: Scene > Math Vis Console and Python Console: Menu",
"description": "Display console defined mathutils variables in the 3D view",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "3d_view/math_vis_console.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "3d_view/math_vis_console.html",
"support": "OFFICIAL",
"category": "3D View",
}
diff --git a/space_view3d_math_vis/draw.py b/space_view3d_math_vis/draw.py
index 8adeeb0b..60467faa 100644
--- a/space_view3d_math_vis/draw.py
+++ b/space_view3d_math_vis/draw.py
@@ -244,4 +244,4 @@ def draw_bounding_boxes(matrices, scale, color):
single_color_shader.bind()
single_color_shader.uniform_float("color", color)
- batch.draw(single_color_shader) \ No newline at end of file
+ batch.draw(single_color_shader)
diff --git a/space_view3d_modifier_tools.py b/space_view3d_modifier_tools.py
index ba71532e..a4bc1d0e 100644
--- a/space_view3d_modifier_tools.py
+++ b/space_view3d_modifier_tools.py
@@ -25,8 +25,8 @@ bl_info = {
"location": "Properties > Modifiers",
"description": "Modifiers Specials Show/Hide/Apply Selected",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "interface/modifier_tools.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "interface/modifier_tools.html",
"category": "Interface"
}
diff --git a/space_view3d_pie_menus/__init__.py b/space_view3d_pie_menus/__init__.py
index 92e7e74e..a9044df5 100644
--- a/space_view3d_pie_menus/__init__.py
+++ b/space_view3d_pie_menus/__init__.py
@@ -39,8 +39,8 @@ bl_info = {
"description": "Pie Menu Activation",
"location": "Addons Preferences",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "interface/viewport_pies.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "interface/viewport_pies.html",
"category": "Interface"
}
@@ -178,14 +178,14 @@ class PIEToolsPreferences(AddonPreferences):
split.label(text='Warning:')
split.label(text=' ' + info['warning'], icon='ERROR')
- tot_row = int(bool(info.get('wiki_url')))
+ tot_row = int(bool(info.get('doc_url')))
if tot_row:
split = col.row().split(factor=0.15)
split.label(text='Internet:')
- if info.get('wiki_url'):
+ if info.get('doc_url'):
op = split.operator('wm.url_open',
text='Documentation', icon='HELP')
- op.url = info.get('wiki_url')
+ op.url = info.get('doc_url')
for i in range(4 - tot_row):
split.separator()
diff --git a/space_view3d_pie_menus/pie_align_menu.py b/space_view3d_pie_menus/pie_align_menu.py
index e3ad60a9..2dcf9e20 100644
--- a/space_view3d_pie_menus/pie_align_menu.py
+++ b/space_view3d_pie_menus/pie_align_menu.py
@@ -26,7 +26,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "Mesh Edit Mode",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Edit Align Pie"
}
diff --git a/space_view3d_pie_menus/pie_animation_menu.py b/space_view3d_pie_menus/pie_animation_menu.py
index d18b2640..eda7ed4d 100644
--- a/space_view3d_pie_menus/pie_animation_menu.py
+++ b/space_view3d_pie_menus/pie_animation_menu.py
@@ -26,7 +26,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "3D View",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Animation Pie"
}
diff --git a/space_view3d_pie_menus/pie_apply_transform_menu.py b/space_view3d_pie_menus/pie_apply_transform_menu.py
index 2be7843a..7646571d 100644
--- a/space_view3d_pie_menus/pie_apply_transform_menu.py
+++ b/space_view3d_pie_menus/pie_apply_transform_menu.py
@@ -26,7 +26,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "3D View",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Apply Transform Pie"
}
diff --git a/space_view3d_pie_menus/pie_defaults_menu.py b/space_view3d_pie_menus/pie_defaults_menu.py
index cda67e7c..8c068c47 100644
--- a/space_view3d_pie_menus/pie_defaults_menu.py
+++ b/space_view3d_pie_menus/pie_defaults_menu.py
@@ -24,7 +24,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "All Editors",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Interface"
}
diff --git a/space_view3d_pie_menus/pie_delete_menu.py b/space_view3d_pie_menus/pie_delete_menu.py
index ee3e2b58..97e0c774 100644
--- a/space_view3d_pie_menus/pie_delete_menu.py
+++ b/space_view3d_pie_menus/pie_delete_menu.py
@@ -26,7 +26,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "Mesh Edit Mode",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Edit Delete Pie"
}
diff --git a/space_view3d_pie_menus/pie_editor_switch_menu.py b/space_view3d_pie_menus/pie_editor_switch_menu.py
index d648217f..5b6475d6 100644
--- a/space_view3d_pie_menus/pie_editor_switch_menu.py
+++ b/space_view3d_pie_menus/pie_editor_switch_menu.py
@@ -26,7 +26,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "All Editors",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Editor Switch Pie"
}
diff --git a/space_view3d_pie_menus/pie_manipulator_menu.py b/space_view3d_pie_menus/pie_manipulator_menu.py
index 8d7387e8..428254d4 100644
--- a/space_view3d_pie_menus/pie_manipulator_menu.py
+++ b/space_view3d_pie_menus/pie_manipulator_menu.py
@@ -26,7 +26,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "3D View",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Manipulator Pie"
}
diff --git a/space_view3d_pie_menus/pie_modes_menu.py b/space_view3d_pie_menus/pie_modes_menu.py
index 62273c2b..c7ec302f 100644
--- a/space_view3d_pie_menus/pie_modes_menu.py
+++ b/space_view3d_pie_menus/pie_modes_menu.py
@@ -26,7 +26,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "3D View",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Mode Switch Pie"
}
diff --git a/space_view3d_pie_menus/pie_origin.py b/space_view3d_pie_menus/pie_origin.py
index 9fc36898..bc74fd1b 100644
--- a/space_view3d_pie_menus/pie_origin.py
+++ b/space_view3d_pie_menus/pie_origin.py
@@ -26,7 +26,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "3D View",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Origin Pie"
}
@@ -277,7 +277,7 @@ class PIE_MT_OriginPivot(Menu):
# 2 - BOTTOM
pie.operator("object.pivotobottom_edit", text="Origin to Bottom",
icon='TRIA_DOWN')
- # 8 - TOP
+ # 8 - TOP
pie.operator("object.setorigintoselected_edit", text="Origin To Selected",
icon='SNAP_INCREMENT')
# 7 - TOP - LEFT
diff --git a/space_view3d_pie_menus/pie_proportional_menu.py b/space_view3d_pie_menus/pie_proportional_menu.py
index 81312c72..10575a55 100644
--- a/space_view3d_pie_menus/pie_proportional_menu.py
+++ b/space_view3d_pie_menus/pie_proportional_menu.py
@@ -26,7 +26,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "3D View Object & Edit modes",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Proportional Edit Pie"
}
diff --git a/space_view3d_pie_menus/pie_save_open_menu.py b/space_view3d_pie_menus/pie_save_open_menu.py
index 9e02b321..ff253d2f 100644
--- a/space_view3d_pie_menus/pie_save_open_menu.py
+++ b/space_view3d_pie_menus/pie_save_open_menu.py
@@ -24,7 +24,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "All Editors",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Save Open Pie"
}
diff --git a/space_view3d_pie_menus/pie_sculpt_menu.py b/space_view3d_pie_menus/pie_sculpt_menu.py
index 0f919c9b..e50a47fa 100644
--- a/space_view3d_pie_menus/pie_sculpt_menu.py
+++ b/space_view3d_pie_menus/pie_sculpt_menu.py
@@ -26,7 +26,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "W key",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Sculpt Pie"
}
diff --git a/space_view3d_pie_menus/pie_select_menu.py b/space_view3d_pie_menus/pie_select_menu.py
index c1cdf2af..025cddaa 100644
--- a/space_view3d_pie_menus/pie_select_menu.py
+++ b/space_view3d_pie_menus/pie_select_menu.py
@@ -26,7 +26,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "3D View",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Select Pie"
}
diff --git a/space_view3d_pie_menus/pie_shading_menu.py b/space_view3d_pie_menus/pie_shading_menu.py
index ec6c3fbb..28603d25 100644
--- a/space_view3d_pie_menus/pie_shading_menu.py
+++ b/space_view3d_pie_menus/pie_shading_menu.py
@@ -26,7 +26,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "3D View",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "Shading Pie"
}
diff --git a/space_view3d_pie_menus/pie_views_numpad_menu.py b/space_view3d_pie_menus/pie_views_numpad_menu.py
index eb9f85b6..d96b6b63 100644
--- a/space_view3d_pie_menus/pie_views_numpad_menu.py
+++ b/space_view3d_pie_menus/pie_views_numpad_menu.py
@@ -26,7 +26,7 @@ bl_info = {
"blender": (2, 80, 0),
"location": "Alt Q key",
"warning": "",
- "wiki_url": "",
+ "doc_url": "",
"category": "View Numpad Pie"
}
diff --git a/space_view3d_spacebar_menu/__init__.py b/space_view3d_spacebar_menu/__init__.py
index 5694c3fa..51a7d4dd 100644
--- a/space_view3d_spacebar_menu/__init__.py
+++ b/space_view3d_spacebar_menu/__init__.py
@@ -25,8 +25,8 @@ bl_info = {
"location": "View3D > Spacebar",
"description": "Object Mode Context Sensitive Spacebar Menu",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "interface/context_menu.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "interface/context_menu.html",
"category": "Interface",
}
@@ -827,20 +827,20 @@ class VIEW3D_MT_Space_Dynamic_Menu(Menu):
# Text Edit Mode
def menu_func(self, context):
- layout = self.layout
-
- layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL')
- layout.menu("VIEW3D_MT_select_edit_text", icon='VIEW3D')
- layout.separator()
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM')
- layout.menu("VIEW3D_MT_Animation_Player",
- text="Animation", icon='PLAY')
- layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART')
- layout.operator("object.editmode_toggle", text="Enter Object Mode",
- icon='OBJECT_DATA')
- layout.separator()
- layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT')
+ layout = self.layout
+
+ layout.menu("VIEW3D_MT_View_Menu", icon='ZOOM_ALL')
+ layout.menu("VIEW3D_MT_select_edit_text", icon='VIEW3D')
+ layout.separator()
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.operator("wm.search_menu", text="Search", icon='VIEWZOOM')
+ layout.menu("VIEW3D_MT_Animation_Player",
+ text="Animation", icon='PLAY')
+ layout.menu("SCREEN_MT_user_menu", text="Quick Favorites", icon='HEART')
+ layout.operator("object.editmode_toggle", text="Enter Object Mode",
+ icon='OBJECT_DATA')
+ layout.separator()
+ layout.menu("VIEW3D_MT_UndoS", icon='ARROW_LEFTRIGHT')
# Preferences utility functions
diff --git a/space_view3d_spacebar_menu/edit_mesh.py b/space_view3d_spacebar_menu/edit_mesh.py
index eff16c0d..c7098c69 100644
--- a/space_view3d_spacebar_menu/edit_mesh.py
+++ b/space_view3d_spacebar_menu/edit_mesh.py
@@ -20,13 +20,13 @@
import bpy
from bpy.types import (
- Operator,
- Menu,
- )
+ Operator,
+ Menu,
+ )
from bpy.props import (
- BoolProperty,
- StringProperty,
- )
+ BoolProperty,
+ StringProperty,
+ )
from .object_menus import *
from .snap_origin_cursor import *
@@ -36,210 +36,210 @@ from .snap_origin_cursor import *
# ********** Edit Multiselect **********
class VIEW3D_MT_Edit_Multi(Menu):
- bl_label = "Mode Select"
+ bl_label = "Mode Select"
- def draw(self, context):
- layout = self.layout
+ def draw(self, context):
+ layout = self.layout
- layout.operator("selectedit.vertex", text="Vertex", icon='VERTEXSEL')
- layout.operator("selectedit.edge", text="Edge", icon='EDGESEL')
- layout.operator("selectedit.face", text="Face", icon='FACESEL')
- layout.operator("selectedit.vertsfaces", text="Vertex/Faces", icon='VERTEXSEL')
- layout.operator("selectedit.vertsedges", text="Vertex/Edges", icon='EDGESEL')
- layout.operator("selectedit.edgesfaces", text="Edges/Faces", icon='FACESEL')
- layout.operator("selectedit.vertsedgesfaces", text="Vertex/Edges/Faces", icon='OBJECT_DATAMODE')
+ layout.operator("selectedit.vertex", text="Vertex", icon='VERTEXSEL')
+ layout.operator("selectedit.edge", text="Edge", icon='EDGESEL')
+ layout.operator("selectedit.face", text="Face", icon='FACESEL')
+ layout.operator("selectedit.vertsfaces", text="Vertex/Faces", icon='VERTEXSEL')
+ layout.operator("selectedit.vertsedges", text="Vertex/Edges", icon='EDGESEL')
+ layout.operator("selectedit.edgesfaces", text="Edges/Faces", icon='FACESEL')
+ layout.operator("selectedit.vertsedgesfaces", text="Vertex/Edges/Faces", icon='OBJECT_DATAMODE')
# ********** Edit Mesh Edge **********
class VIEW3D_MT_EditM_Edge(Menu):
- bl_label = "Edges"
+ bl_label = "Edges"
- def draw(self, context):
- layout = self.layout
- layout.operator_context = 'INVOKE_REGION_WIN'
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("mesh.mark_seam")
- layout.operator("mesh.mark_seam", text="Clear Seam").clear = True
- layout.separator()
+ layout.operator("mesh.mark_seam")
+ layout.operator("mesh.mark_seam", text="Clear Seam").clear = True
+ layout.separator()
- layout.operator("mesh.mark_sharp")
- layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
- layout.operator("mesh.extrude_move_along_normals", text="Extrude")
- layout.separator()
+ layout.operator("mesh.mark_sharp")
+ layout.operator("mesh.mark_sharp", text="Clear Sharp").clear = True
+ layout.operator("mesh.extrude_move_along_normals", text="Extrude")
+ layout.separator()
- layout.operator("mesh.edge_rotate",
- text="Rotate Edge CW").direction = 'CW'
- layout.operator("mesh.edge_rotate",
- text="Rotate Edge CCW").direction = 'CCW'
- layout.separator()
+ layout.operator("mesh.edge_rotate",
+ text="Rotate Edge CW").direction = 'CW'
+ layout.operator("mesh.edge_rotate",
+ text="Rotate Edge CCW").direction = 'CCW'
+ layout.separator()
- layout.operator("TFM_OT_edge_slide", text="Edge Slide")
- layout.operator("mesh.loop_multi_select", text="Edge Loop")
- layout.operator("mesh.loop_multi_select", text="Edge Ring").ring = True
- layout.operator("mesh.loop_to_region")
- layout.operator("mesh.region_to_loop")
+ layout.operator("TFM_OT_edge_slide", text="Edge Slide")
+ layout.operator("mesh.loop_multi_select", text="Edge Loop")
+ layout.operator("mesh.loop_multi_select", text="Edge Ring").ring = True
+ layout.operator("mesh.loop_to_region")
+ layout.operator("mesh.region_to_loop")
# multiple edit select modes.
class VIEW3D_OT_selecteditVertex(Operator):
- bl_idname = "selectedit.vertex"
- bl_label = "Vertex Mode"
- bl_description = "Vert Select"
- bl_options = {'REGISTER', 'UNDO'}
+ bl_idname = "selectedit.vertex"
+ bl_label = "Vertex Mode"
+ bl_description = "Vert Select"
+ bl_options = {'REGISTER', 'UNDO'}
- def execute(self, context):
- if context.object.mode != "EDIT":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- if bpy.ops.mesh.select_mode != "EDGE, FACE":
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- return {'FINISHED'}
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ if bpy.ops.mesh.select_mode != "EDGE, FACE":
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ return {'FINISHED'}
class VIEW3D_OT_selecteditEdge(Operator):
- bl_idname = "selectedit.edge"
- bl_label = "Edge Mode"
- bl_description = "Edge Select"
- bl_options = {'REGISTER', 'UNDO'}
+ bl_idname = "selectedit.edge"
+ bl_label = "Edge Mode"
+ bl_description = "Edge Select"
+ bl_options = {'REGISTER', 'UNDO'}
- def execute(self, context):
- if context.object.mode != "EDIT":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
- if bpy.ops.mesh.select_mode != "VERT, FACE":
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
- return {'FINISHED'}
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
+ if bpy.ops.mesh.select_mode != "VERT, FACE":
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
+ return {'FINISHED'}
class VIEW3D_OT_selecteditFace(Operator):
- bl_idname = "selectedit.face"
- bl_label = "Multiedit Face"
- bl_description = "Face Mode"
- bl_options = {'REGISTER', 'UNDO'}
+ bl_idname = "selectedit.face"
+ bl_label = "Multiedit Face"
+ bl_description = "Face Mode"
+ bl_options = {'REGISTER', 'UNDO'}
- def execute(self, context):
- if context.object.mode != "EDIT":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
- if bpy.ops.mesh.select_mode != "VERT, EDGE":
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
- return {'FINISHED'}
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
+ if bpy.ops.mesh.select_mode != "VERT, EDGE":
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='FACE')
+ return {'FINISHED'}
# Components Multi Selection Mode
class VIEW3D_OT_selecteditVertsEdges(Operator):
- bl_idname = "selectedit.vertsedges"
- bl_label = "Verts Edges Mode"
- bl_description = "Vert/Edge Select"
- bl_options = {'REGISTER', 'UNDO'}
-
- def execute(self, context):
- if context.object.mode != "EDIT":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='EDGE')
- return {'FINISHED'}
+ bl_idname = "selectedit.vertsedges"
+ bl_label = "Verts Edges Mode"
+ bl_description = "Vert/Edge Select"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='EDGE')
+ return {'FINISHED'}
class VIEW3D_OT_selecteditEdgesFaces(Operator):
- bl_idname = "selectedit.edgesfaces"
- bl_label = "Edges Faces Mode"
- bl_description = "Edge/Face Select"
- bl_options = {'REGISTER', 'UNDO'}
-
- def execute(self, context):
- if context.object.mode != "EDIT":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
- if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
- bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='FACE')
- return {'FINISHED'}
+ bl_idname = "selectedit.edgesfaces"
+ bl_label = "Edges Faces Mode"
+ bl_description = "Edge/Face Select"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
+ if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='EDGE')
+ bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='FACE')
+ return {'FINISHED'}
class VIEW3D_OT_selecteditVertsFaces(Operator):
- bl_idname = "selectedit.vertsfaces"
- bl_label = "Verts Faces Mode"
- bl_description = "Vert/Face Select"
- bl_options = {'REGISTER', 'UNDO'}
-
- def execute(self, context):
- if context.object.mode != "EDIT":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='FACE')
- return {'FINISHED'}
+ bl_idname = "selectedit.vertsfaces"
+ bl_label = "Verts Faces Mode"
+ bl_description = "Vert/Face Select"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='FACE')
+ return {'FINISHED'}
class VIEW3D_OT_selecteditVertsEdgesFaces(Operator):
- bl_idname = "selectedit.vertsedgesfaces"
- bl_label = "Verts Edges Faces Mode"
- bl_description = "Vert/Edge/Face Select"
- bl_options = {'REGISTER', 'UNDO'}
-
- def execute(self, context):
- if context.object.mode != "EDIT":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
- bpy.ops.object.mode_set(mode="EDIT")
- bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
- bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='EDGE')
- bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='FACE')
- return {'FINISHED'}
+ bl_idname = "selectedit.vertsedgesfaces"
+ bl_label = "Verts Edges Faces Mode"
+ bl_description = "Vert/Edge/Face Select"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ if context.object.mode != "EDIT":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ if bpy.ops.mesh.select_mode != "VERT, EDGE, FACE":
+ bpy.ops.object.mode_set(mode="EDIT")
+ bpy.ops.mesh.select_mode(use_extend=False, use_expand=False, type='VERT')
+ bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='EDGE')
+ bpy.ops.mesh.select_mode(use_extend=True, use_expand=False, type='FACE')
+ return {'FINISHED'}
# ********** Normals / Auto Smooth Menu **********
# Thanks to marvin.k.breuer for the Autosmooth part of the menu
def menu_func(self, context):
- layout = self.layout
- obj = context.object
- obj_data = context.active_object.data
- layout.separator()
- layout.prop(obj_data, "use_auto_smooth", text="Normals: Auto Smooth")
+ layout = self.layout
+ obj = context.object
+ obj_data = context.active_object.data
+ layout.separator()
+ layout.prop(obj_data, "use_auto_smooth", text="Normals: Auto Smooth")
- # Auto Smooth Angle - two tab spaces to align it with the rest of the menu
- layout.prop(obj_data, "auto_smooth_angle",
- text=" Auto Smooth Angle")
+ # Auto Smooth Angle - two tab spaces to align it with the rest of the menu
+ layout.prop(obj_data, "auto_smooth_angle",
+ text=" Auto Smooth Angle")
# List The Classes #
classes = (
- VIEW3D_MT_Edit_Multi,
- VIEW3D_MT_EditM_Edge,
- VIEW3D_OT_selecteditVertex,
- VIEW3D_OT_selecteditEdge,
- VIEW3D_OT_selecteditFace,
- VIEW3D_OT_selecteditVertsEdges,
- VIEW3D_OT_selecteditEdgesFaces,
- VIEW3D_OT_selecteditVertsFaces,
- VIEW3D_OT_selecteditVertsEdgesFaces,
+ VIEW3D_MT_Edit_Multi,
+ VIEW3D_MT_EditM_Edge,
+ VIEW3D_OT_selecteditVertex,
+ VIEW3D_OT_selecteditEdge,
+ VIEW3D_OT_selecteditFace,
+ VIEW3D_OT_selecteditVertsEdges,
+ VIEW3D_OT_selecteditEdgesFaces,
+ VIEW3D_OT_selecteditVertsFaces,
+ VIEW3D_OT_selecteditVertsEdgesFaces,
)
# Register Classes & Hotkeys #
def register():
- for cls in classes:
- bpy.utils.register_class(cls)
+ for cls in classes:
+ bpy.utils.register_class(cls)
- bpy.types.VIEW3D_MT_edit_mesh_normals.append(menu_func)
+ bpy.types.VIEW3D_MT_edit_mesh_normals.append(menu_func)
# Unregister Classes & Hotkeys #
def unregister():
- for cls in reversed(classes):
- bpy.utils.unregister_class(cls)
+ for cls in reversed(classes):
+ bpy.utils.unregister_class(cls)
- bpy.types.VIEW3D_MT_edit_mesh_normals.remove(menu_func)
+ bpy.types.VIEW3D_MT_edit_mesh_normals.remove(menu_func)
if __name__ == "__main__":
- register()
+ register()
diff --git a/space_view3d_spacebar_menu/snap_origin_cursor.py b/space_view3d_spacebar_menu/snap_origin_cursor.py
index f10f2dfc..b150a492 100644
--- a/space_view3d_spacebar_menu/snap_origin_cursor.py
+++ b/space_view3d_spacebar_menu/snap_origin_cursor.py
@@ -20,283 +20,283 @@
import bpy
from bpy.types import (
- Operator,
- Menu,
- )
+ Operator,
+ Menu,
+)
from bpy.props import (
- BoolProperty,
- StringProperty,
- )
+ BoolProperty,
+ StringProperty,
+)
from .object_menus import *
# ********** Object Snap Cursor **********
class VIEW3D_MT_Snap_Context(Menu):
- bl_label = "Snapping"
+ bl_label = "Snapping"
- def draw(self, context):
- layout = self.layout
- toolsettings = context.tool_settings
- layout.prop(toolsettings, "use_snap")
- layout.prop(toolsettings, "snap_elements", expand=True)
+ def draw(self, context):
+ layout = self.layout
+ toolsettings = context.tool_settings
+ layout.prop(toolsettings, "use_snap")
+ layout.prop(toolsettings, "snap_elements", expand=True)
class VIEW3D_MT_Snap_Origin(Menu):
- bl_label = "Snap Origin"
-
- def draw(self, context):
- layout = self.layout
- layout.operator_context = 'EXEC_AREA'
- layout.operator("object.origin_set",
- text="Geometry to Origin").type = 'GEOMETRY_ORIGIN'
- layout.separator()
- layout.operator("object.origin_set",
- text="Origin to Geometry").type = 'ORIGIN_GEOMETRY'
- layout.operator("object.origin_set",
- text="Origin to 3D Cursor").type = 'ORIGIN_CURSOR'
- layout.operator("object.origin_set",
- text="Origin to Center of Mass").type = 'ORIGIN_CENTER_OF_MASS'
+ bl_label = "Snap Origin"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'EXEC_AREA'
+ layout.operator("object.origin_set",
+ text="Geometry to Origin").type = 'GEOMETRY_ORIGIN'
+ layout.separator()
+ layout.operator("object.origin_set",
+ text="Origin to Geometry").type = 'ORIGIN_GEOMETRY'
+ layout.operator("object.origin_set",
+ text="Origin to 3D Cursor").type = 'ORIGIN_CURSOR'
+ layout.operator("object.origin_set",
+ text="Origin to Center of Mass").type = 'ORIGIN_CENTER_OF_MASS'
class VIEW3D_MT_CursorMenu(Menu):
- bl_label = "Snap To"
-
- def draw(self, context):
- layout = self.layout
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.menu("VIEW3D_MT_Snap_Origin")
- layout.menu("VIEW3D_MT_Snap_Context")
- layout.separator()
- layout.operator("view3d.snap_cursor_to_selected",
- text="Cursor to Selected")
- layout.operator("view3d.snap_cursor_to_center",
- text="Cursor to World Origin")
- layout.operator("view3d.snap_cursor_to_grid",
- text="Cursor to Grid")
- layout.operator("view3d.snap_cursor_to_active",
- text="Cursor to Active")
- layout.separator()
- layout.operator("view3d.snap_selected_to_cursor",
- text="Selection to Cursor").use_offset = False
- layout.operator("view3d.snap_selected_to_cursor",
- text="Selection to Cursor (Keep Offset)").use_offset = True
- layout.operator("view3d.snap_selected_to_grid",
- text="Selection to Grid")
- layout.operator("view3d.snap_cursor_selected_to_center",
- text="Selection and Cursor to World Origin")
+ bl_label = "Snap To"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.menu("VIEW3D_MT_Snap_Origin")
+ layout.menu("VIEW3D_MT_Snap_Context")
+ layout.separator()
+ layout.operator("view3d.snap_cursor_to_selected",
+ text="Cursor to Selected")
+ layout.operator("view3d.snap_cursor_to_center",
+ text="Cursor to World Origin")
+ layout.operator("view3d.snap_cursor_to_grid",
+ text="Cursor to Grid")
+ layout.operator("view3d.snap_cursor_to_active",
+ text="Cursor to Active")
+ layout.separator()
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor").use_offset = False
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor (Keep Offset)").use_offset = True
+ layout.operator("view3d.snap_selected_to_grid",
+ text="Selection to Grid")
+ layout.operator("view3d.snap_cursor_selected_to_center",
+ text="Selection and Cursor to World Origin")
class VIEW3D_MT_CursorMenuLite(Menu):
- bl_label = "Snap to"
-
- def draw(self, context):
- layout = self.layout
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.menu("VIEW3D_MT_Snap_Origin")
- layout.separator()
- layout.operator("view3d.snap_cursor_to_selected",
- text="Cursor to Selected")
- layout.operator("view3d.snap_cursor_to_center",
- text="Cursor to World Origin")
- layout.operator("view3d.snap_cursor_to_grid",
- text="Cursor to Grid")
- layout.operator("view3d.snap_cursor_to_active",
- text="Cursor to Active")
- layout.separator()
- layout.operator("view3d.snap_selected_to_cursor",
- text="Selection to Cursor").use_offset = False
- layout.operator("view3d.snap_selected_to_cursor",
- text="Selection to Cursor (Keep Offset)").use_offset = True
- layout.operator("view3d.snap_selected_to_grid",
- text="Selection to Grid")
- layout.operator("view3d.snap_cursor_selected_to_center",
- text="Selection and Cursor to World Origin")
+ bl_label = "Snap to"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.menu("VIEW3D_MT_Snap_Origin")
+ layout.separator()
+ layout.operator("view3d.snap_cursor_to_selected",
+ text="Cursor to Selected")
+ layout.operator("view3d.snap_cursor_to_center",
+ text="Cursor to World Origin")
+ layout.operator("view3d.snap_cursor_to_grid",
+ text="Cursor to Grid")
+ layout.operator("view3d.snap_cursor_to_active",
+ text="Cursor to Active")
+ layout.separator()
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor").use_offset = False
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor (Keep Offset)").use_offset = True
+ layout.operator("view3d.snap_selected_to_grid",
+ text="Selection to Grid")
+ layout.operator("view3d.snap_cursor_selected_to_center",
+ text="Selection and Cursor to World Origin")
# Code thanks to Isaac Weaver (wisaac) D1963
class VIEW3D_OT_SnapCursSelToCenter(Operator):
- bl_idname = "view3d.snap_cursor_selected_to_center"
- bl_label = "Snap Cursor & Selection to World Origin"
- bl_description = ("Snap 3D cursor and selected objects to the center \n"
- "Works only in Object Mode")
+ bl_idname = "view3d.snap_cursor_selected_to_center"
+ bl_label = "Snap Cursor & Selection to World Origin"
+ bl_description = ("Snap 3D cursor and selected objects to the center \n"
+ "Works only in Object Mode")
- @classmethod
- def poll(cls, context):
- return (context.area.type == "VIEW_3D" and context.mode == "OBJECT")
+ @classmethod
+ def poll(cls, context):
+ return (context.area.type == "VIEW_3D" and context.mode == "OBJECT")
- def execute(self, context):
- context.scene.cursor.location = (0, 0, 0)
- for obj in context.selected_objects:
- obj.location = (0, 0, 0)
- return {'FINISHED'}
+ def execute(self, context):
+ context.scene.cursor.location = (0, 0, 0)
+ for obj in context.selected_objects:
+ obj.location = (0, 0, 0)
+ return {'FINISHED'}
# Cursor Edge Intersection Defs #
def abs(val):
- if val > 0:
- return val
- return -val
+ if val > 0:
+ return val
+ return -val
def edgeIntersect(context, operator):
- from mathutils.geometry import intersect_line_line
+ from mathutils.geometry import intersect_line_line
- obj = context.active_object
+ obj = context.active_object
- if (obj.type != "MESH"):
- operator.report({'ERROR'}, "Object must be a mesh")
- return None
+ if (obj.type != "MESH"):
+ operator.report({'ERROR'}, "Object must be a mesh")
+ return None
- edges = []
- mesh = obj.data
- verts = mesh.vertices
+ edges = []
+ mesh = obj.data
+ verts = mesh.vertices
- is_editmode = (obj.mode == 'EDIT')
- if is_editmode:
- bpy.ops.object.mode_set(mode='OBJECT')
+ is_editmode = (obj.mode == 'EDIT')
+ if is_editmode:
+ bpy.ops.object.mode_set(mode='OBJECT')
- for e in mesh.edges:
- if e.select:
- edges.append(e)
+ for e in mesh.edges:
+ if e.select:
+ edges.append(e)
- if len(edges) > 2:
- break
+ if len(edges) > 2:
+ break
- if is_editmode:
- bpy.ops.object.mode_set(mode='EDIT')
+ if is_editmode:
+ bpy.ops.object.mode_set(mode='EDIT')
- if len(edges) != 2:
- operator.report({'ERROR'},
- "Operator requires exactly 2 edges to be selected")
- return
+ if len(edges) != 2:
+ operator.report({'ERROR'},
+ "Operator requires exactly 2 edges to be selected")
+ return
- line = intersect_line_line(verts[edges[0].vertices[0]].co,
- verts[edges[0].vertices[1]].co,
- verts[edges[1].vertices[0]].co,
- verts[edges[1].vertices[1]].co)
+ line = intersect_line_line(verts[edges[0].vertices[0]].co,
+ verts[edges[0].vertices[1]].co,
+ verts[edges[1].vertices[0]].co,
+ verts[edges[1].vertices[1]].co)
- if line is None:
- operator.report({'ERROR'}, "Selected edges do not intersect")
- return
+ if line is None:
+ operator.report({'ERROR'}, "Selected edges do not intersect")
+ return
- point = line[0].lerp(line[1], 0.5)
- context.scene.cursor.location = obj.matrix_world @ point
+ point = line[0].lerp(line[1], 0.5)
+ context.scene.cursor.location = obj.matrix_world @ point
# Cursor Edge Intersection Operator #
class VIEW3D_OT_CursorToEdgeIntersection(Operator):
- bl_idname = "view3d.snap_cursor_to_edge_intersection"
- bl_label = "Cursor to Edge Intersection"
- bl_description = "Finds the mid-point of the shortest distance between two edges"
+ bl_idname = "view3d.snap_cursor_to_edge_intersection"
+ bl_label = "Cursor to Edge Intersection"
+ bl_description = "Finds the mid-point of the shortest distance between two edges"
- @classmethod
- def poll(cls, context):
- obj = context.active_object
- return (obj is not None and obj.type == 'MESH')
+ @classmethod
+ def poll(cls, context):
+ obj = context.active_object
+ return (obj is not None and obj.type == 'MESH')
- def execute(self, context):
- # Prevent unsupported Execution in Local View modes
- space = bpy.context.space_data
- if space.local_view:
- self.report({'INFO'}, 'Global Perspective modes only unable to continue.')
- return {'FINISHED'}
- edgeIntersect(context, self)
- return {'FINISHED'}
+ def execute(self, context):
+ # Prevent unsupported Execution in Local View modes
+ space = bpy.context.space_data
+ if space.local_view:
+ self.report({'INFO'}, 'Global Perspective modes only unable to continue.')
+ return {'FINISHED'}
+ edgeIntersect(context, self)
+ return {'FINISHED'}
# Origin To Selected Edit Mode #
def vfeOrigin(context):
- try:
- cursorPositionX = context.scene.cursor.location[0]
- cursorPositionY = context.scene.cursor.location[1]
- cursorPositionZ = context.scene.cursor.location[2]
- bpy.ops.view3d.snap_cursor_to_selected()
- bpy.ops.object.mode_set()
- bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='MEDIAN')
- bpy.ops.object.mode_set(mode='EDIT')
- context.scene.cursor.location[0] = cursorPositionX
- context.scene.cursor.location[1] = cursorPositionY
- context.scene.cursor.location[2] = cursorPositionZ
- return True
- except:
- return False
+ try:
+ cursorPositionX = context.scene.cursor.location[0]
+ cursorPositionY = context.scene.cursor.location[1]
+ cursorPositionZ = context.scene.cursor.location[2]
+ bpy.ops.view3d.snap_cursor_to_selected()
+ bpy.ops.object.mode_set()
+ bpy.ops.object.origin_set(type='ORIGIN_CURSOR', center='MEDIAN')
+ bpy.ops.object.mode_set(mode='EDIT')
+ context.scene.cursor.location[0] = cursorPositionX
+ context.scene.cursor.location[1] = cursorPositionY
+ context.scene.cursor.location[2] = cursorPositionZ
+ return True
+ except:
+ return False
class VIEW3D_OT_SetOriginToSelected(Operator):
- bl_idname = "object.setorigintoselected"
- bl_label = "Set Origin to Selected"
- bl_description = "Set Origin to Selected"
+ bl_idname = "object.setorigintoselected"
+ bl_label = "Set Origin to Selected"
+ bl_description = "Set Origin to Selected"
- @classmethod
- def poll(cls, context):
- return (context.area.type == "VIEW_3D" and context.active_object is not None)
+ @classmethod
+ def poll(cls, context):
+ return (context.area.type == "VIEW_3D" and context.active_object is not None)
- def execute(self, context):
- check = vfeOrigin(context)
- if not check:
- self.report({"ERROR"}, "Set Origin to Selected could not be performed")
- return {'CANCELLED'}
+ def execute(self, context):
+ check = vfeOrigin(context)
+ if not check:
+ self.report({"ERROR"}, "Set Origin to Selected could not be performed")
+ return {'CANCELLED'}
- return {'FINISHED'}
+ return {'FINISHED'}
# ********** Edit Mesh Cursor **********
class VIEW3D_MT_EditCursorMenu(Menu):
- bl_label = "Snap To"
-
- def draw(self, context):
- layout = self.layout
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("object.setorigintoselected",
- text="Origin to Selected V/F/E")
- layout.separator()
- layout.menu("VIEW3D_MT_Snap_Origin")
- layout.menu("VIEW3D_MT_Snap_Context")
- layout.separator()
- layout.operator("view3d.snap_cursor_to_selected",
- text="Cursor to Selected")
- layout.operator("view3d.snap_cursor_to_center",
- text="Cursor to World Origin")
- layout.operator("view3d.snap_cursor_to_grid",
- text="Cursor to Grid")
- layout.operator("view3d.snap_cursor_to_active",
- text="Cursor to Active")
- layout.operator("view3d.snap_cursor_to_edge_intersection",
- text="Cursor to Edge Intersection")
- layout.separator()
- layout.operator("view3d.snap_selected_to_cursor",
- text="Selection to Cursor").use_offset = False
- layout.operator("view3d.snap_selected_to_cursor",
- text="Selection to Cursor (Keep Offset)").use_offset = True
- layout.operator("view3d.snap_selected_to_grid",
- text="Selection to Grid")
+ bl_label = "Snap To"
+
+ def draw(self, context):
+ layout = self.layout
+ layout.operator_context = 'INVOKE_REGION_WIN'
+ layout.operator("object.setorigintoselected",
+ text="Origin to Selected V/F/E")
+ layout.separator()
+ layout.menu("VIEW3D_MT_Snap_Origin")
+ layout.menu("VIEW3D_MT_Snap_Context")
+ layout.separator()
+ layout.operator("view3d.snap_cursor_to_selected",
+ text="Cursor to Selected")
+ layout.operator("view3d.snap_cursor_to_center",
+ text="Cursor to World Origin")
+ layout.operator("view3d.snap_cursor_to_grid",
+ text="Cursor to Grid")
+ layout.operator("view3d.snap_cursor_to_active",
+ text="Cursor to Active")
+ layout.operator("view3d.snap_cursor_to_edge_intersection",
+ text="Cursor to Edge Intersection")
+ layout.separator()
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor").use_offset = False
+ layout.operator("view3d.snap_selected_to_cursor",
+ text="Selection to Cursor (Keep Offset)").use_offset = True
+ layout.operator("view3d.snap_selected_to_grid",
+ text="Selection to Grid")
# List The Classes #
classes = (
- VIEW3D_MT_CursorMenu,
- VIEW3D_MT_CursorMenuLite,
- VIEW3D_MT_Snap_Context,
- VIEW3D_MT_Snap_Origin,
- VIEW3D_OT_SnapCursSelToCenter,
- VIEW3D_OT_CursorToEdgeIntersection,
- VIEW3D_OT_SetOriginToSelected,
- VIEW3D_MT_EditCursorMenu,
+ VIEW3D_MT_CursorMenu,
+ VIEW3D_MT_CursorMenuLite,
+ VIEW3D_MT_Snap_Context,
+ VIEW3D_MT_Snap_Origin,
+ VIEW3D_OT_SnapCursSelToCenter,
+ VIEW3D_OT_CursorToEdgeIntersection,
+ VIEW3D_OT_SetOriginToSelected,
+ VIEW3D_MT_EditCursorMenu,
)
# Register Classes & Hotkeys #
def register():
- for cls in classes:
- bpy.utils.register_class(cls)
+ for cls in classes:
+ bpy.utils.register_class(cls)
# Unregister Classes & Hotkeys #
def unregister():
- for cls in reversed(classes):
- bpy.utils.unregister_class(cls)
+ for cls in reversed(classes):
+ bpy.utils.unregister_class(cls)
if __name__ == "__main__":
- register()
+ register()
diff --git a/space_view3d_stored_views/__init__.py b/space_view3d_stored_views/__init__.py
index f35d6c16..527ef040 100644
--- a/space_view3d_stored_views/__init__.py
+++ b/space_view3d_stored_views/__init__.py
@@ -24,8 +24,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D > Sidebar > View > Stored Views",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "3d_view/stored_views.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "3d_view/stored_views.html",
"category": "3D View"
}
diff --git a/space_view3d_stored_views/io.py b/space_view3d_stored_views/io.py
index 4f9aaa83..83a5499d 100644
--- a/space_view3d_stored_views/io.py
+++ b/space_view3d_stored_views/io.py
@@ -340,4 +340,4 @@ def register():
def unregister():
for cls in classes:
- bpy.utils.unregister_class(cls) \ No newline at end of file
+ bpy.utils.unregister_class(cls)
diff --git a/space_view3d_stored_views/operators.py b/space_view3d_stored_views/operators.py
index 4cf8a2cf..284e785c 100644
--- a/space_view3d_stored_views/operators.py
+++ b/space_view3d_stored_views/operators.py
@@ -179,4 +179,4 @@ def register():
def unregister():
for cls in classes:
- bpy.utils.unregister_class(cls) \ No newline at end of file
+ bpy.utils.unregister_class(cls)
diff --git a/space_view3d_stored_views/properties.py b/space_view3d_stored_views/properties.py
index 0bf95097..51666ce2 100644
--- a/space_view3d_stored_views/properties.py
+++ b/space_view3d_stored_views/properties.py
@@ -134,4 +134,4 @@ def register():
def unregister():
for cls in classes:
- bpy.utils.unregister_class(cls) \ No newline at end of file
+ bpy.utils.unregister_class(cls)
diff --git a/space_view3d_stored_views/stored_views_test.py b/space_view3d_stored_views/stored_views_test.py
index c31639ad..19b2a0ef 100644
--- a/space_view3d_stored_views/stored_views_test.py
+++ b/space_view3d_stored_views/stored_views_test.py
@@ -24,8 +24,8 @@ bl_info = {
"blender": (2, 80, 0),
"location": "View3D > Properties > Stored Views",
"warning": "",
- "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.5/"
- "Py/Scripts/3D_interaction/stored_views",
+ "doc_url": "https://wiki.blender.org/index.php/Extensions:2.5/"
+ "Py/Scripts/3D_interaction/stored_views",
"category": "3D View"
}
diff --git a/sun_position/__init__.py b/sun_position/__init__.py
index cca1bc21..499cafc3 100644
--- a/sun_position/__init__.py
+++ b/sun_position/__init__.py
@@ -38,9 +38,10 @@ bl_info = {
"blender": (2, 80, 0),
"location": "World > Sun Position",
"description": "Show sun position with objects and/or sky texture",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "lighting/sun_position.html",
- "category": "Lighting"}
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "lighting/sun_position.html",
+ "category": "Lighting",
+}
if "bpy" in locals():
import importlib
diff --git a/sun_position/geo.py b/sun_position/geo.py
index 6d49f2ad..59c27e39 100644
--- a/sun_position/geo.py
+++ b/sun_position/geo.py
@@ -36,7 +36,7 @@ class Parser:
def add(self, name, pattern, virtual=False):
""" Adds a new named pattern (regular expression) that can reference previously added patterns by %(pattern_name)s.
- Virtual patterns can be used to make expressions more compact but don't show up in the parse tree. """
+ Virtual patterns can be used to make expressions more compact but don't show up in the parse tree. """
self.raw_patterns[name] = "(?:" + pattern + ")"
self.virtual[name] = virtual
@@ -169,7 +169,7 @@ def get_coordinate(b):
def parse_position(s):
""" Takes a (utf8-encoded) string describing a position and returns a tuple of floats for latitude and longitude in degrees.
- Tries to be as tolerant as possible with input. Returns None if parsing doesn't succeed. """
+ Tries to be as tolerant as possible with input. Returns None if parsing doesn't succeed. """
parse_tree = position_parser.parse("position", s)
if parse_tree == None: return None
diff --git a/sun_position/properties.py b/sun_position/properties.py
index 945bdebf..118de702 100644
--- a/sun_position/properties.py
+++ b/sun_position/properties.py
@@ -257,7 +257,6 @@ class SunPosAddonPreferences(AddonPreferences):
col.label(text="Show options or labels:")
flow = col.grid_flow(columns=0, even_columns=True, even_rows=False, align=False)
flow.prop(self, "show_time_place")
- flow.prop(self, "show_object_collection")
flow.prop(self, "show_dms")
flow.prop(self, "show_north")
flow.prop(self, "show_refraction")
diff --git a/system_blend_info.py b/system_blend_info.py
index 8c181dd4..b2e7b926 100644
--- a/system_blend_info.py
+++ b/system_blend_info.py
@@ -28,8 +28,8 @@ bl_info = {
"location": "Properties > Scene > Blend Info Panel",
"description": "Show information about the .blend",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "system/blend_info.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "system/blend_info.html",
"category": "System",
}
diff --git a/system_demo_mode/__init__.py b/system_demo_mode/__init__.py
index ce85a862..f7cc7d7c 100644
--- a/system_demo_mode/__init__.py
+++ b/system_demo_mode/__init__.py
@@ -25,8 +25,8 @@ bl_info = {
"location": "File > Demo Menu",
"description": "Demo mode lets you select multiple blend files and loop over them.",
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "system/demo_mode.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "system/demo_mode.html",
"support": 'OFFICIAL',
"category": "System",
}
diff --git a/system_property_chart.py b/system_property_chart.py
index c7065608..901d06ec 100644
--- a/system_property_chart.py
+++ b/system_property_chart.py
@@ -27,8 +27,8 @@ bl_info = {
"description": ("Edit arbitrary selected properties for "
"objects/sequence strips of the same type"),
"warning": "",
- "wiki_url": "https://docs.blender.org/manual/en/dev/addons/"
- "system/property_chart.html",
+ "doc_url": "https://docs.blender.org/manual/en/dev/addons/"
+ "system/property_chart.html",
"category": "System",
}
diff --git a/ui_translate/__init__.py b/ui_translate/__init__.py
index 51686fd4..72f63a92 100644
--- a/ui_translate/__init__.py
+++ b/ui_translate/__init__.py
@@ -27,9 +27,10 @@ bl_info = {
"description": "Allows managing UI translations directly from Blender "
"(update main .po files, update scripts' translations, etc.)",
"warning": "Still in development, not all features are fully implemented yet!",
- "wiki_url": "http://wiki.blender.org/index.php/Dev:Doc/How_to/Translate_Blender",
+ "doc_url": "http://wiki.blender.org/index.php/Dev:Doc/How_to/Translate_Blender",
"support": 'OFFICIAL',
- "category": "System"}
+ "category": "System",
+}
if "bpy" in locals():