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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoão Araújo <jaraujo98@gmail.com>2017-07-26 13:25:24 +0300
committerJoão Araújo <jaraujo98@gmail.com>2017-07-26 13:25:24 +0300
commit59908f5eb73670c97c5bb817290a0dac99089900 (patch)
tree709de097c1fac2ff7b172a8b50dc8a91d7b74860 /source/blender
parent595f2ca2e06e07acaccc473982bde7a5ed644b50 (diff)
parentedc6bec9d60204cb81d2e7533402630b076d0d32 (diff)
Merge remote-tracking branch 'origin/master' into gsoc2016-improved_extrusiongsoc2016-improved_extrusion
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/alembic/ABC_alembic.h55
-rw-r--r--source/blender/alembic/intern/abc_archive.cc41
-rw-r--r--source/blender/alembic/intern/abc_archive.h9
-rw-r--r--source/blender/alembic/intern/abc_camera.cc20
-rw-r--r--source/blender/alembic/intern/abc_camera.h7
-rw-r--r--source/blender/alembic/intern/abc_curves.cc78
-rw-r--r--source/blender/alembic/intern/abc_curves.h14
-rw-r--r--source/blender/alembic/intern/abc_customdata.cc173
-rw-r--r--source/blender/alembic/intern/abc_exporter.cc262
-rw-r--r--source/blender/alembic/intern/abc_exporter.h18
-rw-r--r--source/blender/alembic/intern/abc_hair.cc45
-rw-r--r--source/blender/alembic/intern/abc_hair.h2
-rw-r--r--source/blender/alembic/intern/abc_mesh.cc101
-rw-r--r--source/blender/alembic/intern/abc_mesh.h22
-rw-r--r--source/blender/alembic/intern/abc_nurbs.cc3
-rw-r--r--source/blender/alembic/intern/abc_nurbs.h2
-rw-r--r--source/blender/alembic/intern/abc_object.cc65
-rw-r--r--source/blender/alembic/intern/abc_object.h26
-rw-r--r--source/blender/alembic/intern/abc_points.cc34
-rw-r--r--source/blender/alembic/intern/abc_points.h13
-rw-r--r--source/blender/alembic/intern/abc_transform.cc37
-rw-r--r--source/blender/alembic/intern/abc_transform.h9
-rw-r--r--source/blender/alembic/intern/abc_util.cc23
-rw-r--r--source/blender/alembic/intern/abc_util.h10
-rw-r--r--source/blender/alembic/intern/alembic_capi.cc180
-rw-r--r--source/blender/blenfont/BLF_api.h2
-rw-r--r--source/blender/blenfont/intern/blf.c7
-rw-r--r--source/blender/blenfont/intern/blf_glyph.c1
-rw-r--r--source/blender/blenkernel/BKE_DerivedMesh.h6
-rw-r--r--source/blender/blenkernel/BKE_action.h4
-rw-r--r--source/blender/blenkernel/BKE_animsys.h6
-rw-r--r--source/blender/blenkernel/BKE_armature.h3
-rw-r--r--source/blender/blenkernel/BKE_blender.h1
-rw-r--r--source/blender/blenkernel/BKE_blender_version.h2
-rw-r--r--source/blender/blenkernel/BKE_boids.h2
-rw-r--r--source/blender/blenkernel/BKE_brush.h2
-rw-r--r--source/blender/blenkernel/BKE_cachefile.h2
-rw-r--r--source/blender/blenkernel/BKE_camera.h2
-rw-r--r--source/blender/blenkernel/BKE_colortools.h4
-rw-r--r--source/blender/blenkernel/BKE_curve.h7
-rw-r--r--source/blender/blenkernel/BKE_deform.h4
-rw-r--r--source/blender/blenkernel/BKE_fcurve.h14
-rw-r--r--source/blender/blenkernel/BKE_font.h3
-rw-r--r--source/blender/blenkernel/BKE_global.h5
-rw-r--r--source/blender/blenkernel/BKE_gpencil.h2
-rw-r--r--source/blender/blenkernel/BKE_group.h2
-rw-r--r--source/blender/blenkernel/BKE_icons.h6
-rw-r--r--source/blender/blenkernel/BKE_idprop.h13
-rw-r--r--source/blender/blenkernel/BKE_image.h2
-rw-r--r--source/blender/blenkernel/BKE_key.h2
-rw-r--r--source/blender/blenkernel/BKE_lamp.h2
-rw-r--r--source/blender/blenkernel/BKE_lattice.h2
-rw-r--r--source/blender/blenkernel/BKE_library.h12
-rw-r--r--source/blender/blenkernel/BKE_library_query.h9
-rw-r--r--source/blender/blenkernel/BKE_library_remap.h5
-rw-r--r--source/blender/blenkernel/BKE_linestyle.h10
-rw-r--r--source/blender/blenkernel/BKE_mask.h8
-rw-r--r--source/blender/blenkernel/BKE_material.h2
-rw-r--r--source/blender/blenkernel/BKE_mball.h2
-rw-r--r--source/blender/blenkernel/BKE_mesh.h5
-rw-r--r--source/blender/blenkernel/BKE_movieclip.h2
-rw-r--r--source/blender/blenkernel/BKE_node.h8
-rw-r--r--source/blender/blenkernel/BKE_object.h10
-rw-r--r--source/blender/blenkernel/BKE_paint.h4
-rw-r--r--source/blender/blenkernel/BKE_particle.h9
-rw-r--r--source/blender/blenkernel/BKE_property.h4
-rw-r--r--source/blender/blenkernel/BKE_rigidbody.h4
-rw-r--r--source/blender/blenkernel/BKE_sca.h8
-rw-r--r--source/blender/blenkernel/BKE_speaker.h2
-rw-r--r--source/blender/blenkernel/BKE_text.h2
-rw-r--r--source/blender/blenkernel/BKE_texture.h10
-rw-r--r--source/blender/blenkernel/BKE_tracking.h2
-rw-r--r--source/blender/blenkernel/BKE_world.h2
-rw-r--r--source/blender/blenkernel/intern/DerivedMesh.c55
-rw-r--r--source/blender/blenkernel/intern/action.c4
-rw-r--r--source/blender/blenkernel/intern/anim_sys.c80
-rw-r--r--source/blender/blenkernel/intern/armature.c11
-rw-r--r--source/blender/blenkernel/intern/armature_update.c6
-rw-r--r--source/blender/blenkernel/intern/blender.c13
-rw-r--r--source/blender/blenkernel/intern/blendfile.c4
-rw-r--r--source/blender/blenkernel/intern/boids.c2
-rw-r--r--source/blender/blenkernel/intern/bpath.c2
-rw-r--r--source/blender/blenkernel/intern/brush.c4
-rw-r--r--source/blender/blenkernel/intern/bvhutils.c6
-rw-r--r--source/blender/blenkernel/intern/cachefile.c9
-rw-r--r--source/blender/blenkernel/intern/camera.c2
-rw-r--r--source/blender/blenkernel/intern/cdderivedmesh.c256
-rw-r--r--source/blender/blenkernel/intern/colortools.c4
-rw-r--r--source/blender/blenkernel/intern/constraint.c12
-rw-r--r--source/blender/blenkernel/intern/curve.c42
-rw-r--r--source/blender/blenkernel/intern/customdata.c16
-rw-r--r--source/blender/blenkernel/intern/deform.c4
-rw-r--r--source/blender/blenkernel/intern/depsgraph.c2
-rw-r--r--source/blender/blenkernel/intern/displist.c11
-rw-r--r--source/blender/blenkernel/intern/dynamicpaint.c4
-rw-r--r--source/blender/blenkernel/intern/editderivedmesh.c58
-rw-r--r--source/blender/blenkernel/intern/effect.c26
-rw-r--r--source/blender/blenkernel/intern/fcurve.c6
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c14
-rw-r--r--source/blender/blenkernel/intern/font.c10
-rw-r--r--source/blender/blenkernel/intern/gpencil.c2
-rw-r--r--source/blender/blenkernel/intern/group.c4
-rw-r--r--source/blender/blenkernel/intern/icons.c6
-rw-r--r--source/blender/blenkernel/intern/idprop.c117
-rw-r--r--source/blender/blenkernel/intern/image.c48
-rw-r--r--source/blender/blenkernel/intern/image_gen.c2
-rw-r--r--source/blender/blenkernel/intern/key.c2
-rw-r--r--source/blender/blenkernel/intern/lamp.c2
-rw-r--r--source/blender/blenkernel/intern/lattice.c2
-rw-r--r--source/blender/blenkernel/intern/library.c269
-rw-r--r--source/blender/blenkernel/intern/library_query.c153
-rw-r--r--source/blender/blenkernel/intern/library_remap.c93
-rw-r--r--source/blender/blenkernel/intern/linestyle.c10
-rw-r--r--source/blender/blenkernel/intern/mask.c12
-rw-r--r--source/blender/blenkernel/intern/material.c2
-rw-r--r--source/blender/blenkernel/intern/mball.c2
-rw-r--r--source/blender/blenkernel/intern/mball_tessellate.c11
-rw-r--r--source/blender/blenkernel/intern/mesh.c25
-rw-r--r--source/blender/blenkernel/intern/mesh_evaluate.c83
-rw-r--r--source/blender/blenkernel/intern/mesh_mapping.c2
-rw-r--r--source/blender/blenkernel/intern/mesh_validate.c4
-rw-r--r--source/blender/blenkernel/intern/movieclip.c2
-rw-r--r--source/blender/blenkernel/intern/node.c38
-rw-r--r--source/blender/blenkernel/intern/object.c23
-rw-r--r--source/blender/blenkernel/intern/object_dupli.c36
-rw-r--r--source/blender/blenkernel/intern/object_update.c12
-rw-r--r--source/blender/blenkernel/intern/ocean.c2
-rw-r--r--source/blender/blenkernel/intern/packedFile.c4
-rw-r--r--source/blender/blenkernel/intern/paint.c4
-rw-r--r--source/blender/blenkernel/intern/particle.c69
-rw-r--r--source/blender/blenkernel/intern/particle_child.c8
-rw-r--r--source/blender/blenkernel/intern/particle_distribute.c36
-rw-r--r--source/blender/blenkernel/intern/particle_system.c13
-rw-r--r--source/blender/blenkernel/intern/pbvh.c68
-rw-r--r--source/blender/blenkernel/intern/pbvh_bmesh.c2
-rw-r--r--source/blender/blenkernel/intern/pointcache.c4
-rw-r--r--source/blender/blenkernel/intern/property.c4
-rw-r--r--source/blender/blenkernel/intern/rigidbody.c66
-rw-r--r--source/blender/blenkernel/intern/sca.c8
-rw-r--r--source/blender/blenkernel/intern/scene.c34
-rw-r--r--source/blender/blenkernel/intern/seqeffects.c2
-rw-r--r--source/blender/blenkernel/intern/seqmodifier.c15
-rw-r--r--source/blender/blenkernel/intern/sequencer.c12
-rw-r--r--source/blender/blenkernel/intern/softbody.c12
-rw-r--r--source/blender/blenkernel/intern/speaker.c2
-rw-r--r--source/blender/blenkernel/intern/text.c2
-rw-r--r--source/blender/blenkernel/intern/texture.c40
-rw-r--r--source/blender/blenkernel/intern/tracking.c65
-rw-r--r--source/blender/blenkernel/intern/tracking_auto.c17
-rw-r--r--source/blender/blenkernel/intern/tracking_stabilize.c2
-rw-r--r--source/blender/blenkernel/intern/tracking_util.c62
-rw-r--r--source/blender/blenkernel/intern/world.c2
-rw-r--r--source/blender/blenkernel/intern/writeframeserver.c4
-rw-r--r--source/blender/blenkernel/tracking_private.h11
-rw-r--r--source/blender/blenlib/BLI_alloca.h4
-rw-r--r--source/blender/blenlib/BLI_array.h4
-rw-r--r--source/blender/blenlib/BLI_compiler_attrs.h8
-rw-r--r--source/blender/blenlib/BLI_compiler_compat.h5
-rw-r--r--source/blender/blenlib/BLI_dynstr.h6
-rw-r--r--source/blender/blenlib/BLI_fileops.h4
-rw-r--r--source/blender/blenlib/BLI_fileops_types.h6
-rw-r--r--source/blender/blenlib/BLI_ghash.h21
-rw-r--r--source/blender/blenlib/BLI_hash.h66
-rw-r--r--source/blender/blenlib/BLI_kdopbvh.h4
-rw-r--r--source/blender/blenlib/BLI_listbase.h5
-rw-r--r--source/blender/blenlib/BLI_math_rotation.h8
-rw-r--r--source/blender/blenlib/BLI_math_vector.h4
-rw-r--r--source/blender/blenlib/BLI_path_util.h2
-rw-r--r--source/blender/blenlib/BLI_rect.h1
-rw-r--r--source/blender/blenlib/BLI_stack.h8
-rw-r--r--source/blender/blenlib/BLI_strict_flags.h2
-rw-r--r--source/blender/blenlib/BLI_sys_types.h4
-rw-r--r--source/blender/blenlib/BLI_task.h7
-rw-r--r--source/blender/blenlib/BLI_winstuff.h29
-rw-r--r--source/blender/blenlib/CMakeLists.txt1
-rw-r--r--source/blender/blenlib/intern/BLI_dynstr.c70
-rw-r--r--source/blender/blenlib/intern/BLI_ghash.c17
-rw-r--r--source/blender/blenlib/intern/BLI_kdopbvh.c154
-rw-r--r--source/blender/blenlib/intern/array_store.c4
-rw-r--r--source/blender/blenlib/intern/fileops.c5
-rw-r--r--source/blender/blenlib/intern/hash_mm2a.c6
-rw-r--r--source/blender/blenlib/intern/listbase.c2
-rw-r--r--source/blender/blenlib/intern/math_color_blend_inline.c2
-rw-r--r--source/blender/blenlib/intern/math_geom.c6
-rw-r--r--source/blender/blenlib/intern/math_matrix.c22
-rw-r--r--source/blender/blenlib/intern/math_rotation.c55
-rw-r--r--source/blender/blenlib/intern/math_vector.c85
-rw-r--r--source/blender/blenlib/intern/noise.c10
-rw-r--r--source/blender/blenlib/intern/path_util.c20
-rw-r--r--source/blender/blenlib/intern/polyfill2d.c96
-rw-r--r--source/blender/blenlib/intern/rct.c8
-rw-r--r--source/blender/blenlib/intern/storage.c32
-rw-r--r--source/blender/blenlib/intern/string.c4
-rw-r--r--source/blender/blenlib/intern/string_utf8.c12
-rw-r--r--source/blender/blenlib/intern/task.c173
-rw-r--r--source/blender/blenlib/intern/threads.c5
-rw-r--r--source/blender/blenlib/intern/winstuff.c2
-rw-r--r--source/blender/blenloader/intern/readfile.c254
-rw-r--r--source/blender/blenloader/intern/versioning_260.c3
-rw-r--r--source/blender/blenloader/intern/versioning_270.c79
-rw-r--r--source/blender/blenloader/intern/versioning_defaults.c4
-rw-r--r--source/blender/blenloader/intern/versioning_legacy.c3
-rw-r--r--source/blender/blenloader/intern/writefile.c28
-rw-r--r--source/blender/blentranslation/CMakeLists.txt2
-rw-r--r--source/blender/blentranslation/msgfmt/CMakeLists.txt50
-rw-r--r--source/blender/blentranslation/msgfmt/msgfmt.c464
-rw-r--r--source/blender/bmesh/bmesh_class.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_callback_generic.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_construct.c4
-rw-r--r--source/blender/bmesh/intern/bmesh_edgeloop.c2
-rw-r--r--source/blender/bmesh/intern/bmesh_iterators.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_log.c68
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.c14
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh.h8
-rw-r--r--source/blender/bmesh/intern/bmesh_mesh_conv.h8
-rw-r--r--source/blender/bmesh/intern/bmesh_opdefines.c5
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.c18
-rw-r--r--source/blender/bmesh/intern/bmesh_operators.h15
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.c14
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon_edgenet.c101
-rw-r--r--source/blender/bmesh/intern/bmesh_polygon_edgenet.h4
-rw-r--r--source/blender/bmesh/intern/bmesh_private.h2
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.c72
-rw-r--r--source/blender/bmesh/intern/bmesh_queries.h4
-rw-r--r--source/blender/bmesh/operators/bmo_bevel.c2
-rw-r--r--source/blender/bmesh/operators/bmo_connect.c2
-rw-r--r--source/blender/bmesh/operators/bmo_connect_nonplanar.c4
-rw-r--r--source/blender/bmesh/operators/bmo_connect_pair.c8
-rw-r--r--source/blender/bmesh/operators/bmo_create.c18
-rw-r--r--source/blender/bmesh/operators/bmo_dissolve.c2
-rw-r--r--source/blender/bmesh/operators/bmo_dupe.c2
-rw-r--r--source/blender/bmesh/operators/bmo_fill_attribute.c4
-rw-r--r--source/blender/bmesh/operators/bmo_fill_grid.c20
-rw-r--r--source/blender/bmesh/operators/bmo_fill_holes.c2
-rw-r--r--source/blender/bmesh/operators/bmo_inset.c2
-rw-r--r--source/blender/bmesh/operators/bmo_join_triangles.c12
-rw-r--r--source/blender/bmesh/operators/bmo_primitive.c86
-rw-r--r--source/blender/bmesh/operators/bmo_removedoubles.c21
-rw-r--r--source/blender/bmesh/operators/bmo_smooth_laplacian.c6
-rw-r--r--source/blender/bmesh/operators/bmo_subdivide_edgering.c26
-rw-r--r--source/blender/bmesh/operators/bmo_triangulate.c10
-rw-r--r--source/blender/bmesh/tools/bmesh_beautify.c4
-rw-r--r--source/blender/bmesh/tools/bmesh_bevel.c136
-rw-r--r--source/blender/bmesh/tools/bmesh_bisect_plane.c16
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_collapse.c8
-rw-r--r--source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c28
-rw-r--r--source/blender/bmesh/tools/bmesh_edgenet.c40
-rw-r--r--source/blender/bmesh/tools/bmesh_edgesplit.c2
-rw-r--r--source/blender/bmesh/tools/bmesh_intersect.c60
-rw-r--r--source/blender/bmesh/tools/bmesh_path.h4
-rw-r--r--source/blender/bmesh/tools/bmesh_region_match.c98
-rw-r--r--source/blender/bmesh/tools/bmesh_region_match.h2
-rw-r--r--source/blender/bmesh/tools/bmesh_separate.c8
-rw-r--r--source/blender/collada/AnimationExporter.cpp2
-rw-r--r--source/blender/collada/ArmatureExporter.cpp5
-rw-r--r--source/blender/collada/ControllerExporter.cpp5
-rw-r--r--source/blender/collada/DocumentExporter.cpp8
-rw-r--r--source/blender/collada/DocumentImporter.cpp8
-rw-r--r--source/blender/collada/EffectExporter.cpp134
-rw-r--r--source/blender/collada/EffectExporter.h1
-rw-r--r--source/blender/collada/ErrorHandler.cpp9
-rw-r--r--source/blender/collada/ExportSettings.h4
-rw-r--r--source/blender/collada/GeometryExporter.cpp303
-rw-r--r--source/blender/collada/GeometryExporter.h34
-rw-r--r--source/blender/collada/ImageExporter.cpp28
-rw-r--r--source/blender/collada/InstanceWriter.cpp63
-rw-r--r--source/blender/collada/InstanceWriter.h3
-rw-r--r--source/blender/collada/MaterialExporter.cpp35
-rw-r--r--source/blender/collada/MeshImporter.cpp7
-rw-r--r--source/blender/collada/SceneExporter.cpp5
-rw-r--r--source/blender/collada/SkinInfo.cpp2
-rw-r--r--source/blender/collada/collada.cpp6
-rw-r--r--source/blender/collada/collada.h14
-rw-r--r--source/blender/collada/collada_internal.cpp8
-rw-r--r--source/blender/collada/collada_internal.h1
-rw-r--r--source/blender/collada/collada_utils.cpp158
-rw-r--r--source/blender/collada/collada_utils.h10
-rw-r--r--source/blender/compositor/CMakeLists.txt4
-rw-r--r--source/blender/compositor/COM_compositor.h13
-rw-r--r--source/blender/compositor/intern/COM_WorkScheduler.cpp105
-rw-r--r--source/blender/compositor/nodes/COM_BrightnessNode.cpp2
-rw-r--r--source/blender/compositor/nodes/COM_ImageNode.cpp45
-rw-r--r--source/blender/compositor/nodes/COM_RenderLayersNode.cpp87
-rw-r--r--source/blender/compositor/nodes/COM_RenderLayersNode.h8
-rw-r--r--source/blender/compositor/operations/COM_BrightnessOperation.cpp14
-rw-r--r--source/blender/compositor/operations/COM_BrightnessOperation.h3
-rw-r--r--source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp4
-rw-r--r--source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_PlaneTrackOperation.cpp2
-rw-r--r--source/blender/compositor/operations/COM_RenderLayersProg.cpp186
-rw-r--r--source/blender/compositor/operations/COM_RenderLayersProg.h122
-rw-r--r--source/blender/compositor/operations/COM_TextureOperation.cpp29
-rw-r--r--source/blender/compositor/operations/COM_TextureOperation.h2
-rw-r--r--source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp6
-rw-r--r--source/blender/depsgraph/CMakeLists.txt2
-rw-r--r--source/blender/depsgraph/DEG_depsgraph_build.h3
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder.cc24
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_cycle.cc42
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.cc358
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes.h17
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc102
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc8
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc2
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.cc719
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations.h45
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc11
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc165
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc6
-rw-r--r--source/blender/depsgraph/intern/builder/deg_builder_transitive.cc4
-rw-r--r--source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc121
-rw-r--r--source/blender/depsgraph/intern/depsgraph.cc127
-rw-r--r--source/blender/depsgraph/intern/depsgraph.h23
-rw-r--r--source/blender/depsgraph/intern/depsgraph_build.cc72
-rw-r--r--source/blender/depsgraph/intern/depsgraph_debug.cc8
-rw-r--r--source/blender/depsgraph/intern/depsgraph_eval.cc8
-rw-r--r--source/blender/depsgraph/intern/depsgraph_query.cc2
-rw-r--r--source/blender/depsgraph/intern/depsgraph_tag.cc13
-rw-r--r--source/blender/depsgraph/intern/depsgraph_type_defines.cc13
-rw-r--r--source/blender/depsgraph/intern/depsgraph_types.h140
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval.cc12
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_debug.cc6
-rw-r--r--source/blender/depsgraph/intern/eval/deg_eval_flush.cc46
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node.cc108
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node.h53
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_component.cc59
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_component.h10
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_operation.cc20
-rw-r--r--source/blender/depsgraph/intern/nodes/deg_node_operation.h13
-rw-r--r--source/blender/depsgraph/util/deg_util_foreach.h25
-rw-r--r--source/blender/editors/animation/anim_draw.c1
-rw-r--r--source/blender/editors/animation/anim_markers.c5
-rw-r--r--source/blender/editors/animation/keyframes_edit.c2
-rw-r--r--source/blender/editors/armature/armature_naming.c4
-rw-r--r--source/blender/editors/armature/pose_lib.c2
-rw-r--r--source/blender/editors/armature/pose_slide.c2
-rw-r--r--source/blender/editors/armature/reeb.c2
-rw-r--r--source/blender/editors/curve/editcurve.c8
-rw-r--r--source/blender/editors/gpencil/drawgpencil.c18
-rw-r--r--source/blender/editors/gpencil/gpencil_brush.c29
-rw-r--r--source/blender/editors/gpencil/gpencil_edit.c106
-rw-r--r--source/blender/editors/gpencil/gpencil_intern.h94
-rw-r--r--source/blender/editors/gpencil/gpencil_interpolate.c3
-rw-r--r--source/blender/editors/gpencil/gpencil_paint.c37
-rw-r--r--source/blender/editors/gpencil/gpencil_select.c2
-rw-r--r--source/blender/editors/gpencil/gpencil_utils.c66
-rw-r--r--source/blender/editors/include/ED_clip.h2
-rw-r--r--source/blender/editors/include/ED_image.h2
-rw-r--r--source/blender/editors/include/ED_node.h2
-rw-r--r--source/blender/editors/include/ED_transform_snap_object_context.h2
-rw-r--r--source/blender/editors/include/ED_view3d.h7
-rw-r--r--source/blender/editors/include/UI_icons.h4
-rw-r--r--source/blender/editors/include/UI_interface.h3
-rw-r--r--source/blender/editors/interface/interface.c39
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c18
-rw-r--r--source/blender/editors/interface/interface_handlers.c68
-rw-r--r--source/blender/editors/interface/interface_intern.h4
-rw-r--r--source/blender/editors/interface/interface_layout.c7
-rw-r--r--source/blender/editors/interface/interface_regions.c4
-rw-r--r--source/blender/editors/interface/interface_utils.c13
-rw-r--r--source/blender/editors/io/io_alembic.c84
-rw-r--r--source/blender/editors/io/io_cache.c32
-rw-r--r--source/blender/editors/io/io_collada.c46
-rw-r--r--source/blender/editors/mask/mask_add.c13
-rw-r--r--source/blender/editors/mask/mask_draw.c7
-rw-r--r--source/blender/editors/mask/mask_ops.c4
-rw-r--r--source/blender/editors/mesh/editface.c67
-rw-r--r--source/blender/editors/mesh/editmesh_add.c2
-rw-r--r--source/blender/editors/mesh/editmesh_knife.c2
-rw-r--r--source/blender/editors/mesh/editmesh_select.c6
-rw-r--r--source/blender/editors/mesh/editmesh_tools.c6
-rw-r--r--source/blender/editors/mesh/meshtools.c38
-rw-r--r--source/blender/editors/object/object_add.c32
-rw-r--r--source/blender/editors/object/object_bake_api.c29
-rw-r--r--source/blender/editors/object/object_group.c3
-rw-r--r--source/blender/editors/object/object_modifier.c2
-rw-r--r--source/blender/editors/object/object_relations.c223
-rw-r--r--source/blender/editors/object/object_transform.c4
-rw-r--r--source/blender/editors/physics/dynamicpaint_ops.c36
-rw-r--r--source/blender/editors/physics/particle_edit.c2
-rw-r--r--source/blender/editors/physics/physics_fluid.c112
-rw-r--r--source/blender/editors/physics/physics_pointcache.c42
-rw-r--r--source/blender/editors/render/render_internal.c7
-rw-r--r--source/blender/editors/render/render_opengl.c23
-rw-r--r--source/blender/editors/render/render_preview.c2
-rw-r--r--source/blender/editors/render/render_shading.c4
-rw-r--r--source/blender/editors/render/render_update.c6
-rw-r--r--source/blender/editors/render/render_view.c19
-rw-r--r--source/blender/editors/screen/glutil.c8
-rw-r--r--source/blender/editors/screen/screen_edit.c15
-rw-r--r--source/blender/editors/screen/screen_ops.c52
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_2d.c6
-rw-r--r--source/blender/editors/sculpt_paint/paint_image_proj.c11
-rw-r--r--source/blender/editors/sculpt_paint/paint_utils.c2
-rw-r--r--source/blender/editors/sound/sound_ops.c2
-rw-r--r--source/blender/editors/space_buttons/buttons_texture.c2
-rw-r--r--source/blender/editors/space_clip/clip_editor.c12
-rw-r--r--source/blender/editors/space_clip/space_clip.c2
-rw-r--r--source/blender/editors/space_clip/tracking_ops.c3
-rw-r--r--source/blender/editors/space_clip/tracking_ops_plane.c3
-rw-r--r--source/blender/editors/space_file/filelist.c83
-rw-r--r--source/blender/editors/space_file/filelist.h3
-rw-r--r--source/blender/editors/space_file/fsmenu.c3
-rw-r--r--source/blender/editors/space_file/space_file.c5
-rw-r--r--source/blender/editors/space_image/image_buttons.c36
-rw-r--r--source/blender/editors/space_image/image_ops.c29
-rw-r--r--source/blender/editors/space_info/info_ops.c1
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c2
-rw-r--r--source/blender/editors/space_nla/nla_draw.c2
-rw-r--r--source/blender/editors/space_node/drawnode.c19
-rw-r--r--source/blender/editors/space_node/node_add.c6
-rw-r--r--source/blender/editors/space_node/node_draw.c28
-rw-r--r--source/blender/editors/space_node/node_edit.c16
-rw-r--r--source/blender/editors/space_node/node_group.c23
-rw-r--r--source/blender/editors/space_node/node_view.c14
-rw-r--r--source/blender/editors/space_node/space_node.c4
-rw-r--r--source/blender/editors/space_outliner/outliner_edit.c5
-rw-r--r--source/blender/editors/space_outliner/outliner_select.c10
-rw-r--r--source/blender/editors/space_outliner/outliner_tools.c16
-rw-r--r--source/blender/editors/space_outliner/outliner_tree.c9
-rw-r--r--source/blender/editors/space_sequencer/sequencer_edit.c11
-rw-r--r--source/blender/editors/space_sequencer/sequencer_select.c2
-rw-r--r--source/blender/editors/space_text/CMakeLists.txt2
-rw-r--r--source/blender/editors/space_text/space_text.c4
-rw-r--r--source/blender/editors/space_text/text_autocomplete.c6
-rw-r--r--source/blender/editors/space_text/text_format.h2
-rw-r--r--source/blender/editors/space_text/text_format_pov.c809
-rw-r--r--source/blender/editors/space_text/text_format_pov_ini.c488
-rw-r--r--source/blender/editors/space_view3d/drawarmature.c10
-rw-r--r--source/blender/editors/space_view3d/drawobject.c46
-rw-r--r--source/blender/editors/space_view3d/drawsimdebug.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_draw.c164
-rw-r--r--source/blender/editors/space_view3d/view3d_edit.c126
-rw-r--r--source/blender/editors/space_view3d/view3d_intern.h2
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c2
-rw-r--r--source/blender/editors/space_view3d/view3d_view.c14
-rw-r--r--source/blender/editors/space_view3d/view3d_walk.c12
-rw-r--r--source/blender/editors/transform/transform.c63
-rw-r--r--source/blender/editors/transform/transform_conversions.c170
-rw-r--r--source/blender/editors/transform/transform_generics.c2
-rw-r--r--source/blender/editors/transform/transform_input.c13
-rw-r--r--source/blender/editors/transform/transform_manipulator.c22
-rw-r--r--source/blender/editors/transform/transform_orientations.c46
-rw-r--r--source/blender/editors/transform/transform_snap_object.c1413
-rw-r--r--source/blender/editors/util/numinput.c4
-rw-r--r--source/blender/editors/util/undo.c8
-rw-r--r--source/blender/editors/uvedit/uvedit_draw.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_ops.c9
-rw-r--r--source/blender/editors/uvedit/uvedit_parametrizer.c2
-rw-r--r--source/blender/editors/uvedit/uvedit_smart_stitch.c1
-rw-r--r--source/blender/freestyle/intern/application/AppView.cpp6
-rw-r--r--source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp2
-rw-r--r--source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp12
-rw-r--r--source/blender/freestyle/intern/geometry/matrix_util.h6
-rw-r--r--source/blender/gpu/GPU_buffers.h45
-rw-r--r--source/blender/gpu/GPU_material.h5
-rw-r--r--source/blender/gpu/intern/gpu_basic_shader.c4
-rw-r--r--source/blender/gpu/intern/gpu_buffers.c104
-rw-r--r--source/blender/gpu/intern/gpu_codegen.c2
-rw-r--r--source/blender/gpu/intern/gpu_compositing.c4
-rw-r--r--source/blender/gpu/intern/gpu_debug.c5
-rw-r--r--source/blender/gpu/intern/gpu_draw.c36
-rw-r--r--source/blender/gpu/intern/gpu_framebuffer.c6
-rw-r--r--source/blender/gpu/intern/gpu_material.c29
-rw-r--r--source/blender/gpu/intern/gpu_select.c6
-rw-r--r--source/blender/gpu/intern/gpu_select_sample_query.c18
-rw-r--r--source/blender/gpu/intern/gpu_shader.c1
-rw-r--r--source/blender/gpu/intern/gpu_texture.c14
-rw-r--r--source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl2
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl205
-rw-r--r--source/blender/ikplugin/intern/iksolver_plugin.c50
-rw-r--r--source/blender/imbuf/IMB_colormanagement.h2
-rw-r--r--source/blender/imbuf/IMB_imbuf.h3
-rw-r--r--source/blender/imbuf/IMB_imbuf_types.h22
-rw-r--r--source/blender/imbuf/intern/IMB_anim.h7
-rw-r--r--source/blender/imbuf/intern/IMB_colormanagement_intern.h2
-rw-r--r--source/blender/imbuf/intern/allocimbuf.c2
-rw-r--r--source/blender/imbuf/intern/anim_movie.c13
-rw-r--r--source/blender/imbuf/intern/cineon/dpxlib.c2
-rw-r--r--source/blender/imbuf/intern/cineon/logImageCore.c15
-rw-r--r--source/blender/imbuf/intern/colormanagement.c68
-rw-r--r--source/blender/imbuf/intern/dds/dds_api.cpp4
-rw-r--r--source/blender/imbuf/intern/filter.c6
-rw-r--r--source/blender/imbuf/intern/metadata.c2
-rw-r--r--source/blender/imbuf/intern/oiio/openimageio_api.cpp4
-rw-r--r--source/blender/imbuf/intern/openexr/openexr_api.cpp18
-rw-r--r--source/blender/imbuf/intern/png.c3
-rw-r--r--source/blender/imbuf/intern/radiance_hdr.c3
-rw-r--r--source/blender/imbuf/intern/rectop.c49
-rw-r--r--source/blender/makesdna/DNA_ID.h2
-rw-r--r--source/blender/makesdna/DNA_cachefile_types.h4
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h4
-rw-r--r--source/blender/makesdna/DNA_node_types.h6
-rw-r--r--source/blender/makesdna/DNA_object_fluidsim.h1
-rw-r--r--source/blender/makesdna/DNA_object_types.h2
-rw-r--r--source/blender/makesdna/DNA_particle_types.h2
-rw-r--r--source/blender/makesdna/DNA_scene_types.h40
-rw-r--r--source/blender/makesdna/DNA_space_types.h2
-rw-r--r--source/blender/makesrna/RNA_access.h2
-rw-r--r--source/blender/makesrna/RNA_define.h1
-rw-r--r--source/blender/makesrna/RNA_types.h2
-rw-r--r--source/blender/makesrna/intern/CMakeLists.txt3
-rw-r--r--source/blender/makesrna/intern/makesrna.c2
-rw-r--r--source/blender/makesrna/intern/rna_ID.c8
-rw-r--r--source/blender/makesrna/intern/rna_access.c83
-rw-r--r--source/blender/makesrna/intern/rna_color.c5
-rw-r--r--source/blender/makesrna/intern/rna_define.c17
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c36
-rw-r--r--source/blender/makesrna/intern/rna_fluidsim.c8
-rw-r--r--source/blender/makesrna/intern/rna_image.c2
-rw-r--r--source/blender/makesrna/intern/rna_internal.h1
-rw-r--r--source/blender/makesrna/intern/rna_internal_types.h1
-rw-r--r--source/blender/makesrna/intern/rna_linestyle.c1
-rw-r--r--source/blender/makesrna/intern/rna_nla.c5
-rw-r--r--source/blender/makesrna/intern/rna_nodetree.c52
-rw-r--r--source/blender/makesrna/intern/rna_object.c13
-rw-r--r--source/blender/makesrna/intern/rna_object_api.c62
-rw-r--r--source/blender/makesrna/intern/rna_particle.c45
-rw-r--r--source/blender/makesrna/intern/rna_render.c104
-rw-r--r--source/blender/makesrna/intern/rna_scene.c47
-rw-r--r--source/blender/makesrna/intern/rna_scene_api.c29
-rw-r--r--source/blender/makesrna/intern/rna_sequencer.c73
-rw-r--r--source/blender/makesrna/intern/rna_space.c330
-rw-r--r--source/blender/makesrna/intern/rna_space_api.c2
-rw-r--r--source/blender/makesrna/intern/rna_ui.c1
-rw-r--r--source/blender/makesrna/intern/rna_ui_api.c3
-rw-r--r--source/blender/makesrna/intern/rna_userdef.c13
-rw-r--r--source/blender/makesrna/intern/rna_wm.c242
-rw-r--r--source/blender/modifiers/intern/MOD_array.c43
-rw-r--r--source/blender/modifiers/intern/MOD_curve.c5
-rw-r--r--source/blender/modifiers/intern/MOD_displace.c1
-rw-r--r--source/blender/modifiers/intern/MOD_dynamicpaint.c10
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim.c13
-rw-r--r--source/blender/modifiers/intern/MOD_fluidsim_util.c31
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_mdd.c5
-rw-r--r--source/blender/modifiers/intern/MOD_meshcache_pc2.c6
-rw-r--r--source/blender/modifiers/intern/MOD_meshdeform.c6
-rw-r--r--source/blender/modifiers/intern/MOD_ocean.c29
-rw-r--r--source/blender/modifiers/intern/MOD_surfacedeform.c23
-rw-r--r--source/blender/modifiers/intern/MOD_uvproject.c6
-rw-r--r--source/blender/modifiers/intern/MOD_warp.c4
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgedit.c3
-rw-r--r--source/blender/modifiers/intern/MOD_weightvgmix.c3
-rw-r--r--source/blender/nodes/CMakeLists.txt5
-rw-r--r--source/blender/nodes/NOD_composite.h4
-rw-r--r--source/blender/nodes/NOD_shader.h1
-rw-r--r--source/blender/nodes/NOD_static_types.h3
-rw-r--r--source/blender/nodes/composite/node_composite_tree.c35
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_bilateralblur.c1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_brightness.c5
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_directionalblur.c1
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_image.c541
-rw-r--r--source/blender/nodes/composite/nodes/node_composite_switchview.c1
-rw-r--r--source/blender/nodes/intern/node_exec.c3
-rw-r--r--source/blender/nodes/shader/node_shader_util.c52
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c114
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_normal_map.c6
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_object_info.c12
-rw-r--r--source/blender/python/generic/bpy_internal_import.c13
-rw-r--r--source/blender/python/generic/idprop_py_api.c21
-rw-r--r--source/blender/python/generic/py_capi_utils.c9
-rw-r--r--source/blender/python/intern/CMakeLists.txt9
-rw-r--r--source/blender/python/intern/bpy_app.c19
-rw-r--r--source/blender/python/intern/bpy_app_handlers.c4
-rw-r--r--source/blender/python/intern/bpy_app_opensubdiv.c109
-rw-r--r--source/blender/python/intern/bpy_app_opensubdiv.h (renamed from source/blender/depsgraph/util/deg_util_hash.h)23
-rw-r--r--source/blender/python/intern/bpy_app_sdl.c2
-rw-r--r--source/blender/python/intern/bpy_interface.c16
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.c4
-rw-r--r--source/blender/python/intern/bpy_operator_wrap.h4
-rw-r--r--source/blender/python/intern/bpy_props.c136
-rw-r--r--source/blender/python/intern/bpy_props.h4
-rw-r--r--source/blender/python/intern/bpy_rna.c88
-rw-r--r--source/blender/python/intern/bpy_rna.h1
-rw-r--r--source/blender/python/mathutils/mathutils.c35
-rw-r--r--source/blender/python/mathutils/mathutils_Color.c2
-rw-r--r--source/blender/python/mathutils/mathutils_Euler.c4
-rw-r--r--source/blender/python/mathutils/mathutils_Matrix.c10
-rw-r--r--source/blender/python/mathutils/mathutils_Quaternion.c2
-rw-r--r--source/blender/render/CMakeLists.txt5
-rw-r--r--source/blender/render/extern/include/RE_engine.h7
-rw-r--r--source/blender/render/extern/include/RE_pipeline.h25
-rw-r--r--source/blender/render/extern/include/RE_shader_ext.h4
-rw-r--r--source/blender/render/intern/include/render_result.h7
-rw-r--r--source/blender/render/intern/include/render_types.h4
-rw-r--r--source/blender/render/intern/include/rendercore.h8
-rw-r--r--source/blender/render/intern/raytrace/rayobject_rtbuild.cpp12
-rw-r--r--source/blender/render/intern/raytrace/rayobject_rtbuild.h5
-rw-r--r--source/blender/render/intern/source/bake_api.c4
-rw-r--r--source/blender/render/intern/source/convertblender.c20
-rw-r--r--source/blender/render/intern/source/envmap.c16
-rw-r--r--source/blender/render/intern/source/external_engine.c41
-rw-r--r--source/blender/render/intern/source/pipeline.c79
-rw-r--r--source/blender/render/intern/source/render_result.c671
-rw-r--r--source/blender/render/intern/source/render_texture.c2
-rw-r--r--source/blender/render/intern/source/rendercore.c410
-rw-r--r--source/blender/render/intern/source/renderdatabase.c9
-rw-r--r--source/blender/render/intern/source/shadeoutput.c10
-rw-r--r--source/blender/render/intern/source/sunsky.c2
-rw-r--r--source/blender/render/intern/source/volumetric.c6
-rw-r--r--source/blender/render/intern/source/zbuf.c229
-rw-r--r--source/blender/windowmanager/WM_api.h6
-rw-r--r--source/blender/windowmanager/intern/wm.c5
-rw-r--r--source/blender/windowmanager/intern/wm_draw.c17
-rw-r--r--source/blender/windowmanager/intern/wm_event_system.c12
-rw-r--r--source/blender/windowmanager/intern/wm_files.c17
-rw-r--r--source/blender/windowmanager/intern/wm_files_link.c3
-rw-r--r--source/blender/windowmanager/intern/wm_init_exit.c2
-rw-r--r--source/blender/windowmanager/intern/wm_operators.c8
-rw-r--r--source/blender/windowmanager/intern/wm_playanim.c5
-rw-r--r--source/blender/windowmanager/intern/wm_window.c39
612 files changed, 12856 insertions, 8072 deletions
diff --git a/source/blender/alembic/ABC_alembic.h b/source/blender/alembic/ABC_alembic.h
index e92d5f2d9f7..70250310213 100644
--- a/source/blender/alembic/ABC_alembic.h
+++ b/source/blender/alembic/ABC_alembic.h
@@ -47,47 +47,63 @@ struct AlembicExportParams {
double frame_start;
double frame_end;
- double frame_step_xform;
- double frame_step_shape;
+ unsigned int frame_samples_xform;
+ unsigned int frame_samples_shape;
double shutter_open;
double shutter_close;
- /* bools */
- unsigned int selected_only : 1;
- unsigned int uvs : 1;
- unsigned int normals : 1;
- unsigned int vcolors : 1;
- unsigned int apply_subdiv : 1;
- unsigned int flatten_hierarchy : 1;
- unsigned int visible_layers_only : 1;
- unsigned int renderable_only : 1;
- unsigned int face_sets : 1;
- unsigned int use_subdiv_schema : 1;
- unsigned int packuv : 1;
- unsigned int triangulate : 1;
+ bool selected_only;
+ bool uvs;
+ bool normals;
+ bool vcolors;
+ bool apply_subdiv;
+ bool flatten_hierarchy;
+ bool visible_layers_only;
+ bool renderable_only;
+ bool face_sets;
+ bool use_subdiv_schema;
+ bool packuv;
+ bool triangulate;
+ bool export_hair;
+ bool export_particles;
unsigned int compression_type : 1;
+ /* See MOD_TRIANGULATE_NGON_xxx and MOD_TRIANGULATE_QUAD_xxx
+ * in DNA_modifier_types.h */
int quad_method;
int ngon_method;
+
float global_scale;
};
-void ABC_export(
+/* The ABC_export and ABC_import functions both take a as_background_job
+ * parameter, and return a boolean.
+ *
+ * When as_background_job=true, returns false immediately after scheduling
+ * a background job.
+ *
+ * When as_background_job=false, performs the export synchronously, and returns
+ * true when the export was ok, and false if there were any errors.
+ */
+
+bool ABC_export(
struct Scene *scene,
struct bContext *C,
const char *filepath,
- const struct AlembicExportParams *params);
+ const struct AlembicExportParams *params,
+ bool as_background_job);
-void ABC_import(struct bContext *C,
+bool ABC_import(struct bContext *C,
const char *filepath,
float scale,
bool is_sequence,
bool set_frame_range,
int sequence_len,
int offset,
- bool validate_meshes);
+ bool validate_meshes,
+ bool as_background_job);
AbcArchiveHandle *ABC_create_handle(const char *filename, struct ListBase *object_paths);
@@ -105,6 +121,7 @@ struct DerivedMesh *ABC_read_mesh(struct CacheReader *reader,
const char **err_str,
int flags);
+void CacheReader_incref(struct CacheReader *reader);
void CacheReader_free(struct CacheReader *reader);
struct CacheReader *CacheReader_open_alembic_object(struct AbcArchiveHandle *handle,
diff --git a/source/blender/alembic/intern/abc_archive.cc b/source/blender/alembic/intern/abc_archive.cc
index 5f8fc1a3739..bd16196cb78 100644
--- a/source/blender/alembic/intern/abc_archive.cc
+++ b/source/blender/alembic/intern/abc_archive.cc
@@ -23,11 +23,17 @@
*/
#include "abc_archive.h"
+extern "C"
+{
+ #include "BKE_blender_version.h"
+}
#ifdef WIN32
# include "utfconv.h"
#endif
+#include <fstream>
+
using Alembic::Abc::Exception;
using Alembic::Abc::ErrorHandler;
using Alembic::Abc::IArchive;
@@ -38,8 +44,9 @@ static IArchive open_archive(const std::string &filename,
const std::vector<std::istream *> &input_streams,
bool &is_hdf5)
{
+ is_hdf5 = false;
+
try {
- is_hdf5 = false;
Alembic::AbcCoreOgawa::ReadArchive archive_reader(input_streams);
return IArchive(archive_reader(filename),
@@ -63,6 +70,27 @@ static IArchive open_archive(const std::string &filename,
return IArchive();
}
#else
+ /* Inspect the file to see whether it's really a HDF5 file. */
+ char header[4]; /* char(0x89) + "HDF" */
+ std::ifstream the_file(filename.c_str(), std::ios::in | std::ios::binary);
+ if (!the_file) {
+ std::cerr << "Unable to open " << filename << std::endl;
+ }
+ else if (!the_file.read(header, sizeof(header))) {
+ std::cerr << "Unable to read from " << filename << std::endl;
+ }
+ else if (strncmp(header + 1, "HDF", 3)) {
+ std::cerr << filename << " has an unknown file format, unable to read." << std::endl;
+ }
+ else {
+ is_hdf5 = true;
+ std::cerr << filename << " is in the obsolete HDF5 format, unable to read." << std::endl;
+ }
+
+ if (the_file.is_open()) {
+ the_file.close();
+ }
+
return IArchive();
#endif
}
@@ -83,16 +111,20 @@ ArchiveReader::ArchiveReader(const char *filename)
m_streams.push_back(&m_infile);
- bool is_hdf5;
- m_archive = open_archive(filename, m_streams, is_hdf5);
+ m_archive = open_archive(filename, m_streams, m_is_hdf5);
/* We can't open an HDF5 file from a stream, so close it. */
- if (is_hdf5) {
+ if (m_is_hdf5) {
m_infile.close();
m_streams.clear();
}
}
+bool ArchiveReader::is_hdf5() const
+{
+ return m_is_hdf5;
+}
+
bool ArchiveReader::valid() const
{
return m_archive.valid();
@@ -115,6 +147,7 @@ static OArchive create_archive(std::ostream *ostream,
{
md.set(Alembic::Abc::kApplicationNameKey, "Blender");
md.set(Alembic::Abc::kUserDescriptionKey, scene_name);
+ md.set("blender_version", versionstr);
time_t raw_time;
time(&raw_time);
diff --git a/source/blender/alembic/intern/abc_archive.h b/source/blender/alembic/intern/abc_archive.h
index d412574b736..84309fbc9df 100644
--- a/source/blender/alembic/intern/abc_archive.h
+++ b/source/blender/alembic/intern/abc_archive.h
@@ -44,12 +44,21 @@ class ArchiveReader {
Alembic::Abc::IArchive m_archive;
std::ifstream m_infile;
std::vector<std::istream *> m_streams;
+ bool m_is_hdf5;
public:
explicit ArchiveReader(const char *filename);
bool valid() const;
+ /**
+ * Returns true when either Blender is compiled with HDF5 support and
+ * the archive was succesfully opened (valid() will also return true),
+ * or when Blender was built without HDF5 support but a HDF5 file was
+ * detected (valid() will return false).
+ */
+ bool is_hdf5() const;
+
Alembic::Abc::IObject getTop();
};
diff --git a/source/blender/alembic/intern/abc_camera.cc b/source/blender/alembic/intern/abc_camera.cc
index 4f70b2a972c..16416205983 100644
--- a/source/blender/alembic/intern/abc_camera.cc
+++ b/source/blender/alembic/intern/abc_camera.cc
@@ -117,11 +117,27 @@ bool AbcCameraReader::valid() const
return m_schema.valid();
}
-void AbcCameraReader::readObjectData(Main *bmain, float time)
+bool AbcCameraReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const
+{
+ if (!Alembic::AbcGeom::ICamera::matches(alembic_header)) {
+ *err_str = "Object type mismatch, Alembic object path pointed to Camera when importing, but not any more.";
+ return false;
+ }
+
+ if (ob->type != OB_CAMERA) {
+ *err_str = "Object type mismatch, Alembic object path points to Camera.";
+ return false;
+ }
+
+ return true;
+}
+
+void AbcCameraReader::readObjectData(Main *bmain, const ISampleSelector &sample_sel)
{
Camera *bcam = static_cast<Camera *>(BKE_camera_add(bmain, m_data_name.c_str()));
- ISampleSelector sample_sel(time);
CameraSample cam_sample;
m_schema.get(cam_sample, sample_sel);
diff --git a/source/blender/alembic/intern/abc_camera.h b/source/blender/alembic/intern/abc_camera.h
index fafb4d3eb39..16c5cccd5ea 100644
--- a/source/blender/alembic/intern/abc_camera.h
+++ b/source/blender/alembic/intern/abc_camera.h
@@ -54,8 +54,11 @@ public:
AbcCameraReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
bool valid() const;
+ bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const;
- void readObjectData(Main *bmain, float time);
+ void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
};
-#endif /* __ABC_CAMERA_H__ */ \ No newline at end of file
+#endif /* __ABC_CAMERA_H__ */
diff --git a/source/blender/alembic/intern/abc_curves.cc b/source/blender/alembic/intern/abc_curves.cc
index 0542255d84b..f73fe957fea 100644
--- a/source/blender/alembic/intern/abc_curves.cc
+++ b/source/blender/alembic/intern/abc_curves.cc
@@ -49,19 +49,26 @@ using Alembic::Abc::Int32ArraySamplePtr;
using Alembic::Abc::FloatArraySamplePtr;
using Alembic::Abc::P3fArraySamplePtr;
using Alembic::Abc::UcharArraySamplePtr;
+using Alembic::Abc::PropertyHeader;
+using Alembic::AbcGeom::ICompoundProperty;
using Alembic::AbcGeom::ICurves;
using Alembic::AbcGeom::ICurvesSchema;
using Alembic::AbcGeom::IFloatGeomParam;
+using Alembic::AbcGeom::IInt16Property;
using Alembic::AbcGeom::ISampleSelector;
using Alembic::AbcGeom::kWrapExisting;
using Alembic::AbcGeom::CurvePeriodicity;
+using Alembic::AbcGeom::OCompoundProperty;
using Alembic::AbcGeom::OCurves;
using Alembic::AbcGeom::OCurvesSchema;
+using Alembic::AbcGeom::OInt16Property;
using Alembic::AbcGeom::ON3fGeomParam;
using Alembic::AbcGeom::OV2fGeomParam;
+#define ABC_CURVE_RESOLUTION_U_PROPNAME "blender:resolution"
+
/* ************************************************************************** */
AbcCurveWriter::AbcCurveWriter(Scene *scene,
@@ -73,6 +80,11 @@ AbcCurveWriter::AbcCurveWriter(Scene *scene,
{
OCurves curves(parent->alembicXform(), m_name, m_time_sampling);
m_schema = curves.getSchema();
+
+ Curve *cu = static_cast<Curve *>(m_object->data);
+ OCompoundProperty user_props = m_schema.getUserProperties();
+ OInt16Property user_prop_resolu(user_props, ABC_CURVE_RESOLUTION_U_PROPNAME);
+ user_prop_resolu.set(cu->resolu);
}
void AbcCurveWriter::do_write()
@@ -95,7 +107,7 @@ void AbcCurveWriter::do_write()
for (; nurbs; nurbs = nurbs->next) {
if (nurbs->bp) {
curve_basis = Alembic::AbcGeom::kNoBasis;
- curve_type = Alembic::AbcGeom::kLinear;
+ curve_type = Alembic::AbcGeom::kVariableOrder;
const int totpoint = nurbs->pntsu * nurbs->pntsv;
@@ -160,7 +172,7 @@ void AbcCurveWriter::do_write()
}
}
- orders.push_back(nurbs->orderu + 1);
+ orders.push_back(nurbs->orderu);
vert_counts.push_back(verts.size());
}
@@ -199,17 +211,44 @@ bool AbcCurveReader::valid() const
return m_curves_schema.valid();
}
-void AbcCurveReader::readObjectData(Main *bmain, float time)
+bool AbcCurveReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const
+{
+ if (!Alembic::AbcGeom::ICurves::matches(alembic_header)) {
+ *err_str = "Object type mismatch, Alembic object path pointed to Curves when importing, but not any more.";
+ return false;
+ }
+
+ if (ob->type != OB_CURVE) {
+ *err_str = "Object type mismatch, Alembic object path points to Curves.";
+ return false;
+ }
+
+ return true;
+}
+
+void AbcCurveReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel)
{
Curve *cu = BKE_curve_add(bmain, m_data_name.c_str(), OB_CURVE);
cu->flag |= CU_DEFORM_FILL | CU_3D;
cu->actvert = CU_ACT_NONE;
+ cu->resolu = 1;
+
+ ICompoundProperty user_props = m_curves_schema.getUserProperties();
+ if (user_props) {
+ const PropertyHeader *header = user_props.getPropertyHeader(ABC_CURVE_RESOLUTION_U_PROPNAME);
+ if (header != NULL && header->isScalar() && IInt16Property::matches(*header)) {
+ IInt16Property resolu(user_props, header->getName());
+ cu->resolu = resolu.getValue(sample_sel);
+ }
+ }
m_object = BKE_object_add_only_object(bmain, OB_CURVE, m_object_name.c_str());
m_object->data = cu;
- read_curve_sample(cu, m_curves_schema, time);
+ read_curve_sample(cu, m_curves_schema, sample_sel);
if (has_animations(m_curves_schema, m_settings)) {
addCacheModifier();
@@ -218,9 +257,8 @@ void AbcCurveReader::readObjectData(Main *bmain, float time)
/* ************************************************************************** */
-void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const float time)
+void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const ISampleSelector &sample_sel)
{
- const ISampleSelector sample_sel(time);
ICurvesSchema::Sample smp = schema.getValue(sample_sel);
const Int32ArraySamplePtr num_vertices = smp.getCurvesNumVertices();
const P3fArraySamplePtr positions = smp.getPositions();
@@ -250,13 +288,19 @@ void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const float time)
nu->pntsv = 1;
nu->flag |= CU_SMOOTH;
- nu->orderu = num_verts;
-
- if (smp.getType() == Alembic::AbcGeom::kCubic) {
- nu->orderu = 3;
- }
- else if (orders && orders->size() > i) {
- nu->orderu = static_cast<short>((*orders)[i] - 1);
+ switch (smp.getType()) {
+ case Alembic::AbcGeom::kCubic:
+ nu->orderu = 4;
+ break;
+ case Alembic::AbcGeom::kVariableOrder:
+ if (orders && orders->size() > i) {
+ nu->orderu = static_cast<short>((*orders)[i]);
+ break;
+ }
+ ATTR_FALLTHROUGH;
+ case Alembic::AbcGeom::kLinear:
+ default:
+ nu->orderu = 2;
}
if (periodicity == Alembic::AbcGeom::kNonPeriodic) {
@@ -361,9 +405,11 @@ void read_curve_sample(Curve *cu, const ICurvesSchema &schema, const float time)
* object directly and create a new DerivedMesh from that. Also we might need to
* create new or delete existing NURBS in the curve.
*/
-DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh * /*dm*/, const float time, int /*read_flag*/, const char ** /*err_str*/)
+DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh * /*dm*/,
+ const ISampleSelector &sample_sel,
+ int /*read_flag*/,
+ const char ** /*err_str*/)
{
- ISampleSelector sample_sel(time);
const ICurvesSchema::Sample sample = m_curves_schema.getValue(sample_sel);
const P3fArraySamplePtr &positions = sample.getPositions();
@@ -377,7 +423,7 @@ DerivedMesh *AbcCurveReader::read_derivedmesh(DerivedMesh * /*dm*/, const float
if (curve_count != num_vertices->size()) {
BKE_nurbList_free(&curve->nurb);
- read_curve_sample(curve, m_curves_schema, time);
+ read_curve_sample(curve, m_curves_schema, sample_sel);
}
else {
Nurb *nurbs = static_cast<Nurb *>(curve->nurb.first);
diff --git a/source/blender/alembic/intern/abc_curves.h b/source/blender/alembic/intern/abc_curves.h
index 2757d179a47..a9231f947b2 100644
--- a/source/blender/alembic/intern/abc_curves.h
+++ b/source/blender/alembic/intern/abc_curves.h
@@ -54,13 +54,21 @@ public:
AbcCurveReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
bool valid() const;
+ bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const;
- void readObjectData(Main *bmain, float time);
- DerivedMesh *read_derivedmesh(DerivedMesh *, const float time, int read_flag, const char **err_str);
+ void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
+ DerivedMesh *read_derivedmesh(DerivedMesh *dm,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
};
/* ************************************************************************** */
-void read_curve_sample(Curve *cu, const Alembic::AbcGeom::ICurvesSchema &schema, const float time);
+void read_curve_sample(Curve *cu,
+ const Alembic::AbcGeom::ICurvesSchema &schema,
+ const Alembic::Abc::ISampleSelector &sample_selector);
#endif /* __ABC_CURVES_H__ */
diff --git a/source/blender/alembic/intern/abc_customdata.cc b/source/blender/alembic/intern/abc_customdata.cc
index 0d11ab79ddd..1d2bc689027 100644
--- a/source/blender/alembic/intern/abc_customdata.cc
+++ b/source/blender/alembic/intern/abc_customdata.cc
@@ -227,48 +227,6 @@ using Alembic::AbcGeom::IC3fGeomParam;
using Alembic::AbcGeom::IC4fGeomParam;
using Alembic::AbcGeom::IV2fGeomParam;
-static void read_mcols(const CDStreamConfig &config, void *data,
- const C3fArraySamplePtr &c3f_ptr, const C4fArraySamplePtr &c4f_ptr)
-{
- MCol *cfaces = static_cast<MCol *>(data);
- MPoly *polys = config.mpoly;
- MLoop *mloops = config.mloop;
-
- if (c3f_ptr) {
- for (int i = 0; i < config.totpoly; ++i) {
- MPoly *p = &polys[i];
- MCol *cface = &cfaces[p->loopstart + p->totloop];
- MLoop *mloop = &mloops[p->loopstart + p->totloop];
-
- for (int j = 0; j < p->totloop; ++j) {
- cface--;
- mloop--;
- const Imath::C3f &color = (*c3f_ptr)[mloop->v];
- cface->a = FTOCHAR(color[0]);
- cface->r = FTOCHAR(color[1]);
- cface->g = FTOCHAR(color[2]);
- cface->b = 255;
- }
- }
- }
- else if (c4f_ptr) {
- for (int i = 0; i < config.totpoly; ++i) {
- MPoly *p = &polys[i];
- MCol *cface = &cfaces[p->loopstart + p->totloop];
- MLoop *mloop = &mloops[p->loopstart + p->totloop];
-
- for (int j = 0; j < p->totloop; ++j) {
- cface--;
- mloop--;
- const Imath::C4f &color = (*c4f_ptr)[mloop->v];
- cface->a = FTOCHAR(color[0]);
- cface->r = FTOCHAR(color[1]);
- cface->g = FTOCHAR(color[2]);
- cface->b = FTOCHAR(color[3]);
- }
- }
- }
-}
static void read_uvs(const CDStreamConfig &config, void *data,
const Alembic::AbcGeom::V2fArraySamplePtr &uvs,
@@ -294,57 +252,108 @@ static void read_uvs(const CDStreamConfig &config, void *data,
}
}
-static void read_custom_data_ex(const ICompoundProperty &prop,
- const PropertyHeader &prop_header,
- const CDStreamConfig &config,
- const Alembic::Abc::ISampleSelector &iss,
- int data_type)
+static void read_custom_data_mcols(const ICompoundProperty &arbGeomParams,
+ const PropertyHeader &prop_header,
+ const CDStreamConfig &config,
+ const Alembic::Abc::ISampleSelector &iss)
{
- if (data_type == CD_MLOOPCOL) {
- C3fArraySamplePtr c3f_ptr = C3fArraySamplePtr();
- C4fArraySamplePtr c4f_ptr = C4fArraySamplePtr();
+ C3fArraySamplePtr c3f_ptr = C3fArraySamplePtr();
+ C4fArraySamplePtr c4f_ptr = C4fArraySamplePtr();
+ bool use_c3f_ptr;
+ bool is_facevarying;
+
+ /* Find the correct interpretation of the data */
+ if (IC3fGeomParam::matches(prop_header)) {
+ IC3fGeomParam color_param(arbGeomParams, prop_header.getName());
+ IC3fGeomParam::Sample sample;
+ BLI_assert(!strcmp("rgb", color_param.getInterpretation()));
+
+ color_param.getIndexed(sample, iss);
+ is_facevarying = sample.getScope() == kFacevaryingScope &&
+ config.totloop == sample.getIndices()->size();
+
+ c3f_ptr = sample.getVals();
+ use_c3f_ptr = true;
+ }
+ else if (IC4fGeomParam::matches(prop_header)) {
+ IC4fGeomParam color_param(arbGeomParams, prop_header.getName());
+ IC4fGeomParam::Sample sample;
+ BLI_assert(!strcmp("rgba", color_param.getInterpretation()));
- if (IC3fGeomParam::matches(prop_header)) {
- IC3fGeomParam color_param(prop, prop_header.getName());
- IC3fGeomParam::Sample sample;
- color_param.getIndexed(sample, iss);
+ color_param.getIndexed(sample, iss);
+ is_facevarying = sample.getScope() == kFacevaryingScope &&
+ config.totloop == sample.getIndices()->size();
- c3f_ptr = sample.getVals();
- }
- else if (IC4fGeomParam::matches(prop_header)) {
- IC4fGeomParam color_param(prop, prop_header.getName());
- IC4fGeomParam::Sample sample;
- color_param.getIndexed(sample, iss);
+ c4f_ptr = sample.getVals();
+ use_c3f_ptr = false;
+ }
+ else {
+ /* this won't happen due to the checks in read_custom_data() */
+ return;
+ }
+ BLI_assert(c3f_ptr || c4f_ptr);
- c4f_ptr = sample.getVals();
- }
+ /* Read the vertex colors */
+ void *cd_data = config.add_customdata_cb(config.user_data,
+ prop_header.getName().c_str(),
+ CD_MLOOPCOL);
+ MCol *cfaces = static_cast<MCol *>(cd_data);
+ MPoly *mpolys = config.mpoly;
+ MLoop *mloops = config.mloop;
- void *cd_data = config.add_customdata_cb(config.user_data,
- prop_header.getName().c_str(),
- data_type);
+ size_t face_index = 0;
+ size_t color_index;
+ for (int i = 0; i < config.totpoly; ++i) {
+ MPoly *poly = &mpolys[i];
+ MCol *cface = &cfaces[poly->loopstart + poly->totloop];
+ MLoop *mloop = &mloops[poly->loopstart + poly->totloop];
- read_mcols(config, cd_data, c3f_ptr, c4f_ptr);
- }
- else if (data_type == CD_MLOOPUV) {
- IV2fGeomParam uv_param(prop, prop_header.getName());
+ for (int j = 0; j < poly->totloop; ++j, ++face_index) {
+ --cface;
+ --mloop;
+ color_index = is_facevarying ? face_index : mloop->v;
- if (!uv_param.isIndexed()) {
- return;
+ if (use_c3f_ptr) {
+ const Imath::C3f &color = (*c3f_ptr)[color_index];
+ cface->a = FTOCHAR(color[0]);
+ cface->r = FTOCHAR(color[1]);
+ cface->g = FTOCHAR(color[2]);
+ cface->b = 255;
+ }
+ else {
+ const Imath::C4f &color = (*c4f_ptr)[color_index];
+ cface->a = FTOCHAR(color[0]);
+ cface->r = FTOCHAR(color[1]);
+ cface->g = FTOCHAR(color[2]);
+ cface->b = FTOCHAR(color[3]);
+ }
}
+ }
+}
- IV2fGeomParam::Sample sample;
- uv_param.getIndexed(sample, iss);
+static void read_custom_data_uvs(const ICompoundProperty &prop,
+ const PropertyHeader &prop_header,
+ const CDStreamConfig &config,
+ const Alembic::Abc::ISampleSelector &iss)
+{
+ IV2fGeomParam uv_param(prop, prop_header.getName());
- if (uv_param.getScope() != kFacevaryingScope) {
- return;
- }
+ if (!uv_param.isIndexed()) {
+ return;
+ }
- void *cd_data = config.add_customdata_cb(config.user_data,
- prop_header.getName().c_str(),
- data_type);
+ IV2fGeomParam::Sample sample;
+ uv_param.getIndexed(sample, iss);
- read_uvs(config, cd_data, sample.getVals(), sample.getIndices());
+ if (uv_param.getScope() != kFacevaryingScope) {
+ return;
}
+
+ void *cd_data = config.add_customdata_cb(config.user_data,
+ prop_header.getName().c_str(),
+ CD_MLOOPUV);
+
+ read_uvs(config, cd_data, sample.getVals(), sample.getIndices());
}
void read_custom_data(const ICompoundProperty &prop, const CDStreamConfig &config, const Alembic::Abc::ISampleSelector &iss)
@@ -367,7 +376,7 @@ void read_custom_data(const ICompoundProperty &prop, const CDStreamConfig &confi
continue;
}
- read_custom_data_ex(prop, prop_header, config, iss, CD_MLOOPUV);
+ read_custom_data_uvs(prop, prop_header, config, iss);
continue;
}
@@ -377,7 +386,7 @@ void read_custom_data(const ICompoundProperty &prop, const CDStreamConfig &confi
continue;
}
- read_custom_data_ex(prop, prop_header, config, iss, CD_MLOOPCOL);
+ read_custom_data_mcols(prop, prop_header, config, iss);
continue;
}
}
diff --git a/source/blender/alembic/intern/abc_exporter.cc b/source/blender/alembic/intern/abc_exporter.cc
index ec9504a2f3a..4fe65b96f36 100644
--- a/source/blender/alembic/intern/abc_exporter.cc
+++ b/source/blender/alembic/intern/abc_exporter.cc
@@ -72,8 +72,8 @@ ExportSettings::ExportSettings()
, renderable_only(false)
, frame_start(1)
, frame_end(1)
- , frame_step_xform(1)
- , frame_step_shape(1)
+ , frame_samples_xform(1)
+ , frame_samples_shape(1)
, shutter_open(0.0)
, shutter_close(1.0)
, global_scale(1.0f)
@@ -83,6 +83,8 @@ ExportSettings::ExportSettings()
, export_vcols(false)
, export_face_sets(false)
, export_vweigths(false)
+ , export_hair(true)
+ , export_particles(true)
, apply_subdiv(false)
, use_subdiv_schema(false)
, export_child_hairs(true)
@@ -106,7 +108,7 @@ static bool object_is_smoke_sim(Object *ob)
return false;
}
-static bool object_is_shape(Object *ob)
+static bool object_type_is_exportable(Object *ob)
{
switch (ob->type) {
case OB_MESH:
@@ -115,6 +117,7 @@ static bool object_is_shape(Object *ob)
}
return true;
+ case OB_EMPTY:
case OB_CURVE:
case OB_SURF:
case OB_CAMERA:
@@ -124,14 +127,31 @@ static bool object_is_shape(Object *ob)
}
}
-static bool export_object(const ExportSettings * const settings, Object *ob)
+
+/**
+ * Returns whether this object should be exported into the Alembic file.
+ *
+ * \param settings: export settings, used for options like 'selected only'.
+ * \param ob: the object in question.
+ * \param is_duplicated: Normally false; true when the object is instanced
+ * into the scene by a dupli-object (e.g. part of a dupligroup).
+ * This ignores selection and layer visibility,
+ * and assumes that the dupli-object itself (e.g. the group-instantiating empty) is exported.
+ */
+static bool export_object(const ExportSettings * const settings, Object *ob,
+ bool is_duplicated)
{
- if (settings->selected_only && !parent_selected(ob)) {
- return false;
- }
+ if (!is_duplicated) {
+ /* These two tests only make sense when the object isn't being instanced
+ * into the scene. When it is, its exportability is determined by
+ * its dupli-object and the DupliObject::no_draw property. */
+ if (settings->selected_only && !parent_selected(ob)) {
+ return false;
+ }
- if (settings->visible_layers_only && !(settings->scene->lay & ob->lay)) {
- return false;
+ if (settings->visible_layers_only && !(settings->scene->lay & ob->lay)) {
+ return false;
+ }
}
if (settings->renderable_only && (ob->restrictflag & OB_RESTRICT_RENDER)) {
@@ -168,60 +188,56 @@ AbcExporter::~AbcExporter()
delete m_writer;
}
-void AbcExporter::getShutterSamples(double step, bool time_relative,
+void AbcExporter::getShutterSamples(unsigned int nr_of_samples,
+ bool time_relative,
std::vector<double> &samples)
{
+ Scene *scene = m_scene; /* for use in the FPS macro */
samples.clear();
- const double time_factor = time_relative ? m_scene->r.frs_sec : 1.0;
- const double shutter_open = m_settings.shutter_open;
- const double shutter_close = m_settings.shutter_close;
+ unsigned int frame_offset = time_relative ? m_settings.frame_start : 0;
+ double time_factor = time_relative ? FPS : 1.0;
+ double shutter_open = m_settings.shutter_open;
+ double shutter_close = m_settings.shutter_close;
+ double time_inc = (shutter_close - shutter_open) / nr_of_samples;
- /* sample all frame */
- if (shutter_open == 0.0 && shutter_close == 1.0) {
- for (double t = 0.0; t < 1.0; t += step) {
- samples.push_back((t + m_settings.frame_start) / time_factor);
- }
- }
- else {
- /* sample between shutter open & close */
- const int nsamples = static_cast<int>(std::max((1.0 / step) - 1.0, 1.0));
- const double time_inc = (shutter_close - shutter_open) / nsamples;
+ /* sample between shutter open & close */
+ for (int sample=0; sample < nr_of_samples; ++sample) {
+ double sample_time = shutter_open + time_inc * sample;
+ double time = (frame_offset + sample_time) / time_factor;
- for (double t = shutter_open; t <= shutter_close; t += time_inc) {
- samples.push_back((t + m_settings.frame_start) / time_factor);
- }
+ samples.push_back(time);
}
}
Alembic::Abc::TimeSamplingPtr AbcExporter::createTimeSampling(double step)
{
- TimeSamplingPtr time_sampling;
std::vector<double> samples;
if (m_settings.frame_start == m_settings.frame_end) {
- time_sampling.reset(new Alembic::Abc::TimeSampling());
- return time_sampling;
+ return TimeSamplingPtr(new Alembic::Abc::TimeSampling());
}
getShutterSamples(step, true, samples);
- Alembic::Abc::TimeSamplingType ts(static_cast<uint32_t>(samples.size()), 1.0 / m_scene->r.frs_sec);
- time_sampling.reset(new Alembic::Abc::TimeSampling(ts, samples));
+ Alembic::Abc::TimeSamplingType ts(
+ static_cast<uint32_t>(samples.size()),
+ 1.0 / m_scene->r.frs_sec);
- return time_sampling;
+ return TimeSamplingPtr(new Alembic::Abc::TimeSampling(ts, samples));
}
-void AbcExporter::getFrameSet(double step, std::set<double> &frames)
+void AbcExporter::getFrameSet(unsigned int nr_of_samples,
+ std::set<double> &frames)
{
frames.clear();
std::vector<double> shutter_samples;
- getShutterSamples(step, false, shutter_samples);
+ getShutterSamples(nr_of_samples, false, shutter_samples);
for (double frame = m_settings.frame_start; frame <= m_settings.frame_end; frame += 1.0) {
- for (int j = 0, e = shutter_samples.size(); j < e; ++j) {
+ for (size_t j = 0; j < nr_of_samples; ++j) {
frames.insert(frame + shutter_samples[j]);
}
}
@@ -253,44 +269,37 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled)
/* Create time samplings for transforms and shapes. */
- TimeSamplingPtr trans_time = createTimeSampling(m_settings.frame_step_xform);
+ TimeSamplingPtr trans_time = createTimeSampling(m_settings.frame_samples_xform);
m_trans_sampling_index = m_writer->archive().addTimeSampling(*trans_time);
TimeSamplingPtr shape_time;
- if ((m_settings.frame_step_shape == m_settings.frame_step_xform) ||
+ if ((m_settings.frame_samples_shape == m_settings.frame_samples_xform) ||
(m_settings.frame_start == m_settings.frame_end))
{
shape_time = trans_time;
m_shape_sampling_index = m_trans_sampling_index;
}
else {
- shape_time = createTimeSampling(m_settings.frame_step_shape);
+ shape_time = createTimeSampling(m_settings.frame_samples_shape);
m_shape_sampling_index = m_writer->archive().addTimeSampling(*shape_time);
}
OBox3dProperty archive_bounds_prop = Alembic::AbcGeom::CreateOArchiveBounds(m_writer->archive(), m_trans_sampling_index);
- if (m_settings.flatten_hierarchy) {
- createTransformWritersFlat();
- }
- else {
- createTransformWritersHierarchy(bmain->eval_ctx);
- }
-
+ createTransformWritersHierarchy(bmain->eval_ctx);
createShapeWriters(bmain->eval_ctx);
/* Make a list of frames to export. */
std::set<double> xform_frames;
- getFrameSet(m_settings.frame_step_xform, xform_frames);
+ getFrameSet(m_settings.frame_samples_xform, xform_frames);
std::set<double> shape_frames;
- getFrameSet(m_settings.frame_step_shape, shape_frames);
+ getFrameSet(m_settings.frame_samples_shape, shape_frames);
/* Merge all frames needed. */
-
std::set<double> frames(xform_frames);
frames.insert(shape_frames.begin(), shape_frames.end());
@@ -313,7 +322,7 @@ void AbcExporter::operator()(Main *bmain, float &progress, bool &was_canceled)
const double frame = *begin;
/* 'frame' is offset by start frame, so need to cancel the offset. */
- setCurrentFrame(bmain, frame - m_settings.frame_start);
+ setCurrentFrame(bmain, frame);
if (shape_frames.count(frame) != 0) {
for (int i = 0, e = m_shapes.size(); i != e; ++i) {
@@ -349,34 +358,16 @@ void AbcExporter::createTransformWritersHierarchy(EvaluationContext *eval_ctx)
while (base) {
Object *ob = base->object;
- if (export_object(&m_settings, ob)) {
- switch (ob->type) {
- case OB_LAMP:
- case OB_LATTICE:
- case OB_MBALL:
- case OB_SPEAKER:
- /* We do not export transforms for objects of these classes. */
- break;
-
- default:
- exploreTransform(eval_ctx, ob, ob->parent, NULL);
- }
- }
-
- base = base->next;
- }
-}
-
-void AbcExporter::createTransformWritersFlat()
-{
- Base *base = static_cast<Base *>(m_scene->base.first);
+ switch (ob->type) {
+ case OB_LAMP:
+ case OB_LATTICE:
+ case OB_MBALL:
+ case OB_SPEAKER:
+ /* We do not export transforms for objects of these classes. */
+ break;
- while (base) {
- Object *ob = base->object;
-
- if (export_object(&m_settings, ob) && object_is_shape(ob)) {
- std::string name = get_id_name(ob);
- m_xforms[name] = new AbcTransformWriter(ob, m_writer->archive().getTop(), 0, m_trans_sampling_index, m_settings);
+ default:
+ exploreTransform(eval_ctx, ob, ob->parent);
}
base = base->next;
@@ -385,8 +376,13 @@ void AbcExporter::createTransformWritersFlat()
void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Object *ob, Object *parent, Object *dupliObParent)
{
+ /* If an object isn't exported itself, its duplilist shouldn't be
+ * exported either. */
+ if (!export_object(&m_settings, ob, dupliObParent != NULL)) {
+ return;
+ }
- if (export_object(&m_settings, ob) && object_is_shape(ob)) {
+ if (object_type_is_exportable(ob)) {
createTransformWriter(ob, parent, dupliObParent);
}
@@ -397,15 +393,18 @@ void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Object *ob, Obje
Object *dupli_ob = NULL;
Object *dupli_parent = NULL;
- while (link) {
+ for (; link; link = link->next) {
+ /* This skips things like custom bone shapes. */
+ if (m_settings.renderable_only && link->no_draw) {
+ continue;
+ }
+
if (link->type == OB_DUPLIGROUP) {
dupli_ob = link->ob;
dupli_parent = (dupli_ob->parent) ? dupli_ob->parent : ob;
exploreTransform(eval_ctx, dupli_ob, dupli_parent, ob);
}
-
- link = link->next;
}
}
@@ -414,28 +413,44 @@ void AbcExporter::exploreTransform(EvaluationContext *eval_ctx, Object *ob, Obje
AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *parent, Object *dupliObParent)
{
- const std::string name = get_object_dag_path_name(ob, dupliObParent);
-
/* An object should not be its own parent, or we'll get infinite loops. */
BLI_assert(ob != parent);
BLI_assert(ob != dupliObParent);
+ std::string name;
+ if (m_settings.flatten_hierarchy) {
+ name = get_id_name(ob);
+ }
+ else {
+ name = get_object_dag_path_name(ob, dupliObParent);
+ }
+
/* check if we have already created a transform writer for this object */
AbcTransformWriter *my_writer = getXForm(name);
- if (my_writer != NULL){
+ if (my_writer != NULL) {
return my_writer;
}
AbcTransformWriter *parent_writer = NULL;
Alembic::Abc::OObject alembic_parent;
- if (parent) {
+ if (m_settings.flatten_hierarchy || parent == NULL) {
+ /* Parentless objects still have the "top object" as parent
+ * in Alembic. */
+ alembic_parent = m_writer->archive().getTop();
+ }
+ else {
/* Since there are so many different ways to find parents (as evident
* in the number of conditions below), we can't really look up the
* parent by name. We'll just call createTransformWriter(), which will
* return the parent's AbcTransformWriter pointer. */
if (parent->parent) {
- parent_writer = createTransformWriter(parent, parent->parent, dupliObParent);
+ if (parent == dupliObParent) {
+ parent_writer = createTransformWriter(parent, parent->parent, NULL);
+ }
+ else {
+ parent_writer = createTransformWriter(parent, parent->parent, dupliObParent);
+ }
}
else if (parent == dupliObParent) {
if (dupliObParent->parent == NULL) {
@@ -452,14 +467,15 @@ AbcTransformWriter * AbcExporter::createTransformWriter(Object *ob, Object *pare
BLI_assert(parent_writer);
alembic_parent = parent_writer->alembicXform();
}
- else {
- /* Parentless objects still have the "top object" as parent
- * in Alembic. */
- alembic_parent = m_writer->archive().getTop();
- }
my_writer = new AbcTransformWriter(ob, alembic_parent, parent_writer,
m_trans_sampling_index, m_settings);
+
+ /* When flattening, the matrix of the dupliobject has to be added. */
+ if (m_settings.flatten_hierarchy && dupliObParent) {
+ my_writer->m_proxy_from = dupliObParent;
+ }
+
m_xforms[name] = my_writer;
return my_writer;
}
@@ -478,32 +494,60 @@ void AbcExporter::createShapeWriters(EvaluationContext *eval_ctx)
void AbcExporter::exploreObject(EvaluationContext *eval_ctx, Object *ob, Object *dupliObParent)
{
- ListBase *lb = object_duplilist(eval_ctx, m_scene, ob);
-
+ /* If an object isn't exported itself, its duplilist shouldn't be
+ * exported either. */
+ if (!export_object(&m_settings, ob, dupliObParent != NULL)) {
+ return;
+ }
+
createShapeWriter(ob, dupliObParent);
+ ListBase *lb = object_duplilist(eval_ctx, m_scene, ob);
+
if (lb) {
- DupliObject *dupliob = static_cast<DupliObject *>(lb->first);
+ DupliObject *link = static_cast<DupliObject *>(lb->first);
- while (dupliob) {
- if (dupliob->type == OB_DUPLIGROUP) {
- exploreObject(eval_ctx, dupliob->ob, ob);
+ for (; link; link = link->next) {
+ /* This skips things like custom bone shapes. */
+ if (m_settings.renderable_only && link->no_draw) {
+ continue;
}
- dupliob = dupliob->next;
+ if (link->type == OB_DUPLIGROUP) {
+ exploreObject(eval_ctx, link->ob, ob);
+ }
}
}
free_object_duplilist(lb);
}
-void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent)
+void AbcExporter::createParticleSystemsWriters(Object *ob, AbcTransformWriter *xform)
{
- if (!object_is_shape(ob)) {
+ if (!m_settings.export_hair && !m_settings.export_particles) {
return;
}
- if (!export_object(&m_settings, ob)) {
+ ParticleSystem *psys = static_cast<ParticleSystem *>(ob->particlesystem.first);
+
+ for (; psys; psys = psys->next) {
+ if (!psys_check_enabled(ob, psys, G.is_rendering) || !psys->part) {
+ continue;
+ }
+
+ if (m_settings.export_hair && psys->part->type == PART_HAIR) {
+ m_settings.export_child_hairs = true;
+ m_shapes.push_back(new AbcHairWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys));
+ }
+ else if (m_settings.export_particles && psys->part->type == PART_EMITTER) {
+ m_shapes.push_back(new AbcPointsWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys));
+ }
+ }
+}
+
+void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent)
+{
+ if (!object_type_is_exportable(ob)) {
return;
}
@@ -523,28 +567,14 @@ void AbcExporter::createShapeWriter(Object *ob, Object *dupliObParent)
return;
}
- ParticleSystem *psys = static_cast<ParticleSystem *>(ob->particlesystem.first);
-
- for (; psys; psys = psys->next) {
- if (!psys_check_enabled(ob, psys, G.is_rendering) || !psys->part) {
- continue;
- }
-
- if (psys->part->type == PART_HAIR) {
- m_settings.export_child_hairs = true;
- m_shapes.push_back(new AbcHairWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys));
- }
- else if (psys->part->type == PART_EMITTER) {
- m_shapes.push_back(new AbcPointsWriter(m_scene, ob, xform, m_shape_sampling_index, m_settings, psys));
- }
- }
+ createParticleSystemsWriters(ob, xform);
switch (ob->type) {
case OB_MESH:
{
Mesh *me = static_cast<Mesh *>(ob->data);
- if (!me || me->totvert == 0) {
+ if (!me) {
return;
}
diff --git a/source/blender/alembic/intern/abc_exporter.h b/source/blender/alembic/intern/abc_exporter.h
index 0f08037fd17..f763922a73b 100644
--- a/source/blender/alembic/intern/abc_exporter.h
+++ b/source/blender/alembic/intern/abc_exporter.h
@@ -50,8 +50,8 @@ struct ExportSettings {
bool renderable_only;
double frame_start, frame_end;
- double frame_step_xform;
- double frame_step_shape;
+ double frame_samples_xform;
+ double frame_samples_shape;
double shutter_open;
double shutter_close;
float global_scale;
@@ -63,6 +63,8 @@ struct ExportSettings {
bool export_vcols;
bool export_face_sets;
bool export_vweigths;
+ bool export_hair;
+ bool export_particles;
bool apply_subdiv;
bool use_subdiv_schema;
@@ -101,20 +103,22 @@ public:
void operator()(Main *bmain, float &progress, bool &was_canceled);
-private:
- void getShutterSamples(double step, bool time_relative, std::vector<double> &samples);
+protected:
+ void getShutterSamples(unsigned int nr_of_samples,
+ bool time_relative,
+ std::vector<double> &samples);
+ void getFrameSet(unsigned int nr_of_samples, std::set<double> &frames);
+private:
Alembic::Abc::TimeSamplingPtr createTimeSampling(double step);
- void getFrameSet(double step, std::set<double> &frames);
-
void createTransformWritersHierarchy(EvaluationContext *eval_ctx);
- void createTransformWritersFlat();
AbcTransformWriter * createTransformWriter(Object *ob, Object *parent, Object *dupliObParent);
void exploreTransform(EvaluationContext *eval_ctx, Object *ob, Object *parent, Object *dupliObParent = NULL);
void exploreObject(EvaluationContext *eval_ctx, Object *ob, Object *dupliObParent);
void createShapeWriters(EvaluationContext *eval_ctx);
void createShapeWriter(Object *ob, Object *dupliObParent);
+ void createParticleSystemsWriters(Object *ob, AbcTransformWriter *xform);
AbcTransformWriter *getXForm(const std::string &name);
diff --git a/source/blender/alembic/intern/abc_hair.cc b/source/blender/alembic/intern/abc_hair.cc
index e328df24e53..8f8ed2019d5 100644
--- a/source/blender/alembic/intern/abc_hair.cc
+++ b/source/blender/alembic/intern/abc_hair.cc
@@ -56,6 +56,7 @@ AbcHairWriter::AbcHairWriter(Scene *scene,
ExportSettings &settings,
ParticleSystem *psys)
: AbcObjectWriter(scene, ob, time_sampling, settings, parent)
+ , m_uv_warning_shown(false)
{
m_psys = psys;
@@ -75,7 +76,7 @@ void AbcHairWriter::do_write()
return;
}
- DerivedMesh *dm = mesh_create_derived_view(m_scene, m_object, CD_MASK_MESH);
+ DerivedMesh *dm = mesh_create_derived_render(m_scene, m_object, CD_MASK_MESH);
DM_ensure_tessface(dm);
std::vector<Imath::V3f> verts;
@@ -132,8 +133,10 @@ void AbcHairWriter::write_hair_sample(DerivedMesh *dm,
MFace *mface = dm->getTessFaceArray(dm);
MVert *mverts = dm->getVertArray(dm);
- if (!mtface || !mface) {
- std::fprintf(stderr, "Warning, no UV set found for underlying geometry.\n");
+ if ((!mtface || !mface) && !m_uv_warning_shown) {
+ std::fprintf(stderr, "Warning, no UV set found for underlying geometry of %s.\n",
+ m_object->id.name + 2);
+ m_uv_warning_shown = true;
}
ParticleData * pa = m_psys->particles;
@@ -238,13 +241,8 @@ void AbcHairWriter::write_hair_child_sample(DerivedMesh *dm,
invert_m4_m4_safe(inv_mat, m_object->obmat);
MTFace *mtface = static_cast<MTFace *>(CustomData_get_layer(&dm->faceData, CD_MTFACE));
- MFace *mface = dm->getTessFaceArray(dm);
MVert *mverts = dm->getVertArray(dm);
- if (!mtface || !mface) {
- std::fprintf(stderr, "Warning, no UV set found for underlying geometry.\n");
- }
-
ParticleCacheKey **cache = m_psys->childcache;
ParticleCacheKey *path;
@@ -253,22 +251,37 @@ void AbcHairWriter::write_hair_child_sample(DerivedMesh *dm,
for (int p = 0; p < m_psys->totchild; ++p, ++pc) {
path = cache[p];
- if (part->from == PART_FROM_FACE) {
+ if (part->from == PART_FROM_FACE &&
+ part->childtype != PART_CHILD_PARTICLES &&
+ mtface) {
const int num = pc->num;
+ if (num < 0) {
+ ABC_LOG(m_settings.logger)
+ << "Warning, child particle of hair system " << m_psys->name
+ << " has unknown face index of geometry of "<< (m_object->id.name + 2)
+ << ", skipping child hair." << std::endl;
+ continue;
+ }
MFace *face = static_cast<MFace *>(dm->getTessFaceData(dm, num, CD_MFACE));
MTFace *tface = mtface + num;
- if (mface && mtface) {
- float r_uv[2], tmpnor[3], mapfw[4], vec[3];
+ float r_uv[2], tmpnor[3], mapfw[4], vec[3];
- psys_interpolate_uvs(tface, face->v4, pc->fuv, r_uv);
- uv_values.push_back(Imath::V2f(r_uv[0], r_uv[1]));
+ psys_interpolate_uvs(tface, face->v4, pc->fuv, r_uv);
+ uv_values.push_back(Imath::V2f(r_uv[0], r_uv[1]));
- psys_interpolate_face(mverts, face, tface, NULL, mapfw, vec, tmpnor, NULL, NULL, NULL, NULL);
+ psys_interpolate_face(mverts, face, tface, NULL, mapfw, vec, tmpnor, NULL, NULL, NULL, NULL);
- /* Convert Z-up to Y-up. */
- norm_values.push_back(Imath::V3f(tmpnor[0], tmpnor[2], -tmpnor[1]));
+ /* Convert Z-up to Y-up. */
+ norm_values.push_back(Imath::V3f(tmpnor[0], tmpnor[2], -tmpnor[1]));
+ }
+ else {
+ if (uv_values.size()) {
+ uv_values.push_back(uv_values[pc->parent]);
+ }
+ if (norm_values.size()) {
+ norm_values.push_back(norm_values[pc->parent]);
}
}
diff --git a/source/blender/alembic/intern/abc_hair.h b/source/blender/alembic/intern/abc_hair.h
index d132b60be12..61f5fe361f8 100644
--- a/source/blender/alembic/intern/abc_hair.h
+++ b/source/blender/alembic/intern/abc_hair.h
@@ -37,6 +37,8 @@ class AbcHairWriter : public AbcObjectWriter {
Alembic::AbcGeom::OCurvesSchema m_schema;
Alembic::AbcGeom::OCurvesSchema::Sample m_sample;
+ bool m_uv_warning_shown;
+
public:
AbcHairWriter(Scene *scene,
Object *ob,
diff --git a/source/blender/alembic/intern/abc_mesh.cc b/source/blender/alembic/intern/abc_mesh.cc
index 5a57e43326a..9a4ca6f99a8 100644
--- a/source/blender/alembic/intern/abc_mesh.cc
+++ b/source/blender/alembic/intern/abc_mesh.cc
@@ -355,7 +355,7 @@ bool AbcMeshWriter::isAnimated() const
md = md->next;
}
- return false;
+ return me->adt != NULL;
}
void AbcMeshWriter::do_write()
@@ -897,19 +897,31 @@ static void *add_customdata_cb(void *user_data, const char *name, int data_type)
{
DerivedMesh *dm = static_cast<DerivedMesh *>(user_data);
CustomDataType cd_data_type = static_cast<CustomDataType>(data_type);
- void *cd_ptr = NULL;
-
- if (ELEM(cd_data_type, CD_MLOOPUV, CD_MLOOPCOL)) {
- cd_ptr = CustomData_get_layer_named(dm->getLoopDataLayout(dm), cd_data_type, name);
-
- if (cd_ptr == NULL) {
- cd_ptr = CustomData_add_layer_named(dm->getLoopDataLayout(dm),
- cd_data_type,
- CD_DEFAULT,
- NULL,
- dm->getNumLoops(dm),
- name);
- }
+ void *cd_ptr;
+ CustomData *loopdata;
+ int numloops;
+
+ /* unsupported custom data type -- don't do anything. */
+ if (!ELEM(cd_data_type, CD_MLOOPUV, CD_MLOOPCOL)) {
+ return NULL;
+ }
+
+ loopdata = dm->getLoopDataLayout(dm);
+ cd_ptr = CustomData_get_layer_named(loopdata, cd_data_type, name);
+ if (cd_ptr != NULL) {
+ /* layer already exists, so just return it. */
+ return cd_ptr;
+ }
+
+ /* create a new layer, taking care to construct the hopefully-soon-to-be-removed
+ * CD_MTEXPOLY layer too, with the same name. */
+ numloops = dm->getNumLoops(dm);
+ cd_ptr = CustomData_add_layer_named(loopdata, cd_data_type, CD_DEFAULT,
+ NULL, numloops, name);
+ if (cd_data_type == CD_MLOOPUV) {
+ CustomData_add_layer_named(dm->getPolyDataLayout(dm),
+ CD_MTEXPOLY, CD_DEFAULT,
+ NULL, numloops, name);
}
return cd_ptr;
@@ -1009,17 +1021,15 @@ bool AbcMeshReader::valid() const
return m_schema.valid();
}
-void AbcMeshReader::readObjectData(Main *bmain, float time)
+void AbcMeshReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel)
{
Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
m_object = BKE_object_add_only_object(bmain, OB_MESH, m_object_name.c_str());
m_object->data = mesh;
- const ISampleSelector sample_sel(time);
-
DerivedMesh *dm = CDDM_from_mesh(mesh);
- DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL, NULL);
+ DerivedMesh *ndm = this->read_derivedmesh(dm, sample_sel, MOD_MESHSEQ_READ_ALL, NULL);
if (ndm != dm) {
dm->release(dm);
@@ -1038,9 +1048,28 @@ void AbcMeshReader::readObjectData(Main *bmain, float time)
}
}
-DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str)
+bool AbcMeshReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const
+{
+ if (!Alembic::AbcGeom::IPolyMesh::matches(alembic_header)) {
+ *err_str = "Object type mismatch, Alembic object path pointed to PolyMesh when importing, but not any more.";
+ return false;
+ }
+
+ if (ob->type != OB_MESH) {
+ *err_str = "Object type mismatch, Alembic object path points to PolyMesh.";
+ return false;
+ }
+
+ return true;
+}
+
+DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm,
+ const ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str)
{
- ISampleSelector sample_sel(time);
const IPolyMeshSchema::Sample sample = m_schema.getValue(sample_sel);
const P3fArraySamplePtr &positions = sample.getPositions();
@@ -1080,7 +1109,7 @@ DerivedMesh *AbcMeshReader::read_derivedmesh(DerivedMesh *dm, const float time,
}
CDStreamConfig config = get_config(new_dm ? new_dm : dm);
- config.time = time;
+ config.time = sample_sel.getRequestedTime();
bool do_normals = false;
read_mesh_sample(&settings, m_schema, sample_sel, config, do_normals);
@@ -1227,7 +1256,24 @@ bool AbcSubDReader::valid() const
return m_schema.valid();
}
-void AbcSubDReader::readObjectData(Main *bmain, float time)
+bool AbcSubDReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const
+{
+ if (!Alembic::AbcGeom::ISubD::matches(alembic_header)) {
+ *err_str = "Object type mismatch, Alembic object path pointed to SubD when importing, but not any more.";
+ return false;
+ }
+
+ if (ob->type != OB_MESH) {
+ *err_str = "Object type mismatch, Alembic object path points to SubD.";
+ return false;
+ }
+
+ return true;
+}
+
+void AbcSubDReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel)
{
Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
@@ -1235,7 +1281,7 @@ void AbcSubDReader::readObjectData(Main *bmain, float time)
m_object->data = mesh;
DerivedMesh *dm = CDDM_from_mesh(mesh);
- DerivedMesh *ndm = this->read_derivedmesh(dm, time, MOD_MESHSEQ_READ_ALL, NULL);
+ DerivedMesh *ndm = this->read_derivedmesh(dm, sample_sel, MOD_MESHSEQ_READ_ALL, NULL);
if (ndm != dm) {
dm->release(dm);
@@ -1243,7 +1289,6 @@ void AbcSubDReader::readObjectData(Main *bmain, float time)
DM_to_mesh(ndm, mesh, m_object, CD_MASK_MESH, true);
- const ISampleSelector sample_sel(time);
const ISubDSchema::Sample sample = m_schema.getValue(sample_sel);
Int32ArraySamplePtr indices = sample.getCreaseIndices();
Alembic::Abc::FloatArraySamplePtr sharpnesses = sample.getCreaseSharpnesses();
@@ -1274,9 +1319,11 @@ void AbcSubDReader::readObjectData(Main *bmain, float time)
}
}
-DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str)
+DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm,
+ const ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str)
{
- ISampleSelector sample_sel(time);
const ISubDSchema::Sample sample = m_schema.getValue(sample_sel);
const P3fArraySamplePtr &positions = sample.getPositions();
@@ -1316,7 +1363,7 @@ DerivedMesh *AbcSubDReader::read_derivedmesh(DerivedMesh *dm, const float time,
/* Only read point data when streaming meshes, unless we need to create new ones. */
CDStreamConfig config = get_config(new_dm ? new_dm : dm);
- config.time = time;
+ config.time = sample_sel.getRequestedTime();
read_subd_sample(&settings, m_schema, sample_sel, config);
if (new_dm) {
diff --git a/source/blender/alembic/intern/abc_mesh.h b/source/blender/alembic/intern/abc_mesh.h
index 64a3109232c..6bf1dde3d1d 100644
--- a/source/blender/alembic/intern/abc_mesh.h
+++ b/source/blender/alembic/intern/abc_mesh.h
@@ -99,10 +99,15 @@ public:
AbcMeshReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
bool valid() const;
+ bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const;
+ void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
- void readObjectData(Main *bmain, float time);
-
- DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str);
+ DerivedMesh *read_derivedmesh(DerivedMesh *dm,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
private:
void readFaceSetsSample(Main *bmain, Mesh *mesh, size_t poly_start,
@@ -120,9 +125,14 @@ public:
AbcSubDReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
bool valid() const;
-
- void readObjectData(Main *bmain, float time);
- DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str);
+ bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const;
+ void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
+ DerivedMesh *read_derivedmesh(DerivedMesh *dm,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
};
/* ************************************************************************** */
diff --git a/source/blender/alembic/intern/abc_nurbs.cc b/source/blender/alembic/intern/abc_nurbs.cc
index d0b9561f679..eaef06fd6d1 100644
--- a/source/blender/alembic/intern/abc_nurbs.cc
+++ b/source/blender/alembic/intern/abc_nurbs.cc
@@ -239,7 +239,7 @@ static bool set_knots(const FloatArraySamplePtr &knots, float *&nu_knots)
return true;
}
-void AbcNurbsReader::readObjectData(Main *bmain, float time)
+void AbcNurbsReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel)
{
Curve *cu = static_cast<Curve *>(BKE_curve_add(bmain, "abc_curve", OB_SURF));
cu->actvert = CU_ACT_NONE;
@@ -253,7 +253,6 @@ void AbcNurbsReader::readObjectData(Main *bmain, float time)
nu->resolu = cu->resolu;
nu->resolv = cu->resolv;
- const ISampleSelector sample_sel(time);
const INuPatchSchema &schema = it->first;
const INuPatchSchema::Sample smp = schema.getValue(sample_sel);
diff --git a/source/blender/alembic/intern/abc_nurbs.h b/source/blender/alembic/intern/abc_nurbs.h
index 1b2e7a8391f..abe460a8988 100644
--- a/source/blender/alembic/intern/abc_nurbs.h
+++ b/source/blender/alembic/intern/abc_nurbs.h
@@ -54,7 +54,7 @@ public:
bool valid() const;
- void readObjectData(Main *bmain, float time);
+ void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
private:
void getNurbsPatches(const Alembic::Abc::IObject &obj);
diff --git a/source/blender/alembic/intern/abc_object.cc b/source/blender/alembic/intern/abc_object.cc
index c8716d55218..6c4cb60d63c 100644
--- a/source/blender/alembic/intern/abc_object.cc
+++ b/source/blender/alembic/intern/abc_object.cc
@@ -140,6 +140,38 @@ AbcObjectReader::AbcObjectReader(const IObject &object, ImportSettings &settings
else {
m_object_name = m_data_name = parts[parts.size() - 1];
}
+
+ determine_inherits_xform();
+}
+
+/* Determine whether we can inherit our parent's XForm */
+void AbcObjectReader::determine_inherits_xform()
+{
+ m_inherits_xform = false;
+
+ IXform ixform = xform();
+ if (!ixform) {
+ return;
+ }
+
+ const IXformSchema & schema(ixform.getSchema());
+ if (!schema.valid()) {
+ std::cerr << "Alembic object " << ixform.getFullName()
+ << " has an invalid schema." << std::endl;
+ return;
+ }
+
+ m_inherits_xform = schema.getInheritsXforms();
+
+ IObject ixform_parent = ixform.getParent();
+ if (!ixform_parent.getParent()) {
+ /* The archive top object certainly is not a transform itself, so handle
+ * it as "no parent". */
+ m_inherits_xform = false;
+ }
+ else {
+ m_inherits_xform = ixform_parent && m_inherits_xform;
+ }
}
AbcObjectReader::~AbcObjectReader()
@@ -215,6 +247,14 @@ Imath::M44d get_matrix(const IXformSchema &schema, const float time)
return s0.getMatrix();
}
+DerivedMesh *AbcObjectReader::read_derivedmesh(DerivedMesh *dm,
+ const Alembic::Abc::ISampleSelector &UNUSED(sample_sel),
+ int UNUSED(read_flag),
+ const char **UNUSED(err_str))
+{
+ return dm;
+}
+
void AbcObjectReader::setupObjectTransform(const float time)
{
bool is_constant = false;
@@ -278,32 +318,10 @@ void AbcObjectReader::read_matrix(float r_mat[4][4], const float time,
return;
}
- bool has_alembic_parent;
- IObject ixform_parent = ixform.getParent();
- if (!ixform_parent.getParent()) {
- /* The archive top object certainly is not a transform itself, so handle
- * it as "no parent". */
- has_alembic_parent = false;
- }
- else {
- has_alembic_parent = ixform_parent && schema.getInheritsXforms();
-
- if (has_alembic_parent && m_object->parent == NULL) {
- /* TODO Sybren: This happened in some files. I think I solved it,
- * but I'll leave this check in here anyway until we've tested it
- * more thoroughly. Better than crashing on a null parent anyway. */
- std::cerr << "Alembic object " << m_iobject.getFullName()
- << " with transform " << ixform.getFullName()
- << " has an Alembic parent but no parent Blender object."
- << std::endl;
- has_alembic_parent = false;
- }
- }
-
const Imath::M44d matrix = get_matrix(schema, time);
convert_matrix(matrix, m_object, r_mat);
- if (has_alembic_parent) {
+ if (m_inherits_xform) {
/* In this case, the matrix in Alembic is in local coordinates, so
* convert to world matrix. To prevent us from reading and accumulating
* all parent matrices in the Alembic file, we assume that the Blender
@@ -362,4 +380,5 @@ void AbcObjectReader::incref()
void AbcObjectReader::decref()
{
--m_refcount;
+ BLI_assert(m_refcount >= 0);
}
diff --git a/source/blender/alembic/intern/abc_object.h b/source/blender/alembic/intern/abc_object.h
index d5344533b55..852ef451f23 100644
--- a/source/blender/alembic/intern/abc_object.h
+++ b/source/blender/alembic/intern/abc_object.h
@@ -90,7 +90,7 @@ struct ImportSettings {
/* Length and frame offset of file sequences. */
int sequence_len;
- int offset;
+ int sequence_offset;
/* From MeshSeqCacheModifierData.read_flag */
int read_flag;
@@ -107,7 +107,7 @@ struct ImportSettings {
, is_sequence(false)
, set_frame_range(false)
, sequence_len(1)
- , offset(0)
+ , sequence_offset(0)
, read_flag(0)
, validate_meshes(false)
, cache_file(NULL)
@@ -143,6 +143,8 @@ protected:
* modifiers and/or constraints. */
int m_refcount;
+ bool m_inherits_xform;
+
public:
AbcObjectReader *parent_reader;
@@ -167,18 +169,19 @@ public:
const std::string & name() const { return m_name; }
const std::string & object_name() const { return m_object_name; }
const std::string & data_name() const { return m_data_name; }
+ bool inherits_xform() const { return m_inherits_xform; }
virtual bool valid() const = 0;
+ virtual bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const = 0;
- virtual void readObjectData(Main *bmain, float time) = 0;
+ virtual void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel) = 0;
- virtual DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str)
- {
- (void)time;
- (void)read_flag;
- (void)err_str;
- return dm;
- }
+ virtual DerivedMesh *read_derivedmesh(DerivedMesh *dm,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
/** Reads the object matrix and sets up an object transform if animated. */
void setupObjectTransform(const float time);
@@ -194,6 +197,9 @@ public:
void read_matrix(float r_mat[4][4], const float time,
const float scale, bool &is_constant);
+
+protected:
+ void determine_inherits_xform();
};
Imath::M44d get_matrix(const Alembic::AbcGeom::IXformSchema &schema, const float time);
diff --git a/source/blender/alembic/intern/abc_points.cc b/source/blender/alembic/intern/abc_points.cc
index fc84759b1d9..80567cd6bf0 100644
--- a/source/blender/alembic/intern/abc_points.cc
+++ b/source/blender/alembic/intern/abc_points.cc
@@ -151,12 +151,29 @@ bool AbcPointsReader::valid() const
return m_schema.valid();
}
-void AbcPointsReader::readObjectData(Main *bmain, float time)
+bool AbcPointsReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const
+{
+ if (!Alembic::AbcGeom::IPoints::matches(alembic_header)) {
+ *err_str = "Object type mismatch, Alembic object path pointed to Points when importing, but not any more.";
+ return false;
+ }
+
+ if (ob->type != OB_MESH) {
+ *err_str = "Object type mismatch, Alembic object path points to Points.";
+ return false;
+ }
+
+ return true;
+}
+
+void AbcPointsReader::readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel)
{
Mesh *mesh = BKE_mesh_add(bmain, m_data_name.c_str());
DerivedMesh *dm = CDDM_from_mesh(mesh);
- DerivedMesh *ndm = this->read_derivedmesh(dm, time, 0, NULL);
+ DerivedMesh *ndm = this->read_derivedmesh(dm, sample_sel, 0, NULL);
if (ndm != dm) {
dm->release(dm);
@@ -178,8 +195,7 @@ void AbcPointsReader::readObjectData(Main *bmain, float time)
void read_points_sample(const IPointsSchema &schema,
const ISampleSelector &selector,
- CDStreamConfig &config,
- float time)
+ CDStreamConfig &config)
{
Alembic::AbcGeom::IPointsSchema::Sample sample = schema.getValue(selector);
@@ -189,7 +205,7 @@ void read_points_sample(const IPointsSchema &schema,
N3fArraySamplePtr vnormals;
if (has_property(prop, "N")) {
- const Alembic::Util::uint32_t itime = static_cast<Alembic::Util::uint32_t>(time);
+ const Alembic::Util::uint32_t itime = static_cast<Alembic::Util::uint32_t>(selector.getRequestedTime());
const IN3fArrayProperty &normals_prop = IN3fArrayProperty(prop, "N", itime);
if (normals_prop) {
@@ -200,9 +216,11 @@ void read_points_sample(const IPointsSchema &schema,
read_mverts(config.mvert, positions, vnormals);
}
-DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm, const float time, int /*read_flag*/, const char ** /*err_str*/)
+DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm,
+ const ISampleSelector &sample_sel,
+ int /*read_flag*/,
+ const char ** /*err_str*/)
{
- ISampleSelector sample_sel(time);
const IPointsSchema::Sample sample = m_schema.getValue(sample_sel);
const P3fArraySamplePtr &positions = sample.getPositions();
@@ -214,7 +232,7 @@ DerivedMesh *AbcPointsReader::read_derivedmesh(DerivedMesh *dm, const float time
}
CDStreamConfig config = get_config(new_dm ? new_dm : dm);
- read_points_sample(m_schema, sample_sel, config, time);
+ read_points_sample(m_schema, sample_sel, config);
return new_dm ? new_dm : dm;
}
diff --git a/source/blender/alembic/intern/abc_points.h b/source/blender/alembic/intern/abc_points.h
index cb68dbca4d5..369a802d763 100644
--- a/source/blender/alembic/intern/abc_points.h
+++ b/source/blender/alembic/intern/abc_points.h
@@ -58,15 +58,20 @@ public:
AbcPointsReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
bool valid() const;
+ bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const;
- void readObjectData(Main *bmain, float time);
+ void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
- DerivedMesh *read_derivedmesh(DerivedMesh *dm, const float time, int read_flag, const char **err_str);
+ DerivedMesh *read_derivedmesh(DerivedMesh *dm,
+ const Alembic::Abc::ISampleSelector &sample_sel,
+ int read_flag,
+ const char **err_str);
};
void read_points_sample(const Alembic::AbcGeom::IPointsSchema &schema,
const Alembic::AbcGeom::ISampleSelector &selector,
- CDStreamConfig &config,
- float time);
+ CDStreamConfig &config);
#endif /* __ABC_POINTS_H__ */
diff --git a/source/blender/alembic/intern/abc_transform.cc b/source/blender/alembic/intern/abc_transform.cc
index cad1eae4764..5392387663f 100644
--- a/source/blender/alembic/intern/abc_transform.cc
+++ b/source/blender/alembic/intern/abc_transform.cc
@@ -36,6 +36,7 @@ extern "C" {
using Alembic::AbcGeom::OObject;
using Alembic::AbcGeom::OXform;
+using Alembic::Abc::ISampleSelector;
/* ************************************************************************** */
@@ -62,6 +63,7 @@ AbcTransformWriter::AbcTransformWriter(Object *ob,
unsigned int time_sampling,
ExportSettings &settings)
: AbcObjectWriter(NULL, ob, time_sampling, settings, parent)
+ , m_proxy_from(NULL)
{
m_is_animated = hasAnimation(m_object);
@@ -71,6 +73,9 @@ AbcTransformWriter::AbcTransformWriter(Object *ob,
m_xform = OXform(abc_parent, get_id_name(m_object), time_sampling);
m_schema = m_xform.getSchema();
+
+ /* Blender objects can't have a parent without inheriting the transform. */
+ m_inherits_xform = parent != NULL;
}
void AbcTransformWriter::do_write()
@@ -86,28 +91,29 @@ void AbcTransformWriter::do_write()
}
float yup_mat[4][4];
- create_transform_matrix(m_object, yup_mat);
+ create_transform_matrix(m_object, yup_mat,
+ m_inherits_xform ? ABC_MATRIX_LOCAL : ABC_MATRIX_WORLD,
+ m_proxy_from);
/* Only apply rotation to root camera, parenting will propagate it. */
- if (m_object->type == OB_CAMERA && !has_parent_camera(m_object)) {
+ if (m_object->type == OB_CAMERA && (!m_inherits_xform || !has_parent_camera(m_object))) {
float rot_mat[4][4];
axis_angle_to_mat4_single(rot_mat, 'X', -M_PI_2);
mul_m4_m4m4(yup_mat, yup_mat, rot_mat);
}
- if (!m_object->parent) {
+ if (!m_object->parent || !m_inherits_xform) {
/* Only apply scaling to root objects, parenting will propagate it. */
- /* TODO Sybren: when we're exporting as "flat", i.e. non-hierarchial,
- * we should apply the scale even when the object has a parent
- * Blender Object. */
float scale_mat[4][4];
scale_m4_fl(scale_mat, m_settings.global_scale);
scale_mat[3][3] = m_settings.global_scale; /* also scale translation */
mul_m4_m4m4(yup_mat, yup_mat, scale_mat);
+ yup_mat[3][3] /= m_settings.global_scale; /* normalise the homogeneous component */
}
m_matrix = convert_matrix(yup_mat);
m_sample.setMatrix(m_matrix);
+ m_sample.setInheritsXforms(m_inherits_xform);
m_schema.set(m_sample);
}
@@ -149,7 +155,24 @@ bool AbcEmptyReader::valid() const
return m_schema.valid();
}
-void AbcEmptyReader::readObjectData(Main *bmain, float /*time*/)
+bool AbcEmptyReader::accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const
+{
+ if (!Alembic::AbcGeom::IXform::matches(alembic_header)) {
+ *err_str = "Object type mismatch, Alembic object path pointed to XForm when importing, but not any more.";
+ return false;
+ }
+
+ if (ob->type != OB_EMPTY) {
+ *err_str = "Object type mismatch, Alembic object path points to XForm.";
+ return false;
+ }
+
+ return true;
+}
+
+void AbcEmptyReader::readObjectData(Main *bmain, const ISampleSelector &UNUSED(sample_sel))
{
m_object = BKE_object_add_only_object(bmain, OB_EMPTY,
m_object_name.c_str());
diff --git a/source/blender/alembic/intern/abc_transform.h b/source/blender/alembic/intern/abc_transform.h
index b55fa12dadf..753a4247e9f 100644
--- a/source/blender/alembic/intern/abc_transform.h
+++ b/source/blender/alembic/intern/abc_transform.h
@@ -38,6 +38,10 @@ class AbcTransformWriter : public AbcObjectWriter {
bool m_is_animated;
bool m_visible;
+ bool m_inherits_xform;
+
+public:
+ Object *m_proxy_from;
public:
AbcTransformWriter(Object *ob,
@@ -64,8 +68,11 @@ public:
AbcEmptyReader(const Alembic::Abc::IObject &object, ImportSettings &settings);
bool valid() const;
+ bool accepts_object_type(const Alembic::AbcCoreAbstract::ObjectHeader &alembic_header,
+ const Object *const ob,
+ const char **err_str) const;
- void readObjectData(Main *bmain, float time);
+ void readObjectData(Main *bmain, const Alembic::Abc::ISampleSelector &sample_sel);
};
#endif /* __ABC_TRANSFORM_H__ */
diff --git a/source/blender/alembic/intern/abc_util.cc b/source/blender/alembic/intern/abc_util.cc
index 224e0eccd00..26eb7620fb1 100644
--- a/source/blender/alembic/intern/abc_util.cc
+++ b/source/blender/alembic/intern/abc_util.cc
@@ -142,7 +142,7 @@ void create_swapped_rotation_matrix(
float rz;
/* Apply transformation */
- switch(mode) {
+ switch (mode) {
case ABC_ZUP_FROM_YUP:
ry = -euler[2];
rz = euler[1];
@@ -217,7 +217,7 @@ void copy_m44_axis_swap(float dst_mat[4][4], float src_mat[4][4], AbcAxisSwapMod
copy_m4_m3(dst_mat, dst_rot);
/* Apply translation */
- switch(mode) {
+ switch (mode) {
case ABC_ZUP_FROM_YUP:
copy_zup_from_yup(dst_mat[3], src_trans);
break;
@@ -257,24 +257,27 @@ void convert_matrix(const Imath::M44d &xform, Object *ob, float r_mat[4][4])
/* Recompute transform matrix of object in new coordinate system
* (from Z-Up to Y-Up). */
-void create_transform_matrix(Object *obj, float r_yup_mat[4][4])
+void create_transform_matrix(Object *obj, float r_yup_mat[4][4], AbcMatrixMode mode,
+ Object *proxy_from)
{
float zup_mat[4][4];
- /* get local matrix. */
- /* TODO Sybren: when we're exporting as "flat", i.e. non-hierarchial,
- * we should export the world matrix even when the object has a parent
- * Blender Object. */
- if (obj->parent) {
+ /* get local or world matrix. */
+ if (mode == ABC_MATRIX_LOCAL && obj->parent) {
/* Note that this produces another matrix than the local matrix, due to
* constraints and modifiers as well as the obj->parentinv matrix. */
invert_m4_m4(obj->parent->imat, obj->parent->obmat);
mul_m4_m4m4(zup_mat, obj->parent->imat, obj->obmat);
- copy_m44_axis_swap(r_yup_mat, zup_mat, ABC_YUP_FROM_ZUP);
}
else {
- copy_m44_axis_swap(r_yup_mat, obj->obmat, ABC_YUP_FROM_ZUP);
+ copy_m4_m4(zup_mat, obj->obmat);
}
+
+ if (proxy_from) {
+ mul_m4_m4m4(zup_mat, proxy_from->obmat, zup_mat);
+ }
+
+ copy_m44_axis_swap(r_yup_mat, zup_mat, ABC_YUP_FROM_ZUP);
}
bool has_property(const Alembic::Abc::ICompoundProperty &prop, const std::string &name)
diff --git a/source/blender/alembic/intern/abc_util.h b/source/blender/alembic/intern/abc_util.h
index 5b53c86a859..2526958111a 100644
--- a/source/blender/alembic/intern/abc_util.h
+++ b/source/blender/alembic/intern/abc_util.h
@@ -33,7 +33,7 @@
#endif
/**
- * @brief The CacheReader struct is only used for anonymous pointers,
+ * \brief The CacheReader struct is only used for anonymous pointers,
* to interface between C and C++ code. This library only creates
* pointers to AbcObjectReader (or subclasses thereof).
*/
@@ -57,7 +57,13 @@ bool object_selected(Object *ob);
bool parent_selected(Object *ob);
Imath::M44d convert_matrix(float mat[4][4]);
-void create_transform_matrix(Object *obj, float r_transform_mat[4][4]);
+
+typedef enum {
+ ABC_MATRIX_WORLD = 1,
+ ABC_MATRIX_LOCAL = 2,
+} AbcMatrixMode;
+void create_transform_matrix(Object *obj, float r_transform_mat[4][4],
+ AbcMatrixMode mode, Object *proxy_from);
void split(const std::string &s, const char delim, std::vector<std::string> &tokens);
diff --git a/source/blender/alembic/intern/alembic_capi.cc b/source/blender/alembic/intern/alembic_capi.cc
index 9529b370928..bee8e92e969 100644
--- a/source/blender/alembic/intern/alembic_capi.cc
+++ b/source/blender/alembic/intern/alembic_capi.cc
@@ -172,7 +172,7 @@ static bool gather_objects_paths(const IObject &object, ListBase *object_paths)
void *abc_path_void = MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath");
AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(abc_path_void);
- BLI_strncpy(abc_path->path, object.getFullName().c_str(), PATH_MAX);
+ BLI_strncpy(abc_path->path, object.getFullName().c_str(), sizeof(abc_path->path));
BLI_addtail(object_paths, abc_path);
}
@@ -238,6 +238,7 @@ struct ExportJobData {
float *progress;
bool was_canceled;
+ bool export_ok;
};
static void export_startjob(void *customdata, short *stop, short *do_update, float *progress)
@@ -271,6 +272,8 @@ static void export_startjob(void *customdata, short *stop, short *do_update, flo
BKE_scene_update_for_newframe(data->bmain->eval_ctx, data->bmain,
scene, scene->lay);
}
+
+ data->export_ok = !data->was_canceled;
}
catch (const std::exception &e) {
ABC_LOG(data->settings.logger) << "Abc Export error: " << e.what() << '\n';
@@ -297,15 +300,17 @@ static void export_endjob(void *customdata)
BKE_spacedata_draw_locks(false);
}
-void ABC_export(
+bool ABC_export(
Scene *scene,
bContext *C,
const char *filepath,
- const struct AlembicExportParams *params)
+ const struct AlembicExportParams *params,
+ bool as_background_job)
{
ExportJobData *job = static_cast<ExportJobData *>(MEM_mallocN(sizeof(ExportJobData), "ExportJobData"));
job->scene = scene;
job->bmain = CTX_data_main(C);
+ job->export_ok = false;
BLI_strncpy(job->filename, filepath, 1024);
/* Alright, alright, alright....
@@ -327,8 +332,8 @@ void ABC_export(
job->settings.scene = job->scene;
job->settings.frame_start = params->frame_start;
job->settings.frame_end = params->frame_end;
- job->settings.frame_step_xform = params->frame_step_xform;
- job->settings.frame_step_shape = params->frame_step_shape;
+ job->settings.frame_samples_xform = params->frame_samples_xform;
+ job->settings.frame_samples_shape = params->frame_samples_shape;
job->settings.shutter_open = params->shutter_open;
job->settings.shutter_close = params->shutter_close;
job->settings.selected_only = params->selected_only;
@@ -336,6 +341,8 @@ void ABC_export(
job->settings.export_normals = params->normals;
job->settings.export_uvs = params->uvs;
job->settings.export_vcols = params->vcolors;
+ job->settings.export_hair = params->export_hair;
+ job->settings.export_particles = params->export_particles;
job->settings.apply_subdiv = params->apply_subdiv;
job->settings.flatten_hierarchy = params->flatten_hierarchy;
job->settings.visible_layers_only = params->visible_layers_only;
@@ -352,19 +359,35 @@ void ABC_export(
std::swap(job->settings.frame_start, job->settings.frame_end);
}
- wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
- CTX_wm_window(C),
- job->scene,
- "Alembic Export",
- WM_JOB_PROGRESS,
- WM_JOB_TYPE_ALEMBIC);
+ bool export_ok = false;
+ if (as_background_job) {
+ wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
+ CTX_wm_window(C),
+ job->scene,
+ "Alembic Export",
+ WM_JOB_PROGRESS,
+ WM_JOB_TYPE_ALEMBIC);
+
+ /* setup job */
+ WM_jobs_customdata_set(wm_job, job, MEM_freeN);
+ WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
+ WM_jobs_callbacks(wm_job, export_startjob, NULL, NULL, export_endjob);
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
+ }
+ else {
+ /* Fake a job context, so that we don't need NULL pointer checks while exporting. */
+ short stop = 0, do_update = 0;
+ float progress = 0.f;
+
+ export_startjob(job, &stop, &do_update, &progress);
+ export_endjob(job);
+ export_ok = job->export_ok;
- /* setup job */
- WM_jobs_customdata_set(wm_job, job, MEM_freeN);
- WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
- WM_jobs_callbacks(wm_job, export_startjob, NULL, NULL, export_endjob);
+ MEM_freeN(job);
+ }
- WM_jobs_start(CTX_wm_manager(C), wm_job);
+ return export_ok;
}
/* ********************** Import file ********************** */
@@ -429,7 +452,8 @@ static std::pair<bool, AbcObjectReader *> visit_object(
else {
if (child_claims_this_object) {
claiming_child_readers.push_back(child_reader);
- } else {
+ }
+ else {
nonclaiming_child_readers.push_back(child_reader);
}
}
@@ -523,7 +547,7 @@ static std::pair<bool, AbcObjectReader *> visit_object(
AlembicObjectPath *abc_path = static_cast<AlembicObjectPath *>(
MEM_callocN(sizeof(AlembicObjectPath), "AlembicObjectPath"));
- BLI_strncpy(abc_path->path, full_name.c_str(), PATH_MAX);
+ BLI_strncpy(abc_path->path, full_name.c_str(), sizeof(abc_path->path));
BLI_addtail(&settings.cache_file->object_paths, abc_path);
/* We can now assign this reader as parent for our children. */
@@ -576,6 +600,7 @@ static std::pair<bool, AbcObjectReader *> visit_object(
enum {
ABC_NO_ERROR = 0,
ABC_ARCHIVE_FAIL,
+ ABC_UNSUPPORTED_HDF5,
};
struct ImportJobData {
@@ -593,6 +618,7 @@ struct ImportJobData {
char error_code;
bool was_cancelled;
+ bool import_ok;
};
ABC_INLINE bool is_mesh_and_strands(const IObject &object)
@@ -639,8 +665,12 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
ArchiveReader *archive = new ArchiveReader(data->filename);
if (!archive->valid()) {
- delete archive;
+#ifndef WITH_ALEMBIC_HDF5
+ data->error_code = archive->is_hdf5() ? ABC_UNSUPPORTED_HDF5 : ABC_ARCHIVE_FAIL;
+#else
data->error_code = ABC_ARCHIVE_FAIL;
+#endif
+ delete archive;
return;
}
@@ -684,12 +714,13 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
chrono_t min_time = std::numeric_limits<chrono_t>::max();
chrono_t max_time = std::numeric_limits<chrono_t>::min();
+ ISampleSelector sample_sel(0.0f);
std::vector<AbcObjectReader *>::iterator iter;
for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
AbcObjectReader *reader = *iter;
if (reader->valid()) {
- reader->readObjectData(data->bmain, 0.0f);
+ reader->readObjectData(data->bmain, sample_sel);
min_time = std::min(min_time, reader->minTime());
max_time = std::max(max_time, reader->maxTime());
@@ -712,13 +743,13 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
Scene *scene = data->scene;
if (data->settings.is_sequence) {
- SFRA = data->settings.offset;
+ SFRA = data->settings.sequence_offset;
EFRA = SFRA + (data->settings.sequence_len - 1);
CFRA = SFRA;
}
else if (min_time < max_time) {
- SFRA = static_cast<int>(min_time * FPS);
- EFRA = static_cast<int>(max_time * FPS);
+ SFRA = static_cast<int>(round(min_time * FPS));
+ EFRA = static_cast<int>(round(max_time * FPS));
CFRA = SFRA;
}
}
@@ -729,7 +760,7 @@ static void import_startjob(void *user_data, short *stop, short *do_update, floa
const AbcObjectReader *parent_reader = reader->parent_reader;
Object *ob = reader->object();
- if (parent_reader == NULL) {
+ if (parent_reader == NULL || !reader->inherits_xform()) {
ob->parent = NULL;
}
else {
@@ -775,13 +806,16 @@ static void import_endjob(void *user_data)
}
else {
/* Add object to scene. */
+ Base *base;
+
BKE_scene_base_deselect_all(data->scene);
for (iter = data->readers.begin(); iter != data->readers.end(); ++iter) {
Object *ob = (*iter)->object();
ob->lay = data->scene->lay;
- BKE_scene_base_add(data->scene, ob);
+ base = BKE_scene_base_add(data->scene, ob);
+ BKE_scene_base_select(data->scene, base);
DAG_id_tag_update_ex(data->bmain, &ob->id, OB_RECALC_OB | OB_RECALC_DATA | OB_RECALC_TIME);
}
@@ -801,10 +835,14 @@ static void import_endjob(void *user_data)
switch (data->error_code) {
default:
case ABC_NO_ERROR:
+ data->import_ok = !data->was_cancelled;
break;
case ABC_ARCHIVE_FAIL:
WM_report(RPT_ERROR, "Could not open Alembic archive for reading! See console for detail.");
break;
+ case ABC_UNSUPPORTED_HDF5:
+ WM_report(RPT_ERROR, "Alembic archive in obsolete HDF5 format is not supported.");
+ break;
}
WM_main_add_notifier(NC_SCENE | ND_FRAME, data->scene);
@@ -816,39 +854,58 @@ static void import_freejob(void *user_data)
delete data;
}
-void ABC_import(bContext *C, const char *filepath, float scale, bool is_sequence, bool set_frame_range, int sequence_len, int offset, bool validate_meshes)
+bool ABC_import(bContext *C, const char *filepath, float scale, bool is_sequence,
+ bool set_frame_range, int sequence_len, int offset,
+ bool validate_meshes, bool as_background_job)
{
/* Using new here since MEM_* funcs do not call ctor to properly initialize
* data. */
ImportJobData *job = new ImportJobData();
job->bmain = CTX_data_main(C);
job->scene = CTX_data_scene(C);
+ job->import_ok = false;
BLI_strncpy(job->filename, filepath, 1024);
job->settings.scale = scale;
job->settings.is_sequence = is_sequence;
job->settings.set_frame_range = set_frame_range;
job->settings.sequence_len = sequence_len;
- job->settings.offset = offset;
+ job->settings.sequence_offset = offset;
job->settings.validate_meshes = validate_meshes;
job->error_code = ABC_NO_ERROR;
job->was_cancelled = false;
G.is_break = false;
- wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
- CTX_wm_window(C),
- job->scene,
- "Alembic Import",
- WM_JOB_PROGRESS,
- WM_JOB_TYPE_ALEMBIC);
+ bool import_ok = false;
+ if (as_background_job) {
+ wmJob *wm_job = WM_jobs_get(CTX_wm_manager(C),
+ CTX_wm_window(C),
+ job->scene,
+ "Alembic Import",
+ WM_JOB_PROGRESS,
+ WM_JOB_TYPE_ALEMBIC);
- /* setup job */
- WM_jobs_customdata_set(wm_job, job, import_freejob);
- WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
- WM_jobs_callbacks(wm_job, import_startjob, NULL, NULL, import_endjob);
+ /* setup job */
+ WM_jobs_customdata_set(wm_job, job, import_freejob);
+ WM_jobs_timer(wm_job, 0.1, NC_SCENE | ND_FRAME, NC_SCENE | ND_FRAME);
+ WM_jobs_callbacks(wm_job, import_startjob, NULL, NULL, import_endjob);
+
+ WM_jobs_start(CTX_wm_manager(C), wm_job);
+ }
+ else {
+ /* Fake a job context, so that we don't need NULL pointer checks while importing. */
+ short stop = 0, do_update = 0;
+ float progress = 0.f;
+
+ import_startjob(job, &stop, &do_update, &progress);
+ import_endjob(job);
+ import_ok = job->import_ok;
+
+ import_freejob(job);
+ }
- WM_jobs_start(CTX_wm_manager(C), wm_job);
+ return import_ok;
}
/* ************************************************************************** */
@@ -883,42 +940,15 @@ DerivedMesh *ABC_read_mesh(CacheReader *reader,
}
const ObjectHeader &header = iobject.getHeader();
-
- if (IPolyMesh::matches(header)) {
- if (ob->type != OB_MESH) {
- *err_str = "Object type mismatch: object path points to a mesh!";
- return NULL;
- }
-
- return abc_reader->read_derivedmesh(dm, time, read_flag, err_str);
- }
- else if (ISubD::matches(header)) {
- if (ob->type != OB_MESH) {
- *err_str = "Object type mismatch: object path points to a subdivision mesh!";
- return NULL;
- }
-
- return abc_reader->read_derivedmesh(dm, time, read_flag, err_str);
- }
- else if (IPoints::matches(header)) {
- if (ob->type != OB_MESH) {
- *err_str = "Object type mismatch: object path points to a point cloud (requires a mesh object)!";
- return NULL;
- }
-
- return abc_reader->read_derivedmesh(dm, time, read_flag, err_str);
- }
- else if (ICurves::matches(header)) {
- if (ob->type != OB_CURVE) {
- *err_str = "Object type mismatch: object path points to a curve!";
- return NULL;
- }
-
- return abc_reader->read_derivedmesh(dm, time, read_flag, err_str);
+ if (!abc_reader->accepts_object_type(header, ob, err_str)) {
+ /* err_str is set by acceptsObjectType() */
+ return NULL;
}
- *err_str = "Unsupported object type: verify object path"; // or poke developer
- return NULL;
+ /* kFloorIndex is used to be compatible with non-interpolating
+ * properties; they use the floor. */
+ ISampleSelector sample_sel(time, ISampleSelector::kFloorIndex);
+ return abc_reader->read_derivedmesh(dm, sample_sel, read_flag, err_str);
}
/* ************************************************************************** */
@@ -933,6 +963,12 @@ void CacheReader_free(CacheReader *reader)
}
}
+void CacheReader_incref(CacheReader *reader)
+{
+ AbcObjectReader *abc_reader = reinterpret_cast<AbcObjectReader *>(reader);
+ abc_reader->incref();
+}
+
CacheReader *CacheReader_open_alembic_object(AbcArchiveHandle *handle, CacheReader *reader, Object *object, const char *object_path)
{
if (object_path[0] == '\0') {
diff --git a/source/blender/blenfont/BLF_api.h b/source/blender/blenfont/BLF_api.h
index 1f38d64924c..8c8aef3de57 100644
--- a/source/blender/blenfont/BLF_api.h
+++ b/source/blender/blenfont/BLF_api.h
@@ -38,7 +38,7 @@ struct rctf;
struct ColorManagedDisplay;
struct ResultBLF;
-int BLF_init(int points, int dpi);
+int BLF_init(void);
void BLF_exit(void);
void BLF_default_dpi(int dpi);
void BLF_default_set(int fontid);
diff --git a/source/blender/blenfont/intern/blf.c b/source/blender/blenfont/intern/blf.c
index 132a0ec3808..5bd62980b6d 100644
--- a/source/blender/blenfont/intern/blf.c
+++ b/source/blender/blenfont/intern/blf.c
@@ -96,15 +96,16 @@ static FontBLF *blf_get(int fontid)
return NULL;
}
-int BLF_init(int points, int dpi)
+int BLF_init(void)
{
int i;
for (i = 0; i < BLF_MAX_FONT; i++)
global_font[i] = NULL;
- global_font_points = points;
- global_font_dpi = dpi;
+ global_font_points = 11;
+ global_font_dpi = 72;
+
return blf_font_init();
}
diff --git a/source/blender/blenfont/intern/blf_glyph.c b/source/blender/blenfont/intern/blf_glyph.c
index aa7d539538b..bbbabfb8ba2 100644
--- a/source/blender/blenfont/intern/blf_glyph.c
+++ b/source/blender/blenfont/intern/blf_glyph.c
@@ -135,6 +135,7 @@ void blf_glyph_cache_clear(FontBLF *font)
while ((gc = BLI_pophead(&font->cache))) {
blf_glyph_cache_free(gc);
}
+ font->glyph_cache = NULL;
}
void blf_glyph_cache_free(GlyphCacheBLF *gc)
diff --git a/source/blender/blenkernel/BKE_DerivedMesh.h b/source/blender/blenkernel/BKE_DerivedMesh.h
index 789bc8df7e5..63ff1149a68 100644
--- a/source/blender/blenkernel/BKE_DerivedMesh.h
+++ b/source/blender/blenkernel/BKE_DerivedMesh.h
@@ -201,7 +201,7 @@ struct DerivedMesh {
/* use for converting to BMesh which doesn't store bevel weight and edge crease by default */
char cd_flag;
- char tangent_mask; /* which tangent layers are calculated */
+ short tangent_mask; /* which tangent layers are calculated */
/** Calculate vert and face normals */
void (*calcNormals)(DerivedMesh *dm);
@@ -791,11 +791,13 @@ void DM_calc_tangents_names_from_gpu(
void DM_add_named_tangent_layer_for_uv(
CustomData *uv_data, CustomData *tan_data, int numLoopData,
const char *layer_name);
+
+#define DM_TANGENT_MASK_ORCO (1 << 9)
void DM_calc_loop_tangents_step_0(
const CustomData *loopData, bool calc_active_tangent,
const char (*tangent_names)[MAX_NAME], int tangent_names_count,
bool *rcalc_act, bool *rcalc_ren, int *ract_uv_n, int *rren_uv_n,
- char *ract_uv_name, char *rren_uv_name, char *rtangent_mask);
+ char *ract_uv_name, char *rren_uv_name, short *rtangent_mask);
void DM_calc_loop_tangents(
DerivedMesh *dm, bool calc_active_tangent, const char (*tangent_names)[MAX_NAME],
int tangent_names_count);
diff --git a/source/blender/blenkernel/BKE_action.h b/source/blender/blenkernel/BKE_action.h
index 6527ba7f94f..5db0c3c9130 100644
--- a/source/blender/blenkernel/BKE_action.h
+++ b/source/blender/blenkernel/BKE_action.h
@@ -58,7 +58,7 @@ extern "C" {
struct bAction *add_empty_action(struct Main *bmain, const char name[]);
/* Allocate a copy of the given Action and all its data */
-struct bAction *BKE_action_copy(struct Main *bmain, struct bAction *src);
+struct bAction *BKE_action_copy(struct Main *bmain, const struct bAction *src);
/* Deallocate all of the Action's data, but not the Action itself */
void BKE_action_free(struct bAction *act);
@@ -150,7 +150,7 @@ void BKE_pose_free_data_ex(struct bPose *pose, bool do_id_user);
void BKE_pose_free_data(struct bPose *pose);
void BKE_pose_free(struct bPose *pose);
void BKE_pose_free_ex(struct bPose *pose, bool do_id_user);
-void BKE_pose_copy_data(struct bPose **dst, struct bPose *src, const bool copy_constraints);
+void BKE_pose_copy_data(struct bPose **dst, const struct bPose *src, const bool copy_constraints);
void BKE_pose_channel_copy_data(struct bPoseChannel *pchan, const struct bPoseChannel *pchan_from);
struct bPoseChannel *BKE_pose_channel_find_name(const struct bPose *pose, const char *name);
struct bPoseChannel *BKE_pose_channel_active(struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_animsys.h b/source/blender/blenkernel/BKE_animsys.h
index a67e903877a..420ae4bb12d 100644
--- a/source/blender/blenkernel/BKE_animsys.h
+++ b/source/blender/blenkernel/BKE_animsys.h
@@ -89,12 +89,6 @@ typedef enum eAnimData_MergeCopy_Modes {
void BKE_animdata_merge_copy(struct ID *dst_id, struct ID *src_id, eAnimData_MergeCopy_Modes action_mode, bool fix_drivers);
-/* Make Local */
-void BKE_animdata_make_local(struct AnimData *adt);
-
-/* Re-Assign ID's */
-void BKE_animdata_relink(struct AnimData *adt);
-
/* ************************************* */
/* KeyingSets API */
diff --git a/source/blender/blenkernel/BKE_armature.h b/source/blender/blenkernel/BKE_armature.h
index 78d6f6c7cb9..6bfc8c918d6 100644
--- a/source/blender/blenkernel/BKE_armature.h
+++ b/source/blender/blenkernel/BKE_armature.h
@@ -77,7 +77,7 @@ int BKE_armature_bonelist_count(struct ListBase *lb);
void BKE_armature_bonelist_free(struct ListBase *lb);
void BKE_armature_free(struct bArmature *arm);
void BKE_armature_make_local(struct Main *bmain, struct bArmature *arm, const bool lib_local);
-struct bArmature *BKE_armature_copy(struct Main *bmain, struct bArmature *arm);
+struct bArmature *BKE_armature_copy(struct Main *bmain, const struct bArmature *arm);
/* Bounding box. */
struct BoundBox *BKE_armature_boundbox_get(struct Object *ob);
@@ -177,6 +177,7 @@ void BKE_pose_eval_bone(struct EvaluationContext *eval_ctx,
struct bPoseChannel *pchan);
void BKE_pose_constraints_evaluate(struct EvaluationContext *eval_ctx,
+ struct Scene *scene,
struct Object *ob,
struct bPoseChannel *pchan);
diff --git a/source/blender/blenkernel/BKE_blender.h b/source/blender/blenkernel/BKE_blender.h
index d55926ffb1e..ec0bfa6f5fa 100644
--- a/source/blender/blenkernel/BKE_blender.h
+++ b/source/blender/blenkernel/BKE_blender.h
@@ -50,7 +50,6 @@ void BKE_blender_version_string(
void BKE_blender_userdef_set_data(struct UserDef *userdef);
void BKE_blender_userdef_free_data(struct UserDef *userdef);
-void BKE_blender_userdef_refresh(void);
void BKE_blender_userdef_set_app_template(struct UserDef *userdef);
diff --git a/source/blender/blenkernel/BKE_blender_version.h b/source/blender/blenkernel/BKE_blender_version.h
index 4f4787f9da5..207631d36bd 100644
--- a/source/blender/blenkernel/BKE_blender_version.h
+++ b/source/blender/blenkernel/BKE_blender_version.h
@@ -28,7 +28,7 @@
* and keep comment above the defines.
* Use STRINGIFY() rather than defining with quotes */
#define BLENDER_VERSION 278
-#define BLENDER_SUBVERSION 4
+#define BLENDER_SUBVERSION 5
/* Several breakages with 270, e.g. constraint deg vs rad */
#define BLENDER_MINVERSION 270
#define BLENDER_MINSUBVERSION 6
diff --git a/source/blender/blenkernel/BKE_boids.h b/source/blender/blenkernel/BKE_boids.h
index 582cd0cef8d..24f19951efe 100644
--- a/source/blender/blenkernel/BKE_boids.h
+++ b/source/blender/blenkernel/BKE_boids.h
@@ -61,6 +61,6 @@ BoidRule *boid_new_rule(int type);
BoidState *boid_new_state(BoidSettings *boids);
BoidState *boid_duplicate_state(BoidSettings *boids, BoidState *state);
void boid_free_settings(BoidSettings *boids);
-BoidSettings *boid_copy_settings(BoidSettings *boids);
+BoidSettings *boid_copy_settings(const BoidSettings *boids);
BoidState *boid_get_current_state(BoidSettings *boids);
#endif
diff --git a/source/blender/blenkernel/BKE_brush.h b/source/blender/blenkernel/BKE_brush.h
index 8bd4bdf89e1..42e4e73f2d5 100644
--- a/source/blender/blenkernel/BKE_brush.h
+++ b/source/blender/blenkernel/BKE_brush.h
@@ -44,7 +44,7 @@ void BKE_brush_system_exit(void);
void BKE_brush_init(struct Brush *brush);
struct Brush *BKE_brush_add(struct Main *bmain, const char *name, short ob_mode);
struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode);
-struct Brush *BKE_brush_copy(struct Main *bmain, struct Brush *brush);
+struct Brush *BKE_brush_copy(struct Main *bmain, const struct Brush *brush);
void BKE_brush_make_local(struct Main *bmain, struct Brush *brush, const bool lib_local);
void BKE_brush_unlink(struct Main *bmain, struct Brush *brush);
void BKE_brush_free(struct Brush *brush);
diff --git a/source/blender/blenkernel/BKE_cachefile.h b/source/blender/blenkernel/BKE_cachefile.h
index 0d4ed2083b1..f1e643c4a19 100644
--- a/source/blender/blenkernel/BKE_cachefile.h
+++ b/source/blender/blenkernel/BKE_cachefile.h
@@ -47,7 +47,7 @@ void BKE_cachefile_init(struct CacheFile *cache_file);
void BKE_cachefile_free(struct CacheFile *cache_file);
-struct CacheFile *BKE_cachefile_copy(struct Main *bmain, struct CacheFile *cache_file);
+struct CacheFile *BKE_cachefile_copy(struct Main *bmain, const struct CacheFile *cache_file);
void BKE_cachefile_make_local(struct Main *bmain, struct CacheFile *cache_file, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_camera.h b/source/blender/blenkernel/BKE_camera.h
index 31a732cf7e5..b2f22aacb28 100644
--- a/source/blender/blenkernel/BKE_camera.h
+++ b/source/blender/blenkernel/BKE_camera.h
@@ -52,7 +52,7 @@ struct GPUFXSettings;
void BKE_camera_init(struct Camera *cam);
void *BKE_camera_add(struct Main *bmain, const char *name);
-struct Camera *BKE_camera_copy(struct Main *bmain, struct Camera *cam);
+struct Camera *BKE_camera_copy(struct Main *bmain, const struct Camera *cam);
void BKE_camera_make_local(struct Main *bmain, struct Camera *cam, const bool lib_local);
void BKE_camera_free(struct Camera *ca);
diff --git a/source/blender/blenkernel/BKE_colortools.h b/source/blender/blenkernel/BKE_colortools.h
index 5b4f5910821..f68c4a2757b 100644
--- a/source/blender/blenkernel/BKE_colortools.h
+++ b/source/blender/blenkernel/BKE_colortools.h
@@ -46,8 +46,8 @@ void curvemapping_set_defaults(struct CurveMapping *cumap, int to
struct CurveMapping *curvemapping_add(int tot, float minx, float miny, float maxx, float maxy);
void curvemapping_free_data(struct CurveMapping *cumap);
void curvemapping_free(struct CurveMapping *cumap);
-void curvemapping_copy_data(struct CurveMapping *target, struct CurveMapping *cumap);
-struct CurveMapping *curvemapping_copy(struct CurveMapping *cumap);
+void curvemapping_copy_data(struct CurveMapping *target, const struct CurveMapping *cumap);
+struct CurveMapping *curvemapping_copy(const struct CurveMapping *cumap);
void curvemapping_set_black_white_ex(const float black[3], const float white[3], float r_bwmul[3]);
void curvemapping_set_black_white(struct CurveMapping *cumap, const float black[3], const float white[3]);
diff --git a/source/blender/blenkernel/BKE_curve.h b/source/blender/blenkernel/BKE_curve.h
index e111bd0e16b..635e999dd95 100644
--- a/source/blender/blenkernel/BKE_curve.h
+++ b/source/blender/blenkernel/BKE_curve.h
@@ -78,7 +78,7 @@ void BKE_curve_free(struct Curve *cu);
void BKE_curve_editfont_free(struct Curve *cu);
void BKE_curve_init(struct Curve *cu);
struct Curve *BKE_curve_add(struct Main *bmain, const char *name, int type);
-struct Curve *BKE_curve_copy(struct Main *bmain, struct Curve *cu);
+struct Curve *BKE_curve_copy(struct Main *bmain, const struct Curve *cu);
void BKE_curve_make_local(struct Main *bmain, struct Curve *cu, const bool lib_local);
short BKE_curve_type_get(struct Curve *cu);
void BKE_curve_type_test(struct Object *ob);
@@ -142,7 +142,7 @@ int BKE_nurbList_verts_count(struct ListBase *nurb);
int BKE_nurbList_verts_count_without_handles(struct ListBase *nurb);
void BKE_nurbList_free(struct ListBase *lb);
-void BKE_nurbList_duplicate(struct ListBase *lb1, struct ListBase *lb2);
+void BKE_nurbList_duplicate(struct ListBase *lb1, const struct ListBase *lb2);
void BKE_nurbList_handles_set(struct ListBase *editnurb, const char code);
void BKE_nurbList_handles_recalculate(struct ListBase *editnurb, const bool calc_length, const char flag);
@@ -150,7 +150,7 @@ void BKE_nurbList_handles_autocalc(ListBase *editnurb, int flag);
void BKE_nurbList_flag_set(ListBase *editnurb, short flag);
void BKE_nurb_free(struct Nurb *nu);
-struct Nurb *BKE_nurb_duplicate(struct Nurb *nu);
+struct Nurb *BKE_nurb_duplicate(const struct Nurb *nu);
struct Nurb *BKE_nurb_copy(struct Nurb *src, int pntsu, int pntsv);
void BKE_nurb_test2D(struct Nurb *nu);
@@ -198,6 +198,7 @@ void BKE_nurb_bezt_calc_normal(struct Nurb *nu, struct BezTriple *bezt, float r_
void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_plane[3]);
void BKE_nurb_bpoint_calc_normal(struct Nurb *nu, struct BPoint *bp, float r_normal[3]);
+void BKE_nurb_bpoint_calc_plane(struct Nurb *nu, struct BPoint *bp, float r_plane[3]);
void BKE_nurb_handle_calc(struct BezTriple *bezt, struct BezTriple *prev, struct BezTriple *next,
const bool is_fcurve);
diff --git a/source/blender/blenkernel/BKE_deform.h b/source/blender/blenkernel/BKE_deform.h
index 3ce08a14177..a20c5a4240c 100644
--- a/source/blender/blenkernel/BKE_deform.h
+++ b/source/blender/blenkernel/BKE_deform.h
@@ -44,8 +44,8 @@ struct MLoop;
struct MPoly;
struct bDeformGroup *BKE_defgroup_new(struct Object *ob, const char *name);
-void defgroup_copy_list(struct ListBase *lb1, struct ListBase *lb2);
-struct bDeformGroup *defgroup_duplicate(struct bDeformGroup *ingroup);
+void defgroup_copy_list(struct ListBase *lb1, const struct ListBase *lb2);
+struct bDeformGroup *defgroup_duplicate(const struct bDeformGroup *ingroup);
struct bDeformGroup *defgroup_find_name(struct Object *ob, const char *name);
int *defgroup_flip_map(struct Object *ob, int *flip_map_len, const bool use_default);
int *defgroup_flip_map_single(struct Object *ob, int *flip_map_len, const bool use_default, int defgroup);
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index 3a45097efc5..b38f1299763 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -92,7 +92,7 @@ void bezt_add_to_cfra_elem(ListBase *lb, struct BezTriple *bezt);
/* ---------------------- */
void fcurve_free_driver(struct FCurve *fcu);
-struct ChannelDriver *fcurve_copy_driver(struct ChannelDriver *driver);
+struct ChannelDriver *fcurve_copy_driver(const struct ChannelDriver *driver);
void driver_variables_copy(struct ListBase *dst_list, const struct ListBase *src_list);
@@ -138,7 +138,7 @@ typedef struct FModifierTypeInfo {
/* free any data that is allocated separately (optional) */
void (*free_data)(struct FModifier *fcm);
/* copy any special data that is allocated separately (optional) */
- void (*copy_data)(struct FModifier *fcm, struct FModifier *src);
+ void (*copy_data)(struct FModifier *fcm, const struct FModifier *src);
/* set settings for data that will be used for FCuModifier.data (memory already allocated using MEM_callocN) */
void (*new_data)(void *mdata);
/* verifies that the modifier settings are valid */
@@ -183,14 +183,14 @@ typedef enum eFMI_Requirement_Flags {
} eFMI_Requirement_Flags;
/* Function Prototypes for FModifierTypeInfo's */
-const FModifierTypeInfo *fmodifier_get_typeinfo(struct FModifier *fcm);
-const FModifierTypeInfo *get_fmodifier_typeinfo(int type);
+const FModifierTypeInfo *fmodifier_get_typeinfo(const struct FModifier *fcm);
+const FModifierTypeInfo *get_fmodifier_typeinfo(const int type);
/* ---------------------- */
struct FModifier *add_fmodifier(ListBase *modifiers, int type);
-struct FModifier *copy_fmodifier(struct FModifier *src);
-void copy_fmodifiers(ListBase *dst, ListBase *src);
+struct FModifier *copy_fmodifier(const struct FModifier *src);
+void copy_fmodifiers(ListBase *dst, const ListBase *src);
bool remove_fmodifier(ListBase *modifiers, struct FModifier *fcm);
void free_fmodifiers(ListBase *modifiers);
@@ -216,7 +216,7 @@ int BKE_fcm_envelope_find_index(struct FCM_EnvelopeData *array, float frame, int
/* -------- Data Management -------- */
void free_fcurve(struct FCurve *fcu);
-struct FCurve *copy_fcurve(struct FCurve *fcu);
+struct FCurve *copy_fcurve(const struct FCurve *fcu);
void free_fcurves(ListBase *list);
void copy_fcurves(ListBase *dst, ListBase *src);
diff --git a/source/blender/blenkernel/BKE_font.h b/source/blender/blenkernel/BKE_font.h
index 6775639125f..e7ae0f606e7 100644
--- a/source/blender/blenkernel/BKE_font.h
+++ b/source/blender/blenkernel/BKE_font.h
@@ -60,8 +60,9 @@ typedef struct EditFont {
struct CharInfo *textbufinfo;
/* array of rectangles & rotation */
- EditFontSelBox *selboxes;
float textcurs[4][2];
+ EditFontSelBox *selboxes;
+ int selboxes_len;
/* positional vars relative to the textbuf, textbufinfo (not utf8 bytes)
* a copy of these is kept in Curve, but use these in editmode */
diff --git a/source/blender/blenkernel/BKE_global.h b/source/blender/blenkernel/BKE_global.h
index 4bb2b950901..830518906ab 100644
--- a/source/blender/blenkernel/BKE_global.h
+++ b/source/blender/blenkernel/BKE_global.h
@@ -189,11 +189,6 @@ enum {
# error Either __BIG_ENDIAN__ or __LITTLE_ENDIAN__ must be defined.
#endif
-/* there is really no good place for this */
-#if defined(FREE_WINDOWS) && ((__GNUC__ < 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ < 6)))
-# error "Mingw requires GCC 4.6 minimum"
-#endif
-
#define L_ENDIAN 1
#define B_ENDIAN 0
diff --git a/source/blender/blenkernel/BKE_gpencil.h b/source/blender/blenkernel/BKE_gpencil.h
index 3378f4acc60..bdd28baf137 100644
--- a/source/blender/blenkernel/BKE_gpencil.h
+++ b/source/blender/blenkernel/BKE_gpencil.h
@@ -60,7 +60,7 @@ struct bGPdata *BKE_gpencil_data_addnew(const char name[]);
struct bGPDframe *BKE_gpencil_frame_duplicate(const struct bGPDframe *gpf_src);
struct bGPDlayer *BKE_gpencil_layer_duplicate(const struct bGPDlayer *gpl_src);
-struct bGPdata *BKE_gpencil_data_duplicate(struct Main *bmain, struct bGPdata *gpd, bool internal_copy);
+struct bGPdata *BKE_gpencil_data_duplicate(struct Main *bmain, const struct bGPdata *gpd, bool internal_copy);
void BKE_gpencil_make_local(struct Main *bmain, struct bGPdata *gpd, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_group.h b/source/blender/blenkernel/BKE_group.h
index 09a069ee36f..684251c9561 100644
--- a/source/blender/blenkernel/BKE_group.h
+++ b/source/blender/blenkernel/BKE_group.h
@@ -42,7 +42,7 @@ struct Scene;
void BKE_group_free(struct Group *group);
struct Group *BKE_group_add(struct Main *bmain, const char *name);
-struct Group *BKE_group_copy(struct Main *bmain, struct Group *group);
+struct Group *BKE_group_copy(struct Main *bmain, const struct Group *group);
void BKE_group_make_local(struct Main *bmain, struct Group *group, const bool lib_local);
bool BKE_group_object_add(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
bool BKE_group_object_unlink(struct Group *group, struct Object *ob, struct Scene *scene, struct Base *base);
diff --git a/source/blender/blenkernel/BKE_icons.h b/source/blender/blenkernel/BKE_icons.h
index 6944c5ccd28..39e6b145755 100644
--- a/source/blender/blenkernel/BKE_icons.h
+++ b/source/blender/blenkernel/BKE_icons.h
@@ -88,7 +88,7 @@ void BKE_previewimg_clear(struct PreviewImage *prv);
void BKE_previewimg_clear_single(struct PreviewImage *prv, enum eIconSizes size);
/* get the preview from any pointer */
-struct PreviewImage **BKE_previewimg_id_get_p(struct ID *id);
+struct PreviewImage **BKE_previewimg_id_get_p(const struct ID *id);
/* free the preview image belonging to the id */
void BKE_previewimg_id_free(struct ID *id);
@@ -97,9 +97,9 @@ void BKE_previewimg_id_free(struct ID *id);
struct PreviewImage *BKE_previewimg_create(void);
/* create a copy of the preview image */
-struct PreviewImage *BKE_previewimg_copy(struct PreviewImage *prv);
+struct PreviewImage *BKE_previewimg_copy(const struct PreviewImage *prv);
-void BKE_previewimg_id_copy(struct ID *new_id, struct ID *old_id);
+void BKE_previewimg_id_copy(struct ID *new_id, const struct ID *old_id);
/* retrieve existing or create new preview image */
struct PreviewImage *BKE_previewimg_id_ensure(struct ID *id);
diff --git a/source/blender/blenkernel/BKE_idprop.h b/source/blender/blenkernel/BKE_idprop.h
index 5b10d7ebc06..ab8728faedb 100644
--- a/source/blender/blenkernel/BKE_idprop.h
+++ b/source/blender/blenkernel/BKE_idprop.h
@@ -60,8 +60,6 @@ typedef union IDPropertyTemplate {
IDProperty *IDP_NewIDPArray(const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
IDProperty *IDP_CopyIDPArray(const IDProperty *array) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-void IDP_FreeIDPArray(IDProperty *prop);
-
/* shallow copies item */
void IDP_SetIndexArray(struct IDProperty *prop, int index, struct IDProperty *item) ATTR_NONNULL();
struct IDProperty *IDP_GetIndexArray(struct IDProperty *prop, int index) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
@@ -81,8 +79,8 @@ void IDP_ConcatString(struct IDProperty *str1, struct IDProperty *append) ATTR_N
void IDP_FreeString(struct IDProperty *prop) ATTR_NONNULL();
/*-------- ID Type -------*/
-void IDP_LinkID(struct IDProperty *prop, ID *id);
-void IDP_UnlinkID(struct IDProperty *prop);
+
+typedef void(*IDPWalkFunc)(void *userData, IDProperty *idp);
/*-------- Group Functions -------*/
@@ -112,11 +110,12 @@ bool IDP_EqualsProperties(struct IDProperty *prop1, struct IDProperty *prop2) AT
struct IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void IDP_FreeProperty_ex(struct IDProperty *prop, const bool do_id_user);
void IDP_FreeProperty(struct IDProperty *prop);
void IDP_ClearProperty(IDProperty *prop);
-void IDP_UnlinkProperty(struct IDProperty *prop);
+void IDP_RelinkProperty(struct IDProperty *prop);
#define IDP_Int(prop) ((prop)->data.val)
#define IDP_Array(prop) ((prop)->data.pointer)
@@ -134,11 +133,15 @@ void IDP_UnlinkProperty(struct IDProperty *prop);
# define IDP_IDPArray(prop) _Generic((prop), \
IDProperty *: ((IDProperty *) (prop)->data.pointer), \
const IDProperty *: ((const IDProperty *) (prop)->data.pointer))
+# define IDP_Id(prop) _Generic((prop), \
+ IDProperty *: ((ID *) (prop)->data.pointer), \
+ const IDProperty *: ((const ID *) (prop)->data.pointer))
#else
# define IDP_Float(prop) (*(float *)&(prop)->data.val)
# define IDP_Double(prop) (*(double *)&(prop)->data.val)
# define IDP_String(prop) ((char *) (prop)->data.pointer)
# define IDP_IDPArray(prop) ((IDProperty *) (prop)->data.pointer)
+# define IDP_Id(prop) ((ID *) (prop)->data.pointer)
#endif
#ifndef NDEBUG
diff --git a/source/blender/blenkernel/BKE_image.h b/source/blender/blenkernel/BKE_image.h
index 132c73209d1..e155b0719cc 100644
--- a/source/blender/blenkernel/BKE_image.h
+++ b/source/blender/blenkernel/BKE_image.h
@@ -250,7 +250,7 @@ void BKE_image_packfiles_from_mem(struct ReportList *reports, struct Image *ima,
void BKE_image_print_memlist(void);
/* empty image block, of similar type and filename */
-struct Image *BKE_image_copy(struct Main *bmain, struct Image *ima);
+struct Image *BKE_image_copy(struct Main *bmain, const struct Image *ima);
/* merge source into dest, and free source */
void BKE_image_merge(struct Image *dest, struct Image *source);
diff --git a/source/blender/blenkernel/BKE_key.h b/source/blender/blenkernel/BKE_key.h
index e590ff148d7..94e8a24fbc5 100644
--- a/source/blender/blenkernel/BKE_key.h
+++ b/source/blender/blenkernel/BKE_key.h
@@ -51,7 +51,7 @@ extern "C" {
void BKE_key_free(struct Key *sc);
void BKE_key_free_nolib(struct Key *key);
struct Key *BKE_key_add(struct ID *id);
-struct Key *BKE_key_copy(struct Main *bmain, struct Key *key);
+struct Key *BKE_key_copy(struct Main *bmain, const struct Key *key);
struct Key *BKE_key_copy_nolib(struct Key *key);
void BKE_key_sort(struct Key *key);
diff --git a/source/blender/blenkernel/BKE_lamp.h b/source/blender/blenkernel/BKE_lamp.h
index 4d53850c572..713ca80fb1a 100644
--- a/source/blender/blenkernel/BKE_lamp.h
+++ b/source/blender/blenkernel/BKE_lamp.h
@@ -44,7 +44,7 @@ struct Scene;
void BKE_lamp_init(struct Lamp *la);
struct Lamp *BKE_lamp_add(struct Main *bmain, const char *name) ATTR_WARN_UNUSED_RESULT;
-struct Lamp *BKE_lamp_copy(struct Main *bmain, struct Lamp *la) ATTR_WARN_UNUSED_RESULT;
+struct Lamp *BKE_lamp_copy(struct Main *bmain, const struct Lamp *la) ATTR_WARN_UNUSED_RESULT;
struct Lamp *localize_lamp(struct Lamp *la) ATTR_WARN_UNUSED_RESULT;
void BKE_lamp_make_local(struct Main *bmain, struct Lamp *la, const bool lib_local);
void BKE_lamp_free(struct Lamp *la);
diff --git a/source/blender/blenkernel/BKE_lattice.h b/source/blender/blenkernel/BKE_lattice.h
index 226c82da295..ec1cf79832d 100644
--- a/source/blender/blenkernel/BKE_lattice.h
+++ b/source/blender/blenkernel/BKE_lattice.h
@@ -47,7 +47,7 @@ struct MDeformVert;
void BKE_lattice_resize(struct Lattice *lt, int u, int v, int w, struct Object *ltOb);
void BKE_lattice_init(struct Lattice *lt);
struct Lattice *BKE_lattice_add(struct Main *bmain, const char *name);
-struct Lattice *BKE_lattice_copy(struct Main *bmain, struct Lattice *lt);
+struct Lattice *BKE_lattice_copy(struct Main *bmain, const struct Lattice *lt);
void BKE_lattice_free(struct Lattice *lt);
void BKE_lattice_make_local(struct Main *bmain, struct Lattice *lt, const bool lib_local);
void calc_lat_fudu(int flag, int res, float *r_fu, float *r_du);
diff --git a/source/blender/blenkernel/BKE_library.h b/source/blender/blenkernel/BKE_library.h
index 72ae2cf4efa..258dcc84449 100644
--- a/source/blender/blenkernel/BKE_library.h
+++ b/source/blender/blenkernel/BKE_library.h
@@ -50,11 +50,12 @@ struct bContext;
struct PointerRNA;
struct PropertyRNA;
+size_t BKE_libblock_get_alloc_info(short type, const char **name);
void *BKE_libblock_alloc_notest(short type);
void *BKE_libblock_alloc(struct Main *bmain, short type, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
void BKE_libblock_init_empty(struct ID *id);
-void *BKE_libblock_copy(struct Main *bmain, struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-void *BKE_libblock_copy_nolib(struct ID *id, const bool do_action) ATTR_NONNULL();
+void *BKE_libblock_copy(struct Main *bmain, const struct ID *id) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+void *BKE_libblock_copy_nolib(const struct ID *id, const bool do_action) ATTR_NONNULL();
void BKE_libblock_copy_data(struct ID *id, const struct ID *id_from, const bool do_action);
void BKE_libblock_rename(struct Main *bmain, struct ID *id, const char *name) ATTR_NONNULL();
void BLI_libblock_ensure_unique_name(struct Main *bmain, const char *name) ATTR_NONNULL();
@@ -64,9 +65,10 @@ struct ID *BKE_libblock_find_name(const short type, const char *name) ATTR_WARN_
/* library_remap.c (keep here since they're general functions) */
void BKE_libblock_free(struct Main *bmain, void *idv) ATTR_NONNULL();
+void BKE_libblock_free_datablock(struct ID *id) ATTR_NONNULL();
void BKE_libblock_free_ex(struct Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user) ATTR_NONNULL();
void BKE_libblock_free_us(struct Main *bmain, void *idv) ATTR_NONNULL();
-void BKE_libblock_free_data(struct Main *bmain, struct ID *id) ATTR_NONNULL();
+void BKE_libblock_free_data(struct ID *id, const bool do_id_user) ATTR_NONNULL();
void BKE_libblock_delete(struct Main *bmain, void *idv) ATTR_NONNULL();
void BKE_id_lib_local_paths(struct Main *bmain, struct Library *lib, struct ID *id);
@@ -84,10 +86,10 @@ void BKE_id_clear_newpoin(struct ID *id);
void BKE_id_make_local_generic(struct Main *bmain, struct ID *id, const bool id_in_mainlist, const bool lib_local);
bool id_make_local(struct Main *bmain, struct ID *id, const bool test, const bool force_local);
bool id_single_user(struct bContext *C, struct ID *id, struct PointerRNA *ptr, struct PropertyRNA *prop);
-bool id_copy(struct Main *bmain, struct ID *id, struct ID **newid, bool test);
+bool id_copy(struct Main *bmain, const struct ID *id, struct ID **newid, bool test);
void id_sort_by_name(struct ListBase *lb, struct ID *id);
void BKE_id_expand_local(struct Main *bmain, struct ID *id);
-void BKE_id_copy_ensure_local(struct Main *bmain, struct ID *old_id, struct ID *new_id);
+void BKE_id_copy_ensure_local(struct Main *bmain, const struct ID *old_id, struct ID *new_id);
bool new_id(struct ListBase *lb, struct ID *id, const char *name);
void id_clear_lib_data(struct Main *bmain, struct ID *id);
diff --git a/source/blender/blenkernel/BKE_library_query.h b/source/blender/blenkernel/BKE_library_query.h
index 1258e2fa72e..d6e7d98f371 100644
--- a/source/blender/blenkernel/BKE_library_query.h
+++ b/source/blender/blenkernel/BKE_library_query.h
@@ -51,6 +51,11 @@ enum {
* This means callback shall not *do* anything, only use this as informative data if it needs it. */
IDWALK_CB_PRIVATE = (1 << 3),
+ /** That ID is not really used by its owner, it's just an internal hint/helper.
+ * This addresses Their Highest Ugliness the 'from' pointers: Object->from_proxy and Key->from.
+ * How to handle that kind of cases totally depends on what caller code is doing... */
+ IDWALK_CB_LOOPBACK = (1 << 4),
+
/**
* Adjusts #ID.us reference-count.
* \note keep in sync with 'newlibadr_us' use in readfile.c
@@ -78,6 +83,8 @@ enum {
IDWALK_NOP = 0,
IDWALK_READONLY = (1 << 0),
IDWALK_RECURSE = (1 << 1), /* Also implies IDWALK_READONLY. */
+
+ IDWALK_NO_INDIRECT_PROXY_DATA_USAGE = (1 << 8), /* Ugly special case :(((( */
};
/* Loop over all of the ID's this datablock links to. */
@@ -87,7 +94,7 @@ void BKE_library_update_ID_link_user(struct ID *id_dst, struct ID *id_src, const
int BKE_library_ID_use_ID(struct ID *id_user, struct ID *id_used);
-bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id_type_used);
+bool BKE_library_id_can_use_idtype(struct ID *id_owner, const short id_type_used);
bool BKE_library_ID_is_locally_used(struct Main *bmain, void *idv);
bool BKE_library_ID_is_indirectly_used(struct Main *bmain, void *idv);
diff --git a/source/blender/blenkernel/BKE_library_remap.h b/source/blender/blenkernel/BKE_library_remap.h
index 53d438a0fdd..fd37fd762f4 100644
--- a/source/blender/blenkernel/BKE_library_remap.h
+++ b/source/blender/blenkernel/BKE_library_remap.h
@@ -46,6 +46,11 @@ enum {
/* This tells the callback func to force setting IDs using target one with a 'never NULL' pointer to NULL.
* WARNING! Use with extreme care, this will leave database in broken state and can cause crashes very easily! */
ID_REMAP_FORCE_NEVER_NULL_USAGE = 1 << 3,
+ /* Do not consider proxy/_group pointers of local objects as indirect usages...
+ * Our oh-so-beloved proxies again... Do not consider data used by local proxy object as indirect usage.
+ * This is needed e.g. in reload scenario, since we have to ensure remapping of Armature data of local proxy
+ * is also performed. Usual nightmare... */
+ ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE = 1 << 4,
};
/* Note: Requiring new_id to be non-null, this *may* not be the case ultimately, but makes things simpler for now. */
diff --git a/source/blender/blenkernel/BKE_linestyle.h b/source/blender/blenkernel/BKE_linestyle.h
index af9bf58ce77..c7b323d0f6e 100644
--- a/source/blender/blenkernel/BKE_linestyle.h
+++ b/source/blender/blenkernel/BKE_linestyle.h
@@ -52,7 +52,7 @@ struct bContext;
void BKE_linestyle_init(struct FreestyleLineStyle *linestyle);
FreestyleLineStyle *BKE_linestyle_new(struct Main *bmain, const char *name);
void BKE_linestyle_free(FreestyleLineStyle *linestyle);
-FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, FreestyleLineStyle *linestyle);
+FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, const FreestyleLineStyle *linestyle);
void BKE_linestyle_make_local(struct Main *bmain, struct FreestyleLineStyle *linestyle, const bool lib_local);
@@ -63,10 +63,10 @@ LineStyleModifier *BKE_linestyle_alpha_modifier_add(FreestyleLineStyle *linestyl
LineStyleModifier *BKE_linestyle_thickness_modifier_add(FreestyleLineStyle *linestyle, const char *name, int type);
LineStyleModifier *BKE_linestyle_geometry_modifier_add(FreestyleLineStyle *linestyle, const char *name, int type);
-LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m);
-LineStyleModifier *BKE_linestyle_alpha_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m);
-LineStyleModifier *BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m);
-LineStyleModifier *BKE_linestyle_geometry_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m);
+LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m);
+LineStyleModifier *BKE_linestyle_alpha_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m);
+LineStyleModifier *BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m);
+LineStyleModifier *BKE_linestyle_geometry_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m);
int BKE_linestyle_color_modifier_remove(FreestyleLineStyle *linestyle, LineStyleModifier *modifier);
int BKE_linestyle_alpha_modifier_remove(FreestyleLineStyle *linestyle, LineStyleModifier *modifier);
diff --git a/source/blender/blenkernel/BKE_mask.h b/source/blender/blenkernel/BKE_mask.h
index 3349bffac85..0735d2d97a1 100644
--- a/source/blender/blenkernel/BKE_mask.h
+++ b/source/blender/blenkernel/BKE_mask.h
@@ -77,14 +77,14 @@ void BKE_mask_layer_free(struct MaskLayer *masklay);
void BKE_mask_layer_free_list(struct ListBase *masklayers);
void BKE_mask_spline_free(struct MaskSpline *spline);
void BKE_mask_spline_free_list(struct ListBase *splines);
-struct MaskSpline *BKE_mask_spline_copy(struct MaskSpline *spline);
+struct MaskSpline *BKE_mask_spline_copy(const struct MaskSpline *spline);
void BKE_mask_point_free(struct MaskSplinePoint *point);
void BKE_mask_layer_unique_name(struct Mask *mask, struct MaskLayer *masklay);
void BKE_mask_layer_rename(struct Mask *mask, struct MaskLayer *masklay, char *oldname, char *newname);
-struct MaskLayer *BKE_mask_layer_copy(struct MaskLayer *layer);
-void BKE_mask_layer_copy_list(struct ListBase *masklayers_new, struct ListBase *masklayers);
+struct MaskLayer *BKE_mask_layer_copy(const struct MaskLayer *layer);
+void BKE_mask_layer_copy_list(struct ListBase *masklayers_new, const struct ListBase *masklayers);
/* splines */
struct MaskSpline *BKE_mask_spline_add(struct MaskLayer *masklay);
@@ -123,7 +123,7 @@ void BKE_mask_point_select_set_handle(struct MaskSplinePoint *point, const eMask
/* general */
struct Mask *BKE_mask_new(struct Main *bmain, const char *name);
struct Mask *BKE_mask_copy_nolib(struct Mask *mask);
-struct Mask *BKE_mask_copy(struct Main *bmain, struct Mask *mask);
+struct Mask *BKE_mask_copy(struct Main *bmain, const struct Mask *mask);
void BKE_mask_make_local(struct Main *bmain, struct Mask *mask, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_material.h b/source/blender/blenkernel/BKE_material.h
index 8ae5c2b3c45..7da962dd6d6 100644
--- a/source/blender/blenkernel/BKE_material.h
+++ b/source/blender/blenkernel/BKE_material.h
@@ -54,7 +54,7 @@ void BKE_material_init(struct Material *ma);
void BKE_material_remap_object(struct Object *ob, const unsigned int *remap);
void BKE_material_remap_object_calc(struct Object *ob_dst, struct Object *ob_src, short *remap_src_to_dst);
struct Material *BKE_material_add(struct Main *bmain, const char *name);
-struct Material *BKE_material_copy(struct Main *bmain, struct Material *ma);
+struct Material *BKE_material_copy(struct Main *bmain, const struct Material *ma);
struct Material *localize_material(struct Material *ma);
struct Material *give_node_material(struct Material *ma); /* returns node material or self */
void BKE_material_make_local(struct Main *bmain, struct Material *ma, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_mball.h b/source/blender/blenkernel/BKE_mball.h
index 64320a20281..c00a0743ebb 100644
--- a/source/blender/blenkernel/BKE_mball.h
+++ b/source/blender/blenkernel/BKE_mball.h
@@ -41,7 +41,7 @@ struct MetaElem;
void BKE_mball_free(struct MetaBall *mb);
void BKE_mball_init(struct MetaBall *mb);
struct MetaBall *BKE_mball_add(struct Main *bmain, const char *name);
-struct MetaBall *BKE_mball_copy(struct Main *bmain, struct MetaBall *mb);
+struct MetaBall *BKE_mball_copy(struct Main *bmain, const struct MetaBall *mb);
void BKE_mball_make_local(struct Main *bmain, struct MetaBall *mb, const bool lib_local);
diff --git a/source/blender/blenkernel/BKE_mesh.h b/source/blender/blenkernel/BKE_mesh.h
index b83bec5a302..b55b8b2dd3c 100644
--- a/source/blender/blenkernel/BKE_mesh.h
+++ b/source/blender/blenkernel/BKE_mesh.h
@@ -87,7 +87,7 @@ int BKE_mesh_edge_other_vert(const struct MEdge *e, int v);
void BKE_mesh_free(struct Mesh *me);
void BKE_mesh_init(struct Mesh *me);
struct Mesh *BKE_mesh_add(struct Main *bmain, const char *name);
-struct Mesh *BKE_mesh_copy(struct Main *bmain, struct Mesh *me);
+struct Mesh *BKE_mesh_copy(struct Main *bmain, const struct Mesh *me);
void BKE_mesh_update_customdata_pointers(struct Mesh *me, const bool do_ensure_tess_cd);
void BKE_mesh_ensure_skin_customdata(struct Mesh *me);
@@ -110,7 +110,8 @@ int BKE_mesh_nurbs_displist_to_mdata(
struct MEdge **r_alledge, int *r_totedge,
struct MLoop **r_allloop, struct MPoly **r_allpoly,
struct MLoopUV **r_alluv, int *r_totloop, int *r_totpoly);
-void BKE_mesh_from_nurbs_displist(struct Object *ob, struct ListBase *dispbase, const bool use_orco_uv);
+void BKE_mesh_from_nurbs_displist(
+ struct Object *ob, struct ListBase *dispbase, const bool use_orco_uv, const char *obdata_name);
void BKE_mesh_from_nurbs(struct Object *ob);
void BKE_mesh_to_curve_nurblist(struct DerivedMesh *dm, struct ListBase *nurblist, const int edge_users_test);
void BKE_mesh_to_curve(struct Scene *scene, struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_movieclip.h b/source/blender/blenkernel/BKE_movieclip.h
index 3237c146bc5..69fdad5ef7b 100644
--- a/source/blender/blenkernel/BKE_movieclip.h
+++ b/source/blender/blenkernel/BKE_movieclip.h
@@ -41,7 +41,7 @@ struct MovieDistortion;
void BKE_movieclip_free(struct MovieClip *clip);
-struct MovieClip *BKE_movieclip_copy(struct Main *bmain, struct MovieClip *clip);
+struct MovieClip *BKE_movieclip_copy(struct Main *bmain, const struct MovieClip *clip);
void BKE_movieclip_make_local(struct Main *bmain, struct MovieClip *clip, const bool lib_local);
struct MovieClip *BKE_movieclip_file_add(struct Main *bmain, const char *name);
diff --git a/source/blender/blenkernel/BKE_node.h b/source/blender/blenkernel/BKE_node.h
index 193f1154c54..d5279c5b0ce 100644
--- a/source/blender/blenkernel/BKE_node.h
+++ b/source/blender/blenkernel/BKE_node.h
@@ -335,8 +335,8 @@ struct bNodeTree *ntreeAddTree(struct Main *bmain, const char *name, const char
/* copy/free funcs, need to manage ID users */
void ntreeFreeTree(struct bNodeTree *ntree);
-struct bNodeTree *ntreeCopyTree_ex(struct bNodeTree *ntree, struct Main *bmain, const bool do_id_user);
-struct bNodeTree *ntreeCopyTree(struct Main *bmain, struct bNodeTree *ntree);
+struct bNodeTree *ntreeCopyTree_ex(const struct bNodeTree *ntree, struct Main *bmain, const bool do_id_user);
+struct bNodeTree *ntreeCopyTree(struct Main *bmain, const struct bNodeTree *ntree);
/* node->id user count */
void ntreeUserIncrefID(struct bNodeTree *ntree);
void ntreeUserDecrefID(struct bNodeTree *ntree);
@@ -785,6 +785,7 @@ struct ShadeResult;
#define SH_NODE_OUTPUT_LINESTYLE 190
#define SH_NODE_UVALONGSTROKE 191
#define SH_NODE_TEX_POINTDENSITY 192
+#define SH_NODE_BSDF_PRINCIPLED 193
/* custom defines options for Material node */
#define SH_NODE_MAT_DIFF 1
@@ -972,7 +973,8 @@ void ntreeCompositExecTree(struct Scene *scene, struct bNodeTree *ntree, struct
void ntreeCompositTagRender(struct Scene *sce);
int ntreeCompositTagAnimated(struct bNodeTree *ntree);
void ntreeCompositTagGenerators(struct bNodeTree *ntree);
-void ntreeCompositForceHidden(struct bNodeTree *ntree);
+void ntreeCompositUpdateRLayers(struct bNodeTree *ntree);
+void ntreeCompositRegisterPass(struct bNodeTree *ntree, struct Scene *scene, struct SceneRenderLayer *srl, const char *name, int type);
void ntreeCompositClearTags(struct bNodeTree *ntree);
struct bNodeSocket *ntreeCompositOutputFileAddSocket(struct bNodeTree *ntree, struct bNode *node,
diff --git a/source/blender/blenkernel/BKE_object.h b/source/blender/blenkernel/BKE_object.h
index b6633ea6198..0a5035f9a9b 100644
--- a/source/blender/blenkernel/BKE_object.h
+++ b/source/blender/blenkernel/BKE_object.h
@@ -54,7 +54,7 @@ void BKE_object_workob_calc_parent(struct Scene *scene, struct Object *ob, struc
void BKE_object_transform_copy(struct Object *ob_tar, const struct Object *ob_src);
struct SoftBody *copy_softbody(const struct SoftBody *sb, bool copy_caches);
-struct BulletSoftBody *copy_bulletsoftbody(struct BulletSoftBody *sb);
+struct BulletSoftBody *copy_bulletsoftbody(const struct BulletSoftBody *sb);
struct ParticleSystem *BKE_object_copy_particlesystem(struct ParticleSystem *psys);
void BKE_object_copy_particlesystems(struct Object *ob_dst, const struct Object *ob_src);
void BKE_object_copy_softbody(struct Object *ob_dst, const struct Object *ob_src);
@@ -105,8 +105,8 @@ bool BKE_object_lod_is_usable(struct Object *ob, struct Scene *scene);
struct Object *BKE_object_lod_meshob_get(struct Object *ob, struct Scene *scene);
struct Object *BKE_object_lod_matob_get(struct Object *ob, struct Scene *scene);
-struct Object *BKE_object_copy_ex(struct Main *bmain, struct Object *ob, bool copy_caches);
-struct Object *BKE_object_copy(struct Main *bmain, struct Object *ob);
+struct Object *BKE_object_copy_ex(struct Main *bmain, const struct Object *ob, bool copy_caches);
+struct Object *BKE_object_copy(struct Main *bmain, const struct Object *ob);
void BKE_object_make_local(struct Main *bmain, struct Object *ob, const bool lib_local);
void BKE_object_make_local_ex(struct Main *bmain, struct Object *ob, const bool lib_local, const bool clear_proxy);
bool BKE_object_is_libdata(struct Object *ob);
@@ -189,10 +189,6 @@ void BKE_object_eval_constraints(struct EvaluationContext *eval_ctx,
struct Object *ob);
void BKE_object_eval_done(struct EvaluationContext *eval_ctx, struct Object *ob);
-void BKE_object_eval_modifier(struct EvaluationContext *eval_ctx,
- struct Scene *scene,
- struct Object *ob,
- struct ModifierData *md);
void BKE_object_eval_uber_transform(struct EvaluationContext *eval_ctx,
struct Scene *scene,
struct Object *ob);
diff --git a/source/blender/blenkernel/BKE_paint.h b/source/blender/blenkernel/BKE_paint.h
index 0a3cc950f32..821dc211591 100644
--- a/source/blender/blenkernel/BKE_paint.h
+++ b/source/blender/blenkernel/BKE_paint.h
@@ -99,7 +99,7 @@ void BKE_paint_set_overlay_override(enum OverlayFlags flag);
/* palettes */
void BKE_palette_free(struct Palette *palette);
struct Palette *BKE_palette_add(struct Main *bmain, const char *name);
-struct Palette *BKE_palette_copy(struct Main *bmain, struct Palette *palette);
+struct Palette *BKE_palette_copy(struct Main *bmain, const struct Palette *palette);
void BKE_palette_make_local(struct Main *bmain, struct Palette *palette, const bool lib_local);
struct PaletteColor *BKE_palette_color_add(struct Palette *palette);
bool BKE_palette_is_empty(const struct Palette *palette);
@@ -109,7 +109,7 @@ void BKE_palette_clear(struct Palette *palette);
/* paint curves */
struct PaintCurve *BKE_paint_curve_add(struct Main *bmain, const char *name);
void BKE_paint_curve_free(struct PaintCurve *pc);
-struct PaintCurve *BKE_paint_curve_copy(struct Main *bmain, struct PaintCurve *pc);
+struct PaintCurve *BKE_paint_curve_copy(struct Main *bmain, const struct PaintCurve *pc);
void BKE_paint_curve_make_local(struct Main *bmain, struct PaintCurve *pc, const bool lib_local);
void BKE_paint_init(struct Scene *sce, PaintMode mode, const char col[3]);
diff --git a/source/blender/blenkernel/BKE_particle.h b/source/blender/blenkernel/BKE_particle.h
index 2b6a84a2f87..470e2e468f0 100644
--- a/source/blender/blenkernel/BKE_particle.h
+++ b/source/blender/blenkernel/BKE_particle.h
@@ -324,7 +324,7 @@ struct ParticleSystemModifierData *psys_get_modifier(struct Object *ob, struct P
struct ModifierData *object_add_particle_system(struct Scene *scene, struct Object *ob, const char *name);
void object_remove_particle_system(struct Scene *scene, struct Object *ob);
struct ParticleSettings *psys_new_settings(const char *name, struct Main *main);
-struct ParticleSettings *BKE_particlesettings_copy(struct Main *bmain, struct ParticleSettings *part);
+struct ParticleSettings *BKE_particlesettings_copy(struct Main *bmain, const struct ParticleSettings *part);
void BKE_particlesettings_make_local(struct Main *bmain, struct ParticleSettings *part, const bool lib_local);
void psys_reset(struct ParticleSystem *psys, int mode);
@@ -473,9 +473,8 @@ typedef struct ParticleRenderData {
struct EvaluationContext;
-void BKE_particle_system_eval(struct EvaluationContext *eval_ctx,
- struct Scene *scene,
- struct Object *ob,
- struct ParticleSystem *psys);
+void BKE_particle_system_eval_init(struct EvaluationContext *eval_ctx,
+ struct Scene *scene,
+ struct Object *ob);
#endif
diff --git a/source/blender/blenkernel/BKE_property.h b/source/blender/blenkernel/BKE_property.h
index 99e60757f15..c787e8e8ed1 100644
--- a/source/blender/blenkernel/BKE_property.h
+++ b/source/blender/blenkernel/BKE_property.h
@@ -37,8 +37,8 @@ struct Object;
void BKE_bproperty_free(struct bProperty *prop);
void BKE_bproperty_free_list(struct ListBase *lb);
-struct bProperty *BKE_bproperty_copy(struct bProperty *prop);
-void BKE_bproperty_copy_list(struct ListBase *lbn, struct ListBase *lbo);
+struct bProperty *BKE_bproperty_copy(const struct bProperty *prop);
+void BKE_bproperty_copy_list(struct ListBase *lbn, const struct ListBase *lbo);
void BKE_bproperty_init(struct bProperty *prop);
struct bProperty *BKE_bproperty_new(int type);
void BKE_bproperty_unique(struct bProperty *first, struct bProperty *prop, int force);
diff --git a/source/blender/blenkernel/BKE_rigidbody.h b/source/blender/blenkernel/BKE_rigidbody.h
index 443c3b2b5b2..c72f067a111 100644
--- a/source/blender/blenkernel/BKE_rigidbody.h
+++ b/source/blender/blenkernel/BKE_rigidbody.h
@@ -49,8 +49,8 @@ void BKE_rigidbody_free_constraint(struct Object *ob);
/* ...... */
-struct RigidBodyOb *BKE_rigidbody_copy_object(struct Object *ob);
-struct RigidBodyCon *BKE_rigidbody_copy_constraint(struct Object *ob);
+struct RigidBodyOb *BKE_rigidbody_copy_object(const struct Object *ob);
+struct RigidBodyCon *BKE_rigidbody_copy_constraint(const struct Object *ob);
/* Callback format for performing operations on ID-pointers for rigidbody world. */
typedef void (*RigidbodyWorldIDFunc)(struct RigidBodyWorld *rbw, struct ID **idpoin, void *userdata, int cb_flag);
diff --git a/source/blender/blenkernel/BKE_sca.h b/source/blender/blenkernel/BKE_sca.h
index 1579a0c7bb3..10cddd7b454 100644
--- a/source/blender/blenkernel/BKE_sca.h
+++ b/source/blender/blenkernel/BKE_sca.h
@@ -53,15 +53,15 @@ void free_actuators(struct ListBase *lb);
void free_sensor(struct bSensor *sens);
void free_sensors(struct ListBase *lb);
struct bSensor *copy_sensor(struct bSensor *sens);
-void copy_sensors(struct ListBase *lbn, struct ListBase *lbo);
+void copy_sensors(struct ListBase *lbn, const struct ListBase *lbo);
void init_sensor(struct bSensor *sens);
struct bSensor *new_sensor(int type);
struct bController *copy_controller(struct bController *cont);
-void copy_controllers(struct ListBase *lbn, struct ListBase *lbo);
+void copy_controllers(struct ListBase *lbn, const struct ListBase *lbo);
void init_controller(struct bController *cont);
struct bController *new_controller(int type);
struct bActuator *copy_actuator(struct bActuator *act);
-void copy_actuators(struct ListBase *lbn, struct ListBase *lbo);
+void copy_actuators(struct ListBase *lbn, const struct ListBase *lbo);
void init_actuator(struct bActuator *act);
struct bActuator *new_actuator(int type);
void clear_sca_new_poins_ob(struct Object *ob);
@@ -70,7 +70,7 @@ void set_sca_new_poins_ob(struct Object *ob);
void set_sca_new_poins(void);
void BKE_sca_logic_links_remap(struct Main *bmain, struct Object *ob_old, struct Object *ob_new);
-void BKE_sca_logic_copy(struct Object *ob_new, struct Object *ob);
+void BKE_sca_logic_copy(struct Object *ob_new, const struct Object *ob);
void sca_move_sensor(struct bSensor *sens_to_move, struct Object *ob, int move_up);
void sca_move_controller(struct bController *cont_to_move, struct Object *ob, int move_up);
diff --git a/source/blender/blenkernel/BKE_speaker.h b/source/blender/blenkernel/BKE_speaker.h
index b91b64c4b74..907558f9203 100644
--- a/source/blender/blenkernel/BKE_speaker.h
+++ b/source/blender/blenkernel/BKE_speaker.h
@@ -33,7 +33,7 @@ struct Speaker;
void BKE_speaker_init(struct Speaker *spk);
void *BKE_speaker_add(struct Main *bmain, const char *name);
-struct Speaker *BKE_speaker_copy(struct Main *bmain, struct Speaker *spk);
+struct Speaker *BKE_speaker_copy(struct Main *bmain, const struct Speaker *spk);
void BKE_speaker_make_local(struct Main *bmain, struct Speaker *spk, const bool lib_local);
void BKE_speaker_free(struct Speaker *spk);
diff --git a/source/blender/blenkernel/BKE_text.h b/source/blender/blenkernel/BKE_text.h
index 081b7589af6..c8fb483cdf2 100644
--- a/source/blender/blenkernel/BKE_text.h
+++ b/source/blender/blenkernel/BKE_text.h
@@ -52,7 +52,7 @@ bool BKE_text_reload(struct Text *text);
struct Text *BKE_text_load_ex(struct Main *bmain, const char *file, const char *relpath,
const bool is_internal);
struct Text *BKE_text_load (struct Main *bmain, const char *file, const char *relpath);
-struct Text *BKE_text_copy (struct Main *bmain, struct Text *ta);
+struct Text *BKE_text_copy (struct Main *bmain, const struct Text *ta);
void BKE_text_make_local (struct Main *bmain, struct Text *text, const bool lib_local);
void BKE_text_clear (struct Text *text);
void BKE_text_write (struct Text *text, const char *str);
diff --git a/source/blender/blenkernel/BKE_texture.h b/source/blender/blenkernel/BKE_texture.h
index 9a60eb29957..190fdeafaec 100644
--- a/source/blender/blenkernel/BKE_texture.h
+++ b/source/blender/blenkernel/BKE_texture.h
@@ -70,7 +70,7 @@ void colorband_update_sort(struct ColorBand *coba);
void BKE_texture_free(struct Tex *tex);
void BKE_texture_default(struct Tex *tex);
-struct Tex *BKE_texture_copy(struct Main *bmain, struct Tex *tex);
+struct Tex *BKE_texture_copy(struct Main *bmain, const struct Tex *tex);
struct Tex *BKE_texture_add(struct Main *bmain, const char *name);
struct Tex *BKE_texture_localize(struct Tex *tex);
void BKE_texture_make_local(struct Main *bmain, struct Tex *tex, const bool lib_local);
@@ -114,13 +114,13 @@ void BKE_texture_colormapping_default(struct ColorMapping *color
void BKE_texture_envmap_free_data(struct EnvMap *env);
void BKE_texture_envmap_free(struct EnvMap *env);
struct EnvMap *BKE_texture_envmap_add(void);
-struct EnvMap *BKE_texture_envmap_copy(struct EnvMap *env);
+struct EnvMap *BKE_texture_envmap_copy(const struct EnvMap *env);
void BKE_texture_pointdensity_init_data(struct PointDensity *pd);
void BKE_texture_pointdensity_free_data(struct PointDensity *pd);
void BKE_texture_pointdensity_free(struct PointDensity *pd);
struct PointDensity *BKE_texture_pointdensity_add(void);
-struct PointDensity *BKE_texture_pointdensity_copy(struct PointDensity *pd);
+struct PointDensity *BKE_texture_pointdensity_copy(const struct PointDensity *pd);
void BKE_texture_voxeldata_free_data(struct VoxelData *vd);
void BKE_texture_voxeldata_free(struct VoxelData *vd);
@@ -129,7 +129,7 @@ struct VoxelData *BKE_texture_voxeldata_copy(struct VoxelData *vd);
void BKE_texture_ocean_free(struct OceanTex *ot);
struct OceanTex *BKE_texture_ocean_add(void);
-struct OceanTex *BKE_texture_ocean_copy(struct OceanTex *ot);
+struct OceanTex *BKE_texture_ocean_copy(const struct OceanTex *ot);
bool BKE_texture_dependsOnTime(const struct Tex *texture);
bool BKE_texture_is_image_user(const struct Tex *tex);
@@ -144,6 +144,8 @@ void BKE_texture_get_value(
const struct Scene *scene, struct Tex *texture,
float *tex_co, struct TexResult *texres, bool use_color_management);
+void BKE_texture_fetch_images_for_pool(struct Tex *texture, struct ImagePool *pool);
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenkernel/BKE_tracking.h b/source/blender/blenkernel/BKE_tracking.h
index 30873567297..b48be382073 100644
--- a/source/blender/blenkernel/BKE_tracking.h
+++ b/source/blender/blenkernel/BKE_tracking.h
@@ -52,7 +52,7 @@ struct rcti;
/* **** Common functions **** */
void BKE_tracking_free(struct MovieTracking *tracking);
-void BKE_tracking_copy(struct MovieTracking *tracking_dst, struct MovieTracking *tracking_src);
+void BKE_tracking_copy(struct MovieTracking *tracking_dst, const struct MovieTracking *tracking_src);
void BKE_tracking_settings_init(struct MovieTracking *tracking);
diff --git a/source/blender/blenkernel/BKE_world.h b/source/blender/blenkernel/BKE_world.h
index 23bf9ec3d22..18ae61f7653 100644
--- a/source/blender/blenkernel/BKE_world.h
+++ b/source/blender/blenkernel/BKE_world.h
@@ -39,7 +39,7 @@ struct World;
void BKE_world_free(struct World *sc);
void BKE_world_init(struct World *wrld);
struct World *add_world(struct Main *bmian, const char *name);
-struct World *BKE_world_copy(struct Main *bmain, struct World *wrld);
+struct World *BKE_world_copy(struct Main *bmain, const struct World *wrld);
struct World *localize_world(struct World *wrld);
void BKE_world_make_local(struct Main *bmain, struct World *wrld, const bool lib_local);
diff --git a/source/blender/blenkernel/intern/DerivedMesh.c b/source/blender/blenkernel/intern/DerivedMesh.c
index 8b7329cf940..7eea8224ba1 100644
--- a/source/blender/blenkernel/intern/DerivedMesh.c
+++ b/source/blender/blenkernel/intern/DerivedMesh.c
@@ -2123,6 +2123,8 @@ static void mesh_calc_modifiers(
DM_update_weight_mcol(ob, dm, draw_flag, NULL, 0, NULL);
append_mask |= CD_MASK_PREVIEW_MLOOPCOL;
}
+
+ dm->deformedOnly = false;
}
isPrevDeform = (mti->type == eModifierTypeType_OnlyDeform);
@@ -2463,6 +2465,8 @@ static void editbmesh_calc_modifiers(
deformedVerts = NULL;
}
}
+
+ dm->deformedOnly = false;
}
/* In case of active preview modifier, make sure preview mask remains for following modifiers. */
@@ -3318,7 +3322,8 @@ void DM_calc_loop_tangents_step_0(
const CustomData *loopData, bool calc_active_tangent,
const char (*tangent_names)[MAX_NAME], int tangent_names_count,
bool *rcalc_act, bool *rcalc_ren, int *ract_uv_n, int *rren_uv_n,
- char *ract_uv_name, char *rren_uv_name, char *rtangent_mask) {
+ char *ract_uv_name, char *rren_uv_name, short *rtangent_mask)
+{
/* Active uv in viewport */
int layer_index = CustomData_get_layer_index(loopData, CD_MLOOPUV);
*ract_uv_n = CustomData_get_active_layer(loopData, CD_MLOOPUV);
@@ -3372,21 +3377,22 @@ void DM_calc_loop_tangents_step_0(
if (add)
*rtangent_mask |= 1 << n;
}
+
+ if (uv_layer_num == 0)
+ *rtangent_mask |= DM_TANGENT_MASK_ORCO;
}
void DM_calc_loop_tangents(
DerivedMesh *dm, bool calc_active_tangent,
const char (*tangent_names)[MAX_NAME], int tangent_names_count)
{
- if (CustomData_number_of_layers(&dm->loopData, CD_MLOOPUV) == 0)
- return;
int act_uv_n = -1;
int ren_uv_n = -1;
bool calc_act = false;
bool calc_ren = false;
char act_uv_name[MAX_NAME];
char ren_uv_name[MAX_NAME];
- char tangent_mask = 0;
+ short tangent_mask = 0;
DM_calc_loop_tangents_step_0(
&dm->loopData, calc_active_tangent, tangent_names, tangent_names_count,
&calc_act, &calc_ren, &act_uv_n, &ren_uv_n, act_uv_name, ren_uv_name, &tangent_mask);
@@ -3399,6 +3405,8 @@ void DM_calc_loop_tangents(
for (int i = 0; i < tangent_names_count; i++)
if (tangent_names[i][0])
DM_add_named_tangent_layer_for_uv(&dm->loopData, &dm->loopData, dm->numLoopData, tangent_names[i]);
+ if ((tangent_mask & DM_TANGENT_MASK_ORCO) && CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, "") == -1)
+ CustomData_add_layer_named(&dm->loopData, CD_TANGENT, CD_CALLOC, NULL, dm->numLoopData, "");
if (calc_act && act_uv_name[0])
DM_add_named_tangent_layer_for_uv(&dm->loopData, &dm->loopData, dm->numLoopData, act_uv_name);
if (calc_ren && ren_uv_name[0])
@@ -3456,23 +3464,28 @@ void DM_calc_loop_tangents(
* have to check this is valid...
*/
mesh2tangent->precomputedLoopNormals = dm->getLoopDataArray(dm, CD_NORMAL);
- mesh2tangent->precomputedFaceNormals = CustomData_get_layer(&dm->faceData, CD_NORMAL);
+ mesh2tangent->precomputedFaceNormals = CustomData_get_layer(&dm->polyData, CD_NORMAL);
mesh2tangent->orco = NULL;
mesh2tangent->mloopuv = CustomData_get_layer_named(&dm->loopData, CD_MLOOPUV, dm->loopData.layers[index].name);
+
+ /* Fill the resulting tangent_mask */
if (!mesh2tangent->mloopuv) {
mesh2tangent->orco = dm->getVertDataArray(dm, CD_ORCO);
if (!mesh2tangent->orco)
continue;
+
+ dm->tangent_mask |= DM_TANGENT_MASK_ORCO;
+ }
+ else {
+ int uv_ind = CustomData_get_named_layer_index(&dm->loopData, CD_MLOOPUV, dm->loopData.layers[index].name);
+ int uv_start = CustomData_get_layer_index(&dm->loopData, CD_MLOOPUV);
+ BLI_assert(uv_ind != -1 && uv_start != -1);
+ BLI_assert(uv_ind - uv_start < MAX_MTFACE);
+ dm->tangent_mask |= 1 << (uv_ind - uv_start);
}
- mesh2tangent->tangent = dm->loopData.layers[index].data;
- /* Fill the resulting tangent_mask */
- int uv_ind = CustomData_get_named_layer_index(&dm->loopData, CD_MLOOPUV, dm->loopData.layers[index].name);
- int uv_start = CustomData_get_layer_index(&dm->loopData, CD_MLOOPUV);
- BLI_assert(uv_ind != -1 && uv_start != -1);
- BLI_assert(uv_ind - uv_start < MAX_MTFACE);
- dm->tangent_mask |= 1 << (uv_ind - uv_start);
+ mesh2tangent->tangent = dm->loopData.layers[index].data;
BLI_task_pool_push(task_pool, DM_calc_loop_tangents_thread, mesh2tangent, false, TASK_PRIORITY_LOW);
}
@@ -3488,21 +3501,19 @@ void DM_calc_loop_tangents(
#endif
- int uv_index, tan_index;
-
/* Update active layer index */
- uv_index = CustomData_get_layer_index_n(&dm->loopData, CD_MLOOPUV, act_uv_n);
- if (uv_index != -1) {
- tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, dm->loopData.layers[uv_index].name);
+ int act_uv_index = CustomData_get_layer_index_n(&dm->loopData, CD_MLOOPUV, act_uv_n);
+ if (act_uv_index != -1) {
+ int tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, dm->loopData.layers[act_uv_index].name);
CustomData_set_layer_active_index(&dm->loopData, CD_TANGENT, tan_index);
- }
+ } /* else tangent has been built from orco */
/* Update render layer index */
- uv_index = CustomData_get_layer_index_n(&dm->loopData, CD_MLOOPUV, ren_uv_n);
- if (uv_index != -1) {
- tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, dm->loopData.layers[uv_index].name);
+ int ren_uv_index = CustomData_get_layer_index_n(&dm->loopData, CD_MLOOPUV, ren_uv_n);
+ if (ren_uv_index != -1) {
+ int tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, dm->loopData.layers[ren_uv_index].name);
CustomData_set_layer_render_index(&dm->loopData, CD_TANGENT, tan_index);
- }
+ } /* else tangent has been built from orco */
}
}
diff --git a/source/blender/blenkernel/intern/action.c b/source/blender/blenkernel/intern/action.c
index 1e33fe4ab46..885ea36d404 100644
--- a/source/blender/blenkernel/intern/action.c
+++ b/source/blender/blenkernel/intern/action.c
@@ -120,7 +120,7 @@ void BKE_action_free(bAction *act)
/* .................................. */
-bAction *BKE_action_copy(Main *bmain, bAction *src)
+bAction *BKE_action_copy(Main *bmain, const bAction *src)
{
bAction *dst = NULL;
bActionGroup *dgrp, *sgrp;
@@ -523,7 +523,7 @@ const char *BKE_pose_ikparam_get_name(bPose *pose)
*
* \param dst Should be freed already, makes entire duplicate.
*/
-void BKE_pose_copy_data(bPose **dst, bPose *src, const bool copy_constraints)
+void BKE_pose_copy_data(bPose **dst, const bPose *src, const bool copy_constraints)
{
bPose *outPose;
bPoseChannel *pchan;
diff --git a/source/blender/blenkernel/intern/anim_sys.c b/source/blender/blenkernel/intern/anim_sys.c
index 0b637355ecf..539901a59d5 100644
--- a/source/blender/blenkernel/intern/anim_sys.c
+++ b/source/blender/blenkernel/intern/anim_sys.c
@@ -397,73 +397,6 @@ void BKE_animdata_merge_copy(ID *dst_id, ID *src_id, eAnimData_MergeCopy_Modes a
}
}
-/* Make Local -------------------------------------------- */
-
-static void make_local_strips(ListBase *strips)
-{
- NlaStrip *strip;
-
- for (strip = strips->first; strip; strip = strip->next) {
- if (strip->act) BKE_action_make_local(G.main, strip->act, false);
- if (strip->remap && strip->remap->target) BKE_action_make_local(G.main, strip->remap->target, false);
-
- make_local_strips(&strip->strips);
- }
-}
-
-/* Use local copy instead of linked copy of various ID-blocks */
-void BKE_animdata_make_local(AnimData *adt)
-{
- NlaTrack *nlt;
-
- /* Actions - Active and Temp */
- if (adt->action) BKE_action_make_local(G.main, adt->action, false);
- if (adt->tmpact) BKE_action_make_local(G.main, adt->tmpact, false);
- /* Remaps */
- if (adt->remap && adt->remap->target) BKE_action_make_local(G.main, adt->remap->target, false);
-
- /* Drivers */
- /* TODO: need to remap the ID-targets too? */
-
- /* NLA Data */
- for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next)
- make_local_strips(&nlt->strips);
-}
-
-
-/* When duplicating data (i.e. objects), drivers referring to the original data will
- * get updated to point to the duplicated data (if drivers belong to the new data)
- */
-void BKE_animdata_relink(AnimData *adt)
-{
- /* sanity check */
- if (adt == NULL)
- return;
-
- /* drivers */
- if (adt->drivers.first) {
- FCurve *fcu;
-
- /* check each driver against all the base paths to see if any should go */
- for (fcu = adt->drivers.first; fcu; fcu = fcu->next) {
- ChannelDriver *driver = fcu->driver;
- DriverVar *dvar;
-
- /* driver variables */
- for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
- /* only change the used targets, since the others will need fixing manually anyway */
- DRIVER_TARGETS_USED_LOOPER(dvar)
- {
- if (dtar->id && dtar->id->newid) {
- dtar->id = dtar->id->newid;
- }
- }
- DRIVER_TARGETS_LOOPER_END
- }
- }
- }
-}
-
/* Sub-ID Regrouping ------------------------------------------- */
/**
@@ -1586,7 +1519,8 @@ static bool animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float val
}
case PROP_INT:
{
- const int value_coerce = (int)value;
+ int value_coerce = (int)value;
+ RNA_property_int_clamp(ptr, prop, &value_coerce);
if (array_index != -1) {
if (RNA_property_int_get_index(ptr, prop, array_index) != value_coerce) {
RNA_property_int_set_index(ptr, prop, array_index, value_coerce);
@@ -1603,15 +1537,17 @@ static bool animsys_write_rna_setting(PathResolvedRNA *anim_rna, const float val
}
case PROP_FLOAT:
{
+ float value_coerce = value;
+ RNA_property_float_clamp(ptr, prop, &value_coerce);
if (array_index != -1) {
- if (RNA_property_float_get_index(ptr, prop, array_index) != value) {
- RNA_property_float_set_index(ptr, prop, array_index, value);
+ if (RNA_property_float_get_index(ptr, prop, array_index) != value_coerce) {
+ RNA_property_float_set_index(ptr, prop, array_index, value_coerce);
written = true;
}
}
else {
- if (RNA_property_float_get(ptr, prop) != value) {
- RNA_property_float_set(ptr, prop, value);
+ if (RNA_property_float_get(ptr, prop) != value_coerce) {
+ RNA_property_float_set(ptr, prop, value_coerce);
written = true;
}
}
diff --git a/source/blender/blenkernel/intern/armature.c b/source/blender/blenkernel/intern/armature.c
index 02cc31e5977..35b6fe113bd 100644
--- a/source/blender/blenkernel/intern/armature.c
+++ b/source/blender/blenkernel/intern/armature.c
@@ -150,7 +150,7 @@ void BKE_armature_make_local(Main *bmain, bArmature *arm, const bool lib_local)
BKE_id_make_local_generic(bmain, &arm->id, true, lib_local);
}
-static void copy_bonechildren(Bone *newBone, Bone *oldBone, Bone *actBone, Bone **newActBone)
+static void copy_bonechildren(Bone *newBone, const Bone *oldBone, const Bone *actBone, Bone **newActBone)
{
Bone *curBone, *newChildBone;
@@ -172,7 +172,7 @@ static void copy_bonechildren(Bone *newBone, Bone *oldBone, Bone *actBone, Bone
}
}
-bArmature *BKE_armature_copy(Main *bmain, bArmature *arm)
+bArmature *BKE_armature_copy(Main *bmain, const bArmature *arm)
{
bArmature *newArm;
Bone *oldBone, *newBone;
@@ -982,6 +982,11 @@ void armature_deform_verts(Object *armOb, Object *target, DerivedMesh *dm, float
return;
}
+ if ((armOb->pose->flag & POSE_RECALC) != 0) {
+ printf("ERROR! Trying to evaluate influence of armature '%s' which needs Pose recalc!", armOb->id.name);
+ BLI_assert(0);
+ }
+
invert_m4_m4(obinv, target->obmat);
copy_m4_m4(premat, target->obmat);
mul_m4_m4m4(postmat, obinv, armOb->obmat);
@@ -1980,6 +1985,8 @@ void BKE_pose_rebuild_ex(Object *ob, bArmature *arm, const bool sort_bones)
if (counter > 1 && sort_bones) {
DAG_pose_sort(ob);
}
+#else
+ UNUSED_VARS(sort_bones);
#endif
ob->pose->flag &= ~POSE_RECALC;
diff --git a/source/blender/blenkernel/intern/armature_update.c b/source/blender/blenkernel/intern/armature_update.c
index 3bc81a69c86..a4714041edf 100644
--- a/source/blender/blenkernel/intern/armature_update.c
+++ b/source/blender/blenkernel/intern/armature_update.c
@@ -628,10 +628,10 @@ void BKE_pose_eval_bone(EvaluationContext *UNUSED(eval_ctx),
}
void BKE_pose_constraints_evaluate(EvaluationContext *UNUSED(eval_ctx),
+ Scene *scene,
Object *ob,
bPoseChannel *pchan)
{
- Scene *scene = G.main->scene.first;
DEBUG_PRINT("%s on %s pchan %s\n", __func__, ob->id.name, pchan->name);
bArmature *arm = (bArmature *)ob->data;
if (arm->flag & ARM_RESTPOS) {
@@ -702,4 +702,8 @@ void BKE_pose_eval_proxy_copy(EvaluationContext *UNUSED(eval_ctx), Object *ob)
printf("Proxy copy error, lib Object: %s proxy Object: %s\n",
ob->id.name + 2, ob->proxy_from->id.name + 2);
}
+ /* Rest of operations are NO-OP in depsgraph, so can clear
+ * flag now.
+ */
+ ob->recalc &= ~OB_RECALC_ALL;
}
diff --git a/source/blender/blenkernel/intern/blender.c b/source/blender/blenkernel/intern/blender.c
index ceb641073e0..2624019e63a 100644
--- a/source/blender/blenkernel/intern/blender.c
+++ b/source/blender/blenkernel/intern/blender.c
@@ -226,19 +226,6 @@ void BKE_blender_userdef_free_data(UserDef *userdef)
}
/**
- * Handle changes in settings that need refreshing.
- */
-void BKE_blender_userdef_refresh(void)
-{
- /* prevent accidents */
- if (U.pixelsize == 0) U.pixelsize = 1;
-
- BLF_default_dpi(U.pixelsize * U.dpi);
- U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72;
-
-}
-
-/**
* Write U from userdef.
* This function defines which settings a template will override for the user preferences.
*/
diff --git a/source/blender/blenkernel/intern/blendfile.c b/source/blender/blenkernel/intern/blendfile.c
index a521d671ea4..05ea7983b8e 100644
--- a/source/blender/blenkernel/intern/blendfile.c
+++ b/source/blender/blenkernel/intern/blendfile.c
@@ -413,9 +413,9 @@ bool BKE_blendfile_read_from_memfile(
if (bfd) {
/* remove the unused screens and wm */
while (bfd->main->wm.first)
- BKE_libblock_free_ex(bfd->main, bfd->main->wm.first, true, true);
+ BKE_libblock_free(bfd->main, bfd->main->wm.first);
while (bfd->main->screen.first)
- BKE_libblock_free_ex(bfd->main, bfd->main->screen.first, true, true);
+ BKE_libblock_free(bfd->main, bfd->main->screen.first);
setup_app_data(C, bfd, "<memory1>", reports);
}
diff --git a/source/blender/blenkernel/intern/boids.c b/source/blender/blenkernel/intern/boids.c
index b4bc83bf94c..7ca4e07076d 100644
--- a/source/blender/blenkernel/intern/boids.c
+++ b/source/blender/blenkernel/intern/boids.c
@@ -1581,7 +1581,7 @@ void boid_free_settings(BoidSettings *boids)
MEM_freeN(boids);
}
}
-BoidSettings *boid_copy_settings(BoidSettings *boids)
+BoidSettings *boid_copy_settings(const BoidSettings *boids)
{
BoidSettings *nboids = NULL;
diff --git a/source/blender/blenkernel/intern/bpath.c b/source/blender/blenkernel/intern/bpath.c
index 487b8ffa2b5..f210c6aa7f3 100644
--- a/source/blender/blenkernel/intern/bpath.c
+++ b/source/blender/blenkernel/intern/bpath.c
@@ -243,7 +243,7 @@ static bool missing_files_find__recursive(
continue; /* cant stat, don't bother with this file, could print debug info here */
if (S_ISREG(status.st_mode)) { /* is file */
- if (STREQLEN(filename, de->d_name, FILE_MAX)) { /* name matches */
+ if (BLI_path_ncmp(filename, de->d_name, FILE_MAX) == 0) { /* name matches */
/* open the file to read its size */
size = status.st_size;
if ((size > 0) && (size > *r_filesize)) { /* find the biggest file */
diff --git a/source/blender/blenkernel/intern/brush.c b/source/blender/blenkernel/intern/brush.c
index 57b707a31d3..aae323a5056 100644
--- a/source/blender/blenkernel/intern/brush.c
+++ b/source/blender/blenkernel/intern/brush.c
@@ -172,7 +172,7 @@ struct Brush *BKE_brush_first_search(struct Main *bmain, short ob_mode)
return NULL;
}
-Brush *BKE_brush_copy(Main *bmain, Brush *brush)
+Brush *BKE_brush_copy(Main *bmain, const Brush *brush)
{
Brush *brushn;
@@ -195,7 +195,7 @@ Brush *BKE_brush_copy(Main *bmain, Brush *brush)
brushn->curve = curvemapping_copy(brush->curve);
/* enable fake user by default */
- id_fake_user_set(&brush->id);
+ id_fake_user_set(&brushn->id);
BKE_id_copy_ensure_local(bmain, &brush->id, &brushn->id);
diff --git a/source/blender/blenkernel/intern/bvhutils.c b/source/blender/blenkernel/intern/bvhutils.c
index c0e4ef37a93..c1fad4f80c8 100644
--- a/source/blender/blenkernel/intern/bvhutils.c
+++ b/source/blender/blenkernel/intern/bvhutils.c
@@ -917,10 +917,10 @@ BVHTree *bvhtree_from_mesh_faces(
/**
* Builds a bvh tree where nodes are the given tessellated faces (note: does not copy given mfaces!).
- * \param vert_allocated if true, vert freeing will be done when freeing data.
- * \param face_allocated if true, face freeing will be done when freeing data.
+ * \param vert_allocated: if true, vert freeing will be done when freeing data.
+ * \param face_allocated: if true, face freeing will be done when freeing data.
* \param faces_mask: if not null, true elements give which faces to add to BVH tree.
- * \param numFaces_active if >= 0, number of active faces to add to BVH tree (else will be computed from mask).
+ * \param faces_num_active: if >= 0, number of active faces to add to BVH tree (else will be computed from mask).
*/
BVHTree *bvhtree_from_mesh_faces_ex(
BVHTreeFromMesh *data, const MVert *vert, const bool vert_allocated,
diff --git a/source/blender/blenkernel/intern/cachefile.c b/source/blender/blenkernel/intern/cachefile.c
index 3dce08eb756..cf619a32783 100644
--- a/source/blender/blenkernel/intern/cachefile.c
+++ b/source/blender/blenkernel/intern/cachefile.c
@@ -82,6 +82,7 @@ void BKE_cachefile_init(CacheFile *cache_file)
cache_file->is_sequence = false;
cache_file->scale = 1.0f;
cache_file->handle_mutex = BLI_mutex_alloc();
+ BLI_listbase_clear(&cache_file->object_paths);
}
/** Free (or release) any data used by this cachefile (does not free the cachefile itself). */
@@ -99,12 +100,12 @@ void BKE_cachefile_free(CacheFile *cache_file)
BLI_freelistN(&cache_file->object_paths);
}
-CacheFile *BKE_cachefile_copy(Main *bmain, CacheFile *cache_file)
+CacheFile *BKE_cachefile_copy(Main *bmain, const CacheFile *cache_file)
{
CacheFile *new_cache_file = BKE_libblock_copy(bmain, &cache_file->id);
new_cache_file->handle = NULL;
- BLI_listbase_clear(&cache_file->object_paths);
+ BLI_listbase_clear(&new_cache_file->object_paths);
BKE_id_copy_ensure_local(bmain, &cache_file->id, &new_cache_file->id);
@@ -165,10 +166,12 @@ void BKE_cachefile_update_frame(Main *bmain, Scene *scene, const float ctime, co
const float time = BKE_cachefile_time_offset(cache_file, ctime, fps);
if (BKE_cachefile_filepath_get(bmain, cache_file, time, filename)) {
+ BKE_cachefile_clean(scene, cache_file);
#ifdef WITH_ALEMBIC
ABC_free_handle(cache_file->handle);
cache_file->handle = ABC_create_handle(filename, NULL);
#endif
+ break;
}
}
}
@@ -220,7 +223,6 @@ void BKE_cachefile_clean(Scene *scene, CacheFile *cache_file)
}
#endif
mcmd->reader = NULL;
- mcmd->object_path[0] = '\0';
}
}
@@ -238,7 +240,6 @@ void BKE_cachefile_clean(Scene *scene, CacheFile *cache_file)
}
#endif
data->reader = NULL;
- data->object_path[0] = '\0';
}
}
}
diff --git a/source/blender/blenkernel/intern/camera.c b/source/blender/blenkernel/intern/camera.c
index 9cb553aa27b..915c08674a4 100644
--- a/source/blender/blenkernel/intern/camera.c
+++ b/source/blender/blenkernel/intern/camera.c
@@ -93,7 +93,7 @@ void *BKE_camera_add(Main *bmain, const char *name)
return cam;
}
-Camera *BKE_camera_copy(Main *bmain, Camera *cam)
+Camera *BKE_camera_copy(Main *bmain, const Camera *cam)
{
Camera *camn;
diff --git a/source/blender/blenkernel/intern/cdderivedmesh.c b/source/blender/blenkernel/intern/cdderivedmesh.c
index 7042b46330b..46a067ea0bc 100644
--- a/source/blender/blenkernel/intern/cdderivedmesh.c
+++ b/source/blender/blenkernel/intern/cdderivedmesh.c
@@ -2992,9 +2992,12 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int
STACK_DECLARE(mvert);
STACK_DECLARE(oldv);
- MEdge *med, *medge = MEM_mallocN(sizeof(*medge) * totedge, __func__);
- int *olde = MEM_mallocN(sizeof(*olde) * totedge, __func__);
- int *newe = MEM_mallocN(sizeof(*newe) * totedge, __func__);
+ /* Note: create (totedge + totloop) elements because partially invalid polys due to merge may require
+ * generating new edges, and while in 99% cases we'll still end with less final edges than totedge,
+ * cases can be forged that would end requiring more... */
+ MEdge *med, *medge = MEM_mallocN(sizeof(*medge) * (totedge + totloop), __func__);
+ int *olde = MEM_mallocN(sizeof(*olde) * (totedge + totloop), __func__);
+ int *newe = MEM_mallocN(sizeof(*newe) * (totedge + totloop), __func__);
STACK_DECLARE(medge);
STACK_DECLARE(olde);
@@ -3028,7 +3031,7 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int
STACK_INIT(mloop, totloop);
STACK_INIT(mpoly, totpoly);
- /* fill newl with destination vertex indices */
+ /* fill newv with destination vertex indices */
mv = cddm->mvert;
c = 0;
for (i = 0; i < totvert; i++, mv++) {
@@ -3117,83 +3120,80 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int
mp = cddm->mpoly;
+ mv = cddm->mvert;
for (i = 0; i < totpoly; i++, mp++) {
MPoly *mp_new;
ml = cddm->mloop + mp->loopstart;
/* check faces with all vertices merged */
- {
- bool all_vertices_merged = true;
+ bool all_vertices_merged = true;
- for (j = 0; j < mp->totloop; j++, ml++) {
- if (vtargetmap[ml->v] == -1) {
- all_vertices_merged = false;
- break;
- }
+ for (j = 0; j < mp->totloop; j++, ml++) {
+ if (vtargetmap[ml->v] == -1) {
+ all_vertices_merged = false;
+ /* This will be used to check for poly using several time the same vert. */
+ mv[ml->v].flag &= ~ME_VERT_TMP_TAG;
}
+ else {
+ /* This will be used to check for poly using several time the same vert. */
+ mv[vtargetmap[ml->v]].flag &= ~ME_VERT_TMP_TAG;
+ }
+ }
- if (UNLIKELY(all_vertices_merged)) {
- if (merge_mode == CDDM_MERGE_VERTS_DUMP_IF_MAPPED) {
- /* In this mode, all vertices merged is enough to dump face */
- continue;
+ if (UNLIKELY(all_vertices_merged)) {
+ if (merge_mode == CDDM_MERGE_VERTS_DUMP_IF_MAPPED) {
+ /* In this mode, all vertices merged is enough to dump face */
+ continue;
+ }
+ else if (merge_mode == CDDM_MERGE_VERTS_DUMP_IF_EQUAL) {
+ /* Additional condition for face dump: target vertices must make up an identical face */
+ /* The test has 2 steps: (1) first step is fast ghash lookup, but not failproof */
+ /* (2) second step is thorough but more costly poly compare */
+ int i_poly, v_target;
+ bool found = false;
+ PolyKey pkey;
+
+ /* Use poly_gset for fast (although not 100% certain) identification of same poly */
+ /* First, make up a poly_summary structure */
+ ml = cddm->mloop + mp->loopstart;
+ pkey.hash_sum = pkey.hash_xor = 0;
+ pkey.totloops = 0;
+ for (j = 0; j < mp->totloop; j++, ml++) {
+ v_target = vtargetmap[ml->v]; /* Cannot be -1, they are all mapped */
+ pkey.hash_sum += v_target;
+ pkey.hash_xor ^= v_target;
+ pkey.totloops++;
}
- else if (merge_mode == CDDM_MERGE_VERTS_DUMP_IF_EQUAL) {
- /* Additional condition for face dump: target vertices must make up an identical face */
- /* The test has 2 steps: (1) first step is fast ghash lookup, but not failproof */
- /* (2) second step is thorough but more costly poly compare */
- int i_poly, v_target, v_prev;
- bool found = false;
- PolyKey pkey;
-
- /* Use poly_gset for fast (although not 100% certain) identification of same poly */
- /* First, make up a poly_summary structure */
+ if (BLI_gset_haskey(poly_gset, &pkey)) {
+
+ /* There might be a poly that matches this one.
+ * We could just leave it there and say there is, and do a "continue".
+ * ... but we are checking whether there is an exact poly match.
+ * It's not so costly in terms of CPU since it's very rare, just a lot of complex code.
+ */
+
+ /* Consider current loop again */
ml = cddm->mloop + mp->loopstart;
- pkey.hash_sum = pkey.hash_xor = 0;
- pkey.totloops = 0;
- v_prev = vtargetmap[(ml + mp->totloop -1)->v]; /* since it loops around, the prev of first is the last */
- for (j = 0; j < mp->totloop; j++, ml++) {
- v_target = vtargetmap[ml->v]; /* Cannot be -1, they are all mapped */
- if (v_target == v_prev) {
- /* consecutive vertices in loop map to the same target: discard */
- /* but what about last to first ? */
- continue;
+ /* Consider the target of the loop's first vert */
+ v_target = vtargetmap[ml->v];
+ /* Now see if v_target belongs to a poly that shares all vertices with source poly,
+ * in same order, or reverse order */
+
+ for (i_poly = 0; i_poly < cddm->pmap[v_target].count; i_poly++) {
+ MPoly *target_poly = cddm->mpoly + *(cddm->pmap[v_target].indices + i_poly);
+
+ if (cddm_poly_compare(cddm->mloop, mp, target_poly, vtargetmap, +1) ||
+ cddm_poly_compare(cddm->mloop, mp, target_poly, vtargetmap, -1))
+ {
+ found = true;
+ break;
}
- pkey.hash_sum += v_target;
- pkey.hash_xor ^= v_target;
- pkey.totloops++;
- v_prev = v_target;
}
- if (BLI_gset_haskey(poly_gset, &pkey)) {
-
- /* There might be a poly that matches this one.
- * We could just leave it there and say there is, and do a "continue".
- * ... but we are checking whether there is an exact poly match.
- * It's not so costly in terms of CPU since it's very rare, just a lot of complex code.
- */
-
- /* Consider current loop again */
- ml = cddm->mloop + mp->loopstart;
- /* Consider the target of the loop's first vert */
- v_target = vtargetmap[ml->v];
- /* Now see if v_target belongs to a poly that shares all vertices with source poly,
- * in same order, or reverse order */
-
- for (i_poly = 0; i_poly < cddm->pmap[v_target].count; i_poly++) {
- MPoly *target_poly = cddm->mpoly + *(cddm->pmap[v_target].indices + i_poly);
-
- if (cddm_poly_compare(cddm->mloop, mp, target_poly, vtargetmap, +1) ||
- cddm_poly_compare(cddm->mloop, mp, target_poly, vtargetmap, -1))
- {
- found = true;
- break;
- }
- }
- if (found) {
- /* Current poly's vertices are mapped to a poly that is strictly identical */
- /* Current poly is dumped */
- continue;
- }
+ if (found) {
+ /* Current poly's vertices are mapped to a poly that is strictly identical */
+ /* Current poly is dumped */
+ continue;
}
}
}
@@ -3207,32 +3207,121 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int
ml = cddm->mloop + mp->loopstart;
c = 0;
+ MLoop *last_valid_ml = NULL;
+ MLoop *first_valid_ml = NULL;
+ bool need_edge_from_last_valid_ml = false;
+ bool need_edge_to_first_valid_ml = false;
+ int created_edges = 0;
for (j = 0; j < mp->totloop; j++, ml++) {
- unsigned int v1, v2;
+ const uint mlv = (vtargetmap[ml->v] != -1) ? vtargetmap[ml->v] : ml->v;
+#ifndef NDEBUG
+ {
+ MLoop *next_ml = cddm->mloop + mp->loopstart + ((j + 1) % mp->totloop);
+ uint next_mlv = (vtargetmap[next_ml->v] != -1) ? vtargetmap[next_ml->v] : next_ml->v;
+ med = cddm->medge + ml->e;
+ uint v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
+ uint v2 = (vtargetmap[med->v2] != -1) ? vtargetmap[med->v2] : med->v2;
+ BLI_assert((mlv == v1 && next_mlv == v2) || (mlv == v2 && next_mlv == v1));
+ }
+#endif
+ /* A loop is only valid if its matching edge is, and it's not reusing a vertex already used by this poly. */
+ if (LIKELY((newe[ml->e] != -1) && ((mv[mlv].flag & ME_VERT_TMP_TAG) == 0))) {
+ mv[mlv].flag |= ME_VERT_TMP_TAG;
+
+ if (UNLIKELY(last_valid_ml != NULL && need_edge_from_last_valid_ml)) {
+ /* We need to create a new edge between last valid loop and this one! */
+ void **val_p;
+
+ uint v1 = (vtargetmap[last_valid_ml->v] != -1) ? vtargetmap[last_valid_ml->v] : last_valid_ml->v;
+ uint v2 = mlv;
+ BLI_assert(v1 != v2);
+ if (BLI_edgehash_ensure_p(ehash, v1, v2, &val_p)) {
+ last_valid_ml->e = GET_INT_FROM_POINTER(*val_p);
+ }
+ else {
+ const int new_eidx = STACK_SIZE(medge);
+ STACK_PUSH(olde, olde[last_valid_ml->e]);
+ STACK_PUSH(medge, cddm->medge[last_valid_ml->e]);
+ medge[new_eidx].v1 = last_valid_ml->v;
+ medge[new_eidx].v2 = ml->v;
+ /* DO NOT change newe mapping, could break actual values due to some deleted original edges. */
+ *val_p = SET_INT_IN_POINTER(new_eidx);
+ created_edges++;
+
+ last_valid_ml->e = new_eidx;
+ }
+ need_edge_from_last_valid_ml = false;
+ }
- med = cddm->medge + ml->e;
- v1 = (vtargetmap[med->v1] != -1) ? vtargetmap[med->v1] : med->v1;
- v2 = (vtargetmap[med->v2] != -1) ? vtargetmap[med->v2] : med->v2;
- if (LIKELY(v1 != v2)) {
#ifdef USE_LOOPS
newl[j + mp->loopstart] = STACK_SIZE(mloop);
#endif
STACK_PUSH(oldl, j + mp->loopstart);
- STACK_PUSH(mloop, *ml);
+ last_valid_ml = STACK_PUSH_RET_PTR(mloop);
+ *last_valid_ml = *ml;
+ if (first_valid_ml == NULL) {
+ first_valid_ml = last_valid_ml;
+ }
c++;
+
+ /* We absolutely HAVE to handle edge index remapping here, otherwise potential newly created edges
+ * in that part of code make remapping later totally unreliable. */
+ BLI_assert(newe[ml->e] != -1);
+ last_valid_ml->e = newe[ml->e];
+ }
+ else {
+ if (last_valid_ml != NULL) {
+ need_edge_from_last_valid_ml = true;
+ }
+ else {
+ need_edge_to_first_valid_ml = true;
+ }
}
}
+ if (UNLIKELY(last_valid_ml != NULL && !ELEM(first_valid_ml, NULL, last_valid_ml) &&
+ (need_edge_to_first_valid_ml || need_edge_from_last_valid_ml)))
+ {
+ /* We need to create a new edge between last valid loop and first valid one! */
+ void **val_p;
+
+ uint v1 = (vtargetmap[last_valid_ml->v] != -1) ? vtargetmap[last_valid_ml->v] : last_valid_ml->v;
+ uint v2 = (vtargetmap[first_valid_ml->v] != -1) ? vtargetmap[first_valid_ml->v] : first_valid_ml->v;
+ BLI_assert(v1 != v2);
+ if (BLI_edgehash_ensure_p(ehash, v1, v2, &val_p)) {
+ last_valid_ml->e = GET_INT_FROM_POINTER(*val_p);
+ }
+ else {
+ const int new_eidx = STACK_SIZE(medge);
+ STACK_PUSH(olde, olde[last_valid_ml->e]);
+ STACK_PUSH(medge, cddm->medge[last_valid_ml->e]);
+ medge[new_eidx].v1 = last_valid_ml->v;
+ medge[new_eidx].v2 = first_valid_ml->v;
+ /* DO NOT change newe mapping, could break actual values due to some deleted original edges. */
+ *val_p = SET_INT_IN_POINTER(new_eidx);
+ created_edges++;
+
+ last_valid_ml->e = new_eidx;
+ }
+ need_edge_to_first_valid_ml = need_edge_from_last_valid_ml = false;
+ }
if (UNLIKELY(c == 0)) {
+ BLI_assert(created_edges == 0);
continue;
}
else if (UNLIKELY(c < 3)) {
STACK_DISCARD(oldl, c);
STACK_DISCARD(mloop, c);
+ if (created_edges > 0) {
+ for (j = STACK_SIZE(medge) - created_edges; j < STACK_SIZE(medge); j++) {
+ BLI_edgehash_remove(ehash, medge[j].v1, medge[j].v2, NULL);
+ }
+ STACK_DISCARD(olde, created_edges);
+ STACK_DISCARD(medge, created_edges);
+ }
continue;
}
-
mp_new = STACK_PUSH_RET_PTR(mpoly);
*mp_new = *mp;
mp_new->totloop = c;
@@ -3257,10 +3346,10 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int
/*update edge indices and copy customdata*/
med = medge;
for (i = 0; i < cddm2->dm.numEdgeData; i++, med++) {
- if (newv[med->v1] != -1)
- med->v1 = newv[med->v1];
- if (newv[med->v2] != -1)
- med->v2 = newv[med->v2];
+ BLI_assert(newv[med->v1] != -1);
+ med->v1 = newv[med->v1];
+ BLI_assert(newv[med->v2] != -1);
+ med->v2 = newv[med->v2];
/* Can happen in case vtargetmap contains some double chains, we do not support that. */
BLI_assert(med->v1 != med->v2);
@@ -3271,11 +3360,10 @@ DerivedMesh *CDDM_merge_verts(DerivedMesh *dm, const int *vtargetmap, const int
/*update loop indices and copy customdata*/
ml = mloop;
for (i = 0; i < cddm2->dm.numLoopData; i++, ml++) {
- if (newe[ml->e] != -1)
- ml->e = newe[ml->e];
- if (newv[ml->v] != -1)
- ml->v = newv[ml->v];
-
+ /* Edge remapping has already be done in main loop handling part above. */
+ BLI_assert(newv[ml->v] != -1);
+ ml->v = newv[ml->v];
+
CustomData_copy_data(&dm->loopData, &cddm2->dm.loopData, oldl[i], i, 1);
}
diff --git a/source/blender/blenkernel/intern/colortools.c b/source/blender/blenkernel/intern/colortools.c
index b3a0895d063..ee0f904c3a6 100644
--- a/source/blender/blenkernel/intern/colortools.c
+++ b/source/blender/blenkernel/intern/colortools.c
@@ -130,7 +130,7 @@ void curvemapping_free(CurveMapping *cumap)
}
}
-void curvemapping_copy_data(CurveMapping *target, CurveMapping *cumap)
+void curvemapping_copy_data(CurveMapping *target, const CurveMapping *cumap)
{
int a;
@@ -146,7 +146,7 @@ void curvemapping_copy_data(CurveMapping *target, CurveMapping *cumap)
}
}
-CurveMapping *curvemapping_copy(CurveMapping *cumap)
+CurveMapping *curvemapping_copy(const CurveMapping *cumap)
{
if (cumap) {
CurveMapping *cumapn = MEM_dupallocN(cumap);
diff --git a/source/blender/blenkernel/intern/constraint.c b/source/blender/blenkernel/intern/constraint.c
index 58ad171ee20..07a6b304dff 100644
--- a/source/blender/blenkernel/intern/constraint.c
+++ b/source/blender/blenkernel/intern/constraint.c
@@ -790,7 +790,7 @@ static void default_get_tarmat(bConstraint *con, bConstraintOb *UNUSED(cob), bCo
ct = ctn; \
} \
} (void)0
-
+
/* --------- ChildOf Constraint ------------ */
static void childof_new_data(void *cdata)
@@ -4387,19 +4387,17 @@ static void transformcache_copy(bConstraint *con, bConstraint *srccon)
BLI_strncpy(dst->object_path, src->object_path, sizeof(dst->object_path));
dst->cache_file = src->cache_file;
- if (dst->cache_file) {
- id_us_plus(&dst->cache_file->id);
+#ifdef WITH_ALEMBIC
+ if (dst->reader) {
+ CacheReader_incref(dst->reader);
}
+#endif
}
static void transformcache_free(bConstraint *con)
{
bTransformCacheConstraint *data = con->data;
- if (data->cache_file) {
- id_us_min(&data->cache_file->id);
- }
-
if (data->reader) {
#ifdef WITH_ALEMBIC
CacheReader_free(data->reader);
diff --git a/source/blender/blenkernel/intern/curve.c b/source/blender/blenkernel/intern/curve.c
index 4ba9ad281a3..1cecf41af55 100644
--- a/source/blender/blenkernel/intern/curve.c
+++ b/source/blender/blenkernel/intern/curve.c
@@ -187,7 +187,7 @@ Curve *BKE_curve_add(Main *bmain, const char *name, int type)
return cu;
}
-Curve *BKE_curve_copy(Main *bmain, Curve *cu)
+Curve *BKE_curve_copy(Main *bmain, const Curve *cu)
{
Curve *cun;
int a;
@@ -468,7 +468,7 @@ void BKE_nurbList_free(ListBase *lb)
BLI_listbase_clear(lb);
}
-Nurb *BKE_nurb_duplicate(Nurb *nu)
+Nurb *BKE_nurb_duplicate(const Nurb *nu)
{
Nurb *newnu;
int len;
@@ -532,7 +532,7 @@ Nurb *BKE_nurb_copy(Nurb *src, int pntsu, int pntsv)
return newnu;
}
-void BKE_nurbList_duplicate(ListBase *lb1, ListBase *lb2)
+void BKE_nurbList_duplicate(ListBase *lb1, const ListBase *lb2)
{
Nurb *nu, *nun;
@@ -744,6 +744,7 @@ BezTriple *BKE_nurb_bezt_get_prev(Nurb *nu, BezTriple *bezt)
BezTriple *bezt_prev;
BLI_assert(ARRAY_HAS_ITEM(bezt, nu->bezt, nu->pntsu));
+ BLI_assert(nu->pntsv == 1);
if (bezt == nu->bezt) {
if (nu->flagu & CU_NURB_CYCLIC) {
@@ -765,6 +766,7 @@ BPoint *BKE_nurb_bpoint_get_prev(Nurb *nu, BPoint *bp)
BPoint *bp_prev;
BLI_assert(ARRAY_HAS_ITEM(bp, nu->bp, nu->pntsu));
+ BLI_assert(nu->pntsv == 1);
if (bp == nu->bp) {
if (nu->flagu & CU_NURB_CYCLIC) {
@@ -781,7 +783,7 @@ BPoint *BKE_nurb_bpoint_get_prev(Nurb *nu, BPoint *bp)
return bp_prev;
}
-void BKE_nurb_bezt_calc_normal(struct Nurb *UNUSED(nu), struct BezTriple *bezt, float r_normal[3])
+void BKE_nurb_bezt_calc_normal(struct Nurb *UNUSED(nu), BezTriple *bezt, float r_normal[3])
{
/* calculate the axis matrix from the spline */
float dir_prev[3], dir_next[3];
@@ -796,7 +798,7 @@ void BKE_nurb_bezt_calc_normal(struct Nurb *UNUSED(nu), struct BezTriple *bezt,
normalize_v3(r_normal);
}
-void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_plane[3])
+void BKE_nurb_bezt_calc_plane(struct Nurb *nu, BezTriple *bezt, float r_plane[3])
{
float dir_prev[3], dir_next[3];
@@ -833,7 +835,7 @@ void BKE_nurb_bezt_calc_plane(struct Nurb *nu, struct BezTriple *bezt, float r_p
normalize_v3(r_plane);
}
-void BKE_nurb_bpoint_calc_normal(struct Nurb *nu, struct BPoint *bp, float r_normal[3])
+void BKE_nurb_bpoint_calc_normal(struct Nurb *nu, BPoint *bp, float r_normal[3])
{
BPoint *bp_prev = BKE_nurb_bpoint_get_prev(nu, bp);
BPoint *bp_next = BKE_nurb_bpoint_get_next(nu, bp);
@@ -856,6 +858,34 @@ void BKE_nurb_bpoint_calc_normal(struct Nurb *nu, struct BPoint *bp, float r_nor
normalize_v3(r_normal);
}
+void BKE_nurb_bpoint_calc_plane(struct Nurb *nu, BPoint *bp, float r_plane[3])
+{
+ BPoint *bp_prev = BKE_nurb_bpoint_get_prev(nu, bp);
+ BPoint *bp_next = BKE_nurb_bpoint_get_next(nu, bp);
+
+ float dir_prev[3] = {0.0f}, dir_next[3] = {0.0f};
+
+ if (bp_prev) {
+ sub_v3_v3v3(dir_prev, bp_prev->vec, bp->vec);
+ normalize_v3(dir_prev);
+ }
+ if (bp_next) {
+ sub_v3_v3v3(dir_next, bp->vec, bp_next->vec);
+ normalize_v3(dir_next);
+ }
+ cross_v3_v3v3(r_plane, dir_prev, dir_next);
+
+ /* matches with bones more closely */
+ {
+ float dir_mid[3], tvec[3];
+ add_v3_v3v3(dir_mid, dir_prev, dir_next);
+ cross_v3_v3v3(tvec, r_plane, dir_mid);
+ copy_v3_v3(r_plane, tvec);
+ }
+
+ normalize_v3(r_plane);
+}
+
/* ~~~~~~~~~~~~~~~~~~~~Non Uniform Rational B Spline calculations ~~~~~~~~~~~ */
diff --git a/source/blender/blenkernel/intern/customdata.c b/source/blender/blenkernel/intern/customdata.c
index 7c3f0ac630d..0939d35ed8d 100644
--- a/source/blender/blenkernel/intern/customdata.c
+++ b/source/blender/blenkernel/intern/customdata.c
@@ -1944,11 +1944,15 @@ void *CustomData_add_layer_named(CustomData *data, int type, int alloctype,
bool CustomData_free_layer(CustomData *data, int type, int totelem, int index)
{
- const int n = index - CustomData_get_layer_index(data, type);
+ const int index_first = CustomData_get_layer_index(data, type);
+ const int n = index - index_first;
int i;
-
- if (index < 0)
+
+ BLI_assert(index >= index_first);
+ if ((index_first == -1) || (n < 0)) {
return false;
+ }
+ BLI_assert(data->layers[index].type == type);
customData_free_layer__internal(&data->layers[index], totelem);
@@ -1993,8 +1997,10 @@ bool CustomData_free_layer_active(CustomData *data, int type, int totelem)
void CustomData_free_layers(CustomData *data, int type, int totelem)
{
- while (CustomData_has_layer(data, type))
- CustomData_free_layer_active(data, type, totelem);
+ const int index = CustomData_get_layer_index(data, type);
+ while (CustomData_free_layer(data, type, totelem, index)) {
+ /* pass */
+ }
}
bool CustomData_has_layer(const CustomData *data, int type)
diff --git a/source/blender/blenkernel/intern/deform.c b/source/blender/blenkernel/intern/deform.c
index 13b1aab5e1c..69baaf5e58a 100644
--- a/source/blender/blenkernel/intern/deform.c
+++ b/source/blender/blenkernel/intern/deform.c
@@ -76,7 +76,7 @@ bDeformGroup *BKE_defgroup_new(Object *ob, const char *name)
return defgroup;
}
-void defgroup_copy_list(ListBase *outbase, ListBase *inbase)
+void defgroup_copy_list(ListBase *outbase, const ListBase *inbase)
{
bDeformGroup *defgroup, *defgroupn;
@@ -88,7 +88,7 @@ void defgroup_copy_list(ListBase *outbase, ListBase *inbase)
}
}
-bDeformGroup *defgroup_duplicate(bDeformGroup *ingroup)
+bDeformGroup *defgroup_duplicate(const bDeformGroup *ingroup)
{
bDeformGroup *outgroup;
diff --git a/source/blender/blenkernel/intern/depsgraph.c b/source/blender/blenkernel/intern/depsgraph.c
index 302e55a1f5a..019e0df1623 100644
--- a/source/blender/blenkernel/intern/depsgraph.c
+++ b/source/blender/blenkernel/intern/depsgraph.c
@@ -3053,7 +3053,7 @@ void DAG_id_type_tag(Main *bmain, short idtype)
DAG_id_type_tag(bmain, ID_SCE);
}
- atomic_fetch_and_or_uint8((uint8_t*)&bmain->id_tag_update[BKE_idcode_to_index(idtype)], 1);
+ atomic_fetch_and_or_uint8((uint8_t *)&bmain->id_tag_update[BKE_idcode_to_index(idtype)], 1);
}
int DAG_id_type_tagged(Main *bmain, short idtype)
diff --git a/source/blender/blenkernel/intern/displist.c b/source/blender/blenkernel/intern/displist.c
index f8a9d57f579..2a300cbe47b 100644
--- a/source/blender/blenkernel/intern/displist.c
+++ b/source/blender/blenkernel/intern/displist.c
@@ -167,10 +167,12 @@ void BKE_displist_normals_add(ListBase *lb)
if (dl->nors == NULL) {
dl->nors = MEM_callocN(sizeof(float) * 3, "dlnors");
- if (dl->verts[2] < 0.0f)
+ if (dl->flag & DL_BACK_CURVE) {
dl->nors[2] = -1.0f;
- else
+ }
+ else {
dl->nors[2] = 1.0f;
+ }
}
}
else if (dl->type == DL_SURF) {
@@ -469,6 +471,7 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, const float normal_proj
sf_arena = BLI_memarena_new(BLI_SCANFILL_ARENA_SIZE, __func__);
while (cont) {
+ int dl_flag_accum = 0;
cont = 0;
totvert = 0;
nextcol = 0;
@@ -514,6 +517,7 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, const float normal_proj
nextcol = 1;
}
}
+ dl_flag_accum |= dl->flag;
}
dl = dl->next;
}
@@ -526,6 +530,7 @@ void BKE_displist_fill(ListBase *dispbase, ListBase *to, const float normal_proj
if (tot) {
dlnew = MEM_callocN(sizeof(DispList), "filldisplist");
dlnew->type = DL_INDEX3;
+ dlnew->flag = (dl_flag_accum & (DL_BACK_CURVE | DL_FRONT_CURVE));
dlnew->col = colnr;
dlnew->nr = totvert;
dlnew->parts = tot;
@@ -603,6 +608,7 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
dlnew->nr = dl->parts;
dlnew->parts = 1;
dlnew->type = DL_POLY;
+ dlnew->flag = DL_BACK_CURVE;
dlnew->col = dl->col;
dlnew->charidx = dl->charidx;
@@ -623,6 +629,7 @@ static void bevels_to_filledpoly(Curve *cu, ListBase *dispbase)
dlnew->nr = dl->parts;
dlnew->parts = 1;
dlnew->type = DL_POLY;
+ dlnew->flag = DL_FRONT_CURVE;
dlnew->col = dl->col;
dlnew->charidx = dl->charidx;
diff --git a/source/blender/blenkernel/intern/dynamicpaint.c b/source/blender/blenkernel/intern/dynamicpaint.c
index c525e75b825..1db69d23607 100644
--- a/source/blender/blenkernel/intern/dynamicpaint.c
+++ b/source/blender/blenkernel/intern/dynamicpaint.c
@@ -1897,8 +1897,8 @@ static DerivedMesh *dynamicPaint_Modifier_apply(
/* apply weights into a vertex group, if doesnt exists add a new layer */
if (defgrp_index != -1 && !dvert && (surface->output_name[0] != '\0')) {
- dvert = CustomData_add_layer_named(&result->vertData, CD_MDEFORMVERT, CD_CALLOC,
- NULL, sData->total_points, surface->output_name);
+ dvert = CustomData_add_layer(&result->vertData, CD_MDEFORMVERT, CD_CALLOC,
+ NULL, sData->total_points);
}
if (defgrp_index != -1 && dvert) {
int i;
diff --git a/source/blender/blenkernel/intern/editderivedmesh.c b/source/blender/blenkernel/intern/editderivedmesh.c
index 2fffa0dea28..ab614b8f460 100644
--- a/source/blender/blenkernel/intern/editderivedmesh.c
+++ b/source/blender/blenkernel/intern/editderivedmesh.c
@@ -149,6 +149,8 @@ static void emDM_ensurePolyCenters(EditDerivedBMesh *bmdm)
const float (*vertexCos)[3];
vertexCos = bmdm->vertexCos;
+ BM_mesh_elem_index_ensure(bm, BM_VERT);
+
BM_ITER_MESH_INDEX (efa, &fiter, bm, BM_FACES_OF_MESH, i) {
BM_face_calc_center_mean_vcos(bm, efa, polyCos[i], vertexCos);
}
@@ -487,8 +489,6 @@ static void emDM_calc_loop_tangents(
EditDerivedBMesh *bmdm = (EditDerivedBMesh *)dm;
BMEditMesh *em = bmdm->em;
BMesh *bm = bmdm->em->bm;
- if (CustomData_number_of_layers(&bm->ldata, CD_MLOOPUV) == 0)
- return;
int act_uv_n = -1;
int ren_uv_n = -1;
@@ -496,7 +496,7 @@ static void emDM_calc_loop_tangents(
bool calc_ren = false;
char act_uv_name[MAX_NAME];
char ren_uv_name[MAX_NAME];
- char tangent_mask = 0;
+ short tangent_mask = 0;
DM_calc_loop_tangents_step_0(
&bm->ldata, calc_active_tangent, tangent_names, tangent_names_count,
@@ -506,6 +506,8 @@ static void emDM_calc_loop_tangents(
for (int i = 0; i < tangent_names_count; i++)
if (tangent_names[i][0])
DM_add_named_tangent_layer_for_uv(&bm->ldata, &dm->loopData, dm->numLoopData, tangent_names[i]);
+ if ((tangent_mask & DM_TANGENT_MASK_ORCO) && CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, "") == -1)
+ CustomData_add_layer_named(&dm->loopData, CD_TANGENT, CD_CALLOC, NULL, dm->numLoopData, "");
if (calc_act && act_uv_name[0])
DM_add_named_tangent_layer_for_uv(&bm->ldata, &dm->loopData, dm->numLoopData, act_uv_name);
if (calc_ren && ren_uv_name[0])
@@ -572,7 +574,17 @@ static void emDM_calc_loop_tangents(
continue;
/* needed for orco lookups */
htype_index |= BM_VERT;
+ dm->tangent_mask |= DM_TANGENT_MASK_ORCO;
+ }
+ else {
+ /* Fill the resulting tangent_mask */
+ int uv_ind = CustomData_get_named_layer_index(&bm->ldata, CD_MLOOPUV, dm->loopData.layers[index].name);
+ int uv_start = CustomData_get_layer_index(&bm->ldata, CD_MLOOPUV);
+ BLI_assert(uv_ind != -1 && uv_start != -1);
+ BLI_assert(uv_ind - uv_start < MAX_MTFACE);
+ dm->tangent_mask |= 1 << (uv_ind - uv_start);
}
+
if (mesh2tangent->precomputedFaceNormals) {
/* needed for face normal lookups */
htype_index |= BM_FACE;
@@ -582,12 +594,6 @@ static void emDM_calc_loop_tangents(
mesh2tangent->looptris = (const BMLoop *(*)[3])em->looptris;
mesh2tangent->tangent = dm->loopData.layers[index].data;
- /* Fill the resulting tangent_mask */
- int uv_ind = CustomData_get_named_layer_index(&bm->ldata, CD_MLOOPUV, dm->loopData.layers[index].name);
- int uv_start = CustomData_get_layer_index(&bm->ldata, CD_MLOOPUV);
- BLI_assert(uv_ind != -1 && uv_start != -1);
- BLI_assert(uv_ind - uv_start < MAX_MTFACE);
- dm->tangent_mask |= 1 << (uv_ind - uv_start);
BLI_task_pool_push(task_pool, emDM_calc_loop_tangents_thread, mesh2tangent, false, TASK_PRIORITY_LOW);
}
@@ -602,15 +608,20 @@ static void emDM_calc_loop_tangents(
#undef USE_LOOPTRI_DETECT_QUADS
#endif
}
+
/* Update active layer index */
- int uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, act_uv_n);
- int tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, bm->ldata.layers[uv_index].name);
- CustomData_set_layer_active_index(&dm->loopData, CD_TANGENT, tan_index);
+ int act_uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, act_uv_n);
+ if (act_uv_index >= 0) {
+ int tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, bm->ldata.layers[act_uv_index].name);
+ CustomData_set_layer_active_index(&dm->loopData, CD_TANGENT, tan_index);
+ } /* else tangent has been built from orco */
/* Update render layer index */
- uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, ren_uv_n);
- tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, bm->ldata.layers[uv_index].name);
- CustomData_set_layer_render_index(&dm->loopData, CD_TANGENT, tan_index);
+ int ren_uv_index = CustomData_get_layer_index_n(&bm->ldata, CD_MLOOPUV, ren_uv_n);
+ if (ren_uv_index >= 0) {
+ int tan_index = CustomData_get_named_layer_index(&dm->loopData, CD_TANGENT, bm->ldata.layers[ren_uv_index].name);
+ CustomData_set_layer_render_index(&dm->loopData, CD_TANGENT, tan_index);
+ } /* else tangent has been built from orco */
}
/** \} */
@@ -2053,20 +2064,25 @@ static void *emDM_getTessFaceDataArray(DerivedMesh *dm, int type)
/* layers are store per face for editmesh, we convert to a temporary
* data layer array in the derivedmesh when these are requested */
if (type == CD_MTFACE || type == CD_MCOL) {
- const int type_from = (type == CD_MTFACE) ? CD_MTEXPOLY : CD_MLOOPCOL;
- int index;
const char *bmdata;
char *data;
- index = CustomData_get_layer_index(&bm->pdata, type_from);
+ bool has_type_source = false;
- if (index != -1) {
+ if (type == CD_MTFACE) {
+ has_type_source = CustomData_has_layer(&bm->pdata, CD_MTEXPOLY);
+ }
+ else {
+ has_type_source = CustomData_has_layer(&bm->ldata, CD_MLOOPCOL);
+ }
+
+ if (has_type_source) {
/* offset = bm->pdata.layers[index].offset; */ /* UNUSED */
BMLoop *(*looptris)[3] = bmdm->em->looptris;
const int size = CustomData_sizeof(type);
int i, j;
DM_add_tessface_layer(dm, type, CD_CALLOC, NULL);
- index = CustomData_get_layer_index(&dm->faceData, type);
+ const int index = CustomData_get_layer_index(&dm->faceData, type);
dm->faceData.layers[index].flag |= CD_FLAG_TEMPORARY;
data = datalayer = DM_get_tessface_data_layer(dm, type);
@@ -2625,7 +2641,7 @@ static void statvis_calc_distort(
vertexCos[BM_elem_index_get(l_iter->next->v)]);
}
else {
- BM_loop_calc_face_normal(l_iter, no_corner);
+ BM_loop_calc_face_normal_safe(l_iter, no_corner);
}
/* simple way to detect (what is most likely) concave */
if (dot_v3v3(f_no, no_corner) < 0.0f) {
diff --git a/source/blender/blenkernel/intern/effect.c b/source/blender/blenkernel/intern/effect.c
index 4eee24b378f..38f5c00941c 100644
--- a/source/blender/blenkernel/intern/effect.c
+++ b/source/blender/blenkernel/intern/effect.c
@@ -986,19 +986,19 @@ static void do_physical_effector(EffectorCache *eff, EffectorData *efd, Effected
*/
void pdDoEffectors(ListBase *effectors, ListBase *colliders, EffectorWeights *weights, EffectedPoint *point, float *force, float *impulse)
{
-/*
- * Modifies the force on a particle according to its
- * relation with the effector object
- * Different kind of effectors include:
- * Forcefields: Gravity-like attractor
- * (force power is related to the inverse of distance to the power of a falloff value)
- * Vortex fields: swirling effectors
- * (particles rotate around Z-axis of the object. otherwise, same relation as)
- * (Forcefields, but this is not done through a force/acceleration)
- * Guide: particles on a path
- * (particles are guided along a curve bezier or old nurbs)
- * (is independent of other effectors)
- */
+ /*
+ * Modifies the force on a particle according to its
+ * relation with the effector object
+ * Different kind of effectors include:
+ * Forcefields: Gravity-like attractor
+ * (force power is related to the inverse of distance to the power of a falloff value)
+ * Vortex fields: swirling effectors
+ * (particles rotate around Z-axis of the object. otherwise, same relation as)
+ * (Forcefields, but this is not done through a force/acceleration)
+ * Guide: particles on a path
+ * (particles are guided along a curve bezier or old nurbs)
+ * (is independent of other effectors)
+ */
EffectorCache *eff;
EffectorData efd;
int p=0, tot = 1, step = 1;
diff --git a/source/blender/blenkernel/intern/fcurve.c b/source/blender/blenkernel/intern/fcurve.c
index 7dbc43e0a32..db6c533ab57 100644
--- a/source/blender/blenkernel/intern/fcurve.c
+++ b/source/blender/blenkernel/intern/fcurve.c
@@ -126,7 +126,7 @@ void free_fcurves(ListBase *list)
/* ---------------------- Copy --------------------------- */
/* duplicate an F-Curve */
-FCurve *copy_fcurve(FCurve *fcu)
+FCurve *copy_fcurve(const FCurve *fcu)
{
FCurve *fcu_d;
@@ -1805,7 +1805,7 @@ void fcurve_free_driver(FCurve *fcu)
}
/* This makes a copy of the given driver */
-ChannelDriver *fcurve_copy_driver(ChannelDriver *driver)
+ChannelDriver *fcurve_copy_driver(const ChannelDriver *driver)
{
ChannelDriver *ndriver;
@@ -1945,7 +1945,7 @@ float evaluate_driver(PathResolvedRNA *anim_rna, ChannelDriver *driver, const fl
BLI_mutex_unlock(&python_driver_lock);
}
#else /* WITH_PYTHON*/
- (void)evaltime;
+ UNUSED_VARS(anim_rna, evaltime);
#endif /* WITH_PYTHON*/
break;
}
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index 2c301c04100..f1732ee7a9a 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -116,7 +116,7 @@ static void fcm_generator_free(FModifier *fcm)
MEM_freeN(data->coefficients);
}
-static void fcm_generator_copy(FModifier *fcm, FModifier *src)
+static void fcm_generator_copy(FModifier *fcm, const FModifier *src)
{
FMod_Generator *gen = (FMod_Generator *)fcm->data;
FMod_Generator *ogen = (FMod_Generator *)src->data;
@@ -386,7 +386,7 @@ static void fcm_envelope_free(FModifier *fcm)
MEM_freeN(env->data);
}
-static void fcm_envelope_copy(FModifier *fcm, FModifier *src)
+static void fcm_envelope_copy(FModifier *fcm, const FModifier *src)
{
FMod_Envelope *env = (FMod_Envelope *)fcm->data;
FMod_Envelope *oenv = (FMod_Envelope *)src->data;
@@ -877,7 +877,7 @@ static void fcm_python_new_data(void *mdata)
data->prop->type = IDP_GROUP;
}
-static void fcm_python_copy(FModifier *fcm, FModifier *src)
+static void fcm_python_copy(FModifier *fcm, const FModifier *src)
{
FMod_Python *pymod = (FMod_Python *)fcm->data;
FMod_Python *opymod = (FMod_Python *)src->data;
@@ -1040,7 +1040,7 @@ static void fmods_init_typeinfo(void)
/* This function should be used for getting the appropriate type-info when only
* a F-Curve modifier type is known
*/
-const FModifierTypeInfo *get_fmodifier_typeinfo(int type)
+const FModifierTypeInfo *get_fmodifier_typeinfo(const int type)
{
/* initialize the type-info list? */
if (FMI_INIT) {
@@ -1065,7 +1065,7 @@ const FModifierTypeInfo *get_fmodifier_typeinfo(int type)
/* This function should always be used to get the appropriate type-info, as it
* has checks which prevent segfaults in some weird cases.
*/
-const FModifierTypeInfo *fmodifier_get_typeinfo(FModifier *fcm)
+const FModifierTypeInfo *fmodifier_get_typeinfo(const FModifier *fcm)
{
/* only return typeinfo for valid modifiers */
if (fcm)
@@ -1117,7 +1117,7 @@ FModifier *add_fmodifier(ListBase *modifiers, int type)
}
/* Make a copy of the specified F-Modifier */
-FModifier *copy_fmodifier(FModifier *src)
+FModifier *copy_fmodifier(const FModifier *src)
{
const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(src);
FModifier *dst;
@@ -1142,7 +1142,7 @@ FModifier *copy_fmodifier(FModifier *src)
}
/* Duplicate all of the F-Modifiers in the Modifier stacks */
-void copy_fmodifiers(ListBase *dst, ListBase *src)
+void copy_fmodifiers(ListBase *dst, const ListBase *src)
{
FModifier *fcm, *srcfcm;
diff --git a/source/blender/blenkernel/intern/font.c b/source/blender/blenkernel/intern/font.c
index 580842fe176..401fed74c52 100644
--- a/source/blender/blenkernel/intern/font.c
+++ b/source/blender/blenkernel/intern/font.c
@@ -695,10 +695,14 @@ bool BKE_vfont_to_curve_ex(Main *bmain, Object *ob, int mode, ListBase *r_nubase
if (ef->selboxes)
MEM_freeN(ef->selboxes);
- if (BKE_vfont_select_get(ob, &selstart, &selend))
- ef->selboxes = MEM_callocN((selend - selstart + 1) * sizeof(EditFontSelBox), "font selboxes");
- else
+ if (BKE_vfont_select_get(ob, &selstart, &selend)) {
+ ef->selboxes_len = (selend - selstart) + 1;
+ ef->selboxes = MEM_callocN(ef->selboxes_len * sizeof(EditFontSelBox), "font selboxes");
+ }
+ else {
+ ef->selboxes_len = 0;
ef->selboxes = NULL;
+ }
selboxes = ef->selboxes;
}
diff --git a/source/blender/blenkernel/intern/gpencil.c b/source/blender/blenkernel/intern/gpencil.c
index 30fc8915d46..758438bb051 100644
--- a/source/blender/blenkernel/intern/gpencil.c
+++ b/source/blender/blenkernel/intern/gpencil.c
@@ -754,7 +754,7 @@ bGPDlayer *BKE_gpencil_layer_duplicate(const bGPDlayer *gpl_src)
}
/* make a copy of a given gpencil datablock */
-bGPdata *BKE_gpencil_data_duplicate(Main *bmain, bGPdata *gpd_src, bool internal_copy)
+bGPdata *BKE_gpencil_data_duplicate(Main *bmain, const bGPdata *gpd_src, bool internal_copy)
{
const bGPDlayer *gpl_src;
bGPDlayer *gpl_dst;
diff --git a/source/blender/blenkernel/intern/group.c b/source/blender/blenkernel/intern/group.c
index 9b011dbb003..932f41ac4ba 100644
--- a/source/blender/blenkernel/intern/group.c
+++ b/source/blender/blenkernel/intern/group.c
@@ -80,6 +80,8 @@ Group *BKE_group_add(Main *bmain, const char *name)
Group *group;
group = BKE_libblock_alloc(bmain, ID_GR, name);
+ id_us_min(&group->id);
+ id_us_ensure_real(&group->id);
group->layer = (1 << 20) - 1;
group->preview = NULL;
@@ -87,7 +89,7 @@ Group *BKE_group_add(Main *bmain, const char *name)
return group;
}
-Group *BKE_group_copy(Main *bmain, Group *group)
+Group *BKE_group_copy(Main *bmain, const Group *group)
{
Group *groupn;
diff --git a/source/blender/blenkernel/intern/icons.c b/source/blender/blenkernel/intern/icons.c
index 7669c4ba112..bccf9307912 100644
--- a/source/blender/blenkernel/intern/icons.c
+++ b/source/blender/blenkernel/intern/icons.c
@@ -204,7 +204,7 @@ void BKE_previewimg_clear(struct PreviewImage *prv)
}
}
-PreviewImage *BKE_previewimg_copy(PreviewImage *prv)
+PreviewImage *BKE_previewimg_copy(const PreviewImage *prv)
{
PreviewImage *prv_img = NULL;
int i;
@@ -222,7 +222,7 @@ PreviewImage *BKE_previewimg_copy(PreviewImage *prv)
}
/** Duplicate preview image from \a id and clear icon_id, to be used by datablock copy functions. */
-void BKE_previewimg_id_copy(ID *new_id, ID *old_id)
+void BKE_previewimg_id_copy(ID *new_id, const ID *old_id)
{
PreviewImage **old_prv_p = BKE_previewimg_id_get_p(old_id);
PreviewImage **new_prv_p = BKE_previewimg_id_get_p(new_id);
@@ -239,7 +239,7 @@ void BKE_previewimg_id_copy(ID *new_id, ID *old_id)
}
}
-PreviewImage **BKE_previewimg_id_get_p(ID *id)
+PreviewImage **BKE_previewimg_id_get_p(const ID *id)
{
switch (GS(id->name)) {
#define ID_PRV_CASE(id_code, id_struct) case id_code: { return &((id_struct *)id)->preview; } ((void)0)
diff --git a/source/blender/blenkernel/intern/idprop.c b/source/blender/blenkernel/intern/idprop.c
index 5e4e8eb34ad..e98181be444 100644
--- a/source/blender/blenkernel/intern/idprop.c
+++ b/source/blender/blenkernel/intern/idprop.c
@@ -117,14 +117,14 @@ IDProperty *IDP_CopyIDPArray(const IDProperty *array)
return narray;
}
-void IDP_FreeIDPArray(IDProperty *prop)
+static void IDP_FreeIDPArray(IDProperty *prop, const bool do_id_user)
{
int i;
BLI_assert(prop->type == IDP_IDPARRAY);
for (i = 0; i < prop->len; i++)
- IDP_FreeProperty(GETPROP(prop, i));
+ IDP_FreeProperty_ex(GETPROP(prop, i), do_id_user);
if (prop->data.pointer)
MEM_freeN(prop->data.pointer);
@@ -437,22 +437,24 @@ void IDP_FreeString(IDProperty *prop)
/* -------------------------------------------------------------------- */
-/* ID Type (not in use yet) */
+/* ID Type */
-/** \name IDProperty ID API (unused)
+/** \name IDProperty ID API
* \{ */
-void IDP_LinkID(IDProperty *prop, ID *id)
-{
- if (prop->data.pointer)
- id_us_min(((ID *)prop->data.pointer));
- prop->data.pointer = id;
- id_us_plus(id);
-}
-void IDP_UnlinkID(IDProperty *prop)
+static IDProperty *IDP_CopyID(const IDProperty *prop)
{
- id_us_min(((ID *)prop->data.pointer));
+ IDProperty *newp;
+
+ BLI_assert(prop->type == IDP_ID);
+ newp = idp_generic_copy(prop);
+
+ newp->data.pointer = prop->data.pointer;
+ id_us_plus(IDP_Id(newp));
+
+ return newp;
}
+
/** \} */
@@ -710,13 +712,13 @@ IDProperty *IDP_GetPropertyTypeFromGroup(IDProperty *prop, const char *name, con
* This is because all ID Property freeing functions free only direct data (not the ID Property
* struct itself), but for Groups the child properties *are* considered
* direct data. */
-static void IDP_FreeGroup(IDProperty *prop)
+static void IDP_FreeGroup(IDProperty *prop, const bool do_id_user)
{
IDProperty *loop;
BLI_assert(prop->type == IDP_GROUP);
for (loop = prop->data.group.first; loop; loop = loop->next) {
- IDP_FreeProperty(loop);
+ IDP_FreeProperty_ex(loop, do_id_user);
}
BLI_freelistN(&prop->data.group);
}
@@ -733,12 +735,51 @@ IDProperty *IDP_CopyProperty(const IDProperty *prop)
switch (prop->type) {
case IDP_GROUP: return IDP_CopyGroup(prop);
case IDP_STRING: return IDP_CopyString(prop);
+ case IDP_ID: return IDP_CopyID(prop);
case IDP_ARRAY: return IDP_CopyArray(prop);
case IDP_IDPARRAY: return IDP_CopyIDPArray(prop);
default: return idp_generic_copy(prop);
}
}
+/* Updates ID pointers after an object has been copied */
+/* TODO Nuke this once its only user has been correctly converted to use generic ID management from BKE_library! */
+void IDP_RelinkProperty(struct IDProperty *prop)
+{
+ if (!prop)
+ return;
+
+ switch (prop->type) {
+ case IDP_GROUP:
+ {
+ for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) {
+ IDP_RelinkProperty(loop);
+ }
+ break;
+ }
+ case IDP_IDPARRAY:
+ {
+ IDProperty *idp_array = IDP_Array(prop);
+ for (int i = 0; i < prop->len; i++) {
+ IDP_RelinkProperty(&idp_array[i]);
+ }
+ break;
+ }
+ case IDP_ID:
+ {
+ ID *id = IDP_Id(prop);
+ if (id && id->newid) {
+ id_us_min(IDP_Id(prop));
+ prop->data.pointer = id->newid;
+ id_us_plus(IDP_Id(prop));
+ }
+ break;
+ }
+ default:
+ break; /* Nothing to do for other IDProp types. */
+ }
+}
+
/**
* Get the Group property that contains the id properties for ID id. Set create_if_needed
* to create the Group property and attach it to id if it doesn't exist; otherwise
@@ -835,6 +876,8 @@ bool IDP_EqualsProperties_ex(IDProperty *prop1, IDProperty *prop2, const bool is
return false;
return true;
}
+ case IDP_ID:
+ return (IDP_Id(prop1) == IDP_Id(prop2));
default:
/* should never get here */
BLI_assert(0);
@@ -910,6 +953,7 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *
prop->len = prop->totallen = val->array.len;
break;
}
+ printf("%s: bad array type.\n", __func__);
return NULL;
}
case IDP_STRING:
@@ -956,6 +1000,14 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *
/* heh I think all needed values are set properly by calloc anyway :) */
break;
}
+ case IDP_ID:
+ {
+ prop = MEM_callocN(sizeof(IDProperty), "IDProperty datablock");
+ prop->data.pointer = (void *)val->id;
+ prop->type = IDP_ID;
+ id_us_plus(IDP_Id(prop));
+ break;
+ }
default:
{
prop = MEM_callocN(sizeof(IDProperty), "IDProperty array");
@@ -970,11 +1022,10 @@ IDProperty *IDP_New(const char type, const IDPropertyTemplate *val, const char *
}
/**
- * \note this will free all child properties of list arrays and groups!
- * Also, note that this does NOT unlink anything! Plus it doesn't free
- * the actual struct IDProperty struct either.
+ * \note This will free allocated data, all child properties of arrays and groups, and unlink IDs!
+ * But it does not free the actual IDProperty struct itself.
*/
-void IDP_FreeProperty(IDProperty *prop)
+void IDP_FreeProperty_ex(IDProperty *prop, const bool do_id_user)
{
switch (prop->type) {
case IDP_ARRAY:
@@ -984,14 +1035,24 @@ void IDP_FreeProperty(IDProperty *prop)
IDP_FreeString(prop);
break;
case IDP_GROUP:
- IDP_FreeGroup(prop);
+ IDP_FreeGroup(prop, do_id_user);
break;
case IDP_IDPARRAY:
- IDP_FreeIDPArray(prop);
+ IDP_FreeIDPArray(prop, do_id_user);
+ break;
+ case IDP_ID:
+ if (do_id_user) {
+ id_us_min(IDP_Id(prop));
+ }
break;
}
}
+void IDP_FreeProperty(IDProperty *prop)
+{
+ IDP_FreeProperty_ex(prop, true);
+}
+
void IDP_ClearProperty(IDProperty *prop)
{
IDP_FreeProperty(prop);
@@ -999,18 +1060,4 @@ void IDP_ClearProperty(IDProperty *prop)
prop->len = prop->totallen = 0;
}
-/**
- * Unlinks any struct IDProperty<->ID linkage that might be going on.
- *
- * \note currently unused
- */
-void IDP_UnlinkProperty(IDProperty *prop)
-{
- switch (prop->type) {
- case IDP_ID:
- IDP_UnlinkID(prop);
- break;
- }
-}
-
/** \} */
diff --git a/source/blender/blenkernel/intern/image.c b/source/blender/blenkernel/intern/image.c
index 318f6480aaf..abe08def197 100644
--- a/source/blender/blenkernel/intern/image.c
+++ b/source/blender/blenkernel/intern/image.c
@@ -62,6 +62,7 @@
#include "BLI_blenlib.h"
#include "BLI_math_vector.h"
+#include "BLI_mempool.h"
#include "BLI_threads.h"
#include "BLI_timecode.h" /* for stamp timecode format */
#include "BLI_utildefines.h"
@@ -433,7 +434,7 @@ static void copy_image_packedfiles(ListBase *lb_dst, const ListBase *lb_src)
}
/* empty image block, of similar type and filename */
-Image *BKE_image_copy(Main *bmain, Image *ima)
+Image *BKE_image_copy(Main *bmain, const Image *ima)
{
Image *nima = image_alloc(bmain, ima->id.name + 2, ima->source, ima->type);
@@ -1238,7 +1239,7 @@ char BKE_imtype_valid_channels(const char imtype, bool write_file)
switch (imtype) {
case R_IMF_IMTYPE_BMP:
if (write_file) break;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case R_IMF_IMTYPE_TARGA:
case R_IMF_IMTYPE_RAWTGA:
case R_IMF_IMTYPE_IRIS:
@@ -2216,8 +2217,10 @@ void BKE_imbuf_write_prepare(ImBuf *ibuf, const ImageFormatData *imf)
ibuf->foptions.flag |= OPENEXR_HALF;
ibuf->foptions.flag |= (imf->exr_codec & OPENEXR_COMPRESS);
- if (!(imf->flag & R_IMF_FLAG_ZBUF))
- ibuf->zbuf_float = NULL; /* signal for exr saving */
+ if (!(imf->flag & R_IMF_FLAG_ZBUF)) {
+ /* Signal for exr saving. */
+ IMB_freezbuffloatImBuf(ibuf);
+ }
}
#endif
@@ -2737,7 +2740,6 @@ void BKE_image_signal(Image *ima, ImageUser *iuser, int signal)
}
}
-#define PASSTYPE_UNSET -1
/* return renderpass for a given pass index and active view */
/* fallback to available if there are missing passes for active view */
static RenderPass *image_render_pass_get(RenderLayer *rl, const int pass, const int view, int *r_passindex)
@@ -2746,7 +2748,7 @@ static RenderPass *image_render_pass_get(RenderLayer *rl, const int pass, const
RenderPass *rpass;
int rp_index = 0;
- int rp_passtype = PASSTYPE_UNSET;
+ const char *rp_name = "";
for (rpass = rl->passes.first; rpass; rpass = rpass->next, rp_index++) {
if (rp_index == pass) {
@@ -2756,12 +2758,12 @@ static RenderPass *image_render_pass_get(RenderLayer *rl, const int pass, const
break;
}
else {
- rp_passtype = rpass->passtype;
+ rp_name = rpass->name;
}
}
/* multiview */
- else if ((rp_passtype != PASSTYPE_UNSET) &&
- (rpass->passtype == rp_passtype) &&
+ else if (rp_name[0] &&
+ STREQ(rpass->name, rp_name) &&
(rpass->view_id == view))
{
rpass_ret = rpass;
@@ -2781,7 +2783,6 @@ static RenderPass *image_render_pass_get(RenderLayer *rl, const int pass, const
return rpass_ret;
}
-#undef PASSTYPE_UNSET
/* if layer or pass changes, we need an index for the imbufs list */
/* note it is called for rendered results, but it doesnt use the index! */
@@ -2862,7 +2863,7 @@ bool BKE_image_is_stereo(Image *ima)
{
return BKE_image_is_multiview(ima) &&
(BLI_findstring(&ima->views, STEREO_LEFT_NAME, offsetof(ImageView, name)) &&
- BLI_findstring(&ima->views, STEREO_RIGHT_NAME, offsetof(ImageView, name)));
+ BLI_findstring(&ima->views, STEREO_RIGHT_NAME, offsetof(ImageView, name)));
}
static void image_init_multilayer_multiview(Image *ima, RenderResult *rr)
@@ -3751,7 +3752,7 @@ static ImBuf *image_get_render_result(Image *ima, ImageUser *iuser, void **r_loc
}
for (rpass = rl->passes.first; rpass; rpass = rpass->next)
- if (rpass->passtype == SCE_PASS_Z)
+ if (STREQ(rpass->name, RE_PASSNAME_Z) && rpass->view_id == actview)
rectz = rpass->rect;
}
}
@@ -4132,33 +4133,32 @@ typedef struct ImagePoolEntry {
typedef struct ImagePool {
ListBase image_buffers;
+ BLI_mempool *memory_pool;
} ImagePool;
ImagePool *BKE_image_pool_new(void)
{
ImagePool *pool = MEM_callocN(sizeof(ImagePool), "Image Pool");
+ pool->memory_pool = BLI_mempool_create(sizeof(ImagePoolEntry), 0, 128, BLI_MEMPOOL_NOP);
return pool;
}
void BKE_image_pool_free(ImagePool *pool)
{
- ImagePoolEntry *entry, *next_entry;
-
- /* use single lock to dereference all the image buffers */
+ /* Use single lock to dereference all the image buffers. */
BLI_spin_lock(&image_spin);
-
- for (entry = pool->image_buffers.first; entry; entry = next_entry) {
- next_entry = entry->next;
-
- if (entry->ibuf)
+ for (ImagePoolEntry *entry = pool->image_buffers.first;
+ entry != NULL;
+ entry = entry->next)
+ {
+ if (entry->ibuf) {
IMB_freeImBuf(entry->ibuf);
-
- MEM_freeN(entry);
+ }
}
-
BLI_spin_unlock(&image_spin);
+ BLI_mempool_destroy(pool->memory_pool);
MEM_freeN(pool);
}
@@ -4210,7 +4210,7 @@ ImBuf *BKE_image_pool_acquire_ibuf(Image *ima, ImageUser *iuser, ImagePool *pool
ibuf = image_acquire_ibuf(ima, iuser, NULL);
- entry = MEM_callocN(sizeof(ImagePoolEntry), "Image Pool Entry");
+ entry = BLI_mempool_alloc(pool->memory_pool);
entry->image = ima;
entry->frame = frame;
entry->index = index;
diff --git a/source/blender/blenkernel/intern/image_gen.c b/source/blender/blenkernel/intern/image_gen.c
index 2c8399adece..1f1f4c9d341 100644
--- a/source/blender/blenkernel/intern/image_gen.c
+++ b/source/blender/blenkernel/intern/image_gen.c
@@ -132,7 +132,7 @@ static void image_buf_fill_checker_slice(unsigned char *rect,
float hsv[3] = {0.0f, 0.9f, 0.9f};
float rgb[3];
- float dark_linear_color, bright_linear_color;
+ float dark_linear_color = 0.0f, bright_linear_color = 0.0f;
if (rect_float != NULL) {
dark_linear_color = srgb_to_linearrgb(0.25f);
bright_linear_color = srgb_to_linearrgb(0.58f);
diff --git a/source/blender/blenkernel/intern/key.c b/source/blender/blenkernel/intern/key.c
index 8a7c1dd2833..98b251294ae 100644
--- a/source/blender/blenkernel/intern/key.c
+++ b/source/blender/blenkernel/intern/key.c
@@ -151,7 +151,7 @@ Key *BKE_key_add(ID *id) /* common function */
return key;
}
-Key *BKE_key_copy(Main *bmain, Key *key)
+Key *BKE_key_copy(Main *bmain, const Key *key)
{
Key *keyn;
KeyBlock *kbn, *kb;
diff --git a/source/blender/blenkernel/intern/lamp.c b/source/blender/blenkernel/intern/lamp.c
index 69a2067f4e6..2242ba379fb 100644
--- a/source/blender/blenkernel/intern/lamp.c
+++ b/source/blender/blenkernel/intern/lamp.c
@@ -116,7 +116,7 @@ Lamp *BKE_lamp_add(Main *bmain, const char *name)
return la;
}
-Lamp *BKE_lamp_copy(Main *bmain, Lamp *la)
+Lamp *BKE_lamp_copy(Main *bmain, const Lamp *la)
{
Lamp *lan;
int a;
diff --git a/source/blender/blenkernel/intern/lattice.c b/source/blender/blenkernel/intern/lattice.c
index 54cfae620a1..c9d7dddf25a 100644
--- a/source/blender/blenkernel/intern/lattice.c
+++ b/source/blender/blenkernel/intern/lattice.c
@@ -277,7 +277,7 @@ Lattice *BKE_lattice_add(Main *bmain, const char *name)
return lt;
}
-Lattice *BKE_lattice_copy(Main *bmain, Lattice *lt)
+Lattice *BKE_lattice_copy(Main *bmain, const Lattice *lt)
{
Lattice *ltn;
diff --git a/source/blender/blenkernel/intern/library.c b/source/blender/blenkernel/intern/library.c
index e380b5c17e0..2ea7342ff34 100644
--- a/source/blender/blenkernel/intern/library.c
+++ b/source/blender/blenkernel/intern/library.c
@@ -133,6 +133,12 @@
#include "atomic_ops.h"
+//#define DEBUG_TIME
+
+#ifdef DEBUG_TIME
+# include "PIL_time_utildefines.h"
+#endif
+
/* GS reads the memory pointed at in a specific ordering.
* only use this definition, makes little and big endian systems
* work fine, in conjunction with MAKE_ID */
@@ -301,7 +307,7 @@ void BKE_id_expand_local(Main *bmain, ID *id)
/**
* Ensure new (copied) ID is fully made local.
*/
-void BKE_id_copy_ensure_local(Main *bmain, ID *old_id, ID *new_id)
+void BKE_id_copy_ensure_local(Main *bmain, const ID *old_id, ID *new_id)
{
if (ID_IS_LINKED_DATABLOCK(old_id)) {
BKE_id_expand_local(bmain, new_id);
@@ -482,7 +488,7 @@ bool id_make_local(Main *bmain, ID *id, const bool test, const bool lib_local)
* Invokes the appropriate copy method for the block and returns the result in
* newid, unless test. Returns true if the block can be copied.
*/
-bool id_copy(Main *bmain, ID *id, ID **newid, bool test)
+bool id_copy(Main *bmain, const ID *id, ID **newid, bool test)
{
if (!test) {
*newid = NULL;
@@ -852,118 +858,72 @@ int set_listbasepointers(Main *main, ListBase **lb)
* **************************** */
/**
+ * Get allocation size fo a given datablock type and optionally allocation name.
+ */
+size_t BKE_libblock_get_alloc_info(short type, const char **name)
+{
+#define CASE_RETURN(id_code, type) \
+ case id_code: \
+ do { \
+ if (name != NULL) { \
+ *name = #type; \
+ } \
+ return sizeof(type); \
+ } while(0)
+
+ switch ((ID_Type)type) {
+ CASE_RETURN(ID_SCE, Scene);
+ CASE_RETURN(ID_LI, Library);
+ CASE_RETURN(ID_OB, Object);
+ CASE_RETURN(ID_ME, Mesh);
+ CASE_RETURN(ID_CU, Curve);
+ CASE_RETURN(ID_MB, MetaBall);
+ CASE_RETURN(ID_MA, Material);
+ CASE_RETURN(ID_TE, Tex);
+ CASE_RETURN(ID_IM, Image);
+ CASE_RETURN(ID_LT, Lattice);
+ CASE_RETURN(ID_LA, Lamp);
+ CASE_RETURN(ID_CA, Camera);
+ CASE_RETURN(ID_IP, Ipo);
+ CASE_RETURN(ID_KE, Key);
+ CASE_RETURN(ID_WO, World);
+ CASE_RETURN(ID_SCR, bScreen);
+ CASE_RETURN(ID_VF, VFont);
+ CASE_RETURN(ID_TXT, Text);
+ CASE_RETURN(ID_SPK, Speaker);
+ CASE_RETURN(ID_SO, bSound);
+ CASE_RETURN(ID_GR, Group);
+ CASE_RETURN(ID_AR, bArmature);
+ CASE_RETURN(ID_AC, bAction);
+ CASE_RETURN(ID_NT, bNodeTree);
+ CASE_RETURN(ID_BR, Brush);
+ CASE_RETURN(ID_PA, ParticleSettings);
+ CASE_RETURN(ID_WM, wmWindowManager);
+ CASE_RETURN(ID_GD, bGPdata);
+ CASE_RETURN(ID_MC, MovieClip);
+ CASE_RETURN(ID_MSK, Mask);
+ CASE_RETURN(ID_LS, FreestyleLineStyle);
+ CASE_RETURN(ID_PAL, Palette);
+ CASE_RETURN(ID_PC, PaintCurve);
+ CASE_RETURN(ID_CF, CacheFile);
+ }
+ return 0;
+#undef CASE_RETURN
+}
+
+/**
* Allocates and returns memory of the right size for the specified block type,
* initialized to zero.
*/
void *BKE_libblock_alloc_notest(short type)
{
- ID *id = NULL;
-
- switch ((ID_Type)type) {
- case ID_SCE:
- id = MEM_callocN(sizeof(Scene), "scene");
- break;
- case ID_LI:
- id = MEM_callocN(sizeof(Library), "library");
- break;
- case ID_OB:
- id = MEM_callocN(sizeof(Object), "object");
- break;
- case ID_ME:
- id = MEM_callocN(sizeof(Mesh), "mesh");
- break;
- case ID_CU:
- id = MEM_callocN(sizeof(Curve), "curve");
- break;
- case ID_MB:
- id = MEM_callocN(sizeof(MetaBall), "mball");
- break;
- case ID_MA:
- id = MEM_callocN(sizeof(Material), "mat");
- break;
- case ID_TE:
- id = MEM_callocN(sizeof(Tex), "tex");
- break;
- case ID_IM:
- id = MEM_callocN(sizeof(Image), "image");
- break;
- case ID_LT:
- id = MEM_callocN(sizeof(Lattice), "latt");
- break;
- case ID_LA:
- id = MEM_callocN(sizeof(Lamp), "lamp");
- break;
- case ID_CA:
- id = MEM_callocN(sizeof(Camera), "camera");
- break;
- case ID_IP:
- id = MEM_callocN(sizeof(Ipo), "ipo");
- break;
- case ID_KE:
- id = MEM_callocN(sizeof(Key), "key");
- break;
- case ID_WO:
- id = MEM_callocN(sizeof(World), "world");
- break;
- case ID_SCR:
- id = MEM_callocN(sizeof(bScreen), "screen");
- break;
- case ID_VF:
- id = MEM_callocN(sizeof(VFont), "vfont");
- break;
- case ID_TXT:
- id = MEM_callocN(sizeof(Text), "text");
- break;
- case ID_SPK:
- id = MEM_callocN(sizeof(Speaker), "speaker");
- break;
- case ID_SO:
- id = MEM_callocN(sizeof(bSound), "sound");
- break;
- case ID_GR:
- id = MEM_callocN(sizeof(Group), "group");
- break;
- case ID_AR:
- id = MEM_callocN(sizeof(bArmature), "armature");
- break;
- case ID_AC:
- id = MEM_callocN(sizeof(bAction), "action");
- break;
- case ID_NT:
- id = MEM_callocN(sizeof(bNodeTree), "nodetree");
- break;
- case ID_BR:
- id = MEM_callocN(sizeof(Brush), "brush");
- break;
- case ID_PA:
- id = MEM_callocN(sizeof(ParticleSettings), "ParticleSettings");
- break;
- case ID_WM:
- id = MEM_callocN(sizeof(wmWindowManager), "Window manager");
- break;
- case ID_GD:
- id = MEM_callocN(sizeof(bGPdata), "Grease Pencil");
- break;
- case ID_MC:
- id = MEM_callocN(sizeof(MovieClip), "Movie Clip");
- break;
- case ID_MSK:
- id = MEM_callocN(sizeof(Mask), "Mask");
- break;
- case ID_LS:
- id = MEM_callocN(sizeof(FreestyleLineStyle), "Freestyle Line Style");
- break;
- case ID_PAL:
- id = MEM_callocN(sizeof(Palette), "Palette");
- break;
- case ID_PC:
- id = MEM_callocN(sizeof(PaintCurve), "Paint Curve");
- break;
- case ID_CF:
- id = MEM_callocN(sizeof(CacheFile), "Cache File");
- break;
+ const char *name;
+ size_t size = BKE_libblock_get_alloc_info(type, &name);
+ if (size != 0) {
+ return MEM_callocN(size, name);
}
- return id;
+ BLI_assert(!"Request to allocate unknown data type");
+ return NULL;
}
/**
@@ -1132,7 +1092,7 @@ void BKE_libblock_copy_data(ID *id, const ID *id_from, const bool do_action)
}
/* used everywhere in blenkernel */
-void *BKE_libblock_copy(Main *bmain, ID *id)
+void *BKE_libblock_copy(Main *bmain, const ID *id)
{
ID *idn;
size_t idn_len;
@@ -1154,7 +1114,7 @@ void *BKE_libblock_copy(Main *bmain, ID *id)
return idn;
}
-void *BKE_libblock_copy_nolib(ID *id, const bool do_action)
+void *BKE_libblock_copy_nolib(const ID *id, const bool do_action)
{
ID *idn;
size_t idn_len;
@@ -1716,10 +1676,19 @@ static void library_make_local_copying_check(ID *id, GSet *loop_tags, MainIDRela
for (; entry != NULL; entry = entry->next) {
ID *par_id = (ID *)entry->id_pointer; /* used_to_user stores ID pointer, not pointer to ID pointer... */
- /* Shapekeys are considered 'private' to their owner ID here, and never tagged (since they cannot be linked),
- * so we have to switch effective parent to their owner. */
- if (GS(par_id->name) == ID_KE) {
- par_id = ((Key *)par_id)->from;
+ /* Our oh-so-beloved 'from' pointers... */
+ if (entry->usage_flag & IDWALK_CB_LOOPBACK) {
+ /* We totally disregard Object->proxy_from 'usage' here, this one would only generate fake positives. */
+ if (GS(par_id->name) == ID_OB) {
+ BLI_assert(((Object *)par_id)->proxy_from == (Object *)id);
+ continue;
+ }
+
+ /* Shapekeys are considered 'private' to their owner ID here, and never tagged (since they cannot be linked),
+ * so we have to switch effective parent to their owner. */
+ if (GS(par_id->name) == ID_KE) {
+ par_id = ((Key *)par_id)->from;
+ }
}
if (par_id->lib == NULL) {
@@ -1777,9 +1746,18 @@ void BKE_library_make_local(
LinkNode *copied_ids = NULL;
MemArena *linklist_mem = BLI_memarena_new(512 * sizeof(*todo_ids), __func__);
+ GSet *done_ids = BLI_gset_ptr_new(__func__);
+
+#ifdef DEBUG_TIME
+ TIMEIT_START(make_local);
+#endif
+
BKE_main_relations_create(bmain);
- GSet *done_ids = BLI_gset_ptr_new(__func__);
+#ifdef DEBUG_TIME
+ printf("Pre-compute current ID relations: Done.\n");
+ TIMEIT_VALUE_PRINT(make_local);
+#endif
/* Step 1: Detect datablocks to make local. */
for (a = set_listbasepointers(bmain, lbarray); a--; ) {
@@ -1830,6 +1808,11 @@ void BKE_library_make_local(
}
}
+#ifdef DEBUG_TIME
+ printf("Step 1: Detect datablocks to make local: Done.\n");
+ TIMEIT_VALUE_PRINT(make_local);
+#endif
+
/* Step 2: Check which datablocks we can directly make local (because they are only used by already, or future,
* local data), others will need to be duplicated. */
GSet *loop_tags = BLI_gset_ptr_new(__func__);
@@ -1843,6 +1826,11 @@ void BKE_library_make_local(
/* Next step will most likely add new IDs, better to get rid of this mapping now. */
BKE_main_relations_free(bmain);
+#ifdef DEBUG_TIME
+ printf("Step 2: Check which datablocks we can directly make local: Done.\n");
+ TIMEIT_VALUE_PRINT(make_local);
+#endif
+
/* Step 3: Make IDs local, either directly (quick and simple), or using generic process,
* which involves more complex checks and might instead create a local copy of original linked ID. */
for (LinkNode *it = todo_ids, *it_next; it; it = it_next) {
@@ -1883,11 +1871,16 @@ void BKE_library_make_local(
}
}
+#ifdef DEBUG_TIME
+ printf("Step 3: Make IDs local: Done.\n");
+ TIMEIT_VALUE_PRINT(make_local);
+#endif
+
/* At this point, we are done with directly made local IDs. Now we have to handle duplicated ones, since their
* remaining linked original counterpart may not be needed anymore... */
todo_ids = NULL;
- /* Step 4: We have to remap local usages of old (linked) ID to new (local) id in a separated loop,
+ /* Step 4: We have to remap local usages of old (linked) ID to new (local) ID in a separated loop,
* as lbarray ordering is not enough to ensure us we did catch all dependencies
* (e.g. if making local a parent object before its child...). See T48907. */
/* TODO This is now the biggest step by far (in term of processing time). We may be able to gain here by
@@ -1911,6 +1904,11 @@ void BKE_library_make_local(
}
}
+#ifdef DEBUG_TIME
+ printf("Step 4: Remap local usages of old (linked) ID to new (local) ID: Done.\n");
+ TIMEIT_VALUE_PRINT(make_local);
+#endif
+
/* Note: Keeping both version of the code (old one being safer, since it still has checks against unused IDs)
* for now, we can remove old one once it has been tested for some time in master... */
#if 1
@@ -1955,6 +1953,12 @@ void BKE_library_make_local(
}
}
}
+
+#ifdef DEBUG_TIME
+ printf("Step 5: Proxy 'remapping' hack: Done.\n");
+ TIMEIT_VALUE_PRINT(make_local);
+#endif
+
#else
LinkNode *linked_loop_candidates = NULL;
@@ -2033,6 +2037,11 @@ void BKE_library_make_local(
}
}
+#ifdef DEBUG_TIME
+ printf("Step 5: Remove linked datablocks that have been copied and ended fully localized: Done.\n");
+ TIMEIT_VALUE_PRINT(make_local);
+#endif
+
/* Step 6: Try to find circle dependencies between indirectly-linked-only datablocks.
* Those are fake 'usages' that prevent their deletion. See T49775 for nice ugly case. */
BKE_library_unused_linked_data_set_tag(bmain, false);
@@ -2069,10 +2078,38 @@ void BKE_library_make_local(
it->link = NULL;
}
}
+
+#ifdef DEBUG_TIME
+ printf("Step 6: Try to find circle dependencies between indirectly-linked-only datablocks: Done.\n");
+ TIMEIT_VALUE_PRINT(make_local);
+#endif
+
+#endif
+
+ /* This is probably more of a hack than something we should do here, but...
+ * Issue is, the whole copying + remapping done in complex cases above may leave pose channels of armatures
+ * in complete invalid state (more precisely, the bone pointers of the pchans - very crappy cross-datablocks
+ * relationship), se we tag it to be fully recomputed, but this does not seems to be enough in some cases,
+ * and evaluation code ends up trying to evaluate a not-yet-updated armature object's deformations.
+ * Try "make all local" in 04_01_H.lighting.blend from Agent327 without this, e.g. */
+ for (Object *ob = bmain->object.first; ob; ob = ob->id.next) {
+ if (ob->data != NULL && ob->type == OB_ARMATURE && ob->pose != NULL && ob->pose->flag & POSE_RECALC) {
+ BKE_pose_rebuild(ob, ob->data);
+ }
+ }
+
+#ifdef DEBUG_TIME
+ printf("Hack: Forcefully rebuild armature object poses: Done.\n");
+ TIMEIT_VALUE_PRINT(make_local);
#endif
BKE_main_id_clear_newpoins(bmain);
BLI_memarena_free(linklist_mem);
+
+#ifdef DEBUG_TIME
+ printf("Cleanup and finish: Done.\n");
+ TIMEIT_END(make_local);
+#endif
}
/**
diff --git a/source/blender/blenkernel/intern/library_query.c b/source/blender/blenkernel/intern/library_query.c
index 9685f1f5af6..d1f0c87183d 100644
--- a/source/blender/blenkernel/intern/library_query.c
+++ b/source/blender/blenkernel/intern/library_query.c
@@ -33,6 +33,7 @@
#include "DNA_actuator_types.h"
#include "DNA_anim_types.h"
+#include "DNA_armature_types.h"
#include "DNA_brush_types.h"
#include "DNA_camera_types.h"
#include "DNA_constraint_types.h"
@@ -70,10 +71,12 @@
#include "BKE_animsys.h"
#include "BKE_constraint.h"
#include "BKE_fcurve.h"
+#include "BKE_idprop.h"
#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_main.h"
#include "BKE_modifier.h"
+#include "BKE_node.h"
#include "BKE_particle.h"
#include "BKE_rigidbody.h"
#include "BKE_sca.h"
@@ -82,7 +85,9 @@
#define FOREACH_FINALIZE _finalize
-#define FOREACH_FINALIZE_VOID FOREACH_FINALIZE: (void)0
+#define FOREACH_FINALIZE_VOID \
+ if (0) { goto FOREACH_FINALIZE; } \
+ FOREACH_FINALIZE: ((void)0)
#define FOREACH_CALLBACK_INVOKE_ID_PP(_data, id_pp, _cb_flag) \
CHECK_TYPE(id_pp, ID **); \
@@ -140,6 +145,37 @@ typedef struct LibraryForeachIDData {
BLI_LINKSTACK_DECLARE(ids_todo, ID *);
} LibraryForeachIDData;
+static void library_foreach_idproperty_ID_link(LibraryForeachIDData *data, IDProperty *prop, int flag)
+{
+ if (!prop)
+ return;
+
+ switch (prop->type) {
+ case IDP_GROUP:
+ {
+ for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) {
+ library_foreach_idproperty_ID_link(data, loop, flag);
+ }
+ break;
+ }
+ case IDP_IDPARRAY:
+ {
+ IDProperty *loop = IDP_Array(prop);
+ for (int i = 0; i < prop->len; i++) {
+ library_foreach_idproperty_ID_link(data, &loop[i], flag);
+ }
+ break;
+ }
+ case IDP_ID:
+ FOREACH_CALLBACK_INVOKE_ID(data, prop->data.pointer, flag);
+ break;
+ default:
+ break; /* Nothing to do here with other types of IDProperties... */
+ }
+
+ FOREACH_FINALIZE_VOID;
+}
+
static void library_foreach_rigidbodyworldSceneLooper(
struct RigidBodyWorld *UNUSED(rbw), ID **id_pointer, void *user_data, int cb_flag)
{
@@ -265,6 +301,17 @@ static void library_foreach_paint(LibraryForeachIDData *data, Paint *paint)
FOREACH_FINALIZE_VOID;
}
+static void library_foreach_bone(LibraryForeachIDData *data, Bone *bone)
+{
+ library_foreach_idproperty_ID_link(data, bone->prop, IDWALK_CB_USER);
+
+ for (Bone *curbone = bone->childbase.first; curbone; curbone = curbone->next) {
+ library_foreach_bone(data, curbone);
+ }
+
+ FOREACH_FINALIZE_VOID;
+}
+
static void library_foreach_ID_as_subdata_link(
ID **id_pp, LibraryIDLinkCallback callback, void *user_data, int flag, LibraryForeachIDData *data)
{
@@ -337,6 +384,8 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
continue;
}
+ library_foreach_idproperty_ID_link(&data, id->properties, IDWALK_CB_USER);
+
AnimData *adt = BKE_animdata_from_id(id);
if (adt) {
library_foreach_animationData(&data, adt);
@@ -402,6 +451,7 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
CALLBACK_INVOKE(seq->clip, IDWALK_CB_USER);
CALLBACK_INVOKE(seq->mask, IDWALK_CB_USER);
CALLBACK_INVOKE(seq->sound, IDWALK_CB_USER);
+ library_foreach_idproperty_ID_link(&data, seq->prop, IDWALK_CB_USER);
for (SequenceModifierData *smd = seq->modifiers.first; smd; smd = smd->next) {
CALLBACK_INVOKE(smd->mask_id, IDWALK_CB_USER);
}
@@ -462,7 +512,8 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
/* Object is special, proxies make things hard... */
const int data_cb_flag = data.cb_flag;
- const int proxy_cb_flag = (object->proxy || object->proxy_group) ? IDWALK_CB_INDIRECT_USAGE : 0;
+ const int proxy_cb_flag = ((data.flag & IDWALK_NO_INDIRECT_PROXY_DATA_USAGE) == 0 && (object->proxy || object->proxy_group)) ?
+ IDWALK_CB_INDIRECT_USAGE : 0;
/* object data special case */
data.cb_flag |= proxy_cb_flag;
@@ -490,7 +541,7 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
if (object->proxy_from) {
data.cb_flag = ID_IS_LINKED_DATABLOCK(object->proxy_from) ? IDWALK_CB_INDIRECT_USAGE : 0;
}
- CALLBACK_INVOKE(object->proxy_from, IDWALK_CB_NOP);
+ CALLBACK_INVOKE(object->proxy_from, IDWALK_CB_LOOPBACK);
data.cb_flag = data_cb_flag;
CALLBACK_INVOKE(object->poselib, IDWALK_CB_USER);
@@ -515,6 +566,7 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
data.cb_flag |= proxy_cb_flag;
for (pchan = object->pose->chanbase.first; pchan; pchan = pchan->next) {
+ library_foreach_idproperty_ID_link(&data, pchan->prop, IDWALK_CB_USER);
CALLBACK_INVOKE(pchan->custom, IDWALK_CB_USER);
BKE_constraints_id_loop(&pchan->constraints, library_foreach_constraintObjectLooper, &data);
}
@@ -554,6 +606,16 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
break;
}
+ case ID_AR:
+ {
+ bArmature *arm = (bArmature *)id;
+
+ for (Bone *bone = arm->bonebase.first; bone; bone = bone->next) {
+ library_foreach_bone(&data, bone);
+ }
+ break;
+ }
+
case ID_ME:
{
Mesh *mesh = (Mesh *) id;
@@ -684,12 +746,8 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
case ID_KE:
{
- /* XXX Only ID pointer from shapekeys is the 'from' one, which is not actually ID usage.
- * Maybe we should even nuke it from here, not 100% sure yet...
- * (see also foreach_libblock_id_users_callback).
- */
Key *key = (Key *) id;
- CALLBACK_INVOKE_ID(key->from, IDWALK_CB_NOP);
+ CALLBACK_INVOKE_ID(key->from, IDWALK_CB_LOOPBACK);
break;
}
@@ -736,9 +794,27 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
{
bNodeTree *ntree = (bNodeTree *) id;
bNode *node;
+ bNodeSocket *sock;
+
CALLBACK_INVOKE(ntree->gpd, IDWALK_CB_USER);
+
for (node = ntree->nodes.first; node; node = node->next) {
CALLBACK_INVOKE_ID(node->id, IDWALK_CB_USER);
+
+ library_foreach_idproperty_ID_link(&data, node->prop, IDWALK_CB_USER);
+ for (sock = node->inputs.first; sock; sock = sock->next) {
+ library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER);
+ }
+ for (sock = node->outputs.first; sock; sock = sock->next) {
+ library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER);
+ }
+ }
+
+ for (sock = ntree->inputs.first; sock; sock = sock->next) {
+ library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER);
+ }
+ for (sock = ntree->outputs.first; sock; sock = sock->next) {
+ library_foreach_idproperty_ID_link(&data, sock->prop, IDWALK_CB_USER);
}
break;
}
@@ -892,14 +968,21 @@ void BKE_library_foreach_ID_link(Main *bmain, ID *id, LibraryIDLinkCallback call
}
break;
}
+ case ID_GD:
+ {
+ bGPdata *gpencil = (bGPdata *) id;
+
+ for (bGPDlayer *gp_layer = gpencil->layers.first; gp_layer; gp_layer = gp_layer->next) {
+ CALLBACK_INVOKE(gp_layer->parent, IDWALK_CB_NOP);
+ }
+ break;
+ }
/* Nothing needed for those... */
case ID_IM:
case ID_VF:
case ID_TXT:
case ID_SO:
- case ID_AR:
- case ID_GD:
case ID_WM:
case ID_PAL:
case ID_PC:
@@ -948,9 +1031,25 @@ void BKE_library_update_ID_link_user(ID *id_dst, ID *id_src, const int cb_flag)
*/
/* XXX This has to be fully rethink, basing check on ID type is not really working anymore (and even worth once
* IDProps will support ID pointers), we'll have to do some quick checks on IDs themselves... */
-bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id_type_used)
+bool BKE_library_id_can_use_idtype(ID *id_owner, const short id_type_used)
{
- if (id_type_can_have_animdata(id_type_owner)) {
+ /* any type of ID can be used in custom props. */
+ if (id_owner->properties) {
+ return true;
+ }
+
+ const short id_type_owner = GS(id_owner->name);
+
+ /* IDProps of armature bones and nodes, and bNode->id can use virtually any type of ID. */
+ if (ELEM(id_type_owner, ID_NT, ID_AR)) {
+ return true;
+ }
+
+ if (ntreeFromID(id_owner)) {
+ return true;
+ }
+
+ if (BKE_animdata_from_id(id_owner)) {
return true; /* AnimationData can use virtually any kind of datablocks, through drivers especially. */
}
@@ -959,8 +1058,7 @@ bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id
return ELEM(id_type_used, ID_LI);
case ID_SCE:
return (ELEM(id_type_used, ID_OB, ID_WO, ID_SCE, ID_MC, ID_MA, ID_GR, ID_TXT,
- ID_LS, ID_MSK, ID_SO, ID_GD, ID_BR, ID_PAL, ID_IM, ID_NT) ||
- BKE_library_idtype_can_use_idtype(ID_NT, id_type_used));
+ ID_LS, ID_MSK, ID_SO, ID_GD, ID_BR, ID_PAL, ID_IM, ID_NT));
case ID_OB:
/* Could be the following, but simpler to just always say 'yes' here. */
#if 0
@@ -977,13 +1075,13 @@ bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id
case ID_MB:
return ELEM(id_type_used, ID_MA);
case ID_MA:
- return (ELEM(id_type_used, ID_TE, ID_GR) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used));
+ return (ELEM(id_type_used, ID_TE, ID_GR));
case ID_TE:
- return (ELEM(id_type_used, ID_IM, ID_OB) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used));
+ return (ELEM(id_type_used, ID_IM, ID_OB));
case ID_LT:
return ELEM(id_type_used, ID_KE);
case ID_LA:
- return (ELEM(id_type_used, ID_TE) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used));
+ return (ELEM(id_type_used, ID_TE));
case ID_CA:
return ELEM(id_type_used, ID_OB);
case ID_KE:
@@ -991,7 +1089,7 @@ bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id
case ID_SCR:
return ELEM(id_type_used, ID_SCE);
case ID_WO:
- return (ELEM(id_type_used, ID_TE) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used));
+ return (ELEM(id_type_used, ID_TE));
case ID_SPK:
return ELEM(id_type_used, ID_SO);
case ID_GR:
@@ -1012,7 +1110,7 @@ bool BKE_library_idtype_can_use_idtype(const short id_type_owner, const short id
case ID_MSK:
return ELEM(id_type_used, ID_MC); /* WARNING! mask->parent.id, not typed. */
case ID_LS:
- return (ELEM(id_type_used, ID_TE, ID_OB) || BKE_library_idtype_can_use_idtype(ID_NT, id_type_used));
+ return (ELEM(id_type_used, ID_TE, ID_OB));
case ID_IM:
case ID_VF:
case ID_TXT:
@@ -1045,20 +1143,15 @@ typedef struct IDUsersIter {
int count_direct, count_indirect; /* Set by callback. */
} IDUsersIter;
-static int foreach_libblock_id_users_callback(void *user_data, ID *self_id, ID **id_p, int cb_flag)
+static int foreach_libblock_id_users_callback(void *user_data, ID *UNUSED(self_id), ID **id_p, int cb_flag)
{
IDUsersIter *iter = user_data;
if (*id_p) {
- /* XXX This is actually some kind of hack...
- * Issue is, shapekeys' 'from' ID pointer is not actually ID usage.
- * Maybe we should even nuke it from BKE_library_foreach_ID_link, not 100% sure yet...
+ /* 'Loopback' ID pointers (the ugly 'from' ones, Object->proxy_from and Key->from).
+ * Those are not actually ID usage, we can ignore them here.
*/
- if ((GS(self_id->name) == ID_KE) && (((Key *)self_id)->from == *id_p)) {
- return IDWALK_RET_NOP;
- }
- /* XXX another hack, for similar reasons as above one. */
- if ((GS(self_id->name) == ID_OB) && (((Object *)self_id)->proxy_from == (Object *)*id_p)) {
+ if (cb_flag & IDWALK_CB_LOOPBACK) {
return IDWALK_RET_NOP;
}
@@ -1118,7 +1211,7 @@ static bool library_ID_is_used(Main *bmain, void *idv, const bool check_linked)
while (i-- && !is_defined) {
ID *id_curr = lb_array[i]->first;
- if (!id_curr || !BKE_library_idtype_can_use_idtype(GS(id_curr->name), GS(id->name))) {
+ if (!id_curr || !BKE_library_id_can_use_idtype(id_curr, GS(id->name))) {
continue;
}
@@ -1170,7 +1263,7 @@ void BKE_library_ID_test_usages(Main *bmain, void *idv, bool *is_used_local, boo
while (i-- && !is_defined) {
ID *id_curr = lb_array[i]->first;
- if (!id_curr || !BKE_library_idtype_can_use_idtype(GS(id_curr->name), GS(id->name))) {
+ if (!id_curr || !BKE_library_id_can_use_idtype(id_curr, GS(id->name))) {
continue;
}
diff --git a/source/blender/blenkernel/intern/library_remap.c b/source/blender/blenkernel/intern/library_remap.c
index b6f4621a0b3..5e5ba44f039 100644
--- a/source/blender/blenkernel/intern/library_remap.c
+++ b/source/blender/blenkernel/intern/library_remap.c
@@ -419,6 +419,7 @@ ATTR_NONNULL(1) static void libblock_remap_data(
IDRemap id_remap_data;
ListBase *lb_array[MAX_LIBARRAY];
int i;
+ const int foreach_id_flags = (remap_flags & ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE) != 0 ? IDWALK_NO_INDIRECT_PROXY_DATA_USAGE : IDWALK_NOP;
if (r_id_remap_data == NULL) {
r_id_remap_data = &id_remap_data;
@@ -439,7 +440,7 @@ ATTR_NONNULL(1) static void libblock_remap_data(
#endif
r_id_remap_data->id = id;
libblock_remap_data_preprocess(r_id_remap_data);
- BKE_library_foreach_ID_link(NULL, id, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP);
+ BKE_library_foreach_ID_link(NULL, id, foreach_libblock_remap_callback, (void *)r_id_remap_data, foreach_id_flags);
}
else {
i = set_listbasepointers(bmain, lb_array);
@@ -448,20 +449,16 @@ ATTR_NONNULL(1) static void libblock_remap_data(
* objects actually using given old_id... sounds rather unlikely currently, though, so this will do for now. */
while (i--) {
- ID *id_curr = lb_array[i]->first;
-
- if (!id_curr || !BKE_library_idtype_can_use_idtype(GS(id_curr->name), GS(old_id->name))) {
- continue;
- }
-
- for (; id_curr; id_curr = id_curr->next) {
- /* Note that we cannot skip indirect usages of old_id here (if requested), we still need to check it for
- * the user count handling...
- * XXX No more true (except for debug usage of those skipping counters). */
- r_id_remap_data->id = id_curr;
- libblock_remap_data_preprocess(r_id_remap_data);
- BKE_library_foreach_ID_link(
- NULL, id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, IDWALK_NOP);
+ for (ID *id_curr = lb_array[i]->first; id_curr; id_curr = id_curr->next) {
+ if (BKE_library_id_can_use_idtype(id_curr, GS(old_id->name))) {
+ /* Note that we cannot skip indirect usages of old_id here (if requested), we still need to check it for
+ * the user count handling...
+ * XXX No more true (except for debug usage of those skipping counters). */
+ r_id_remap_data->id = id_curr;
+ libblock_remap_data_preprocess(r_id_remap_data);
+ BKE_library_foreach_ID_link(
+ NULL, id_curr, foreach_libblock_remap_callback, (void *)r_id_remap_data, foreach_id_flags);
+ }
}
}
}
@@ -530,8 +527,12 @@ void BKE_libblock_remap_locked(
id_us_clear_real(old_id);
}
- BLI_assert(old_id->us - skipped_refcounted >= 0);
- UNUSED_VARS_NDEBUG(skipped_refcounted);
+ if (old_id->us - skipped_refcounted < 0) {
+ printf("Error in remapping process from '%s' (%p) to '%s' (%p): "
+ "wrong user count in old ID after process (summing up to %d)\n",
+ old_id->name, old_id, new_id ? new_id->name : "<NULL>", new_id, old_id->us - skipped_refcounted);
+ BLI_assert(0);
+ }
if (skipped_direct == 0) {
/* old_id is assumed to not be used directly anymore... */
@@ -723,38 +724,17 @@ void BKE_libblock_relink_to_newid(ID *id)
BKE_library_foreach_ID_link(NULL, id, id_relink_to_newid_looper, NULL, 0);
}
-void BKE_libblock_free_data(Main *UNUSED(bmain), ID *id)
+void BKE_libblock_free_data(ID *id, const bool do_id_user)
{
if (id->properties) {
- IDP_FreeProperty(id->properties);
+ IDP_FreeProperty_ex(id->properties, do_id_user);
MEM_freeN(id->properties);
}
}
-/**
- * used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c
- *
- * \param do_id_user: if \a true, try to release other ID's 'references' hold by \a idv.
- * (only applies to main database)
- * \param do_ui_user: similar to do_id_user but makes sure UI does not hold references to
- * \a id.
- */
-void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user)
+void BKE_libblock_free_datablock(ID *id)
{
- ID *id = idv;
- short type = GS(id->name);
- ListBase *lb = which_libbase(bmain, type);
-
- DAG_id_type_tag(bmain, type);
-
-#ifdef WITH_PYTHON
- BPY_id_release(id);
-#endif
-
- if (do_id_user) {
- BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
- }
-
+ const short type = GS(id->name);
switch (type) {
case ID_SCE:
BKE_scene_free((Scene *)id);
@@ -860,6 +840,33 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const b
BKE_cachefile_free((CacheFile *)id);
break;
}
+}
+
+/**
+ * used in headerbuttons.c image.c mesh.c screen.c sound.c and library.c
+ *
+ * \param do_id_user: if \a true, try to release other ID's 'references' hold by \a idv.
+ * (only applies to main database)
+ * \param do_ui_user: similar to do_id_user but makes sure UI does not hold references to
+ * \a id.
+ */
+void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const bool do_ui_user)
+{
+ ID *id = idv;
+ short type = GS(id->name);
+ ListBase *lb = which_libbase(bmain, type);
+
+ DAG_id_type_tag(bmain, type);
+
+#ifdef WITH_PYTHON
+ BPY_id_release(id);
+#endif
+
+ if (do_id_user) {
+ BKE_libblock_relink_ex(bmain, id, NULL, NULL, true);
+ }
+
+ BKE_libblock_free_datablock(id);
/* avoid notifying on removed data */
BKE_main_lock(bmain);
@@ -876,7 +883,7 @@ void BKE_libblock_free_ex(Main *bmain, void *idv, const bool do_id_user, const b
BLI_remlink(lb, id);
- BKE_libblock_free_data(bmain, id);
+ BKE_libblock_free_data(id, do_id_user);
BKE_main_unlock(bmain);
MEM_freeN(id);
diff --git a/source/blender/blenkernel/intern/linestyle.c b/source/blender/blenkernel/intern/linestyle.c
index 1eb909bd9f9..771e81ddc4f 100644
--- a/source/blender/blenkernel/intern/linestyle.c
+++ b/source/blender/blenkernel/intern/linestyle.c
@@ -155,7 +155,7 @@ void BKE_linestyle_free(FreestyleLineStyle *linestyle)
BKE_linestyle_geometry_modifier_remove(linestyle, m);
}
-FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, FreestyleLineStyle *linestyle)
+FreestyleLineStyle *BKE_linestyle_copy(struct Main *bmain, const FreestyleLineStyle *linestyle)
{
FreestyleLineStyle *new_linestyle;
LineStyleModifier *m;
@@ -355,7 +355,7 @@ LineStyleModifier *BKE_linestyle_color_modifier_add(FreestyleLineStyle *linestyl
return m;
}
-LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m)
+LineStyleModifier *BKE_linestyle_color_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m)
{
LineStyleModifier *new_m;
@@ -594,7 +594,7 @@ LineStyleModifier *BKE_linestyle_alpha_modifier_add(FreestyleLineStyle *linestyl
return m;
}
-LineStyleModifier *BKE_linestyle_alpha_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m)
+LineStyleModifier *BKE_linestyle_alpha_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m)
{
LineStyleModifier *new_m;
@@ -863,7 +863,7 @@ LineStyleModifier *BKE_linestyle_thickness_modifier_add(FreestyleLineStyle *line
return m;
}
-LineStyleModifier *BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m)
+LineStyleModifier *BKE_linestyle_thickness_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m)
{
LineStyleModifier *new_m;
@@ -1195,7 +1195,7 @@ LineStyleModifier *BKE_linestyle_geometry_modifier_add(FreestyleLineStyle *lines
return m;
}
-LineStyleModifier *BKE_linestyle_geometry_modifier_copy(FreestyleLineStyle *linestyle, LineStyleModifier *m)
+LineStyleModifier *BKE_linestyle_geometry_modifier_copy(FreestyleLineStyle *linestyle, const LineStyleModifier *m)
{
LineStyleModifier *new_m;
diff --git a/source/blender/blenkernel/intern/mask.c b/source/blender/blenkernel/intern/mask.c
index 6f23b82c6df..ae27e9bcd34 100644
--- a/source/blender/blenkernel/intern/mask.c
+++ b/source/blender/blenkernel/intern/mask.c
@@ -192,7 +192,7 @@ void BKE_mask_layer_rename(Mask *mask, MaskLayer *masklay, char *oldname, char *
BKE_animdata_fix_paths_rename_all(&mask->id, "layers", oldname, masklay->name);
}
-MaskLayer *BKE_mask_layer_copy(MaskLayer *masklay)
+MaskLayer *BKE_mask_layer_copy(const MaskLayer *masklay)
{
MaskLayer *masklay_new;
MaskSpline *spline;
@@ -236,7 +236,7 @@ MaskLayer *BKE_mask_layer_copy(MaskLayer *masklay)
return masklay_new;
}
-void BKE_mask_layer_copy_list(ListBase *masklayers_new, ListBase *masklayers)
+void BKE_mask_layer_copy_list(ListBase *masklayers_new, const ListBase *masklayers)
{
MaskLayer *layer;
@@ -840,7 +840,7 @@ Mask *BKE_mask_copy_nolib(Mask *mask)
return mask_new;
}
-Mask *BKE_mask_copy(Main *bmain, Mask *mask)
+Mask *BKE_mask_copy(Main *bmain, const Mask *mask)
{
Mask *mask_new;
@@ -851,7 +851,7 @@ Mask *BKE_mask_copy(Main *bmain, Mask *mask)
BKE_mask_layer_copy_list(&mask_new->masklayers, &mask->masklayers);
/* enable fake user by default */
- id_fake_user_set(&mask->id);
+ id_fake_user_set(&mask_new->id);
BKE_id_copy_ensure_local(bmain, &mask->id, &mask_new->id);
@@ -906,7 +906,7 @@ void BKE_mask_spline_free_list(ListBase *splines)
}
}
-static MaskSplinePoint *mask_spline_points_copy(MaskSplinePoint *points, int tot_point)
+static MaskSplinePoint *mask_spline_points_copy(const MaskSplinePoint *points, int tot_point)
{
MaskSplinePoint *npoints;
int i;
@@ -923,7 +923,7 @@ static MaskSplinePoint *mask_spline_points_copy(MaskSplinePoint *points, int tot
return npoints;
}
-MaskSpline *BKE_mask_spline_copy(MaskSpline *spline)
+MaskSpline *BKE_mask_spline_copy(const MaskSpline *spline)
{
MaskSpline *nspline = MEM_callocN(sizeof(MaskSpline), "new spline");
diff --git a/source/blender/blenkernel/intern/material.c b/source/blender/blenkernel/intern/material.c
index 54945242fe4..f21efb71180 100644
--- a/source/blender/blenkernel/intern/material.c
+++ b/source/blender/blenkernel/intern/material.c
@@ -220,7 +220,7 @@ Material *BKE_material_add(Main *bmain, const char *name)
}
/* XXX keep synced with next function */
-Material *BKE_material_copy(Main *bmain, Material *ma)
+Material *BKE_material_copy(Main *bmain, const Material *ma)
{
Material *man;
int a;
diff --git a/source/blender/blenkernel/intern/mball.c b/source/blender/blenkernel/intern/mball.c
index 97033a9555d..b80579014d6 100644
--- a/source/blender/blenkernel/intern/mball.c
+++ b/source/blender/blenkernel/intern/mball.c
@@ -103,7 +103,7 @@ MetaBall *BKE_mball_add(Main *bmain, const char *name)
return mb;
}
-MetaBall *BKE_mball_copy(Main *bmain, MetaBall *mb)
+MetaBall *BKE_mball_copy(Main *bmain, const MetaBall *mb)
{
MetaBall *mbn;
int a;
diff --git a/source/blender/blenkernel/intern/mball_tessellate.c b/source/blender/blenkernel/intern/mball_tessellate.c
index 5c0b09f0ff0..76965176be8 100644
--- a/source/blender/blenkernel/intern/mball_tessellate.c
+++ b/source/blender/blenkernel/intern/mball_tessellate.c
@@ -316,12 +316,12 @@ static float densfunc(const MetaElem *ball, float x, float y, float z)
if (dvec[2] > ball->expz) dvec[2] -= ball->expz;
else if (dvec[2] < -ball->expz) dvec[2] += ball->expz;
else dvec[2] = 0.0;
- /* fall through */
+ ATTR_FALLTHROUGH;
case MB_PLANE:
if (dvec[1] > ball->expy) dvec[1] -= ball->expy;
else if (dvec[1] < -ball->expy) dvec[1] += ball->expy;
else dvec[1] = 0.0;
- /* fall through */
+ ATTR_FALLTHROUGH;
case MB_TUBE:
if (dvec[0] > ball->expx) dvec[0] -= ball->expx;
else if (dvec[0] < -ball->expx) dvec[0] += ball->expx;
@@ -660,7 +660,7 @@ static void makecubetable(void)
for (i = 0; i < 256; i++) {
for (e = 0; e < 12; e++) done[e] = 0;
for (c = 0; c < 8; c++) pos[c] = MB_BIT(i, c);
- for (e = 0; e < 12; e++)
+ for (e = 0; e < 12; e++) {
if (!done[e] && (pos[corner1[e]] != pos[corner2[e]])) {
INTLIST *ints = NULL;
INTLISTS *lists = MEM_callocN(sizeof(INTLISTS), "mball_intlist");
@@ -687,6 +687,7 @@ static void makecubetable(void)
lists->next = cubetable[i];
cubetable[i] = lists;
}
+ }
}
for (i = 0; i < 256; i++) {
@@ -1193,10 +1194,10 @@ static void init_meta(EvaluationContext *eval_ctx, PROCESS *process, Scene *scen
break;
case MB_CUBE: /* cube is "expanded" by expz, expy and expx */
expz += ml->expz;
- /* fall through */
+ ATTR_FALLTHROUGH;
case MB_PLANE: /* plane is "expanded" by expy and expx */
expy += ml->expy;
- /* fall through */
+ ATTR_FALLTHROUGH;
case MB_TUBE: /* tube is "expanded" by expx */
expx += ml->expx;
break;
diff --git a/source/blender/blenkernel/intern/mesh.c b/source/blender/blenkernel/intern/mesh.c
index c12890a354e..6233caa43fa 100644
--- a/source/blender/blenkernel/intern/mesh.c
+++ b/source/blender/blenkernel/intern/mesh.c
@@ -501,7 +501,7 @@ Mesh *BKE_mesh_add(Main *bmain, const char *name)
return me;
}
-Mesh *BKE_mesh_copy(Main *bmain, Mesh *me)
+Mesh *BKE_mesh_copy(Main *bmain, const Mesh *me)
{
Mesh *men;
int a;
@@ -1339,7 +1339,7 @@ int BKE_mesh_nurbs_displist_to_mdata(
/* this may fail replacing ob->data, be sure to check ob->type */
-void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use_orco_uv)
+void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use_orco_uv, const char *obdata_name)
{
Main *bmain = G.main;
Object *ob1;
@@ -1366,7 +1366,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use
}
/* make mesh */
- me = BKE_mesh_add(bmain, "Mesh");
+ me = BKE_mesh_add(bmain, obdata_name);
me->totvert = totvert;
me->totedge = totedge;
me->totloop = totloop;
@@ -1386,7 +1386,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use
BKE_mesh_calc_normals(me);
}
else {
- me = BKE_mesh_add(bmain, "Mesh");
+ me = BKE_mesh_add(bmain, obdata_name);
DM_to_mesh(dm, me, ob, CD_MASK_MESH, false);
}
@@ -1398,9 +1398,7 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use
cu->mat = NULL;
cu->totcol = 0;
- if (ob->data) {
- BKE_libblock_free(bmain, ob->data);
- }
+ /* Do not decrement ob->data usercount here, it's done at end of func with BKE_libblock_free_us() call. */
ob->data = me;
ob->type = OB_MESH;
@@ -1410,11 +1408,14 @@ void BKE_mesh_from_nurbs_displist(Object *ob, ListBase *dispbase, const bool use
if (ob1->data == cu) {
ob1->type = OB_MESH;
+ id_us_min((ID *)ob1->data);
ob1->data = ob->data;
- id_us_plus((ID *)ob->data);
+ id_us_plus((ID *)ob1->data);
}
ob1 = ob1->id.next;
}
+
+ BKE_libblock_free_us(bmain, cu);
}
void BKE_mesh_from_nurbs(Object *ob)
@@ -1427,7 +1428,7 @@ void BKE_mesh_from_nurbs(Object *ob)
disp = ob->curve_cache->disp;
}
- BKE_mesh_from_nurbs_displist(ob, &disp, use_orco_uv);
+ BKE_mesh_from_nurbs_displist(ob, &disp, use_orco_uv, cu->id.name);
}
typedef struct EdgeLink {
@@ -2486,7 +2487,7 @@ Mesh *BKE_mesh_new_from_object(
/* convert object type to mesh */
uv_from_orco = (tmpcu->flag & CU_UV_ORCO) != 0;
- BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco);
+ BKE_mesh_from_nurbs_displist(tmpobj, &dispbase, uv_from_orco, tmpcu->id.name + 2);
tmpmesh = tmpobj->data;
@@ -2522,7 +2523,7 @@ Mesh *BKE_mesh_new_from_object(
if (ob != basis_ob)
return NULL; /* only do basis metaball */
- tmpmesh = BKE_mesh_add(bmain, "Mesh");
+ tmpmesh = BKE_mesh_add(bmain, ((ID *)ob->data)->name + 2);
/* BKE_mesh_add gives us a user count we don't need */
id_us_min(&tmpmesh->id);
@@ -2577,7 +2578,7 @@ Mesh *BKE_mesh_new_from_object(
else
dm = mesh_create_derived_view(sce, ob, mask);
- tmpmesh = BKE_mesh_add(bmain, "Mesh");
+ tmpmesh = BKE_mesh_add(bmain, ((ID *)ob->data)->name + 2);
DM_to_mesh(dm, tmpmesh, ob, mask, true);
/* Copy autosmooth settings from original mesh. */
diff --git a/source/blender/blenkernel/intern/mesh_evaluate.c b/source/blender/blenkernel/intern/mesh_evaluate.c
index 0d0055113b7..5dfcef9f9bf 100644
--- a/source/blender/blenkernel/intern/mesh_evaluate.c
+++ b/source/blender/blenkernel/intern/mesh_evaluate.c
@@ -1026,7 +1026,7 @@ static bool loop_split_generator_check_cyclic_smooth_fan(
BLI_assert(!BLI_BITMAP_TEST(skip_loops, mlfan_vert_index));
BLI_BITMAP_ENABLE(skip_loops, mlfan_vert_index);
- while(true) {
+ while (true) {
/* Find next loop of the smooth fan. */
loop_manifold_fan_around_vert_next(
mloops, mpolys, loop_to_poly, e2lfan_curr, mv_pivot_index,
@@ -1629,8 +1629,8 @@ void BKE_mesh_normals_loop_custom_from_vertices_set(
/**
* Computes average per-vertex normals from given custom loop normals.
*
- * @param clnors The computed custom loop normals.
- * @param r_vert_clnors The (already allocated) array where to store averaged per-vertex normals.
+ * \param clnors: The computed custom loop normals.
+ * \param r_vert_clnors: The (already allocated) array where to store averaged per-vertex normals.
*/
void BKE_mesh_normals_loop_to_vertex(
const int numVerts, const MLoop *mloops, const int numLoops,
@@ -1993,36 +1993,54 @@ float BKE_mesh_calc_poly_area(
}
}
-/* note, results won't be correct if polygon is non-planar */
-static float mesh_calc_poly_planar_area_centroid(
+/**
+ * Calculate the volume and volume-weighted centroid of the volume formed by the polygon and the origin.
+ * Results will be negative if the origin is "outside" the polygon
+ * (+ve normal side), but the polygon may be non-planar with no effect.
+ *
+ * Method from:
+ * - http://forums.cgsociety.org/archive/index.php?t-756235.html
+ * - http://www.globalspec.com/reference/52702/203279/4-8-the-centroid-of-a-tetrahedron
+ *
+ * \note volume is 6x actual volume, and centroid is 4x actual volume-weighted centroid
+ * (so division can be done once at the end)
+ * \note results will have bias if polygon is non-planar.
+ */
+static float mesh_calc_poly_volume_and_weighted_centroid(
const MPoly *mpoly, const MLoop *loopstart, const MVert *mvarray,
float r_cent[3])
{
- int i;
- float tri_area;
- float total_area = 0.0f;
- float v1[3], v2[3], v3[3], normal[3], tri_cent[3];
+ const float *v_pivot, *v_step1;
+ float total_volume = 0.0f;
- BKE_mesh_calc_poly_normal(mpoly, loopstart, mvarray, normal);
- copy_v3_v3(v1, mvarray[loopstart[0].v].co);
- copy_v3_v3(v2, mvarray[loopstart[1].v].co);
zero_v3(r_cent);
- for (i = 2; i < mpoly->totloop; i++) {
- copy_v3_v3(v3, mvarray[loopstart[i].v].co);
+ v_pivot = mvarray[loopstart[0].v].co;
+ v_step1 = mvarray[loopstart[1].v].co;
- tri_area = area_tri_signed_v3(v1, v2, v3, normal);
- total_area += tri_area;
+ for (int i = 2; i < mpoly->totloop; i++) {
+ const float *v_step2 = mvarray[loopstart[i].v].co;
- mid_v3_v3v3v3(tri_cent, v1, v2, v3);
- madd_v3_v3fl(r_cent, tri_cent, tri_area);
+ /* Calculate the 6x volume of the tetrahedron formed by the 3 vertices
+ * of the triangle and the origin as the fourth vertex */
+ float v_cross[3];
+ cross_v3_v3v3(v_cross, v_pivot, v_step1);
+ const float tetra_volume = dot_v3v3 (v_cross, v_step2);
+ total_volume += tetra_volume;
- copy_v3_v3(v2, v3);
- }
+ /* Calculate the centroid of the tetrahedron formed by the 3 vertices
+ * of the triangle and the origin as the fourth vertex.
+ * The centroid is simply the average of the 4 vertices.
+ *
+ * Note that the vector is 4x the actual centroid so the division can be done once at the end. */
+ for (uint j = 0; j < 3; j++) {
+ r_cent[j] += tetra_volume * (v_pivot[j] + v_step1[j] + v_step2[j]);
+ }
- mul_v3_fl(r_cent, 1.0f / total_area);
+ v_step1 = v_step2;
+ }
- return total_area;
+ return total_volume;
}
#if 0 /* slow version of the function below */
@@ -2143,25 +2161,28 @@ bool BKE_mesh_center_centroid(const Mesh *me, float r_cent[3])
{
int i = me->totpoly;
MPoly *mpoly;
- float poly_area;
- float total_area = 0.0f;
+ float poly_volume;
+ float total_volume = 0.0f;
float poly_cent[3];
zero_v3(r_cent);
- /* calculate a weighted average of polygon centroids */
+ /* calculate a weighted average of polyhedron centroids */
for (mpoly = me->mpoly; i--; mpoly++) {
- poly_area = mesh_calc_poly_planar_area_centroid(mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent);
+ poly_volume = mesh_calc_poly_volume_and_weighted_centroid(mpoly, me->mloop + mpoly->loopstart, me->mvert, poly_cent);
- madd_v3_v3fl(r_cent, poly_cent, poly_area);
- total_area += poly_area;
+ /* poly_cent is already volume-weighted, so no need to multiply by the volume */
+ add_v3_v3(r_cent, poly_cent);
+ total_volume += poly_volume;
}
/* otherwise we get NAN for 0 polys */
- if (me->totpoly) {
- mul_v3_fl(r_cent, 1.0f / total_area);
+ if (total_volume != 0.0f) {
+ /* multipy by 0.25 to get the correct centroid */
+ /* no need to divide volume by 6 as the centroid is weighted by 6x the volume, so it all cancels out */
+ mul_v3_fl(r_cent, 0.25f / total_volume);
}
- /* zero area faces cause this, fallback to median */
+ /* this can happen for non-manifold objects, fallback to median */
if (UNLIKELY(!is_finite_v3(r_cent))) {
return BKE_mesh_center_median(me, r_cent);
}
diff --git a/source/blender/blenkernel/intern/mesh_mapping.c b/source/blender/blenkernel/intern/mesh_mapping.c
index 8562988b5e1..525c0c9728e 100644
--- a/source/blender/blenkernel/intern/mesh_mapping.c
+++ b/source/blender/blenkernel/intern/mesh_mapping.c
@@ -165,7 +165,7 @@ UvVertMap *BKE_mesh_uv_vert_map_create(
vmap->vert[a] = newvlist;
}
- if (use_winding) {
+ if (use_winding) {
MEM_freeN(winding);
}
diff --git a/source/blender/blenkernel/intern/mesh_validate.c b/source/blender/blenkernel/intern/mesh_validate.c
index ba890b005d8..4aeddbb4c45 100644
--- a/source/blender/blenkernel/intern/mesh_validate.c
+++ b/source/blender/blenkernel/intern/mesh_validate.c
@@ -584,8 +584,8 @@ bool BKE_mesh_validate_arrays(Mesh *mesh,
int prev_e = ml->e;
ml->e = GET_INT_FROM_POINTER(BLI_edgehash_lookup(edge_hash, v1, v2));
fix_flag.loops_edge = true;
- PRINT_ERR("\tPoly %u has invalid edge reference (%d), fixed using edge %u\n",
- sp->index, prev_e, ml->e);
+ PRINT_ERR("\tPoly %u has invalid edge reference (%d, is_removed: %d), fixed using edge %u\n",
+ sp->index, prev_e, IS_REMOVED_EDGE(me), ml->e);
}
else {
PRINT_ERR("\tPoly %u has invalid edge reference (%u)\n", sp->index, ml->e);
diff --git a/source/blender/blenkernel/intern/movieclip.c b/source/blender/blenkernel/intern/movieclip.c
index 6794a8e8f93..dfa8742a295 100644
--- a/source/blender/blenkernel/intern/movieclip.c
+++ b/source/blender/blenkernel/intern/movieclip.c
@@ -1488,7 +1488,7 @@ void BKE_movieclip_free(MovieClip *clip)
BKE_animdata_free((ID *) clip, false);
}
-MovieClip *BKE_movieclip_copy(Main *bmain, MovieClip *clip)
+MovieClip *BKE_movieclip_copy(Main *bmain, const MovieClip *clip)
{
MovieClip *clip_new;
diff --git a/source/blender/blenkernel/intern/node.c b/source/blender/blenkernel/intern/node.c
index 3f3b4896653..5acfe4a0aa4 100644
--- a/source/blender/blenkernel/intern/node.c
+++ b/source/blender/blenkernel/intern/node.c
@@ -921,7 +921,7 @@ static void node_socket_copy(bNodeSocket *dst, bNodeSocket *src)
/* keep socket listorder identical, for copying links */
/* ntree is the target tree */
-bNode *nodeCopyNode(struct bNodeTree *ntree, struct bNode *node)
+bNode *nodeCopyNode(bNodeTree *ntree, bNode *node)
{
bNode *nnode = MEM_callocN(sizeof(bNode), "dupli node");
bNodeSocket *sock, *oldsock;
@@ -1200,7 +1200,9 @@ bNodeTree *ntreeAddTree(Main *bmain, const char *name, const char *idname)
* copying for internal use (threads for eg), where you wont want it to modify the
* scene data.
*/
-static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool skip_database, bool do_id_user, bool do_make_extern, bool copy_previews)
+static bNodeTree *ntreeCopyTree_internal(
+ const bNodeTree *ntree, Main *bmain,
+ bool skip_database, bool do_id_user, bool do_make_extern, bool copy_previews)
{
bNodeTree *newtree;
bNode *node /*, *nnode */ /* UNUSED */, *last;
@@ -1299,11 +1301,11 @@ static bNodeTree *ntreeCopyTree_internal(bNodeTree *ntree, Main *bmain, bool ski
return newtree;
}
-bNodeTree *ntreeCopyTree_ex(bNodeTree *ntree, Main *bmain, const bool do_id_user)
+bNodeTree *ntreeCopyTree_ex(const bNodeTree *ntree, Main *bmain, const bool do_id_user)
{
return ntreeCopyTree_internal(ntree, bmain, false, do_id_user, true, true);
}
-bNodeTree *ntreeCopyTree(Main *bmain, bNodeTree *ntree)
+bNodeTree *ntreeCopyTree(Main *bmain, const bNodeTree *ntree)
{
return ntreeCopyTree_ex(ntree, bmain, true);
}
@@ -1698,11 +1700,12 @@ static void node_free_node_ex(bNodeTree *ntree, bNode *node, bool remove_animdat
ntreeTexEndExecTree(ntree->execdata);
ntree->execdata = NULL;
}
-
- if (node->typeinfo->freefunc)
- node->typeinfo->freefunc(node);
}
-
+
+ if (node->typeinfo->freefunc) {
+ node->typeinfo->freefunc(node);
+ }
+
for (sock = node->inputs.first; sock; sock = nextsock) {
nextsock = sock->next;
node_socket_free(ntree, sock, node);
@@ -1828,7 +1831,7 @@ void ntreeFreeTree(bNodeTree *ntree)
if (tntree == ntree)
break;
if (tntree == NULL) {
- BKE_libblock_free_data(G.main, &ntree->id);
+ BKE_libblock_free_data(&ntree->id, true);
}
}
@@ -3172,12 +3175,20 @@ void nodeSynchronizeID(bNode *node, bool copy_to_id)
void nodeLabel(bNodeTree *ntree, bNode *node, char *label, int maxlen)
{
- if (node->label[0] != '\0')
+ if (node->label[0] != '\0') {
BLI_strncpy(label, node->label, maxlen);
- else if (node->typeinfo->labelfunc)
+ }
+ else if (node->typeinfo->labelfunc) {
node->typeinfo->labelfunc(ntree, node, label, maxlen);
- else
- BLI_strncpy(label, IFACE_(node->typeinfo->ui_name), maxlen);
+ }
+ else {
+ /* Kind of hacky and weak... Ideally would be better to use RNA here. :| */
+ const char *tmp = CTX_IFACE_(BLT_I18NCONTEXT_ID_NODETREE, node->typeinfo->ui_name);
+ if (tmp == node->typeinfo->ui_name) {
+ tmp = IFACE_(node->typeinfo->ui_name);
+ }
+ BLI_strncpy(label, tmp, maxlen);
+ }
}
static void node_type_base_defaults(bNodeType *ntype)
@@ -3568,6 +3579,7 @@ static void registerShaderNodes(void)
register_node_type_sh_background();
register_node_type_sh_bsdf_anisotropic();
register_node_type_sh_bsdf_diffuse();
+ register_node_type_sh_bsdf_principled();
register_node_type_sh_bsdf_glossy();
register_node_type_sh_bsdf_glass();
register_node_type_sh_bsdf_translucent();
diff --git a/source/blender/blenkernel/intern/object.c b/source/blender/blenkernel/intern/object.c
index 6e754755cf3..f3086396c3a 100644
--- a/source/blender/blenkernel/intern/object.c
+++ b/source/blender/blenkernel/intern/object.c
@@ -127,6 +127,7 @@
#endif
#include "CCGSubSurf.h"
+#include "atomic_ops.h"
#include "GPU_material.h"
@@ -319,19 +320,24 @@ void BKE_object_link_modifiers(struct Object *ob_dst, const struct Object *ob_sr
/* free data derived from mesh, called when mesh changes or is freed */
void BKE_object_free_derived_caches(Object *ob)
{
- /* also serves as signal to remake texspace */
+ /* Also serves as signal to remake texspace.
+ *
+ * NOTE: This function can be called from threads on different objects
+ * sharing same data datablock. So we need to ensure atomic nature of
+ * data modification here.
+ */
if (ob->type == OB_MESH) {
Mesh *me = ob->data;
if (me && me->bb) {
- me->bb->flag |= BOUNDBOX_DIRTY;
+ atomic_fetch_and_or_uint32((uint*)&me->bb->flag, BOUNDBOX_DIRTY);
}
}
else if (ELEM(ob->type, OB_SURF, OB_CURVE, OB_FONT)) {
Curve *cu = ob->data;
if (cu && cu->bb) {
- cu->bb->flag |= BOUNDBOX_DIRTY;
+ atomic_fetch_and_or_uint32((uint*)&cu->bb->flag, BOUNDBOX_DIRTY);
}
}
@@ -876,7 +882,7 @@ SoftBody *copy_softbody(const SoftBody *sb, bool copy_caches)
return sbn;
}
-BulletSoftBody *copy_bulletsoftbody(BulletSoftBody *bsb)
+BulletSoftBody *copy_bulletsoftbody(const BulletSoftBody *bsb)
{
BulletSoftBody *bsbn;
@@ -1008,7 +1014,7 @@ void BKE_object_copy_softbody(Object *ob_dst, const Object *ob_src)
}
}
-static void copy_object_pose(Object *obn, Object *ob)
+static void copy_object_pose(Object *obn, const Object *ob)
{
bPoseChannel *chan;
@@ -1041,7 +1047,7 @@ static void copy_object_pose(Object *obn, Object *ob)
}
}
-static void copy_object_lod(Object *obn, Object *ob)
+static void copy_object_lod(Object *obn, const Object *ob)
{
BLI_duplicatelist(&obn->lodlevels, &ob->lodlevels);
@@ -1092,7 +1098,7 @@ void BKE_object_transform_copy(Object *ob_tar, const Object *ob_src)
copy_v3_v3(ob_tar->size, ob_src->size);
}
-Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches)
+Object *BKE_object_copy_ex(Main *bmain, const Object *ob, bool copy_caches)
{
Object *obn;
ModifierData *md;
@@ -1139,6 +1145,7 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches)
/* increase user numbers */
id_us_plus((ID *)obn->data);
+ id_us_plus((ID *)obn->poselib);
id_us_plus((ID *)obn->gpd);
id_us_plus((ID *)obn->dup_group);
@@ -1180,7 +1187,7 @@ Object *BKE_object_copy_ex(Main *bmain, Object *ob, bool copy_caches)
}
/* copy objects, will re-initialize cached simulation data */
-Object *BKE_object_copy(Main *bmain, Object *ob)
+Object *BKE_object_copy(Main *bmain, const Object *ob)
{
return BKE_object_copy_ex(bmain, ob, false);
}
diff --git a/source/blender/blenkernel/intern/object_dupli.c b/source/blender/blenkernel/intern/object_dupli.c
index e3b801b3193..076bef71875 100644
--- a/source/blender/blenkernel/intern/object_dupli.c
+++ b/source/blender/blenkernel/intern/object_dupli.c
@@ -64,6 +64,7 @@
#include "BLI_strict_flags.h"
+#include "BLI_hash.h"
/* Dupli-Geometry */
@@ -180,6 +181,23 @@ static DupliObject *make_dupli(const DupliContext *ctx,
if (ob->type == OB_MBALL)
dob->no_draw = true;
+ /* random number */
+ /* the logic here is designed to match Cycles */
+ dob->random_id = BLI_hash_string(dob->ob->id.name + 2);
+
+ if (dob->persistent_id[0] != INT_MAX) {
+ for (i = 0; i < MAX_DUPLI_RECUR * 2; i++) {
+ dob->random_id = BLI_hash_int_2d(dob->random_id, (unsigned int)dob->persistent_id[i]);
+ }
+ }
+ else {
+ dob->random_id = BLI_hash_int_2d(dob->random_id, 0);
+ }
+
+ if (ctx->object != ob) {
+ dob->random_id ^= BLI_hash_int(BLI_hash_string(ctx->object->id.name + 2));
+ }
+
return dob;
}
@@ -529,10 +547,15 @@ static void make_duplis_verts(const DupliContext *ctx)
BMEditMesh *em = BKE_editmesh_from_object(parent);
CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO : CD_MASK_BAREMESH);
- if (em)
+ if (ctx->eval_ctx->mode == DAG_EVAL_RENDER) {
+ vdd.dm = mesh_create_derived_render(scene, parent, dm_mask);
+ }
+ else if (em) {
vdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask);
- else
+ }
+ else {
vdd.dm = mesh_get_derived_final(scene, parent, dm_mask);
+ }
vdd.edit_btmesh = me->edit_btmesh;
if (use_texcoords)
@@ -792,10 +815,15 @@ static void make_duplis_faces(const DupliContext *ctx)
BMEditMesh *em = BKE_editmesh_from_object(parent);
CustomDataMask dm_mask = (use_texcoords ? CD_MASK_BAREMESH | CD_MASK_ORCO | CD_MASK_MLOOPUV : CD_MASK_BAREMESH);
- if (em)
+ if (ctx->eval_ctx->mode == DAG_EVAL_RENDER) {
+ fdd.dm = mesh_create_derived_render(scene, parent, dm_mask);
+ }
+ else if (em) {
fdd.dm = editbmesh_get_derived_cage(scene, parent, em, dm_mask);
- else
+ }
+ else {
fdd.dm = mesh_get_derived_final(scene, parent, dm_mask);
+ }
if (use_texcoords) {
CustomData *ml_data = fdd.dm->getLoopDataLayout(fdd.dm);
diff --git a/source/blender/blenkernel/intern/object_update.c b/source/blender/blenkernel/intern/object_update.c
index a531466294e..e03af585cf2 100644
--- a/source/blender/blenkernel/intern/object_update.c
+++ b/source/blender/blenkernel/intern/object_update.c
@@ -145,18 +145,6 @@ void BKE_object_eval_done(EvaluationContext *UNUSED(eval_ctx), Object *ob)
else ob->transflag &= ~OB_NEG_SCALE;
}
-void BKE_object_eval_modifier(struct EvaluationContext *eval_ctx,
- struct Scene *scene,
- struct Object *ob,
- struct ModifierData *md)
-{
- DEBUG_PRINT("%s on %s\n", __func__, ob->id.name);
- (void) eval_ctx; /* Ignored. */
- (void) scene; /* Ignored. */
- (void) ob; /* Ignored. */
- (void) md; /* Ignored. */
-}
-
void BKE_object_handle_data_update(EvaluationContext *eval_ctx,
Scene *scene,
Object *ob)
diff --git a/source/blender/blenkernel/intern/ocean.c b/source/blender/blenkernel/intern/ocean.c
index 621ac9c2480..537c8926a5b 100644
--- a/source/blender/blenkernel/intern/ocean.c
+++ b/source/blender/blenkernel/intern/ocean.c
@@ -334,10 +334,10 @@ void BKE_ocean_eval_uv(struct Ocean *oc, struct OceanResult *ocr, float u, float
i1 = i1 % oc->_M;
j1 = j1 % oc->_N;
-
#define BILERP(m) (interpf(interpf(m[i1 * oc->_N + j1], m[i0 * oc->_N + j1], frac_x), \
interpf(m[i1 * oc->_N + j0], m[i0 * oc->_N + j0], frac_x), \
frac_z))
+
{
if (oc->_do_disp_y) {
ocr->disp[1] = BILERP(oc->_disp_y);
diff --git a/source/blender/blenkernel/intern/packedFile.c b/source/blender/blenkernel/intern/packedFile.c
index 489fc2f3710..64f90ef5c52 100644
--- a/source/blender/blenkernel/intern/packedFile.c
+++ b/source/blender/blenkernel/intern/packedFile.c
@@ -450,7 +450,7 @@ char *unpackFile(ReportList *reports, const char *abs_name, const char *local_na
break;
}
/* else create it */
- /* fall-through */
+ ATTR_FALLTHROUGH;
}
case PF_WRITE_LOCAL:
if (writePackedFile(reports, local_name, pf, 1) == RET_OK) {
@@ -471,7 +471,7 @@ char *unpackFile(ReportList *reports, const char *abs_name, const char *local_na
break;
}
/* else create it */
- /* fall-through */
+ ATTR_FALLTHROUGH;
}
case PF_WRITE_ORIGINAL:
if (writePackedFile(reports, abs_name, pf, 1) == RET_OK) {
diff --git a/source/blender/blenkernel/intern/paint.c b/source/blender/blenkernel/intern/paint.c
index 6b954f060d3..c7cfe55f659 100644
--- a/source/blender/blenkernel/intern/paint.c
+++ b/source/blender/blenkernel/intern/paint.c
@@ -314,7 +314,7 @@ PaintCurve *BKE_paint_curve_add(Main *bmain, const char *name)
return pc;
}
-PaintCurve *BKE_paint_curve_copy(Main *bmain, PaintCurve *pc)
+PaintCurve *BKE_paint_curve_copy(Main *bmain, const PaintCurve *pc)
{
PaintCurve *pc_new;
@@ -396,7 +396,7 @@ Palette *BKE_palette_add(Main *bmain, const char *name)
return palette;
}
-Palette *BKE_palette_copy(Main *bmain, Palette *palette)
+Palette *BKE_palette_copy(Main *bmain, const Palette *palette)
{
Palette *palette_new;
diff --git a/source/blender/blenkernel/intern/particle.c b/source/blender/blenkernel/intern/particle.c
index 228ae6afaba..416d63cfefb 100644
--- a/source/blender/blenkernel/intern/particle.c
+++ b/source/blender/blenkernel/intern/particle.c
@@ -253,11 +253,16 @@ struct LatticeDeformData *psys_create_lattice_deform_data(ParticleSimulationData
if (psys_in_edit_mode(sim->scene, sim->psys) == 0) {
Object *lattice = NULL;
ModifierData *md = (ModifierData *)psys_get_modifier(sim->ob, sim->psys);
+ int mode = G.is_rendering ? eModifierMode_Render : eModifierMode_Realtime;
for (; md; md = md->next) {
if (md->type == eModifierType_Lattice) {
- LatticeModifierData *lmd = (LatticeModifierData *)md;
- lattice = lmd->object;
+ if (md->mode & mode) {
+ LatticeModifierData *lmd = (LatticeModifierData *)md;
+ lattice = lmd->object;
+ sim->psys->lattice_strength = lmd->strength;
+ }
+
break;
}
}
@@ -590,7 +595,7 @@ void psys_free(Object *ob, ParticleSystem *psys)
BLI_bvhtree_free(psys->bvhtree);
BLI_kdtree_free(psys->tree);
-
+
if (psys->fluid_springs)
MEM_freeN(psys->fluid_springs);
@@ -2706,7 +2711,7 @@ void psys_cache_paths(ParticleSimulationData *sim, float cfra, const bool use_re
/* lattices have to be calculated separately to avoid mixups between effector calculations */
if (psys->lattice_deform_data) {
for (k = 0, ca = cache[p]; k <= segments; k++, ca++)
- calc_latt_deform(psys->lattice_deform_data, ca->co, 1.0f);
+ calc_latt_deform(psys->lattice_deform_data, ca->co, psys->lattice_strength);
}
}
@@ -3326,7 +3331,7 @@ void BKE_particlesettings_rough_curve_init(ParticleSettings *part)
part->roughcurve = cumap;
}
-ParticleSettings *BKE_particlesettings_copy(Main *bmain, ParticleSettings *part)
+ParticleSettings *BKE_particlesettings_copy(Main *bmain, const ParticleSettings *part)
{
ParticleSettings *partn;
int a;
@@ -3369,7 +3374,8 @@ void BKE_particlesettings_make_local(Main *bmain, ParticleSettings *part, const
/* Textures */
/************************************************/
-static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, const float fuv[4], char *name, float *texco)
+static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int index, const float fuv[4],
+ char *name, float *texco, bool from_vert)
{
MFace *mf;
MTFace *tf;
@@ -3385,11 +3391,15 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, co
if (pa) {
i = ELEM(pa->num_dmcache, DMCACHE_NOTFOUND, DMCACHE_ISCHILD) ? pa->num : pa->num_dmcache;
- if (i >= dm->getNumTessFaces(dm))
+ if ((!from_vert && i >= dm->getNumTessFaces(dm)) ||
+ (from_vert && i >= dm->getNumVerts(dm)))
+ {
i = -1;
+ }
+ }
+ else {
+ i = index;
}
- else
- i = face_index;
if (i == -1) {
texco[0] = 0.0f;
@@ -3397,7 +3407,22 @@ static int get_particle_uv(DerivedMesh *dm, ParticleData *pa, int face_index, co
texco[2] = 0.0f;
}
else {
- mf = dm->getTessFaceData(dm, i, CD_MFACE);
+ if (from_vert) {
+ mf = dm->getTessFaceDataArray(dm, CD_MFACE);
+
+ /* This finds the first face to contain the emitting vertex,
+ * this is not ideal, but is mostly fine as UV seams generally
+ * map to equal-colored parts of a texture */
+ for (int j = 0; j < dm->getNumTessFaces(dm); j++, mf++) {
+ if (ELEM(i, mf->v1, mf->v2, mf->v3, mf->v4)) {
+ i = j;
+ break;
+ }
+ }
+ }
+ else {
+ mf = dm->getTessFaceData(dm, i, CD_MFACE);
+ }
psys_interpolate_uvs(&tf[i], mf->v4, fuv, texco);
@@ -3464,9 +3489,13 @@ static void get_cpa_texture(DerivedMesh *dm, ParticleSystem *psys, ParticleSetti
mul_m4_v3(mtex->object->imat, texvec);
break;
case TEXCO_UV:
- if (fw && get_particle_uv(dm, NULL, face_index, fw, mtex->uvname, texvec))
+ if (fw && get_particle_uv(dm, NULL, face_index, fw, mtex->uvname,
+ texvec, (part->from == PART_FROM_VERT)))
+ {
break;
- /* no break, failed to get uv's, so let's try orco's */
+ }
+ /* no break, failed to get uv's, so let's try orco's */
+ ATTR_FALLTHROUGH;
case TEXCO_ORCO:
copy_v3_v3(texvec, orco);
break;
@@ -3536,9 +3565,13 @@ void psys_get_texture(ParticleSimulationData *sim, ParticleData *pa, ParticleTex
mul_m4_v3(mtex->object->imat, texvec);
break;
case TEXCO_UV:
- if (get_particle_uv(sim->psmd->dm_final, pa, 0, pa->fuv, mtex->uvname, texvec))
+ if (get_particle_uv(sim->psmd->dm_final, pa, 0, pa->fuv, mtex->uvname,
+ texvec, (part->from == PART_FROM_VERT)))
+ {
break;
- /* no break, failed to get uv's, so let's try orco's */
+ }
+ /* no break, failed to get uv's, so let's try orco's */
+ ATTR_FALLTHROUGH;
case TEXCO_ORCO:
psys_particle_on_emitter(sim->psmd, sim->psys->part->from, pa->num, pa->num_dmcache, pa->fuv, pa->foffset, co, 0, 0, 0, texvec, 0);
@@ -3746,7 +3779,7 @@ void psys_get_particle_on_path(ParticleSimulationData *sim, int p, ParticleKey *
}
if (psys->lattice_deform_data && edit == 0)
- calc_latt_deform(psys->lattice_deform_data, state->co, 1.0f);
+ calc_latt_deform(psys->lattice_deform_data, state->co, psys->lattice_strength);
}
}
}
@@ -3985,7 +4018,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
do_child_modifiers(NULL, sim, NULL, key1->co, key1->vel, key1->rot, par_orco, cpa, cpa->fuv, mat, state, t);
if (psys->lattice_deform_data)
- calc_latt_deform(psys->lattice_deform_data, state->co, 1.0f);
+ calc_latt_deform(psys->lattice_deform_data, state->co, psys->lattice_strength);
}
else {
if (pa->state.time == cfra || ELEM(part->phystype, PART_PHYS_NO, PART_PHYS_KEYED))
@@ -4044,7 +4077,7 @@ int psys_get_particle_state(ParticleSimulationData *sim, int p, ParticleKey *sta
}
if (sim->psys->lattice_deform_data)
- calc_latt_deform(sim->psys->lattice_deform_data, state->co, 1.0f);
+ calc_latt_deform(sim->psys->lattice_deform_data, state->co, psys->lattice_strength);
}
return 1;
@@ -4291,7 +4324,7 @@ void psys_apply_hair_lattice(Scene *scene, Object *ob, ParticleSystem *psys)
hkey = pa->hair;
for (h = 0; h < pa->totkey; h++, hkey++) {
mul_m4_v3(hairmat, hkey->co);
- calc_latt_deform(psys->lattice_deform_data, hkey->co, 1.0f);
+ calc_latt_deform(psys->lattice_deform_data, hkey->co, psys->lattice_strength);
mul_m4_v3(imat, hkey->co);
}
}
diff --git a/source/blender/blenkernel/intern/particle_child.c b/source/blender/blenkernel/intern/particle_child.c
index 842de869291..bfcda89a635 100644
--- a/source/blender/blenkernel/intern/particle_child.c
+++ b/source/blender/blenkernel/intern/particle_child.c
@@ -355,9 +355,13 @@ void psys_apply_child_modifiers(ParticleThreadContext *ctx, struct ListBase *mod
{
const float step_length = 1.0f / (float)(totkeys - 1);
-
float cur_length = 0.0f;
-
+
+ if (max_length <= 0.0f) {
+ keys->segments = -1;
+ totkeys = 0;
+ }
+
/* we have to correct velocity because of kink & clump */
for (k = 0, key = keys; k < totkeys; ++k, ++key) {
if (k >= 2) {
diff --git a/source/blender/blenkernel/intern/particle_distribute.c b/source/blender/blenkernel/intern/particle_distribute.c
index 44cf5b119c1..4f758bde7f9 100644
--- a/source/blender/blenkernel/intern/particle_distribute.c
+++ b/source/blender/blenkernel/intern/particle_distribute.c
@@ -427,12 +427,38 @@ static int distribute_binary_search(float *sum, int n, float value)
static void distribute_from_verts_exec(ParticleTask *thread, ParticleData *pa, int p)
{
ParticleThreadContext *ctx= thread->ctx;
- int rng_skip_tot= PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */
+ MFace *mface;
+
+ DM_ensure_tessface(ctx->dm);
+ mface = ctx->dm->getTessFaceDataArray(ctx->dm, CD_MFACE);
+
+ int rng_skip_tot = PSYS_RND_DIST_SKIP; /* count how many rng_* calls wont need skipping */
/* TODO_PARTICLE - use original index */
- pa->num= ctx->index[p];
- pa->fuv[0] = 1.0f;
- pa->fuv[1] = pa->fuv[2] = pa->fuv[3] = 0.0;
+ pa->num = ctx->index[p];
+
+ zero_v4(pa->fuv);
+
+ if (pa->num != DMCACHE_NOTFOUND && pa->num < ctx->dm->getNumVerts(ctx->dm)) {
+
+ /* This finds the first face to contain the emitting vertex,
+ * this is not ideal, but is mostly fine as UV seams generally
+ * map to equal-colored parts of a texture */
+ for (int i = 0; i < ctx->dm->getNumTessFaces(ctx->dm); i++, mface++) {
+ if (ELEM(pa->num, mface->v1, mface->v2, mface->v3, mface->v4)) {
+ unsigned int *vert = &mface->v1;
+
+ for (int j = 0; j < 4; j++, vert++) {
+ if (*vert == pa->num) {
+ pa->fuv[j] = 1.0f;
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+ }
#if ONLY_WORKING_WITH_PA_VERTS
if (ctx->tree) {
@@ -1092,7 +1118,7 @@ static int psys_thread_context_init_distribute(ParticleThreadContext *ctx, Parti
/* For hair, sort by origindex (allows optimization's in rendering), */
/* however with virtual parents the children need to be in random order. */
- if (part->type == PART_HAIR && !(part->childtype==PART_CHILD_FACES && part->parents!=0.0f)) {
+ if (part->type == PART_HAIR && !(part->childtype==PART_CHILD_FACES && part->parents != 0.0f)) {
int *orig_index = NULL;
if (from == PART_FROM_VERT) {
diff --git a/source/blender/blenkernel/intern/particle_system.c b/source/blender/blenkernel/intern/particle_system.c
index 943dc781246..b61f6792c89 100644
--- a/source/blender/blenkernel/intern/particle_system.c
+++ b/source/blender/blenkernel/intern/particle_system.c
@@ -1000,7 +1000,7 @@ void reset_particle(ParticleSimulationData *sim, ParticleData *pa, float dtime,
part=psys->part;
/* get precise emitter matrix if particle is born */
- if (part->type!=PART_HAIR && dtime > 0.f && pa->time < cfra && pa->time >= sim->psys->cfra) {
+ if (part->type != PART_HAIR && dtime > 0.f && pa->time < cfra && pa->time >= sim->psys->cfra) {
evaluate_emitter_anim(sim->scene, sim->ob, pa->time);
psys->flag |= PSYS_OB_ANIM_RESTORE;
@@ -1183,7 +1183,7 @@ static void set_keyed_keys(ParticleSimulationData *sim)
key->time = pa->time;
}
- if (psys->flag & PSYS_KEYED_TIMING && pt->duration!=0.0f)
+ if (psys->flag & PSYS_KEYED_TIMING && pt->duration != 0.0f)
k++;
ksim.psys->flag |= keyed_flag;
@@ -4350,13 +4350,12 @@ void BKE_particlesystem_id_loop(ParticleSystem *psys, ParticleSystemIDFunc func,
/* **** Depsgraph evaluation **** */
-void BKE_particle_system_eval(EvaluationContext *UNUSED(eval_ctx),
- Scene *scene,
- Object *ob,
- ParticleSystem *psys)
+void BKE_particle_system_eval_init(EvaluationContext *UNUSED(eval_ctx),
+ Scene *scene,
+ Object *ob)
{
if (G.debug & G_DEBUG_DEPSGRAPH) {
- printf("%s on %s:%s\n", __func__, ob->id.name, psys->name);
+ printf("%s on %s\n", __func__, ob->id.name);
}
BKE_ptcache_object_reset(scene, ob, PTCACHE_RESET_DEPSGRAPH);
}
diff --git a/source/blender/blenkernel/intern/pbvh.c b/source/blender/blenkernel/intern/pbvh.c
index 4fe4d6e75a6..53dfffe2b97 100644
--- a/source/blender/blenkernel/intern/pbvh.c
+++ b/source/blender/blenkernel/intern/pbvh.c
@@ -620,7 +620,7 @@ void BKE_pbvh_free(PBVH *bvh)
if (node->flag & PBVH_Leaf) {
if (node->draw_buffers)
- GPU_free_pbvh_buffers(node->draw_buffers);
+ GPU_pbvh_buffers_free(node->draw_buffers);
if (node->vert_indices)
MEM_freeN((void *)node->vert_indices);
if (node->face_vert_indices)
@@ -635,7 +635,7 @@ void BKE_pbvh_free(PBVH *bvh)
BLI_gset_free(node->bm_other_verts, NULL);
}
}
- GPU_free_pbvh_buffer_multires(&bvh->grid_common_gpu_buffer);
+ GPU_pbvh_multires_buffers_free(&bvh->grid_common_gpu_buffer);
if (bvh->deformed) {
if (bvh->verts) {
@@ -1090,11 +1090,11 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
PBVHNode *node = nodes[n];
if (node->flag & PBVH_RebuildDrawBuffers) {
- GPU_free_pbvh_buffers(node->draw_buffers);
+ GPU_pbvh_buffers_free(node->draw_buffers);
switch (bvh->type) {
case PBVH_GRIDS:
node->draw_buffers =
- GPU_build_grid_pbvh_buffers(node->prim_indices,
+ GPU_pbvh_grid_buffers_build(node->prim_indices,
node->totprim,
bvh->grid_hidden,
bvh->gridkey.grid_size,
@@ -1102,7 +1102,7 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
break;
case PBVH_FACES:
node->draw_buffers =
- GPU_build_mesh_pbvh_buffers(node->face_vert_indices,
+ GPU_pbvh_mesh_buffers_build(node->face_vert_indices,
bvh->mpoly, bvh->mloop, bvh->looptri,
bvh->verts,
node->prim_indices,
@@ -1110,42 +1110,44 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
break;
case PBVH_BMESH:
node->draw_buffers =
- GPU_build_bmesh_pbvh_buffers(bvh->flags & PBVH_DYNTOPO_SMOOTH_SHADING);
+ GPU_pbvh_bmesh_buffers_build(bvh->flags & PBVH_DYNTOPO_SMOOTH_SHADING);
break;
}
-
+
node->flag &= ~PBVH_RebuildDrawBuffers;
}
if (node->flag & PBVH_UpdateDrawBuffers) {
switch (bvh->type) {
case PBVH_GRIDS:
- GPU_update_grid_pbvh_buffers(node->draw_buffers,
- bvh->grids,
- bvh->grid_flag_mats,
- node->prim_indices,
- node->totprim,
- &bvh->gridkey,
- bvh->show_diffuse_color);
+ GPU_pbvh_grid_buffers_update(
+ node->draw_buffers,
+ bvh->grids,
+ bvh->grid_flag_mats,
+ node->prim_indices,
+ node->totprim,
+ &bvh->gridkey,
+ bvh->show_diffuse_color);
break;
case PBVH_FACES:
- GPU_update_mesh_pbvh_buffers(node->draw_buffers,
- bvh->verts,
- node->vert_indices,
- node->uniq_verts +
- node->face_verts,
- CustomData_get_layer(bvh->vdata,
- CD_PAINT_MASK),
- node->face_vert_indices,
- bvh->show_diffuse_color);
+ GPU_pbvh_mesh_buffers_update(
+ node->draw_buffers,
+ bvh->verts,
+ node->vert_indices,
+ node->uniq_verts +
+ node->face_verts,
+ CustomData_get_layer(bvh->vdata, CD_PAINT_MASK),
+ node->face_vert_indices,
+ bvh->show_diffuse_color);
break;
case PBVH_BMESH:
- GPU_update_bmesh_pbvh_buffers(node->draw_buffers,
- bvh->bm,
- node->bm_faces,
- node->bm_unique_verts,
- node->bm_other_verts,
- bvh->show_diffuse_color);
+ GPU_pbvh_bmesh_buffers_update(
+ node->draw_buffers,
+ bvh->bm,
+ node->bm_faces,
+ node->bm_unique_verts,
+ node->bm_other_verts,
+ bvh->show_diffuse_color);
break;
}
@@ -1156,15 +1158,15 @@ static void pbvh_update_draw_buffers(PBVH *bvh, PBVHNode **nodes, int totnode)
static void pbvh_draw_BB(PBVH *bvh)
{
- GPU_init_draw_pbvh_BB();
+ GPU_pbvh_BB_draw_init();
for (int a = 0; a < bvh->totnode; a++) {
PBVHNode *node = &bvh->nodes[a];
- GPU_draw_pbvh_BB(node->vb.bmin, node->vb.bmax, ((node->flag & PBVH_Leaf) != 0));
+ GPU_pbvh_BB_draw(node->vb.bmin, node->vb.bmax, ((node->flag & PBVH_Leaf) != 0));
}
- GPU_end_draw_pbvh_BB();
+ GPU_pbvh_BB_draw_end();
}
static int pbvh_flush_bb(PBVH *bvh, PBVHNode *node, int flag)
@@ -1756,7 +1758,7 @@ void BKE_pbvh_node_draw(PBVHNode *node, void *data_v)
#endif
if (!(node->flag & PBVH_FullyHidden)) {
- GPU_draw_pbvh_buffers(node->draw_buffers,
+ GPU_pbvh_buffers_draw(node->draw_buffers,
data->setMaterial,
data->wireframe,
data->fast);
diff --git a/source/blender/blenkernel/intern/pbvh_bmesh.c b/source/blender/blenkernel/intern/pbvh_bmesh.c
index a821578db1a..c5e49883dc6 100644
--- a/source/blender/blenkernel/intern/pbvh_bmesh.c
+++ b/source/blender/blenkernel/intern/pbvh_bmesh.c
@@ -352,7 +352,7 @@ static void pbvh_bmesh_node_split(PBVH *bvh, const BBC *bbc_array, int node_inde
n->layer_disp = NULL;
if (n->draw_buffers) {
- GPU_free_pbvh_buffers(n->draw_buffers);
+ GPU_pbvh_buffers_free(n->draw_buffers);
n->draw_buffers = NULL;
}
n->flag &= ~PBVH_Leaf;
diff --git a/source/blender/blenkernel/intern/pointcache.c b/source/blender/blenkernel/intern/pointcache.c
index 30eb8dcb287..a7e00a8103a 100644
--- a/source/blender/blenkernel/intern/pointcache.c
+++ b/source/blender/blenkernel/intern/pointcache.c
@@ -3618,9 +3618,7 @@ void BKE_ptcache_bake(PTCacheBaker *baker)
psys_get_pointcache_start_end(scene, pid->calldata, &cache->startframe, &cache->endframe);
}
- if ((cache->flag & PTCACHE_REDO_NEEDED || (cache->flag & PTCACHE_SIMULATION_VALID)==0) &&
- (render || bake))
- {
+ if (((cache->flag & PTCACHE_BAKED) == 0) && (render || bake)) {
BKE_ptcache_id_clear(pid, PTCACHE_CLEAR_ALL, 0);
}
diff --git a/source/blender/blenkernel/intern/property.c b/source/blender/blenkernel/intern/property.c
index dc4063b42ed..b163f623d21 100644
--- a/source/blender/blenkernel/intern/property.c
+++ b/source/blender/blenkernel/intern/property.c
@@ -65,7 +65,7 @@ void BKE_bproperty_free_list(ListBase *lb)
}
}
-bProperty *BKE_bproperty_copy(bProperty *prop)
+bProperty *BKE_bproperty_copy(const bProperty *prop)
{
bProperty *propn;
@@ -80,7 +80,7 @@ bProperty *BKE_bproperty_copy(bProperty *prop)
return propn;
}
-void BKE_bproperty_copy_list(ListBase *lbn, ListBase *lbo)
+void BKE_bproperty_copy_list(ListBase *lbn, const ListBase *lbo)
{
bProperty *prop, *propn;
BKE_bproperty_free_list(lbn); /* in case we are copying to an object with props */
diff --git a/source/blender/blenkernel/intern/rigidbody.c b/source/blender/blenkernel/intern/rigidbody.c
index 5353cc26295..e8c0cf53d0b 100644
--- a/source/blender/blenkernel/intern/rigidbody.c
+++ b/source/blender/blenkernel/intern/rigidbody.c
@@ -184,7 +184,7 @@ void BKE_rigidbody_free_constraint(Object *ob)
* be added to relevant groups later...
*/
-RigidBodyOb *BKE_rigidbody_copy_object(Object *ob)
+RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob)
{
RigidBodyOb *rboN = NULL;
@@ -204,7 +204,7 @@ RigidBodyOb *BKE_rigidbody_copy_object(Object *ob)
return rboN;
}
-RigidBodyCon *BKE_rigidbody_copy_constraint(Object *ob)
+RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob)
{
RigidBodyCon *rbcN = NULL;
@@ -822,7 +822,7 @@ static void rigidbody_validate_sim_constraint(RigidBodyWorld *rbw, Object *ob, b
RB_constraint_set_damping_6dof_spring(rbc->physics_constraint, RB_LIMIT_ANG_Z, rbc->spring_damping_ang_z);
RB_constraint_set_equilibrium_6dof_spring(rbc->physics_constraint);
- /* fall-through */
+ ATTR_FALLTHROUGH;
case RBC_TYPE_6DOF:
if (rbc->type == RBC_TYPE_6DOF) /* a litte awkward but avoids duplicate code for limits */
rbc->physics_constraint = RB_constraint_new_6dof(loc, rot, rb1, rb2);
@@ -1486,24 +1486,60 @@ void BKE_rigidbody_sync_transforms(RigidBodyWorld *rbw, Object *ob, float ctime)
void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], float quat[4], float rotAxis[3], float rotAngle)
{
RigidBodyOb *rbo = ob->rigidbody_object;
+ bool correct_delta = !(rbo->flag & RBO_FLAG_KINEMATIC || rbo->type == RBO_TYPE_PASSIVE);
/* return rigid body and object to their initial states */
copy_v3_v3(rbo->pos, ob->loc);
copy_v3_v3(ob->loc, loc);
+ if (correct_delta) {
+ add_v3_v3(rbo->pos, ob->dloc);
+ }
+
if (ob->rotmode > 0) {
- eulO_to_quat(rbo->orn, ob->rot, ob->rotmode);
+ float qt[4];
+ eulO_to_quat(qt, ob->rot, ob->rotmode);
+
+ if (correct_delta) {
+ float dquat[4];
+ eulO_to_quat(dquat, ob->drot, ob->rotmode);
+
+ mul_qt_qtqt(rbo->orn, dquat, qt);
+ }
+ else {
+ copy_qt_qt(rbo->orn, qt);
+ }
+
copy_v3_v3(ob->rot, rot);
}
else if (ob->rotmode == ROT_MODE_AXISANGLE) {
- axis_angle_to_quat(rbo->orn, ob->rotAxis, ob->rotAngle);
+ float qt[4];
+ axis_angle_to_quat(qt, ob->rotAxis, ob->rotAngle);
+
+ if (correct_delta) {
+ float dquat[4];
+ axis_angle_to_quat(dquat, ob->drotAxis, ob->drotAngle);
+
+ mul_qt_qtqt(rbo->orn, dquat, qt);
+ }
+ else {
+ copy_qt_qt(rbo->orn, qt);
+ }
+
copy_v3_v3(ob->rotAxis, rotAxis);
ob->rotAngle = rotAngle;
}
else {
- copy_qt_qt(rbo->orn, ob->quat);
+ if (correct_delta) {
+ mul_qt_qtqt(rbo->orn, ob->dquat, ob->quat);
+ }
+ else {
+ copy_qt_qt(rbo->orn, ob->quat);
+ }
+
copy_qt_qt(ob->quat, quat);
}
+
if (rbo->physics_object) {
/* allow passive objects to return to original transform */
if (rbo->type == RBO_TYPE_PASSIVE)
@@ -1515,8 +1551,9 @@ void BKE_rigidbody_aftertrans_update(Object *ob, float loc[3], float rot[3], flo
void BKE_rigidbody_cache_reset(RigidBodyWorld *rbw)
{
- if (rbw)
+ if (rbw) {
rbw->pointcache->flag |= PTCACHE_OUTDATED;
+ }
}
/* ------------------ */
@@ -1563,12 +1600,8 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
BKE_ptcache_id_time(&pid, scene, ctime, &startframe, &endframe, NULL);
cache = rbw->pointcache;
- if (ctime <= startframe) {
- rbw->ltime = startframe;
- return;
- }
/* make sure we don't go out of cache frame range */
- else if (ctime > endframe) {
+ if (ctime > endframe) {
ctime = endframe;
}
@@ -1582,9 +1615,12 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
// RB_TODO deal with interpolated, old and baked results
bool can_simulate = (ctime == rbw->ltime + 1) && !(cache->flag & PTCACHE_BAKED);
+ if (cache->flag & PTCACHE_OUTDATED || cache->last_exact == 0) {
+ rbw->ltime = cache->startframe;
+ }
+
if (BKE_ptcache_read(&pid, ctime, can_simulate)) {
BKE_ptcache_validate(cache, (int)ctime);
- rbw->ltime = ctime;
return;
}
@@ -1622,8 +1658,8 @@ void BKE_rigidbody_do_simulation(Scene *scene, float ctime)
# pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
-struct RigidBodyOb *BKE_rigidbody_copy_object(Object *ob) { return NULL; }
-struct RigidBodyCon *BKE_rigidbody_copy_constraint(Object *ob) { return NULL; }
+struct RigidBodyOb *BKE_rigidbody_copy_object(const Object *ob) { return NULL; }
+struct RigidBodyCon *BKE_rigidbody_copy_constraint(const Object *ob) { return NULL; }
void BKE_rigidbody_validate_sim_world(Scene *scene, RigidBodyWorld *rbw, bool rebuild) {}
void BKE_rigidbody_calc_volume(Object *ob, float *r_vol) { if (r_vol) *r_vol = 0.0f; }
void BKE_rigidbody_calc_center_of_mass(Object *ob, float r_center[3]) { zero_v3(r_center); }
diff --git a/source/blender/blenkernel/intern/sca.c b/source/blender/blenkernel/intern/sca.c
index 7920d8b5696..19d646daf9f 100644
--- a/source/blender/blenkernel/intern/sca.c
+++ b/source/blender/blenkernel/intern/sca.c
@@ -87,7 +87,7 @@ bSensor *copy_sensor(bSensor *sens)
return sensn;
}
-void copy_sensors(ListBase *lbn, ListBase *lbo)
+void copy_sensors(ListBase *lbn, const ListBase *lbo)
{
bSensor *sens, *sensn;
@@ -251,7 +251,7 @@ bController *copy_controller(bController *cont)
return contn;
}
-void copy_controllers(ListBase *lbn, ListBase *lbo)
+void copy_controllers(ListBase *lbn, const ListBase *lbo)
{
bController *cont, *contn;
@@ -389,7 +389,7 @@ bActuator *copy_actuator(bActuator *act)
return actn;
}
-void copy_actuators(ListBase *lbn, ListBase *lbo)
+void copy_actuators(ListBase *lbn, const ListBase *lbo)
{
bActuator *act, *actn;
@@ -783,7 +783,7 @@ void BKE_sca_logic_links_remap(Main *bmain, Object *ob_old, Object *ob_new)
* Handle the copying of logic data into a new object, including internal logic links update.
* External links (links between logic bricks of different objects) must be handled separately.
*/
-void BKE_sca_logic_copy(Object *ob_new, Object *ob)
+void BKE_sca_logic_copy(Object *ob_new, const Object *ob)
{
copy_sensors(&ob_new->sensors, &ob->sensors);
copy_controllers(&ob_new->controllers, &ob->controllers);
diff --git a/source/blender/blenkernel/intern/scene.c b/source/blender/blenkernel/intern/scene.c
index 906fa0134a0..a15f270a3ee 100644
--- a/source/blender/blenkernel/intern/scene.c
+++ b/source/blender/blenkernel/intern/scene.c
@@ -188,7 +188,9 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
scen = BKE_libblock_copy(bmain, &sce->id);
BLI_duplicatelist(&(scen->base), &(sce->base));
- id_us_plus((ID *)scen->world);
+ if (type != SCE_COPY_FULL) {
+ id_us_plus((ID *)scen->world);
+ }
id_us_plus((ID *)scen->set);
/* id_us_plus((ID *)scen->gm.dome.warptext); */ /* XXX Not refcounted? see readfile.c */
@@ -233,11 +235,15 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
/* copy Freestyle settings */
new_srl = scen->r.layers.first;
for (srl = sce->r.layers.first; srl; srl = srl->next) {
+ if (new_srl->prop != NULL) {
+ new_srl->prop = IDP_CopyProperty(new_srl->prop);
+ }
BKE_freestyle_config_copy(&new_srl->freestyleConfig, &srl->freestyleConfig);
if (type == SCE_COPY_FULL) {
for (lineset = new_srl->freestyleConfig.linesets.first; lineset; lineset = lineset->next) {
if (lineset->linestyle) {
- id_us_plus((ID *)lineset->linestyle);
+ /* Has been incremented by BKE_freestyle_config_copy(). */
+ id_us_min(&lineset->linestyle->id);
lineset->linestyle = BKE_linestyle_copy(bmain, lineset->linestyle);
}
}
@@ -282,11 +288,19 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
ts->sculpt = MEM_dupallocN(ts->sculpt);
BKE_paint_copy(&ts->sculpt->paint, &ts->sculpt->paint);
}
+ if (ts->uvsculpt) {
+ ts->uvsculpt = MEM_dupallocN(ts->uvsculpt);
+ BKE_paint_copy(&ts->uvsculpt->paint, &ts->uvsculpt->paint);
+ }
BKE_paint_copy(&ts->imapaint.paint, &ts->imapaint.paint);
ts->imapaint.paintcursor = NULL;
id_us_plus((ID *)ts->imapaint.stencil);
+ id_us_plus((ID *)ts->imapaint.clone);
+ id_us_plus((ID *)ts->imapaint.canvas);
ts->particle.paintcursor = NULL;
+ ts->particle.scene = NULL;
+ ts->particle.object = NULL;
/* duplicate Grease Pencil Drawing Brushes */
BLI_listbase_clear(&ts->gp_brushes);
@@ -330,7 +344,6 @@ Scene *BKE_scene_copy(Main *bmain, Scene *sce, int type)
/* world */
if (type == SCE_COPY_FULL) {
if (scen->world) {
- id_us_plus((ID *)scen->world);
scen->world = BKE_world_copy(bmain, scen->world);
BKE_animdata_copy_id_action((ID *)scen->world, false);
}
@@ -416,11 +429,15 @@ void BKE_scene_free(Scene *sce)
MEM_freeN(sce->r.ffcodecdata.properties);
sce->r.ffcodecdata.properties = NULL;
}
-
+
for (srl = sce->r.layers.first; srl; srl = srl->next) {
+ if (srl->prop != NULL) {
+ IDP_FreeProperty(srl->prop);
+ MEM_freeN(srl->prop);
+ }
BKE_freestyle_config_free(&srl->freestyleConfig);
}
-
+
BLI_freelistN(&sce->markers);
BLI_freelistN(&sce->transform_spaces);
BLI_freelistN(&sce->r.layers);
@@ -2063,6 +2080,11 @@ bool BKE_scene_remove_render_layer(Main *bmain, Scene *scene, SceneRenderLayer *
BKE_freestyle_config_free(&srl->freestyleConfig);
+ if (srl->prop) {
+ IDP_FreeProperty(srl->prop);
+ MEM_freeN(srl->prop);
+ }
+
BLI_remlink(&scene->r.layers, srl);
MEM_freeN(srl);
@@ -2125,7 +2147,7 @@ bool BKE_scene_remove_render_view(Scene *scene, SceneRenderView *srv)
int get_render_subsurf_level(const RenderData *r, int lvl, bool for_render)
{
- if (r->mode & R_SIMPLIFY) {
+ if (r->mode & R_SIMPLIFY) {
if (for_render)
return min_ii(r->simplify_subsurf_render, lvl);
else
diff --git a/source/blender/blenkernel/intern/seqeffects.c b/source/blender/blenkernel/intern/seqeffects.c
index 298671beedb..e435d87024e 100644
--- a/source/blender/blenkernel/intern/seqeffects.c
+++ b/source/blender/blenkernel/intern/seqeffects.c
@@ -684,7 +684,7 @@ static float invGammaCorrect(float c)
else if (i >= RE_GAMMA_TABLE_SIZE) res = powf(c, valid_inv_gamma);
else res = inv_gamma_range_table[i] +
((c - color_domain_table[i]) * inv_gamfactor_table[i]);
-
+
return res;
}
diff --git a/source/blender/blenkernel/intern/seqmodifier.c b/source/blender/blenkernel/intern/seqmodifier.c
index 89c2f76c661..e2f74dbab3c 100644
--- a/source/blender/blenkernel/intern/seqmodifier.c
+++ b/source/blender/blenkernel/intern/seqmodifier.c
@@ -202,21 +202,22 @@ static void whiteBalance_apply_threaded(int width, int height, unsigned char *re
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
int pixel_index = (y * width + x) * 4;
- float result[4], mask[3] = {1.0f, 1.0f, 1.0f};
+ float rgba[4], result[4], mask[3] = {1.0f, 1.0f, 1.0f};
if (rect_float) {
- copy_v3_v3(result, rect_float + pixel_index);
+ copy_v3_v3(rgba, rect_float + pixel_index);
}
else {
- straight_uchar_to_premul_float(result, rect + pixel_index);
+ straight_uchar_to_premul_float(rgba, rect + pixel_index);
}
+ copy_v4_v4(result, rgba);
#if 0
mul_v3_v3(result, multiplier);
#else
/* similar to division without the clipping */
for (int i = 0; i < 3; i++) {
- result[i] = 1.0f - powf(1.0f - result[i], multiplier[i]);
+ result[i] = 1.0f - powf(1.0f - rgba[i], multiplier[i]);
}
#endif
@@ -227,9 +228,9 @@ static void whiteBalance_apply_threaded(int width, int height, unsigned char *re
rgb_uchar_to_float(mask, mask_rect + pixel_index);
}
- result[0] = result[0] * (1.0f - mask[0]) + result[0] * mask[0];
- result[1] = result[1] * (1.0f - mask[1]) + result[1] * mask[1];
- result[2] = result[2] * (1.0f - mask[2]) + result[2] * mask[2];
+ result[0] = rgba[0] * (1.0f - mask[0]) + result[0] * mask[0];
+ result[1] = rgba[1] * (1.0f - mask[1]) + result[1] * mask[1];
+ result[2] = rgba[2] * (1.0f - mask[2]) + result[2] * mask[2];
if (rect_float) {
copy_v3_v3(rect_float + pixel_index, result);
diff --git a/source/blender/blenkernel/intern/sequencer.c b/source/blender/blenkernel/intern/sequencer.c
index 2de7cd49901..669f76cf90b 100644
--- a/source/blender/blenkernel/intern/sequencer.c
+++ b/source/blender/blenkernel/intern/sequencer.c
@@ -1775,7 +1775,7 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c
if (proxy->anim == NULL) {
return NULL;
}
-
+
seq_open_anim_file(context->scene, seq, true);
sanim = seq->anims.first;
@@ -1783,7 +1783,7 @@ static ImBuf *seq_proxy_fetch(const SeqRenderData *context, Sequence *seq, int c
return IMB_anim_absolute(proxy->anim, frameno, IMB_TC_NONE, IMB_PROXY_NONE);
}
-
+
if (seq_proxy_get_fname(ed, seq, cfra, render_size, name, context->view_id) == 0) {
return NULL;
}
@@ -2082,7 +2082,7 @@ void BKE_sequencer_proxy_set(struct Sequence *seq, bool value)
}
}
else {
- seq->flag ^= SEQ_USE_PROXY;
+ seq->flag &= ~SEQ_USE_PROXY;
}
}
@@ -4190,9 +4190,10 @@ static bool update_changed_seq_recurs(Scene *scene, Sequence *seq, Sequence *cha
if (free_imbuf) {
if (ibuf_change) {
- if (seq->type == SEQ_TYPE_MOVIE)
+ if (seq->type == SEQ_TYPE_MOVIE) {
BKE_sequence_free_anim(seq);
- if (seq->type == SEQ_TYPE_SPEED) {
+ }
+ else if (seq->type == SEQ_TYPE_SPEED) {
BKE_sequence_effect_speed_rebuild_map(scene, seq, true);
}
}
@@ -5182,6 +5183,7 @@ Sequence *BKE_sequencer_add_sound_strip(bContext *C, ListBase *seqbasep, SeqLoad
sound = BKE_sound_new_file(bmain, seq_load->path); /* handles relative paths */
if (sound->playback_handle == NULL) {
+ BKE_libblock_free(bmain, sound);
#if 0
if (op)
BKE_report(op->reports, RPT_ERROR, "Unsupported audio format");
diff --git a/source/blender/blenkernel/intern/softbody.c b/source/blender/blenkernel/intern/softbody.c
index 03cf33083da..600bc3f453d 100644
--- a/source/blender/blenkernel/intern/softbody.c
+++ b/source/blender/blenkernel/intern/softbody.c
@@ -1856,19 +1856,21 @@ static void dfdx_spring(int ia, int ic, int op, float dir[3], float L, float len
float m, delta_ij;
int i, j;
if (L < len) {
- for (i=0;i<3;i++)
+ for (i=0;i<3;i++) {
for (j=0;j<3;j++) {
delta_ij = (i==j ? (1.0f): (0.0f));
m=factor*(dir[i]*dir[j] + (1-L/len)*(delta_ij - dir[i]*dir[j]));
EIG_linear_solver_matrix_add(ia+i, op+ic+j, m);
}
+ }
}
else {
- for (i=0;i<3;i++)
+ for (i=0;i<3;i++) {
for (j=0;j<3;j++) {
m=factor*dir[i]*dir[j];
EIG_linear_solver_matrix_add(ia+i, op+ic+j, m);
}
+ }
}
}
@@ -2233,9 +2235,9 @@ static void sb_cf_threads_run(Scene *scene, Object *ob, float forcetime, float t
static void softbody_calc_forcesEx(Scene *scene, Object *ob, float forcetime, float timenow)
{
-/* rule we never alter free variables :bp->vec bp->pos in here !
- * this will ruin adaptive stepsize AKA heun! (BM)
- */
+ /* rule we never alter free variables :bp->vec bp->pos in here !
+ * this will ruin adaptive stepsize AKA heun! (BM)
+ */
SoftBody *sb= ob->soft; /* is supposed to be there */
/*BodyPoint *bproot;*/ /* UNUSED */
ListBase *do_effector = NULL;
diff --git a/source/blender/blenkernel/intern/speaker.c b/source/blender/blenkernel/intern/speaker.c
index ee6886e3fb2..d00e4b1a0d2 100644
--- a/source/blender/blenkernel/intern/speaker.c
+++ b/source/blender/blenkernel/intern/speaker.c
@@ -68,7 +68,7 @@ void *BKE_speaker_add(Main *bmain, const char *name)
return spk;
}
-Speaker *BKE_speaker_copy(Main *bmain, Speaker *spk)
+Speaker *BKE_speaker_copy(Main *bmain, const Speaker *spk)
{
Speaker *spkn;
diff --git a/source/blender/blenkernel/intern/text.c b/source/blender/blenkernel/intern/text.c
index 298790a9e9b..466bef7ff36 100644
--- a/source/blender/blenkernel/intern/text.c
+++ b/source/blender/blenkernel/intern/text.c
@@ -449,7 +449,7 @@ Text *BKE_text_load(Main *bmain, const char *file, const char *relpath)
return BKE_text_load_ex(bmain, file, relpath, false);
}
-Text *BKE_text_copy(Main *bmain, Text *ta)
+Text *BKE_text_copy(Main *bmain, const Text *ta)
{
Text *tan;
TextLine *line, *tmp;
diff --git a/source/blender/blenkernel/intern/texture.c b/source/blender/blenkernel/intern/texture.c
index 60990c03b0e..1e0659d3d67 100644
--- a/source/blender/blenkernel/intern/texture.c
+++ b/source/blender/blenkernel/intern/texture.c
@@ -549,11 +549,11 @@ int colorband_element_remove(struct ColorBand *coba, int index)
if (index < 0 || index >= coba->tot)
return 0;
+ coba->tot--;
for (a = index; a < coba->tot; a++) {
coba->data[a] = coba->data[a + 1];
}
if (coba->cur) coba->cur--;
- coba->tot--;
return 1;
}
@@ -846,7 +846,7 @@ MTex *BKE_texture_mtex_add_id(ID *id, int slot)
/* ------------------------------------------------------------------------- */
-Tex *BKE_texture_copy(Main *bmain, Tex *tex)
+Tex *BKE_texture_copy(Main *bmain, const Tex *tex)
{
Tex *texn;
@@ -1263,7 +1263,7 @@ EnvMap *BKE_texture_envmap_add(void)
/* ------------------------------------------------------------------------- */
-EnvMap *BKE_texture_envmap_copy(EnvMap *env)
+EnvMap *BKE_texture_envmap_copy(const EnvMap *env)
{
EnvMap *envn;
int a;
@@ -1336,7 +1336,7 @@ PointDensity *BKE_texture_pointdensity_add(void)
return pd;
}
-PointDensity *BKE_texture_pointdensity_copy(PointDensity *pd)
+PointDensity *BKE_texture_pointdensity_copy(const PointDensity *pd)
{
PointDensity *pdn;
@@ -1430,7 +1430,7 @@ OceanTex *BKE_texture_ocean_add(void)
return ot;
}
-OceanTex *BKE_texture_ocean_copy(struct OceanTex *ot)
+OceanTex *BKE_texture_ocean_copy(const OceanTex *ot)
{
OceanTex *otn = MEM_dupallocN(ot);
@@ -1519,3 +1519,33 @@ void BKE_texture_get_value(
{
BKE_texture_get_value_ex(scene, texture, tex_co, texres, NULL, use_color_management);
}
+
+static void texture_nodes_fetch_images_for_pool(bNodeTree *ntree, struct ImagePool *pool)
+{
+ for (bNode *node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == SH_NODE_TEX_IMAGE && node->id != NULL) {
+ Image *image = (Image *)node->id;
+ BKE_image_pool_acquire_ibuf(image, NULL, pool);
+ }
+ else if (node->type == NODE_GROUP && node->id != NULL) {
+ /* TODO(sergey): Do we need to control recursion here? */
+ bNodeTree *nested_tree = (bNodeTree *)node->id;
+ texture_nodes_fetch_images_for_pool(nested_tree, pool);
+ }
+ }
+}
+
+/* Make sure all images used by texture are loaded into pool. */
+void BKE_texture_fetch_images_for_pool(Tex *texture, struct ImagePool *pool)
+{
+ if (texture->nodetree != NULL) {
+ texture_nodes_fetch_images_for_pool(texture->nodetree, pool);
+ }
+ else {
+ if (texture->type == TEX_IMAGE) {
+ if (texture->ima != NULL) {
+ BKE_image_pool_acquire_ibuf(texture->ima, NULL, pool);
+ }
+ }
+ }
+}
diff --git a/source/blender/blenkernel/intern/tracking.c b/source/blender/blenkernel/intern/tracking.c
index 990d250b854..9120d384a16 100644
--- a/source/blender/blenkernel/intern/tracking.c
+++ b/source/blender/blenkernel/intern/tracking.c
@@ -190,7 +190,7 @@ void BKE_tracking_free(MovieTracking *tracking)
}
/* Copy the whole list of tracks. */
-static void tracking_tracks_copy(ListBase *tracks_dst, ListBase *tracks_src, GHash *tracks_mapping)
+static void tracking_tracks_copy(ListBase *tracks_dst, const ListBase *tracks_src, GHash *tracks_mapping)
{
MovieTrackingTrack *track_dst, *track_src;
@@ -210,7 +210,7 @@ static void tracking_tracks_copy(ListBase *tracks_dst, ListBase *tracks_src, GHa
/* copy the whole list of plane tracks (need whole MovieTracking structures due to embedded pointers to tracks).
* WARNING: implies tracking_[dst/src] and their tracks have already been copied. */
-static void tracking_plane_tracks_copy(ListBase *plane_tracks_dst, ListBase *plane_tracks_src, GHash *tracks_mapping)
+static void tracking_plane_tracks_copy(ListBase *plane_tracks_dst, const ListBase *plane_tracks_src, GHash *tracks_mapping)
{
MovieTrackingPlaneTrack *plane_track_dst, *plane_track_src;
@@ -232,7 +232,7 @@ static void tracking_plane_tracks_copy(ListBase *plane_tracks_dst, ListBase *pla
/* Copy reconstruction structure. */
static void tracking_reconstruction_copy(
- MovieTrackingReconstruction *reconstruction_dst, MovieTrackingReconstruction *reconstruction_src)
+ MovieTrackingReconstruction *reconstruction_dst, const MovieTrackingReconstruction *reconstruction_src)
{
*reconstruction_dst = *reconstruction_src;
if (reconstruction_src->cameras) {
@@ -242,14 +242,14 @@ static void tracking_reconstruction_copy(
/* Copy stabilization structure. */
static void tracking_stabilization_copy(
- MovieTrackingStabilization *stabilization_dst, MovieTrackingStabilization *stabilization_src)
+ MovieTrackingStabilization *stabilization_dst, const MovieTrackingStabilization *stabilization_src)
{
*stabilization_dst = *stabilization_src;
}
/* Copy tracking object. */
static void tracking_object_copy(
- MovieTrackingObject *object_dst, MovieTrackingObject *object_src, GHash *tracks_mapping)
+ MovieTrackingObject *object_dst, const MovieTrackingObject *object_src, GHash *tracks_mapping)
{
*object_dst = *object_src;
tracking_tracks_copy(&object_dst->tracks, &object_src->tracks, tracks_mapping);
@@ -258,7 +258,7 @@ static void tracking_object_copy(
}
/* Copy list of tracking objects. */
-static void tracking_objects_copy(ListBase *objects_dst, ListBase *objects_src, GHash *tracks_mapping)
+static void tracking_objects_copy(ListBase *objects_dst, const ListBase *objects_src, GHash *tracks_mapping)
{
MovieTrackingObject *object_dst, *object_src;
@@ -272,7 +272,7 @@ static void tracking_objects_copy(ListBase *objects_dst, ListBase *objects_src,
}
/* Copy tracking structure content. */
-void BKE_tracking_copy(MovieTracking *tracking_dst, MovieTracking *tracking_src)
+void BKE_tracking_copy(MovieTracking *tracking_dst, const MovieTracking *tracking_src)
{
GHash *tracks_mapping = BLI_ghash_ptr_new(__func__);
@@ -974,8 +974,11 @@ static void track_mask_set_pixel_cb(int x, int x_end, int y, void *user_data)
}
static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height,
- MovieTrackingMarker *marker, bGPDlayer *layer,
- float *mask, int mask_width, int mask_height)
+ const float region_min[2],
+ bGPDlayer *layer,
+ float *mask,
+ int mask_width,
+ int mask_height)
{
bGPDframe *frame = layer->frames.first;
TrackMaskSetPixelData data;
@@ -994,8 +997,8 @@ static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height
point = mask_points = MEM_callocN(2 * stroke->totpoints * sizeof(int),
"track mask rasterization points");
for (int i = 0; i < stroke->totpoints; i++, point += 2) {
- point[0] = (stroke_points[i].x - marker->search_min[0]) * frame_width;
- point[1] = (stroke_points[i].y - marker->search_min[1]) * frame_height;
+ point[0] = stroke_points[i].x * frame_width - region_min[0];
+ point[1] = stroke_points[i].y * frame_height - region_min[1];
}
/* TODO: add an option to control whether AA is enabled or not */
BLI_bitmap_draw_2d_poly_v2i_n(
@@ -1010,26 +1013,42 @@ static void track_mask_gpencil_layer_rasterize(int frame_width, int frame_height
}
}
-float *BKE_tracking_track_get_mask(int frame_width, int frame_height,
- MovieTrackingTrack *track, MovieTrackingMarker *marker)
+/* Region is in pixel space, relative to marker's center. */
+float *tracking_track_get_mask_for_region(int frame_width, int frame_height,
+ const float region_min[2],
+ const float region_max[2],
+ MovieTrackingTrack *track)
{
float *mask = NULL;
bGPDlayer *layer = track_mask_gpencil_layer_get(track);
- int mask_width, mask_height;
-
- mask_width = (marker->search_max[0] - marker->search_min[0]) * frame_width;
- mask_height = (marker->search_max[1] - marker->search_min[1]) * frame_height;
-
- if (layer) {
+ if (layer != NULL) {
+ const int mask_width = region_max[0] - region_min[0];
+ const int mask_height = region_max[1] - region_min[1];
mask = MEM_callocN(mask_width * mask_height * sizeof(float), "track mask");
-
- track_mask_gpencil_layer_rasterize(frame_width, frame_height, marker, layer,
- mask, mask_width, mask_height);
+ track_mask_gpencil_layer_rasterize(frame_width, frame_height,
+ region_min,
+ layer,
+ mask,
+ mask_width, mask_height);
}
-
return mask;
}
+float *BKE_tracking_track_get_mask(int frame_width, int frame_height,
+ MovieTrackingTrack *track,
+ MovieTrackingMarker *marker)
+{
+ /* Convert normalized space marker's search area to pixel-space region. */
+ const float region_min[2] = {marker->search_min[0] * frame_width,
+ marker->search_min[1] * frame_height};
+ const float region_max[2] = {marker->search_max[0] * frame_width,
+ marker->search_max[1] * frame_height};
+ return tracking_track_get_mask_for_region(frame_width, frame_height,
+ region_min,
+ region_max,
+ track);
+}
+
float BKE_tracking_track_get_weight_for_marker(MovieClip *clip, MovieTrackingTrack *track, MovieTrackingMarker *marker)
{
FCurve *weight_fcurve;
diff --git a/source/blender/blenkernel/intern/tracking_auto.c b/source/blender/blenkernel/intern/tracking_auto.c
index 3b56ea271d0..9475925cdda 100644
--- a/source/blender/blenkernel/intern/tracking_auto.c
+++ b/source/blender/blenkernel/intern/tracking_auto.c
@@ -36,8 +36,9 @@
#include "DNA_movieclip_types.h"
#include "DNA_object_types.h" /* SELECT */
-#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
+#include "BLI_threads.h"
#include "BLI_math.h"
#include "BKE_movieclip.h"
@@ -76,6 +77,9 @@ typedef struct AutoTrackContext {
int num_tracks; /* Number of tracks being tracked. */
AutoTrackOptions *options; /* Per-tracking track options. */
+ /* Array of all tracks, indexed by track_index. */
+ MovieTrackingTrack **tracks;
+
bool backwards;
bool sequence;
int first_frame;
@@ -306,8 +310,15 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip,
BLI_spin_init(&context->spin_lock);
+ int num_total_tracks = BLI_listbase_count(tracksbase);
+ context->tracks =
+ MEM_callocN(sizeof(MovieTrackingTrack*) * num_total_tracks,
+ "auto track pointers");
+
context->image_accessor =
- tracking_image_accessor_new(context->clips, 1, user->framenr);
+ tracking_image_accessor_new(context->clips, 1,
+ context->tracks, num_total_tracks,
+ user->framenr);
context->autotrack =
libmv_autoTrackNew(context->image_accessor->libmv_accessor);
@@ -361,6 +372,7 @@ AutoTrackContext *BKE_autotrack_context_new(MovieClip *clip,
options->use_keyframe_match =
track->pattern_match == TRACK_MATCH_KEYFRAME;
}
+ context->tracks[track_index] = track;
++track_index;
}
@@ -565,6 +577,7 @@ void BKE_autotrack_context_free(AutoTrackContext *context)
libmv_autoTrackDestroy(context->autotrack);
tracking_image_accessor_destroy(context->image_accessor);
MEM_freeN(context->options);
+ MEM_freeN(context->tracks);
BLI_spin_end(&context->spin_lock);
MEM_freeN(context);
}
diff --git a/source/blender/blenkernel/intern/tracking_stabilize.c b/source/blender/blenkernel/intern/tracking_stabilize.c
index 3dfaa1ed77d..b8dfb217c16 100644
--- a/source/blender/blenkernel/intern/tracking_stabilize.c
+++ b/source/blender/blenkernel/intern/tracking_stabilize.c
@@ -203,7 +203,7 @@ static float get_animated_scaleinf(StabContext *ctx, int framenr)
static void get_animated_target_pos(StabContext *ctx,
int framenr,
- float target_pos[2])
+ float target_pos[2])
{
target_pos[0] = fetch_from_fcurve(ctx->target_pos[0],
framenr,
diff --git a/source/blender/blenkernel/intern/tracking_util.c b/source/blender/blenkernel/intern/tracking_util.c
index 1c056cda68d..a95399562d5 100644
--- a/source/blender/blenkernel/intern/tracking_util.c
+++ b/source/blender/blenkernel/intern/tracking_util.c
@@ -875,8 +875,64 @@ static void accessor_release_image_callback(libmv_CacheKey cache_key)
IMB_freeImBuf(ibuf);
}
+static libmv_CacheKey accessor_get_mask_for_track_callback(
+ libmv_FrameAccessorUserData* user_data,
+ int clip_index,
+ int frame,
+ int track_index,
+ const libmv_Region *region,
+ float **r_destination,
+ int *r_width,
+ int *r_height)
+{
+ /* Perform sanity checks first. */
+ TrackingImageAccessor *accessor = (TrackingImageAccessor *) user_data;
+ BLI_assert(clip_index < accessor->num_clips);
+ BLI_assert(track_index < accessor->num_tracks);
+ MovieTrackingTrack *track = accessor->tracks[track_index];
+ /* Early output, track does not use mask. */
+ if ((track->algorithm_flag & TRACK_ALGORITHM_FLAG_USE_MASK) == 0) {
+ return NULL;
+ }
+ MovieClip *clip = accessor->clips[clip_index];
+ /* Construct fake user so we can access movie clip. */
+ MovieClipUser user;
+ int scene_frame = BKE_movieclip_remap_clip_to_scene_frame(clip, frame);
+ BKE_movieclip_user_set_frame(&user, scene_frame);
+ user.render_size = MCLIP_PROXY_RENDER_SIZE_FULL;
+ user.render_flag = 0;
+ /* Get frame width and height so we can convert stroke coordinates
+ * and other things from normalized to pixel space.
+ */
+ int frame_width, frame_height;
+ BKE_movieclip_get_size(clip, &user, &frame_width, &frame_height);
+ /* Actual mask sampling. */
+ MovieTrackingMarker *marker = BKE_tracking_marker_get_exact(track, frame);
+ const float region_min[2] = {region->min[0] - marker->pos[0] * frame_width,
+ region->min[1] - marker->pos[1] * frame_height};
+ const float region_max[2] = {region->max[0] - marker->pos[0] * frame_width,
+ region->max[1] - marker->pos[1] * frame_height};
+ *r_destination = tracking_track_get_mask_for_region(frame_width, frame_height,
+ region_min,
+ region_max,
+ track);
+ *r_width = region->max[0] - region->min[0];
+ *r_height = region->max[1] - region->min[1];
+ return *r_destination;
+}
+
+static void accessor_release_mask_callback(libmv_CacheKey cache_key)
+{
+ if (cache_key != NULL) {
+ float *mask = (float *)cache_key;
+ MEM_freeN(mask);
+ }
+}
+
TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP],
int num_clips,
+ MovieTrackingTrack **tracks,
+ int num_tracks,
int start_frame)
{
TrackingImageAccessor *accessor =
@@ -891,12 +947,16 @@ TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR
memcpy(accessor->clips, clips, num_clips * sizeof(MovieClip *));
accessor->num_clips = num_clips;
+ accessor->tracks = tracks;
+ accessor->num_tracks = num_tracks;
accessor->start_frame = start_frame;
accessor->libmv_accessor =
libmv_FrameAccessorNew((libmv_FrameAccessorUserData *) accessor,
accessor_get_image_callback,
- accessor_release_image_callback);
+ accessor_release_image_callback,
+ accessor_get_mask_for_track_callback,
+ accessor_release_mask_callback);
return accessor;
}
diff --git a/source/blender/blenkernel/intern/world.c b/source/blender/blenkernel/intern/world.c
index caa9a1e357f..363c36e644d 100644
--- a/source/blender/blenkernel/intern/world.c
+++ b/source/blender/blenkernel/intern/world.c
@@ -119,7 +119,7 @@ World *add_world(Main *bmain, const char *name)
return wrld;
}
-World *BKE_world_copy(Main *bmain, World *wrld)
+World *BKE_world_copy(Main *bmain, const World *wrld)
{
World *wrldn;
int a;
diff --git a/source/blender/blenkernel/intern/writeframeserver.c b/source/blender/blenkernel/intern/writeframeserver.c
index 212af76a7e8..4757186f546 100644
--- a/source/blender/blenkernel/intern/writeframeserver.c
+++ b/source/blender/blenkernel/intern/writeframeserver.c
@@ -268,11 +268,7 @@ int BKE_frameserver_loop(void *context_v, RenderData *rd, ReportList *UNUSED(rep
struct timeval tv;
struct sockaddr_in addr;
int len, rval;
-#ifdef FREE_WINDOWS
- int socklen;
-#else
unsigned int socklen;
-#endif
char buf[4096];
FrameserverContext *context = context_v;
diff --git a/source/blender/blenkernel/tracking_private.h b/source/blender/blenkernel/tracking_private.h
index 591ee4d0d01..1a68a1cac6a 100644
--- a/source/blender/blenkernel/tracking_private.h
+++ b/source/blender/blenkernel/tracking_private.h
@@ -105,6 +105,13 @@ struct MovieTrackingMarker *tracking_get_keyframed_marker(
int current_frame,
bool backwards);
+/*********************** Masking *************************/
+
+float *tracking_track_get_mask_for_region(int frame_width, int frame_height,
+ const float region_min[2],
+ const float region_max[2],
+ MovieTrackingTrack *track);
+
/*********************** Frame accessr *************************/
struct libmv_FrameAccessor;
@@ -114,12 +121,16 @@ typedef struct TrackingImageAccessor {
struct MovieCache *cache;
struct MovieClip *clips[MAX_ACCESSOR_CLIP];
int num_clips;
+ struct MovieTrackingTrack **tracks;
+ int num_tracks;
int start_frame;
struct libmv_FrameAccessor *libmv_accessor;
} TrackingImageAccessor;
TrackingImageAccessor *tracking_image_accessor_new(MovieClip *clips[MAX_ACCESSOR_CLIP],
int num_clips,
+ MovieTrackingTrack **tracks,
+ int num_tracks,
int start_frame);
void tracking_image_accessor_destroy(TrackingImageAccessor *accessor);
diff --git a/source/blender/blenlib/BLI_alloca.h b/source/blender/blenlib/BLI_alloca.h
index b44e6c66d2a..4fa69a24966 100644
--- a/source/blender/blenlib/BLI_alloca.h
+++ b/source/blender/blenlib/BLI_alloca.h
@@ -29,10 +29,6 @@
/* BLI_array_alloca / alloca */
-#if defined(__MINGW32__)
-# include <malloc.h> /* mingw needs for alloca() */
-#endif
-
#if defined(__GNUC__) || defined(__clang__)
#if defined(__cplusplus) && (__cplusplus > 199711L)
#define BLI_array_alloca(arr, realsize) \
diff --git a/source/blender/blenlib/BLI_array.h b/source/blender/blenlib/BLI_array.h
index c645ff06c00..74f24c808ff 100644
--- a/source/blender/blenlib/BLI_array.h
+++ b/source/blender/blenlib/BLI_array.h
@@ -137,8 +137,8 @@ void _bli_array_grow_func(void **arr_p, const void *arr_static,
#define BLI_array_free(arr) \
if (arr && (char *)arr != _##arr##_static) { \
- BLI_array_fake_user(arr); \
- MEM_freeN(arr); \
+ BLI_array_fake_user(arr); \
+ MEM_freeN(arr); \
} (void)0
#define BLI_array_pop(arr) ( \
diff --git a/source/blender/blenlib/BLI_compiler_attrs.h b/source/blender/blenlib/BLI_compiler_attrs.h
index f0d32670229..4c548654e33 100644
--- a/source/blender/blenlib/BLI_compiler_attrs.h
+++ b/source/blender/blenlib/BLI_compiler_attrs.h
@@ -92,4 +92,12 @@
# define ATTR_PRINTF_FORMAT(format_param, dots_param)
#endif
+/* Use to suppress '-Wimplicit-fallthrough' (in place of 'break'). */
+#if defined(__GNUC__) && (__GNUC__ >= 7) /* gcc7.0+ only */
+#define ATTR_FALLTHROUGH __attribute__((fallthrough))
+#else
+#define ATTR_FALLTHROUGH ((void)0)
+#endif
+
+
#endif /* __BLI_COMPILER_ATTRS_H__ */
diff --git a/source/blender/blenlib/BLI_compiler_compat.h b/source/blender/blenlib/BLI_compiler_compat.h
index 8edbc25bcbc..01fc9d70207 100644
--- a/source/blender/blenlib/BLI_compiler_compat.h
+++ b/source/blender/blenlib/BLI_compiler_compat.h
@@ -32,11 +32,6 @@
# define alloca _alloca
#endif
-/* alloca is defined here for MinGW32 */
-#ifdef __MINGW32__
-# include <malloc.h>
-#endif
-
#if defined(__cplusplus) && ((__cplusplus >= 201103L) || defined(_MSC_VER))
# define HAS_CPP11_FEATURES
#endif
diff --git a/source/blender/blenlib/BLI_dynstr.h b/source/blender/blenlib/BLI_dynstr.h
index 7aa1c30e449..b26accc7f78 100644
--- a/source/blender/blenlib/BLI_dynstr.h
+++ b/source/blender/blenlib/BLI_dynstr.h
@@ -43,11 +43,14 @@
#include "BLI_compiler_attrs.h"
struct DynStr;
+struct MemArena;
/** The abstract DynStr type */
typedef struct DynStr DynStr;
DynStr *BLI_dynstr_new(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+DynStr *BLI_dynstr_new_memarena(void) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT;
+
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr) ATTR_NONNULL();
void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len) ATTR_NONNULL();
@@ -56,8 +59,9 @@ void BLI_dynstr_vappendf(DynStr *__restrict ds, const char *__restrict format
int BLI_dynstr_get_len(DynStr *ds) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
char *BLI_dynstr_get_cstring(DynStr *ds) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-
void BLI_dynstr_get_cstring_ex(DynStr *__restrict ds, char *__restrict str) ATTR_NONNULL();
+
+void BLI_dynstr_clear(DynStr *ds) ATTR_NONNULL();
void BLI_dynstr_free(DynStr *ds) ATTR_NONNULL();
#endif /* __BLI_DYNSTR_H__ */
diff --git a/source/blender/blenlib/BLI_fileops.h b/source/blender/blenlib/BLI_fileops.h
index 91d139c7085..5c1fa57886a 100644
--- a/source/blender/blenlib/BLI_fileops.h
+++ b/source/blender/blenlib/BLI_fileops.h
@@ -65,10 +65,8 @@ int BLI_create_symlink(const char *path, const char *to) ATTR_NONNULL();
/* keep in sync with the definition of struct direntry in BLI_fileops_types.h */
#ifdef WIN32
-# if defined(_MSC_VER) || defined(__MINGW64__)
+# if defined(_MSC_VER)
typedef struct _stat64 BLI_stat_t;
-# elif defined(__MINGW32__)
-typedef struct _stati64 BLI_stat_t;
# else
typedef struct _stat BLI_stat_t;
# endif
diff --git a/source/blender/blenlib/BLI_fileops_types.h b/source/blender/blenlib/BLI_fileops_types.h
index 0cf8c8ddb4a..0ffa3276f1f 100644
--- a/source/blender/blenlib/BLI_fileops_types.h
+++ b/source/blender/blenlib/BLI_fileops_types.h
@@ -35,7 +35,7 @@
#include <sys/stat.h>
-#if defined(WIN32) && !defined(FREE_WINDOWS)
+#if defined(WIN32)
typedef unsigned int mode_t;
#endif
@@ -50,10 +50,8 @@ struct direntry {
const char *relname;
const char *path;
#ifdef WIN32 /* keep in sync with the definition of BLI_stat_t in BLI_fileops.h */
-# if defined(_MSC_VER) || defined(__MINGW64__)
+# if defined(_MSC_VER)
struct _stat64 s;
-# elif defined(__MINGW32__)
- struct _stati64 s;
# else
struct _stat s;
# endif
diff --git a/source/blender/blenlib/BLI_ghash.h b/source/blender/blenlib/BLI_ghash.h
index 7e3a009ede8..7cf3e97bdc9 100644
--- a/source/blender/blenlib/BLI_ghash.h
+++ b/source/blender/blenlib/BLI_ghash.h
@@ -167,6 +167,8 @@ unsigned int BLI_ghashutil_inthash_p_murmur(const void *ptr);
unsigned int BLI_ghashutil_inthash_p_simple(const void *ptr);
bool BLI_ghashutil_intcmp(const void *a, const void *b);
+size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b);
+
unsigned int BLI_ghashutil_uinthash_v4(const unsigned int key[4]);
#define BLI_ghashutil_inthash_v4(key) ( \
@@ -294,6 +296,25 @@ double BLI_ghash_calc_quality(GHash *gh);
double BLI_gset_calc_quality(GSet *gs);
#endif /* GHASH_INTERNAL_API */
+#define GHASH_FOREACH_BEGIN(type, var, what) \
+ do { \
+ GHashIterator gh_iter##var; \
+ GHASH_ITER(gh_iter##var, what) { \
+ type var = (type)(BLI_ghashIterator_getValue(&gh_iter##var)); \
+
+#define GHASH_FOREACH_END() \
+ } \
+ } while(0)
+
+#define GSET_FOREACH_BEGIN(type, var, what) \
+ do { \
+ GSetIterator gh_iter##var; \
+ GSET_ITER(gh_iter##var, what) { \
+ type var = (type)(BLI_gsetIterator_getKey(&gh_iter##var));
+
+#define GSET_FOREACH_END() \
+ } \
+ } while(0)
#ifdef __cplusplus
}
diff --git a/source/blender/blenlib/BLI_hash.h b/source/blender/blenlib/BLI_hash.h
new file mode 100644
index 00000000000..e849e5f8f61
--- /dev/null
+++ b/source/blender/blenlib/BLI_hash.h
@@ -0,0 +1,66 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#ifndef __BLI_HASH_H__
+#define __BLI_HASH_H__
+
+/** \file BLI_hash.h
+ * \ingroup bli
+ */
+
+BLI_INLINE unsigned int BLI_hash_int_2d(unsigned int kx, unsigned int ky)
+{
+#define rot(x, k) (((x) << (k)) | ((x) >> (32 - (k))))
+
+ unsigned int a, b, c;
+
+ a = b = c = 0xdeadbeef + (2 << 2) + 13;
+ a += kx;
+ b += ky;
+
+ c ^= b; c -= rot(b, 14);
+ a ^= c; a -= rot(c, 11);
+ b ^= a; b -= rot(a, 25);
+ c ^= b; c -= rot(b, 16);
+ a ^= c; a -= rot(c, 4);
+ b ^= a; b -= rot(a, 14);
+ c ^= b; c -= rot(b, 24);
+
+ return c;
+
+#undef rot
+}
+
+BLI_INLINE unsigned int BLI_hash_string(const char *str)
+{
+ unsigned int i = 0, c;
+
+ while ((c = *str++)) {
+ i = i * 37 + c;
+ }
+ return i;
+}
+
+BLI_INLINE unsigned int BLI_hash_int(unsigned int k)
+{
+ return BLI_hash_int_2d(k, 0);
+}
+
+#endif // __BLI_HASH_H__
diff --git a/source/blender/blenlib/BLI_kdopbvh.h b/source/blender/blenlib/BLI_kdopbvh.h
index ba565fca522..564659ad21e 100644
--- a/source/blender/blenlib/BLI_kdopbvh.h
+++ b/source/blender/blenlib/BLI_kdopbvh.h
@@ -36,7 +36,7 @@
*/
#ifdef __cplusplus
-extern "C" {
+extern "C" {
#endif
struct BVHTree;
@@ -62,7 +62,7 @@ typedef struct BVHTreeNearest {
int index; /* the index of the nearest found (untouched if none is found within a dist radius from the given coordinates) */
float co[3]; /* nearest coordinates (untouched it none is found within a dist radius from the given coordinates) */
float no[3]; /* normal at nearest coordinates (untouched it none is found within a dist radius from the given coordinates) */
- float dist_sq; /* squared distance to search arround */
+ float dist_sq; /* squared distance to search around */
int flags;
} BVHTreeNearest;
diff --git a/source/blender/blenlib/BLI_listbase.h b/source/blender/blenlib/BLI_listbase.h
index 00e761b81bc..b06944e4985 100644
--- a/source/blender/blenlib/BLI_listbase.h
+++ b/source/blender/blenlib/BLI_listbase.h
@@ -125,6 +125,11 @@ if ((lb)->last && (lb_init || (lb_init = (lb)->last))) { \
(lb_iter != lb_init)); \
}
+#define LINKLIST_FOREACH(type, var, list) \
+ for (type var = (type)((list)->first); \
+ var != NULL; \
+ var = (type)(((Link*)(var))->next))
+
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/blenlib/BLI_math_rotation.h b/source/blender/blenlib/BLI_math_rotation.h
index d60be30e10d..e059327a490 100644
--- a/source/blender/blenlib/BLI_math_rotation.h
+++ b/source/blender/blenlib/BLI_math_rotation.h
@@ -218,8 +218,12 @@ float angle_wrap_deg(float angle);
float angle_compat_rad(float angle, float angle_compat);
-int mat3_from_axis_conversion(int from_forward, int from_up, int to_forward, int to_up,
- float r_mat[3][3]);
+bool mat3_from_axis_conversion(
+ int src_forward, int src_up, int dst_forward, int dst_up,
+ float r_mat[3][3]);
+bool mat3_from_axis_conversion_single(
+ int src_axis, int dst_axis,
+ float r_mat[3][3]);
#ifdef __cplusplus
}
diff --git a/source/blender/blenlib/BLI_math_vector.h b/source/blender/blenlib/BLI_math_vector.h
index 8e0884ba347..43f414f376a 100644
--- a/source/blender/blenlib/BLI_math_vector.h
+++ b/source/blender/blenlib/BLI_math_vector.h
@@ -286,6 +286,8 @@ float angle_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT;
float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) ATTR_WARN_UNUSED_RESULT;
float cos_v3v3v3(const float p1[3], const float p2[3], const float p3[3]) ATTR_WARN_UNUSED_RESULT;
float cos_v2v2v2(const float p1[2], const float p2[2], const float p3[2]) ATTR_WARN_UNUSED_RESULT;
+float angle_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT;
+float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT;
float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT;
float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT;
float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3]) ATTR_WARN_UNUSED_RESULT;
@@ -299,6 +301,8 @@ void project_v2_v2v2(float out[2], const float p[2], const float v_proj[2]);
void project_v3_v3v3(float out[3], const float p[3], const float v_proj[3]);
void project_plane_v3_v3v3(float out[3], const float p[3], const float v_plane[3]);
void project_plane_v2_v2v2(float out[2], const float p[2], const float v_plane[2]);
+void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3]);
+void project_plane_normalized_v2_v2v2(float out[2], const float p[2], const float v_plane[2]);
void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3]);
void reflect_v3_v3v3(float out[3], const float vec[3], const float normal[3]);
void ortho_basis_v3v3_v3(float r_n1[3], float r_n2[3], const float n[3]);
diff --git a/source/blender/blenlib/BLI_path_util.h b/source/blender/blenlib/BLI_path_util.h
index b6a55d34d14..b59e7f99d59 100644
--- a/source/blender/blenlib/BLI_path_util.h
+++ b/source/blender/blenlib/BLI_path_util.h
@@ -44,7 +44,7 @@ void BLI_setenv_if_new(const char *env, const char *val) ATTR_NONNULL(1);
void BLI_make_file_string(const char *relabase, char *string, const char *dir, const char *file);
void BLI_make_exist(char *dir);
-void BLI_make_existing_file(const char *name);
+bool BLI_make_existing_file(const char *name);
void BLI_split_dirfile(const char *string, char *dir, char *file, const size_t dirlen, const size_t filelen);
void BLI_split_dir_part(const char *string, char *dir, const size_t dirlen);
void BLI_split_file_part(const char *string, char *file, const size_t filelen);
diff --git a/source/blender/blenlib/BLI_rect.h b/source/blender/blenlib/BLI_rect.h
index 041679ef876..21b9c75ac35 100644
--- a/source/blender/blenlib/BLI_rect.h
+++ b/source/blender/blenlib/BLI_rect.h
@@ -97,6 +97,7 @@ void BLI_rctf_union(struct rctf *rctf1, const struct rctf *rctf2);
void BLI_rcti_rctf_copy(struct rcti *dst, const struct rctf *src);
void BLI_rctf_rcti_copy(struct rctf *dst, const struct rcti *src);
void BLI_rcti_rctf_copy_floor(struct rcti *dst, const struct rctf *src);
+void BLI_rcti_rctf_copy_round(struct rcti *dst, const struct rctf *src);
void BLI_rctf_rotate_expand(rctf *dst, const rctf *src, const float angle);
diff --git a/source/blender/blenlib/BLI_stack.h b/source/blender/blenlib/BLI_stack.h
index 222005ee92e..d54f2a7bab2 100644
--- a/source/blender/blenlib/BLI_stack.h
+++ b/source/blender/blenlib/BLI_stack.h
@@ -30,6 +30,10 @@
#include "BLI_compiler_attrs.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
typedef struct BLI_Stack BLI_Stack;
BLI_Stack *BLI_stack_new_ex(
@@ -55,4 +59,8 @@ size_t BLI_stack_count(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONN
bool BLI_stack_is_empty(const BLI_Stack *stack) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
+#ifdef __cplusplus
+}
+#endif
+
#endif /* __BLI_STACK_H__ */
diff --git a/source/blender/blenlib/BLI_strict_flags.h b/source/blender/blenlib/BLI_strict_flags.h
index 964ee06469d..86b7285655e 100644
--- a/source/blender/blenlib/BLI_strict_flags.h
+++ b/source/blender/blenlib/BLI_strict_flags.h
@@ -30,6 +30,8 @@
#ifdef __GNUC__
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 406 /* gcc4.6+ only */
# pragma GCC diagnostic error "-Wsign-compare"
+# endif
+# if __GNUC__ >= 6 /* gcc6+ only */
# pragma GCC diagnostic error "-Wconversion"
# endif
# if (__GNUC__ * 100 + __GNUC_MINOR__) >= 408
diff --git a/source/blender/blenlib/BLI_sys_types.h b/source/blender/blenlib/BLI_sys_types.h
index 9d8222c575d..9477f61713c 100644
--- a/source/blender/blenlib/BLI_sys_types.h
+++ b/source/blender/blenlib/BLI_sys_types.h
@@ -65,8 +65,8 @@ typedef uint64_t u_int64_t;
#include <inttypes.h>
-/* MinGW and MSVC >= 2010 */
-#elif defined(FREE_WINDOWS) || defined(_MSC_VER)
+/* MSVC >= 2010 */
+#elif defined(_MSC_VER)
#include <stdint.h>
#else
diff --git a/source/blender/blenlib/BLI_task.h b/source/blender/blenlib/BLI_task.h
index c3c587275e1..721327d26a8 100644
--- a/source/blender/blenlib/BLI_task.h
+++ b/source/blender/blenlib/BLI_task.h
@@ -106,6 +106,13 @@ void *BLI_task_pool_userdata(TaskPool *pool);
/* optional mutex to use from run function */
ThreadMutex *BLI_task_pool_user_mutex(TaskPool *pool);
+/* Delayed push, use that to reduce thread overhead by accumulating
+ * all new tasks into local queue first and pushing it to scheduler
+ * from within a single mutex lock.
+ */
+void BLI_task_pool_delayed_push_begin(TaskPool *pool, int thread_id);
+void BLI_task_pool_delayed_push_end(TaskPool *pool, int thread_id);
+
/* Parallel for routines */
typedef void (*TaskParallelRangeFunc)(void *userdata, const int iter);
typedef void (*TaskParallelRangeFuncEx)(void *userdata, void *userdata_chunk, const int iter, const int thread_id);
diff --git a/source/blender/blenlib/BLI_winstuff.h b/source/blender/blenlib/BLI_winstuff.h
index b421b7dbb90..6fbbed01400 100644
--- a/source/blender/blenlib/BLI_winstuff.h
+++ b/source/blender/blenlib/BLI_winstuff.h
@@ -37,15 +37,6 @@
# error "This include is for Windows only!"
#endif
-#ifdef FREE_WINDOWS
-# ifdef WINVER
-# undef WINVER
-# endif
-
-/* Some stuff requires WINVER 0x500, but mingw's default is 0x400 */
-# define WINVER 0x0501
-#endif
-
#define WIN32_LEAN_AND_MEAN
#ifndef WIN32_SKIP_HKEY_PROTECTION
@@ -94,7 +85,7 @@ extern "C" {
# define snprintf _snprintf
#endif
-#if defined(_MSC_VER) || (defined(FREE_WINDOWS) && !defined(FREE_WINDOWS64))
+#if defined(_MSC_VER)
# define R_OK 4
# define W_OK 2
// not accepted by access() on windows
@@ -102,28 +93,22 @@ extern "C" {
# define F_OK 0
#endif
-#ifndef FREE_WINDOWS
typedef unsigned int mode_t;
-#endif
/* use functions that take a 64 bit offset for files larger than 4GB */
-#ifndef FREE_WINDOWS
-# include <stdio.h>
-# define fseek(stream, offset, origin) _fseeki64(stream, offset, origin)
-# define ftell(stream) _ftelli64(stream)
-# define lseek(fd, offset, origin) _lseeki64(fd, offset, origin)
-# define tell(fd) _telli64(fd)
-#endif
+#include <stdio.h>
+#define fseek(stream, offset, origin) _fseeki64(stream, offset, origin)
+#define ftell(stream) _ftelli64(stream)
+#define lseek(fd, offset, origin) _lseeki64(fd, offset, origin)
+#define tell(fd) _telli64(fd)
+
-/* mingw using _SSIZE_T_ to declare ssize_t type */
#ifndef _SSIZE_T_
# define _SSIZE_T_
/* python uses HAVE_SSIZE_T */
# ifndef HAVE_SSIZE_T
# define HAVE_SSIZE_T 1
-# ifndef FREE_WINDOWS64
typedef long ssize_t;
-# endif
# endif
#endif
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 3277519c66e..fcb02a86a84 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -152,6 +152,7 @@ set(SRC
BLI_ghash.h
BLI_graph.h
BLI_gsqueue.h
+ BLI_hash.h
BLI_hash_md5.h
BLI_hash_mm2a.h
BLI_heap.h
diff --git a/source/blender/blenlib/intern/BLI_dynstr.c b/source/blender/blenlib/intern/BLI_dynstr.c
index ecd4a6e6b09..bce6614beb5 100644
--- a/source/blender/blenlib/intern/BLI_dynstr.c
+++ b/source/blender/blenlib/intern/BLI_dynstr.c
@@ -35,6 +35,7 @@
#include "MEM_guardedalloc.h"
#include "BLI_utildefines.h"
+#include "BLI_memarena.h"
#include "BLI_string.h"
#include "BLI_dynstr.h"
@@ -64,6 +65,7 @@ struct DynStrElem {
struct DynStr {
DynStrElem *elems, *last;
int curlen;
+ MemArena *memarena;
};
/***/
@@ -78,11 +80,32 @@ DynStr *BLI_dynstr_new(void)
DynStr *ds = MEM_mallocN(sizeof(*ds), "DynStr");
ds->elems = ds->last = NULL;
ds->curlen = 0;
+ ds->memarena = NULL;
return ds;
}
/**
+ * Create a new DynStr.
+ *
+ * \return Pointer to a new DynStr.
+ */
+DynStr *BLI_dynstr_new_memarena(void)
+{
+ DynStr *ds = MEM_mallocN(sizeof(*ds), "DynStr");
+ ds->elems = ds->last = NULL;
+ ds->curlen = 0;
+ ds->memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+
+ return ds;
+}
+
+BLI_INLINE void *dynstr_alloc(DynStr *__restrict ds, size_t size)
+{
+ return ds->memarena ? BLI_memarena_alloc(ds->memarena, size) : malloc(size);
+}
+
+/**
* Append a c-string to a DynStr.
*
* \param ds The DynStr to append to.
@@ -90,10 +113,10 @@ DynStr *BLI_dynstr_new(void)
*/
void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr)
{
- DynStrElem *dse = malloc(sizeof(*dse));
+ DynStrElem *dse = dynstr_alloc(ds, sizeof(*dse));
int cstrlen = strlen(cstr);
- dse->str = malloc(cstrlen + 1);
+ dse->str = dynstr_alloc(ds, cstrlen + 1);
memcpy(dse->str, cstr, cstrlen + 1);
dse->next = NULL;
@@ -114,10 +137,10 @@ void BLI_dynstr_append(DynStr *__restrict ds, const char *cstr)
*/
void BLI_dynstr_nappend(DynStr *__restrict ds, const char *cstr, int len)
{
- DynStrElem *dse = malloc(sizeof(*dse));
+ DynStrElem *dse = dynstr_alloc(ds, sizeof(*dse));
int cstrlen = BLI_strnlen(cstr, len);
- dse->str = malloc(cstrlen + 1);
+ dse->str = dynstr_alloc(ds, cstrlen + 1);
memcpy(dse->str, cstr, cstrlen);
dse->str[cstrlen] = '\0';
dse->next = NULL;
@@ -296,22 +319,41 @@ char *BLI_dynstr_get_cstring(DynStr *ds)
}
/**
+ * Clear the DynStr
+ *
+ * \param ds The DynStr to clear.
+ */
+void BLI_dynstr_clear(DynStr *ds)
+{
+ if (ds->memarena) {
+ BLI_memarena_clear(ds->memarena);
+ }
+ else {
+ for (DynStrElem *dse_next, *dse = ds->elems; dse; dse = dse_next) {
+ dse_next = dse->next;
+
+ free(dse->str);
+ free(dse);
+ }
+ }
+
+ ds->elems = ds->last = NULL;
+ ds->curlen = 0;
+}
+
+/**
* Free the DynStr
*
* \param ds The DynStr to free.
*/
void BLI_dynstr_free(DynStr *ds)
{
- DynStrElem *dse;
-
- for (dse = ds->elems; dse; ) {
- DynStrElem *n = dse->next;
-
- free(dse->str);
- free(dse);
-
- dse = n;
+ if (ds->memarena) {
+ BLI_memarena_free(ds->memarena);
}
-
+ else {
+ BLI_dynstr_clear(ds);
+ }
+
MEM_freeN(ds);
}
diff --git a/source/blender/blenlib/intern/BLI_ghash.c b/source/blender/blenlib/intern/BLI_ghash.c
index 944ee18e6b2..69dee12c713 100644
--- a/source/blender/blenlib/intern/BLI_ghash.c
+++ b/source/blender/blenlib/intern/BLI_ghash.c
@@ -116,6 +116,12 @@ struct GHash {
};
+/* -------------------------------------------------------------------- */
+/* GHash API */
+
+/** \name Internal Utility API
+ * \{ */
+
BLI_INLINE void ghash_entry_copy(
GHash *gh_dst, Entry *dst, GHash *gh_src, Entry *src,
GHashKeyCopyFP keycopyfp, GHashValCopyFP valcopyfp)
@@ -132,12 +138,6 @@ BLI_INLINE void ghash_entry_copy(
}
}
-/* -------------------------------------------------------------------- */
-/* GHash API */
-
-/** \name Internal Utility API
- * \{ */
-
/**
* Get the full hash for a key.
*/
@@ -1225,6 +1225,11 @@ bool BLI_ghashutil_intcmp(const void *a, const void *b)
return (a != b);
}
+size_t BLI_ghashutil_combine_hash(size_t hash_a, size_t hash_b)
+{
+ return hash_a ^ (hash_b + 0x9e3779b9 + (hash_a << 6) + (hash_a >> 2));
+}
+
/**
* This function implements the widely used "djb" hash apparently posted
* by Daniel Bernstein to comp.lang.c some time ago. The 32 bit
diff --git a/source/blender/blenlib/intern/BLI_kdopbvh.c b/source/blender/blenlib/intern/BLI_kdopbvh.c
index 19d9711922e..e5ca53a0193 100644
--- a/source/blender/blenlib/intern/BLI_kdopbvh.c
+++ b/source/blender/blenlib/intern/BLI_kdopbvh.c
@@ -55,12 +55,20 @@
#include "BLI_stack.h"
#include "BLI_kdopbvh.h"
#include "BLI_math.h"
-#include "BLI_strict_flags.h"
#include "BLI_task.h"
+#include "BLI_strict_flags.h"
+
/* used for iterative_raycast */
// #define USE_SKIP_LINKS
+/* Use to print balanced output. */
+// #define USE_PRINT_TREE
+
+/* Check tree is valid. */
+// #define USE_VERIFY_TREE
+
+
#define MAX_TREETYPE 32
/* Setting zero so we can catch bugs in BLI_task/KDOPBVH.
@@ -129,7 +137,7 @@ typedef struct BVHOverlapData_Thread {
} BVHOverlapData_Thread;
typedef struct BVHNearestData {
- BVHTree *tree;
+ const BVHTree *tree;
const float *co;
BVHTree_NearestPointCallback callback;
void *userdata;
@@ -139,7 +147,7 @@ typedef struct BVHNearestData {
} BVHNearestData;
typedef struct BVHRayCastData {
- BVHTree *tree;
+ const BVHTree *tree;
BVHTree_RayCastCallback callback;
void *userdata;
@@ -171,9 +179,9 @@ typedef struct BVHRayCastData {
*/
const float bvhtree_kdop_axes[13][3] = {
- {1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0}, {1.0, 1.0, 1.0}, {1.0, -1.0, 1.0}, {1.0, 1.0, -1.0},
- {1.0, -1.0, -1.0}, {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}, {1.0, -1.0, 0}, {1.0, 0, -1.0},
- {0, 1.0, -1.0}
+ {1.0, 0, 0}, {0, 1.0, 0}, {0, 0, 1.0},
+ {1.0, 1.0, 1.0}, {1.0, -1.0, 1.0}, {1.0, 1.0, -1.0}, {1.0, -1.0, -1.0},
+ {1.0, 1.0, 0}, {1.0, 0, 1.0}, {0, 1.0, 1.0}, {1.0, -1.0, 0}, {1.0, 0, -1.0}, {0, 1.0, -1.0}
};
@@ -321,11 +329,16 @@ static int bvh_partition(BVHNode **a, int lo, int hi, BVHNode *x, int axis)
{
int i = lo, j = hi;
while (1) {
- while ((a[i])->bv[axis] < x->bv[axis]) i++;
+ while (a[i]->bv[axis] < x->bv[axis]) {
+ i++;
+ }
j--;
- while (x->bv[axis] < (a[j])->bv[axis]) j--;
- if (!(i < j))
+ while (x->bv[axis] < a[j]->bv[axis]) {
+ j--;
+ }
+ if (!(i < j)) {
return i;
+ }
SWAP(BVHNode *, a[i], a[j]);
i++;
}
@@ -427,19 +440,18 @@ static void sort_along_axis(BVHTree *tree, int start, int end, int axis)
* \note after a call to this function you can expect one of:
* - every node to left of a[n] are smaller or equal to it
* - every node to the right of a[n] are greater or equal to it */
-static int partition_nth_element(BVHNode **a, int _begin, int _end, int n, int axis)
+static void partition_nth_element(BVHNode **a, int begin, int end, const int n, const int axis)
{
- int begin = _begin, end = _end, cut;
while (end - begin > 3) {
- cut = bvh_partition(a, begin, end, bvh_medianof3(a, begin, (begin + end) / 2, end - 1, axis), axis);
- if (cut <= n)
+ const int cut = bvh_partition(a, begin, end, bvh_medianof3(a, begin, (begin + end) / 2, end - 1, axis), axis);
+ if (cut <= n) {
begin = cut;
- else
+ }
+ else {
end = cut;
+ }
}
bvh_insertionsort(a, begin, end, axis);
-
- return n;
}
#ifdef USE_SKIP_LINKS
@@ -464,7 +476,7 @@ static void build_skip_links(BVHTree *tree, BVHNode *node, BVHNode *left, BVHNod
/*
* BVHTree bounding volumes functions
*/
-static void create_kdop_hull(BVHTree *tree, BVHNode *node, const float *co, int numpoints, int moving)
+static void create_kdop_hull(const BVHTree *tree, BVHNode *node, const float *co, int numpoints, int moving)
{
float newminmax;
float *bv = node->bv;
@@ -491,7 +503,7 @@ static void create_kdop_hull(BVHTree *tree, BVHNode *node, const float *co, int
/**
* \note depends on the fact that the BVH's for each face is already build
*/
-static void refit_kdop_hull(BVHTree *tree, BVHNode *node, int start, int end)
+static void refit_kdop_hull(const BVHTree *tree, BVHNode *node, int start, int end)
{
float newmin, newmax;
float *bv = node->bv;
@@ -566,10 +578,12 @@ static void node_join(BVHTree *tree, BVHNode *node)
}
}
-/*
+#ifdef USE_PRINT_TREE
+
+/**
* Debug and information functions
*/
-#if 0
+
static void bvhtree_print_tree(BVHTree *tree, BVHNode *node, int depth)
{
int i;
@@ -592,26 +606,29 @@ static void bvhtree_print_tree(BVHTree *tree, BVHNode *node, int depth)
static void bvhtree_info(BVHTree *tree)
{
- printf("BVHTree info\n");
- printf("tree_type = %d, axis = %d, epsilon = %f\n", tree->tree_type, tree->axis, tree->epsilon);
- printf("nodes = %d, branches = %d, leafs = %d\n", tree->totbranch + tree->totleaf, tree->totbranch, tree->totleaf);
- printf("Memory per node = %ldbytes\n", sizeof(BVHNode) + sizeof(BVHNode *) * tree->tree_type + sizeof(float) * tree->axis);
- printf("BV memory = %dbytes\n", (int)MEM_allocN_len(tree->nodebv));
-
- printf("Total memory = %ldbytes\n", sizeof(BVHTree) +
- MEM_allocN_len(tree->nodes) +
- MEM_allocN_len(tree->nodearray) +
- MEM_allocN_len(tree->nodechild) +
- MEM_allocN_len(tree->nodebv));
-
-// bvhtree_print_tree(tree, tree->nodes[tree->totleaf], 0);
+ printf("BVHTree Info: tree_type = %d, axis = %d, epsilon = %f\n",
+ tree->tree_type, tree->axis, tree->epsilon);
+ printf("nodes = %d, branches = %d, leafs = %d\n",
+ tree->totbranch + tree->totleaf, tree->totbranch, tree->totleaf);
+ printf("Memory per node = %ubytes\n",
+ (uint)(sizeof(BVHNode) + sizeof(BVHNode *) * tree->tree_type + sizeof(float) * tree->axis));
+ printf("BV memory = %ubytes\n",
+ (uint)MEM_allocN_len(tree->nodebv));
+
+ printf("Total memory = %ubytes\n",
+ (uint)(sizeof(BVHTree) +
+ MEM_allocN_len(tree->nodes) +
+ MEM_allocN_len(tree->nodearray) +
+ MEM_allocN_len(tree->nodechild) +
+ MEM_allocN_len(tree->nodebv)));
+
+ bvhtree_print_tree(tree, tree->nodes[tree->totleaf], 0);
}
-#endif
-
-#if 0
+#endif /* USE_PRINT_TREE */
+#ifdef USE_VERIFY_TREE
-static void verify_tree(BVHTree *tree)
+static void bvhtree_verify(BVHTree *tree)
{
int i, j, check = 0;
@@ -649,12 +666,14 @@ static void verify_tree(BVHTree *tree)
}
}
- printf("branches: %d, leafs: %d, total: %d\n", tree->totbranch, tree->totleaf, tree->totbranch + tree->totleaf);
+ printf("branches: %d, leafs: %d, total: %d\n",
+ tree->totbranch, tree->totleaf, tree->totbranch + tree->totleaf);
}
-#endif
+#endif /* USE_VERIFY_TREE */
/* Helper data and structures to build a min-leaf generalized implicit tree
- * This code can be easily reduced (basicly this is only method to calculate pow(k, n) in O(1).. and stuff like that) */
+ * This code can be easily reduced
+ * (basicly this is only method to calculate pow(k, n) in O(1).. and stuff like that) */
typedef struct BVHBuildHelper {
int tree_type; /* */
int totleafs; /* */
@@ -666,7 +685,7 @@ typedef struct BVHBuildHelper {
} BVHBuildHelper;
-static void build_implicit_tree_helper(BVHTree *tree, BVHBuildHelper *data)
+static void build_implicit_tree_helper(const BVHTree *tree, BVHBuildHelper *data)
{
int depth = 0;
int remain;
@@ -696,7 +715,7 @@ static void build_implicit_tree_helper(BVHTree *tree, BVHBuildHelper *data)
}
// return the min index of all the leafs archivable with the given branch
-static int implicit_leafs_index(BVHBuildHelper *data, int depth, int child_index)
+static int implicit_leafs_index(const BVHBuildHelper *data, const int depth, const int child_index)
{
int min_leaf_index = child_index * data->leafs_per_child[depth - 1];
if (min_leaf_index <= data->remain_leafs)
@@ -711,8 +730,8 @@ static int implicit_leafs_index(BVHBuildHelper *data, int depth, int child_index
* Generalized implicit tree build
*
* An implicit tree is a tree where its structure is implied, thus there is no need to store child pointers or indexs.
- * Its possible to find the position of the child or the parent with simple maths (multiplication and adittion). This type
- * of tree is for example used on heaps.. where node N has its childs at indexs N*2 and N*2+1.
+ * Its possible to find the position of the child or the parent with simple maths (multiplication and adittion).
+ * This type of tree is for example used on heaps.. where node N has its childs at indexs N*2 and N*2+1.
*
* Although in this case the tree type is general.. and not know until runtime.
* tree_type stands for the maximum number of childs that a tree node can have.
@@ -753,7 +772,7 @@ static int implicit_needed_branches(int tree_type, int leafs)
*
* TODO: This can be optimized a bit by doing a specialized nth_element instead of K nth_elements
*/
-static void split_leafs(BVHNode **leafs_array, int *nth, int partitions, int split_axis)
+static void split_leafs(BVHNode **leafs_array, const int nth[], const int partitions, const int split_axis)
{
int i;
for (i = 0; i < partitions - 1; i++) {
@@ -765,14 +784,14 @@ static void split_leafs(BVHNode **leafs_array, int *nth, int partitions, int spl
}
typedef struct BVHDivNodesData {
- BVHTree *tree;
+ const BVHTree *tree;
BVHNode *branches_array;
BVHNode **leafs_array;
int tree_type;
int tree_offset;
- BVHBuildHelper *data;
+ const BVHBuildHelper *data;
int depth;
int i;
@@ -785,7 +804,7 @@ static void non_recursive_bvh_div_nodes_task_cb(void *userdata, const int j)
int k;
const int parent_level_index = j - data->i;
- BVHNode *parent = data->branches_array + j;
+ BVHNode *parent = &data->branches_array[j];
int nth_positions[MAX_TREETYPE + 1];
char split_axis;
@@ -824,7 +843,7 @@ static void non_recursive_bvh_div_nodes_task_cb(void *userdata, const int j)
const int child_leafs_end = implicit_leafs_index(data->data, data->depth + 1, child_level_index + 1);
if (child_leafs_end - child_leafs_begin > 1) {
- parent->children[k] = data->branches_array + child_index;
+ parent->children[k] = &data->branches_array[child_index];
parent->children[k]->parent = parent;
}
else if (child_leafs_end - child_leafs_begin == 1) {
@@ -855,7 +874,8 @@ static void non_recursive_bvh_div_nodes_task_cb(void *userdata, const int j)
* To archive this is necessary to find how much leafs are accessible from a certain branch, BVHBuildHelper
* implicit_needed_branches and implicit_leafs_index are auxiliary functions to solve that "optimal-split".
*/
-static void non_recursive_bvh_div_nodes(BVHTree *tree, BVHNode *branches_array, BVHNode **leafs_array, int num_leafs)
+static void non_recursive_bvh_div_nodes(
+ const BVHTree *tree, BVHNode *branches_array, BVHNode **leafs_array, int num_leafs)
{
int i;
@@ -867,13 +887,13 @@ static void non_recursive_bvh_div_nodes(BVHTree *tree, BVHNode *branches_array,
int depth;
/* set parent from root node to NULL */
- BVHNode *tmp = branches_array + 0;
+ BVHNode *tmp = &branches_array[0];
tmp->parent = NULL;
/* Most of bvhtree code relies on 1-leaf trees having at least one branch
* We handle that special case here */
if (num_leafs == 1) {
- BVHNode *root = branches_array + 0;
+ BVHNode *root = &branches_array[0];
refit_kdop_hull(tree, root, 0, num_leafs);
root->main_axis = get_largest_axis(root->bv) / 2;
root->totnode = 1;
@@ -895,16 +915,24 @@ static void non_recursive_bvh_div_nodes(BVHTree *tree, BVHNode *branches_array,
/* Loop tree levels (log N) loops */
for (i = 1, depth = 1; i <= num_branches; i = i * tree_type + tree_offset, depth++) {
const int first_of_next_level = i * tree_type + tree_offset;
- const int end_j = min_ii(first_of_next_level, num_branches + 1); /* index of last branch on this level */
+ const int i_stop = min_ii(first_of_next_level, num_branches + 1); /* index of last branch on this level */
/* Loop all branches on this level */
cb_data.first_of_next_level = first_of_next_level;
cb_data.i = i;
cb_data.depth = depth;
- BLI_task_parallel_range(
- i, end_j, &cb_data, non_recursive_bvh_div_nodes_task_cb,
- num_leafs > KDOPBVH_THREAD_LEAF_THRESHOLD);
+ if (true) {
+ BLI_task_parallel_range(
+ i, i_stop, &cb_data, non_recursive_bvh_div_nodes_task_cb,
+ num_leafs > KDOPBVH_THREAD_LEAF_THRESHOLD);
+ }
+ else {
+ /* Less hassle for debugging. */
+ for (int i_task = i; i_task < i_stop; i_task++) {
+ non_recursive_bvh_div_nodes_task_cb(&cb_data, i_task);
+ }
+ }
}
}
@@ -1021,7 +1049,8 @@ void BLI_bvhtree_balance(BVHTree *tree)
BVHNode *branches_array = tree->nodearray + tree->totleaf;
BVHNode **leafs_array = tree->nodes;
- /* This function should only be called once (some big bug goes here if its being called more than once per tree) */
+ /* This function should only be called once
+ * (some big bug goes here if its being called more than once per tree) */
BLI_assert(tree->totbranch == 0);
/* Build the implicit tree */
@@ -1037,7 +1066,13 @@ void BLI_bvhtree_balance(BVHTree *tree)
build_skip_links(tree, tree->nodes[tree->totleaf], NULL, NULL);
#endif
- /* bvhtree_info(tree); */
+#ifdef USE_VERIFY_TREE
+ bvhtree_verify(tree);
+#endif
+
+#ifdef USE_PRINT_TREE
+ bvhtree_info(tree);
+#endif
}
void BLI_bvhtree_insert(BVHTree *tree, int index, const float co[3], int numpoints)
@@ -1470,7 +1505,8 @@ static void bfs_find_nearest(BVHNearestData *data, BVHNode *node)
else {
/* adjust heap size */
if ((heap_size >= max_heap_size) &&
- ADJUST_MEMORY(default_heap, (void **)&heap, heap_size + 1, &max_heap_size, sizeof(heap[0])) == false)
+ ADJUST_MEMORY(default_heap, (void **)&heap,
+ heap_size + 1, &max_heap_size, sizeof(heap[0])) == false)
{
printf("WARNING: bvh_find_nearest got out of memory\n");
diff --git a/source/blender/blenlib/intern/array_store.c b/source/blender/blenlib/intern/array_store.c
index 295b39c1a2f..d3a63aceb89 100644
--- a/source/blender/blenlib/intern/array_store.c
+++ b/source/blender/blenlib/intern/array_store.c
@@ -878,7 +878,7 @@ static hash_key key_from_chunk_ref(
{
/* in C, will fill in a reusable array */
BChunk *chunk = cref->link;
- BLI_assert(info->accum_read_ahead_bytes * info->chunk_stride);
+ BLI_assert((info->accum_read_ahead_bytes * info->chunk_stride) != 0);
if (info->accum_read_ahead_bytes <= chunk->data_len) {
hash_key key;
@@ -1560,7 +1560,7 @@ BArrayState *BLI_array_store_state_add(
const void *data, const size_t data_len,
const BArrayState *state_reference)
{
- /* ensure we're aligned to the stride */
+ /* ensure we're aligned to the stride */
BLI_assert((data_len % bs->info.chunk_stride) == 0);
#ifdef USE_PARANOID_CHECKS
diff --git a/source/blender/blenlib/intern/fileops.c b/source/blender/blenlib/intern/fileops.c
index db4b3bcf20c..1df7f6f81e4 100644
--- a/source/blender/blenlib/intern/fileops.c
+++ b/source/blender/blenlib/intern/fileops.c
@@ -42,9 +42,6 @@
#include "zlib.h"
#ifdef WIN32
-# ifdef __MINGW32__
-# include <ctype.h>
-# endif
# include <io.h>
# include "BLI_winstuff.h"
# include "BLI_callbacks.h"
@@ -265,7 +262,7 @@ void *BLI_gzopen(const char *filename, const char *mode)
/* temporary #if until we update all libraries to 1.2.7
* for correct wide char path handling */
-#if ZLIB_VERNUM >= 0x1270 && !defined(FREE_WINDOWS)
+#if ZLIB_VERNUM >= 0x1270
UTF16_ENCODE(filename);
gzfile = gzopen_w(filename_16, mode);
diff --git a/source/blender/blenlib/intern/hash_mm2a.c b/source/blender/blenlib/intern/hash_mm2a.c
index af6ef4f355f..e8ca9244f25 100644
--- a/source/blender/blenlib/intern/hash_mm2a.c
+++ b/source/blender/blenlib/intern/hash_mm2a.c
@@ -36,6 +36,8 @@
* for temporary data.
*/
+#include "BLI_compiler_attrs.h"
+
#include "BLI_hash_mm2a.h" /* own include */
/* Helpers. */
@@ -128,10 +130,10 @@ uint32_t BLI_hash_mm2(const unsigned char *data, size_t len, uint32_t seed)
switch (len) {
case 3:
h ^= data[2] << 16;
- /* fall through */
+ ATTR_FALLTHROUGH;
case 2:
h ^= data[1] << 8;
- /* fall through */
+ ATTR_FALLTHROUGH;
case 1:
h ^= data[0];
h *= MM2A_M;
diff --git a/source/blender/blenlib/intern/listbase.c b/source/blender/blenlib/intern/listbase.c
index 6cb7b7d8e3e..46dcee48eda 100644
--- a/source/blender/blenlib/intern/listbase.c
+++ b/source/blender/blenlib/intern/listbase.c
@@ -664,7 +664,7 @@ void *BLI_rfindptr(const ListBase *listbase, const void *ptr, const int offset)
}
/**
- * Returns the 1-based index of the first element of listbase which contains the specified
+ * Returns the 0-based index of the first element of listbase which contains the specified
* null-terminated string at the specified offset, or -1 if not found.
*/
int BLI_findstringindex(const ListBase *listbase, const char *id, const int offset)
diff --git a/source/blender/blenlib/intern/math_color_blend_inline.c b/source/blender/blenlib/intern/math_color_blend_inline.c
index 048ab71c6dc..dc3874f83a2 100644
--- a/source/blender/blenlib/intern/math_color_blend_inline.c
+++ b/source/blender/blenlib/intern/math_color_blend_inline.c
@@ -444,7 +444,7 @@ MINLINE void blend_color_vividlight_byte(unsigned char dst[4], unsigned const ch
else if (src2[i] == 0) {
temp = 0;
}
- else if (src2[i] > 127) {
+ else if (src2[i] > 127) {
temp = min_ii(((src1[i]) * 255) / (2 * (255 - src2[i])), 255);
}
else {
diff --git a/source/blender/blenlib/intern/math_geom.c b/source/blender/blenlib/intern/math_geom.c
index 58699a0593b..bfe1aefcbbd 100644
--- a/source/blender/blenlib/intern/math_geom.c
+++ b/source/blender/blenlib/intern/math_geom.c
@@ -572,8 +572,8 @@ float dist_squared_to_ray_v3(
}
/**
* Find the closest point in a seg to a ray and return the distance squared.
- * \param r_point : Is the point on segment closest to ray (or to ray_origin if the ray and the segment are parallel).
- * \param depth: the distance of r_point projection on ray to the ray_origin.
+ * \param r_point: Is the point on segment closest to ray (or to ray_origin if the ray and the segment are parallel).
+ * \param r_depth: the distance of r_point projection on ray to the ray_origin.
*/
float dist_squared_ray_to_seg_v3(
const float ray_origin[3], const float ray_direction[3],
@@ -1828,7 +1828,7 @@ bool isect_tri_tri_epsilon_v3(
(range[0].max < range[1].min)) == 0)
{
if (r_i1 && r_i2) {
- project_plane_v3_v3v3(plane_co, plane_co, plane_no);
+ project_plane_normalized_v3_v3v3(plane_co, plane_co, plane_no);
madd_v3_v3v3fl(r_i1, plane_co, plane_no, max_ff(range[0].min, range[1].min));
madd_v3_v3v3fl(r_i2, plane_co, plane_no, min_ff(range[0].max, range[1].max));
}
diff --git a/source/blender/blenlib/intern/math_matrix.c b/source/blender/blenlib/intern/math_matrix.c
index 9a60c670ec7..f47f9ad76e6 100644
--- a/source/blender/blenlib/intern/math_matrix.c
+++ b/source/blender/blenlib/intern/math_matrix.c
@@ -1738,16 +1738,16 @@ void blend_m4_m4m4(float out[4][4], float dst[4][4], float src[4][4], const floa
/**
* A polar-decomposition-based interpolation between matrix A and matrix B.
*
- * \note This code is about five times slower as the 'naive' interpolation done by \a blend_m3_m3m3
- * (it typically remains below 2 usec on an average i74700, while \a blend_m3_m3m3 remains below 0.4 usec).
+ * \note This code is about five times slower as the 'naive' interpolation done by #blend_m3_m3m3
+ * (it typically remains below 2 usec on an average i74700, while #blend_m3_m3m3 remains below 0.4 usec).
* However, it gives expected results even with non-uniformaly scaled matrices, see T46418 for an example.
*
* Based on "Matrix Animation and Polar Decomposition", by Ken Shoemake & Tom Duff
*
- * @return R the interpolated matrix.
- * @param A the intput matrix which is totally effective with \a t = 0.0.
- * @param B the intput matrix which is totally effective with \a t = 1.0.
- * @param t the interpolation factor.
+ * \param R: Resulting interpolated matrix.
+ * \param A: Input matrix which is totally effective with `t = 0.0`.
+ * \param B: Input matrix which is totally effective with `t = 1.0`.
+ * \param t: Interpolation factor.
*/
void interp_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t)
{
@@ -1777,12 +1777,12 @@ void interp_m3_m3m3(float R[3][3], float A[3][3], float B[3][3], const float t)
}
/**
- * Complete transform matrix interpolation, based on polar-decomposition-based interpolation from interp_m3_m3m3.
+ * Complete transform matrix interpolation, based on polar-decomposition-based interpolation from #interp_m3_m3m3.
*
- * @return R the interpolated matrix.
- * @param A the intput matrix which is totally effective with \a t = 0.0.
- * @param B the intput matrix which is totally effective with \a t = 1.0.
- * @param t the interpolation factor.
+ * \param R: Resulting interpolated matrix.
+ * \param A: Input matrix which is totally effective with `t = 0.0`.
+ * \param B: Input matrix which is totally effective with `t = 1.0`.
+ * \param t: Interpolation factor.
*/
void interp_m4_m4m4(float R[4][4], float A[4][4], float B[4][4], const float t)
{
diff --git a/source/blender/blenlib/intern/math_rotation.c b/source/blender/blenlib/intern/math_rotation.c
index 9b5dad3f767..23bd5e60e22 100644
--- a/source/blender/blenlib/intern/math_rotation.c
+++ b/source/blender/blenlib/intern/math_rotation.c
@@ -84,8 +84,6 @@ void mul_qt_qtqt(float q[4], const float q1[4], const float q2[4])
* \note:
* Assumes a unit quaternion?
*
- * \note: multiplying by 3x3 matrix is ~25% faster.
- *
* in fact not, but you may want to use a unit quat, read on...
*
* Shortcut for 'q v q*' when \a v is actually a quaternion.
@@ -98,6 +96,8 @@ void mul_qt_qtqt(float q[4], const float q1[4], const float q2[4])
*
* For people used to python mathutils, its like:
* def mul_qt_v3(q, v): (q * Quaternion((0.0, v[0], v[1], v[2])) * q.conjugated())[1:]
+ *
+ * \note: multiplying by 3x3 matrix is ~25% faster.
*/
void mul_qt_v3(const float q[4], float v[3])
{
@@ -2147,38 +2147,37 @@ BLI_INLINE int _axis_signed(const int axis)
return (axis < 3) ? axis : axis - 3;
}
-/*
+/**
* Each argument us an axis in ['X', 'Y', 'Z', '-X', '-Y', '-Z']
* where the first 2 are a source and the second 2 are the target.
*/
-int mat3_from_axis_conversion(int from_forward, int from_up, int to_forward, int to_up,
- float r_mat[3][3])
+bool mat3_from_axis_conversion(
+ int src_forward, int src_up, int dst_forward, int dst_up,
+ float r_mat[3][3])
{
// from functools import reduce
int value;
- unsigned int i;
- if (from_forward == to_forward && from_up == to_up) {
+ if (src_forward == dst_forward && src_up == dst_up) {
unit_m3(r_mat);
return false;
}
- if ((_axis_signed(from_forward) == _axis_signed(from_up)) ||
- (_axis_signed(to_forward) == _axis_signed(to_up)))
+ if ((_axis_signed(src_forward) == _axis_signed(src_up)) ||
+ (_axis_signed(dst_forward) == _axis_signed(dst_up)))
{
/* we could assert here! */
unit_m3(r_mat);
return false;
}
- value = ((from_forward << (0 * 3)) |
- (from_up << (1 * 3)) |
- (to_forward << (2 * 3)) |
- (to_up << (3 * 3)));
+ value = ((src_forward << (0 * 3)) |
+ (src_up << (1 * 3)) |
+ (dst_forward << (2 * 3)) |
+ (dst_up << (3 * 3)));
- for (i = 0; i < (sizeof(_axis_convert_matrix) / sizeof(*_axis_convert_matrix)); i++) {
- unsigned int j;
- for (j = 0; j < (sizeof(*_axis_convert_lut) / sizeof(*_axis_convert_lut[0])); j++) {
+ for (uint i = 0; i < (sizeof(_axis_convert_matrix) / sizeof(*_axis_convert_matrix)); i++) {
+ for (uint j = 0; j < (sizeof(*_axis_convert_lut) / sizeof(*_axis_convert_lut[0])); j++) {
if (_axis_convert_lut[i][j] == value) {
copy_m3_m3(r_mat, _axis_convert_matrix[i]);
return true;
@@ -2189,3 +2188,27 @@ int mat3_from_axis_conversion(int from_forward, int from_up, int to_forward, int
// BLI_assert(0);
return false;
}
+
+/**
+ * Use when the second axis can be guessed.
+ */
+bool mat3_from_axis_conversion_single(
+ int src_axis, int dst_axis,
+ float r_mat[3][3])
+{
+ if (src_axis == dst_axis) {
+ unit_m3(r_mat);
+ return false;
+ }
+
+ /* Pick predictable next axis. */
+ int src_axis_next = (src_axis + 1) % 3;
+ int dst_axis_next = (dst_axis + 1) % 3;
+
+ if ((src_axis < 3) != (dst_axis < 3)) {
+ /* Flip both axis so matrix sign remains positive. */
+ dst_axis_next += 3;
+ }
+
+ return mat3_from_axis_conversion(src_axis, src_axis_next, dst_axis, dst_axis_next, r_mat);
+}
diff --git a/source/blender/blenlib/intern/math_vector.c b/source/blender/blenlib/intern/math_vector.c
index dfecc3b556a..c6e9b8229ba 100644
--- a/source/blender/blenlib/intern/math_vector.c
+++ b/source/blender/blenlib/intern/math_vector.c
@@ -518,38 +518,27 @@ float angle_normalized_v2v2(const float v1[2], const float v2[2])
}
/**
- * angle between 2 vectors defined by 3 coords, about an axis. */
-float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
+ * Angle between 2 vectors, about an axis (axis can be considered a plane).
+ */
+float angle_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3])
{
- float v1_proj[3], v2_proj[3], tproj[3];
-
- sub_v3_v3v3(v1_proj, v1, v2);
- sub_v3_v3v3(v2_proj, v3, v2);
+ float v1_proj[3], v2_proj[3];
/* project the vectors onto the axis */
- project_v3_v3v3(tproj, v1_proj, axis);
- sub_v3_v3(v1_proj, tproj);
-
- project_v3_v3v3(tproj, v2_proj, axis);
- sub_v3_v3(v2_proj, tproj);
+ project_plane_normalized_v3_v3v3(v1_proj, v1, axis);
+ project_plane_normalized_v3_v3v3(v2_proj, v2, axis);
return angle_v3v3(v1_proj, v2_proj);
}
-float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
+float angle_signed_on_axis_v3v3_v3(const float v1[3], const float v2[3], const float axis[3])
{
float v1_proj[3], v2_proj[3], tproj[3];
float angle;
- sub_v3_v3v3(v1_proj, v1, v2);
- sub_v3_v3v3(v2_proj, v3, v2);
-
/* project the vectors onto the axis */
- project_v3_v3v3(tproj, v1_proj, axis);
- sub_v3_v3(v1_proj, tproj);
-
- project_v3_v3v3(tproj, v2_proj, axis);
- sub_v3_v3(v2_proj, tproj);
+ project_plane_normalized_v3_v3v3(v1_proj, v1, axis);
+ project_plane_normalized_v3_v3v3(v2_proj, v2, axis);
angle = angle_v3v3(v1_proj, v2_proj);
@@ -562,6 +551,29 @@ float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const
return angle;
}
+/**
+ * Angle between 2 vectors defined by 3 coords, about an axis (axis can be considered a plane).
+ */
+float angle_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
+{
+ float vec1[3], vec2[3];
+
+ sub_v3_v3v3(vec1, v1, v2);
+ sub_v3_v3v3(vec2, v3, v2);
+
+ return angle_on_axis_v3v3_v3(vec1, vec2, axis);
+}
+
+float angle_signed_on_axis_v3v3v3_v3(const float v1[3], const float v2[3], const float v3[3], const float axis[3])
+{
+ float vec1[3], vec2[3];
+
+ sub_v3_v3v3(vec1, v1, v2);
+ sub_v3_v3v3(vec2, v3, v2);
+
+ return angle_signed_on_axis_v3v3_v3(vec1, vec2, axis);
+}
+
void angle_tri_v3(float angles[3], const float v1[3], const float v2[3], const float v3[3])
{
float ed1[3], ed2[3], ed3[3];
@@ -669,6 +681,25 @@ void project_plane_v2_v2v2(float out[2], const float p[2], const float v_plane[2
out[1] = p[1] - (mul * v_plane[1]);
}
+void project_plane_normalized_v3_v3v3(float out[3], const float p[3], const float v_plane[3])
+{
+ BLI_ASSERT_UNIT_V3(v_plane);
+ const float mul = dot_v3v3(p, v_plane);
+
+ out[0] = p[0] - (mul * v_plane[0]);
+ out[1] = p[1] - (mul * v_plane[1]);
+ out[2] = p[2] - (mul * v_plane[2]);
+}
+
+void project_plane_normalized_v2_v2v2(float out[2], const float p[2], const float v_plane[2])
+{
+ BLI_ASSERT_UNIT_V2(v_plane);
+ const float mul = dot_v2v2(p, v_plane);
+
+ out[0] = p[0] - (mul * v_plane[0]);
+ out[1] = p[1] - (mul * v_plane[1]);
+}
+
/* project a vector on a plane defined by normal and a plane point p */
void project_v3_plane(float out[3], const float plane_no[3], const float plane_co[3])
{
@@ -697,7 +728,19 @@ void bisect_v3_v3v3v3(float out[3], const float v1[3], const float v2[3], const
/**
* Returns a reflection vector from a vector and a normal vector
- * reflect = vec - ((2 * DotVecs(vec, mirror)) * mirror)
+ * reflect = vec - ((2 * dot(vec, mirror)) * mirror).
+ *
+ * <pre>
+ * v
+ * + ^
+ * \ |
+ * \|
+ * + normal: axis of reflection
+ * /
+ * /
+ * +
+ * out: result (negate for a 'bounce').
+ * </pre>
*/
void reflect_v3_v3v3(float out[3], const float v[3], const float normal[3])
{
diff --git a/source/blender/blenlib/intern/noise.c b/source/blender/blenlib/intern/noise.c
index f834c5b4c74..86c24307ae2 100644
--- a/source/blender/blenlib/intern/noise.c
+++ b/source/blender/blenlib/intern/noise.c
@@ -1394,6 +1394,11 @@ static float voronoi_CrS(float x, float y, float z)
/* returns unsigned cellnoise */
static float cellNoiseU(float x, float y, float z)
{
+ /* avoid precision issues on unit coordinates */
+ x = (x + 0.000001f)*1.00001f;
+ y = (y + 0.000001f)*1.00001f;
+ z = (z + 0.000001f)*1.00001f;
+
int xi = (int)(floor(x));
int yi = (int)(floor(y));
int zi = (int)(floor(z));
@@ -1411,6 +1416,11 @@ float cellNoise(float x, float y, float z)
/* returns a vector/point/color in ca, using point hasharray directly */
void cellNoiseV(float x, float y, float z, float ca[3])
{
+ /* avoid precision issues on unit coordinates */
+ x = (x + 0.000001f)*1.00001f;
+ y = (y + 0.000001f)*1.00001f;
+ z = (z + 0.000001f)*1.00001f;
+
int xi = (int)(floor(x));
int yi = (int)(floor(y));
int zi = (int)(floor(z));
diff --git a/source/blender/blenlib/intern/path_util.c b/source/blender/blenlib/intern/path_util.c
index 7b765cfa939..4b3a74d02ae 100644
--- a/source/blender/blenlib/intern/path_util.c
+++ b/source/blender/blenlib/intern/path_util.c
@@ -1173,22 +1173,10 @@ bool BLI_path_program_search(
void BLI_setenv(const char *env, const char *val)
{
/* free windows */
-#if (defined(WIN32) || defined(WIN64)) && defined(FREE_WINDOWS)
- char *envstr;
- if (val)
- envstr = BLI_sprintfN("%s=%s", env, val);
- else
- envstr = BLI_sprintfN("%s=", env);
-
- putenv(envstr);
- MEM_freeN(envstr);
-
- /* non-free windows */
-#elif (defined(WIN32) || defined(WIN64)) /* not free windows */
+#if (defined(WIN32) || defined(WIN64))
uputenv(env, val);
-
#else
/* linux/osx/bsd */
if (val)
@@ -1234,14 +1222,16 @@ void BLI_make_exist(char *dir)
/**
* Ensures that the parent directory of *name exists.
+ *
+ * \return true on success (i.e. given path now exists on FS), false otherwise.
*/
-void BLI_make_existing_file(const char *name)
+bool BLI_make_existing_file(const char *name)
{
char di[FILE_MAX];
BLI_split_dir_part(name, di, sizeof(di));
/* make if the dir doesn't exist */
- BLI_dir_create_recursive(di);
+ return BLI_dir_create_recursive(di);
}
/**
diff --git a/source/blender/blenlib/intern/polyfill2d.c b/source/blender/blenlib/intern/polyfill2d.c
index 2969b0eccf4..5f9b92198a5 100644
--- a/source/blender/blenlib/intern/polyfill2d.c
+++ b/source/blender/blenlib/intern/polyfill2d.c
@@ -105,24 +105,24 @@ typedef bool axis_t;
/* use for sorting */
typedef struct KDTreeNode2D_head {
- unsigned int neg, pos;
- unsigned int index;
+ uint neg, pos;
+ uint index;
} KDTreeNode2D_head;
typedef struct KDTreeNode2D {
- unsigned int neg, pos;
- unsigned int index;
+ uint neg, pos;
+ uint index;
axis_t axis; /* range is only (0-1) */
- unsigned short flag;
- unsigned int parent;
+ ushort flag;
+ uint parent;
} KDTreeNode2D;
struct KDTree2D {
KDTreeNode2D *nodes;
const float (*coords)[2];
- unsigned int root;
- unsigned int totnode;
- unsigned int *nodes_map; /* index -> node lookup */
+ uint root;
+ uint totnode;
+ uint *nodes_map; /* index -> node lookup */
};
struct KDRange2D {
@@ -140,14 +140,14 @@ typedef struct PolyFill {
struct PolyIndex *indices; /* vertex aligned */
const float (*coords)[2];
- unsigned int coords_tot;
+ uint coords_tot;
#ifdef USE_CONVEX_SKIP
- unsigned int coords_tot_concave;
+ uint coords_tot_concave;
#endif
/* A polygon with n vertices has a triangulation of n-2 triangles. */
- unsigned int (*tris)[3];
- unsigned int tris_tot;
+ uint (*tris)[3];
+ uint tris_tot;
#ifdef USE_KDTREE
struct KDTree2D kdtree;
@@ -158,7 +158,7 @@ typedef struct PolyFill {
/* circular linklist */
typedef struct PolyIndex {
struct PolyIndex *next, *prev;
- unsigned int index;
+ uint index;
eSign sign;
} PolyIndex;
@@ -212,7 +212,7 @@ static eSign span_tri_v2_sign(const float v1[2], const float v2[2], const float
#ifdef USE_KDTREE
-#define KDNODE_UNSET ((unsigned int)-1)
+#define KDNODE_UNSET ((uint)-1)
enum {
KDNODE_FLAG_REMOVED = (1 << 0),
@@ -220,7 +220,7 @@ enum {
static void kdtree2d_new(
struct KDTree2D *tree,
- unsigned int tot,
+ uint tot,
const float (*coords)[2])
{
/* set by caller */
@@ -235,11 +235,11 @@ static void kdtree2d_new(
*/
static void kdtree2d_init(
struct KDTree2D *tree,
- const unsigned int coords_tot,
+ const uint coords_tot,
const PolyIndex *indices)
{
KDTreeNode2D *node;
- unsigned int i;
+ uint i;
for (i = 0, node = tree->nodes; i < coords_tot; i++) {
if (indices[i].sign != CONVEX) {
@@ -251,15 +251,15 @@ static void kdtree2d_init(
}
}
- BLI_assert(tree->totnode == (unsigned int)(node - tree->nodes));
+ BLI_assert(tree->totnode == (uint)(node - tree->nodes));
}
-static unsigned int kdtree2d_balance_recursive(
- KDTreeNode2D *nodes, unsigned int totnode, axis_t axis,
- const float (*coords)[2], const unsigned int ofs)
+static uint kdtree2d_balance_recursive(
+ KDTreeNode2D *nodes, uint totnode, axis_t axis,
+ const float (*coords)[2], const uint ofs)
{
KDTreeNode2D *node;
- unsigned int neg, pos, median, i, j;
+ uint neg, pos, median, i, j;
if (totnode <= 0) {
return KDNODE_UNSET;
@@ -317,7 +317,7 @@ static void kdtree2d_balance(
static void kdtree2d_init_mapping(
struct KDTree2D *tree)
{
- unsigned int i;
+ uint i;
KDTreeNode2D *node;
for (i = 0, node = tree->nodes; i < tree->totnode; i++, node++) {
@@ -338,9 +338,9 @@ static void kdtree2d_init_mapping(
static void kdtree2d_node_remove(
struct KDTree2D *tree,
- unsigned int index)
+ uint index)
{
- unsigned int node_index = tree->nodes_map[index];
+ uint node_index = tree->nodes_map[index];
KDTreeNode2D *node;
if (node_index == KDNODE_UNSET) {
@@ -362,7 +362,7 @@ static void kdtree2d_node_remove(
{
KDTreeNode2D *node_parent = &tree->nodes[node->parent];
- BLI_assert((unsigned int)(node - tree->nodes) == node_index);
+ BLI_assert((uint)(node - tree->nodes) == node_index);
if (node_parent->neg == node_index) {
node_parent->neg = KDNODE_UNSET;
}
@@ -383,7 +383,7 @@ static void kdtree2d_node_remove(
static bool kdtree2d_isect_tri_recursive(
const struct KDTree2D *tree,
- const unsigned int tri_index[3],
+ const uint tri_index[3],
const float *tri_coords[3],
const float tri_center[2],
const struct KDRange2D bounds[2],
@@ -446,10 +446,10 @@ static bool kdtree2d_isect_tri_recursive(
static bool kdtree2d_isect_tri(
struct KDTree2D *tree,
- const unsigned int ind[3])
+ const uint ind[3])
{
const float *vs[3];
- unsigned int i;
+ uint i;
struct KDRange2D bounds[2] = {
{FLT_MAX, -FLT_MAX},
{FLT_MAX, -FLT_MAX},
@@ -475,7 +475,7 @@ static bool kdtree2d_isect_tri(
#endif /* USE_KDTREE */
-static unsigned int *pf_tri_add(PolyFill *pf)
+static uint *pf_tri_add(PolyFill *pf)
{
return pf->tris[pf->tris_tot++];
}
@@ -496,7 +496,7 @@ static void pf_coord_remove(PolyFill *pf, PolyIndex *pi)
pf->indices = pi->next;
}
#ifdef DEBUG
- pi->index = (unsigned int)-1;
+ pi->index = (uint)-1;
pi->next = pi->prev = NULL;
#endif
@@ -594,7 +594,7 @@ static void pf_triangulate(PolyFill *pf)
}
if (pf->coords_tot == 3) {
- unsigned int *tri = pf_tri_add(pf);
+ uint *tri = pf_tri_add(pf);
pi_ear = pf->indices;
tri[0] = pi_ear->index; pi_ear = pi_ear->next;
tri[1] = pi_ear->index; pi_ear = pi_ear->next;
@@ -627,10 +627,10 @@ static PolyIndex *pf_ear_tip_find(
)
{
/* localize */
- const unsigned int coords_tot = pf->coords_tot;
+ const uint coords_tot = pf->coords_tot;
PolyIndex *pi_ear;
- unsigned int i;
+ uint i;
#ifdef USE_CLIP_EVEN
pi_ear = pi_ear_init;
@@ -688,7 +688,7 @@ static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip)
#endif
#if defined(USE_CONVEX_SKIP) && !defined(USE_KDTREE)
- unsigned int coords_tot_concave_checked = 0;
+ uint coords_tot_concave_checked = 0;
#endif
@@ -697,8 +697,8 @@ static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip)
#ifdef USE_CONVEX_SKIP_TEST
/* check if counting is wrong */
{
- unsigned int coords_tot_concave_test = 0;
- unsigned int i = pf->coords_tot;
+ uint coords_tot_concave_test = 0;
+ uint i = pf->coords_tot;
while (i--) {
if (coords_sign[indices[i]] != CONVEX) {
coords_tot_concave_test += 1;
@@ -720,7 +720,7 @@ static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip)
#ifdef USE_KDTREE
{
- const unsigned int ind[3] = {
+ const uint ind[3] = {
pi_ear_tip->index,
pi_ear_tip->next->index,
pi_ear_tip->prev->index};
@@ -771,7 +771,7 @@ static bool pf_ear_tip_check(PolyFill *pf, PolyIndex *pi_ear_tip)
static void pf_ear_tip_cut(PolyFill *pf, PolyIndex *pi_ear_tip)
{
- unsigned int *tri = pf_tri_add(pf);
+ uint *tri = pf_tri_add(pf);
tri[0] = pi_ear_tip->prev->index;
tri[1] = pi_ear_tip->index;
@@ -786,15 +786,15 @@ static void pf_ear_tip_cut(PolyFill *pf, PolyIndex *pi_ear_tip)
static void polyfill_prepare(
PolyFill *pf,
const float (*coords)[2],
- const unsigned int coords_tot,
+ const uint coords_tot,
int coords_sign,
- unsigned int (*r_tris)[3],
+ uint (*r_tris)[3],
PolyIndex *r_indices)
{
/* localize */
PolyIndex *indices = r_indices;
- unsigned int i;
+ uint i;
/* assign all polyfill members here */
pf->indices = r_indices;
@@ -832,7 +832,7 @@ static void polyfill_prepare(
}
else {
/* reversed */
- unsigned int n = coords_tot - 1;
+ uint n = coords_tot - 1;
for (i = 0; i < coords_tot; i++) {
indices[i].next = &indices[i + 1];
indices[i].prev = &indices[i - 1];
@@ -876,9 +876,9 @@ static void polyfill_calc(
*/
void BLI_polyfill_calc_arena(
const float (*coords)[2],
- const unsigned int coords_tot,
+ const uint coords_tot,
const int coords_sign,
- unsigned int (*r_tris)[3],
+ uint (*r_tris)[3],
struct MemArena *arena)
{
@@ -932,9 +932,9 @@ void BLI_polyfill_calc_arena(
*/
void BLI_polyfill_calc(
const float (*coords)[2],
- const unsigned int coords_tot,
+ const uint coords_tot,
const int coords_sign,
- unsigned int (*r_tris)[3])
+ uint (*r_tris)[3])
{
PolyFill pf;
PolyIndex *indices = BLI_array_alloca(indices, coords_tot);
diff --git a/source/blender/blenlib/intern/rct.c b/source/blender/blenlib/intern/rct.c
index fd24a00156d..e0c4cbe9990 100644
--- a/source/blender/blenlib/intern/rct.c
+++ b/source/blender/blenlib/intern/rct.c
@@ -693,6 +693,14 @@ void BLI_rcti_rctf_copy_floor(rcti *dst, const rctf *src)
dst->ymax = floorf(src->ymax);
}
+void BLI_rcti_rctf_copy_round(rcti *dst, const rctf *src)
+{
+ dst->xmin = floorf(src->xmin + 0.5f);
+ dst->xmax = floorf(src->xmax + 0.5f);
+ dst->ymin = floorf(src->ymin + 0.5f);
+ dst->ymax = floorf(src->ymax + 0.5f);
+}
+
void BLI_rctf_rcti_copy(rctf *dst, const rcti *src)
{
dst->xmin = src->xmin;
diff --git a/source/blender/blenlib/intern/storage.c b/source/blender/blenlib/intern/storage.c
index 3edc00a8c1a..b819c513fbd 100644
--- a/source/blender/blenlib/intern/storage.c
+++ b/source/blender/blenlib/intern/storage.c
@@ -113,7 +113,7 @@ double BLI_dir_free_space(const char *dir)
#ifdef WIN32
DWORD sectorspc, bytesps, freec, clusters;
char tmp[4];
-
+
tmp[0] = '\\'; tmp[1] = 0; /* Just a failsafe */
if (dir[0] == '/' || dir[0] == '\\') {
tmp[0] = '\\';
@@ -139,10 +139,10 @@ double BLI_dir_free_space(const char *dir)
char name[FILE_MAXDIR], *slash;
int len = strlen(dir);
-
+
if (len >= FILE_MAXDIR) /* path too long */
return -1;
-
+
strcpy(name, dir);
if (len) {
@@ -194,7 +194,7 @@ size_t BLI_file_size(const char *path)
*/
int BLI_exists(const char *name)
{
-#if defined(WIN32)
+#if defined(WIN32)
BLI_stat_t st;
wchar_t *tmp_16 = alloc_utf16_from_8(name, 1);
int len, res;
@@ -253,10 +253,8 @@ int BLI_stat(const char *path, BLI_stat_t *buffer)
int BLI_wstat(const wchar_t *path, BLI_stat_t *buffer)
{
-#if defined(_MSC_VER) || defined(__MINGW64__)
+#if defined(_MSC_VER)
return _wstat64(path, buffer);
-#elif defined(__MINGW32__)
- return _wstati64(path, buffer);
#else
return _wstat(path, buffer);
#endif
@@ -372,7 +370,7 @@ LinkNode *BLI_file_read_as_lines(const char *name)
size_t size;
if (!fp) return NULL;
-
+
fseek(fp, 0, SEEK_END);
size = (size_t)ftell(fp);
fseek(fp, 0, SEEK_SET);
@@ -385,7 +383,7 @@ LinkNode *BLI_file_read_as_lines(const char *name)
buf = MEM_mallocN(size, "file_as_lines");
if (buf) {
size_t i, last = 0;
-
+
/*
* size = because on win32 reading
* all the bytes in the file will return
@@ -403,10 +401,10 @@ LinkNode *BLI_file_read_as_lines(const char *name)
last = i + 1;
}
}
-
+
MEM_freeN(buf);
}
-
+
fclose(fp);
return lines.list;
@@ -424,23 +422,13 @@ void BLI_file_free_lines(LinkNode *lines)
bool BLI_file_older(const char *file1, const char *file2)
{
#ifdef WIN32
-#ifndef __MINGW32__
struct _stat st1, st2;
-#else
- struct _stati64 st1, st2;
-#endif
UTF16_ENCODE(file1);
UTF16_ENCODE(file2);
-
-#ifndef __MINGW32__
+
if (_wstat(file1_16, &st1)) return false;
if (_wstat(file2_16, &st2)) return false;
-#else
- if (_wstati64(file1_16, &st1)) return false;
- if (_wstati64(file2_16, &st2)) return false;
-#endif
-
UTF16_UN_ENCODE(file2);
UTF16_UN_ENCODE(file1);
diff --git a/source/blender/blenlib/intern/string.c b/source/blender/blenlib/intern/string.c
index f62ffe9e985..6022732025b 100644
--- a/source/blender/blenlib/intern/string.c
+++ b/source/blender/blenlib/intern/string.c
@@ -332,7 +332,7 @@ size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const siz
goto escape_finish;
case '\\':
case '"':
- /* fall-through */
+ ATTR_FALLTHROUGH;
/* less common but should also be support */
case '\t':
@@ -346,7 +346,7 @@ size_t BLI_strescape(char *__restrict dst, const char *__restrict src, const siz
/* not enough space to escape */
break;
}
- /* fall-through */
+ ATTR_FALLTHROUGH;
default:
*dst = *src;
break;
diff --git a/source/blender/blenlib/intern/string_utf8.c b/source/blender/blenlib/intern/string_utf8.c
index 83d4a75952f..229a97a2fa7 100644
--- a/source/blender/blenlib/intern/string_utf8.c
+++ b/source/blender/blenlib/intern/string_utf8.c
@@ -167,7 +167,7 @@ utf8_error:
/**
* Remove any invalid utf-8 byte (taking into account multi-bytes sequence of course).
*
- * @return number of stripped bytes.
+ * \return number of stripped bytes.
*/
int BLI_utf8_invalid_strip(char *str, size_t length)
{
@@ -205,11 +205,11 @@ int BLI_utf8_invalid_strip(char *str, size_t length)
while (*src != '\0' && (utf8_size = utf8_skip_data[*src]) < maxncpy) {\
maxncpy -= utf8_size; \
switch (utf8_size) { \
- case 6: *dst ++ = *src ++; \
- case 5: *dst ++ = *src ++; \
- case 4: *dst ++ = *src ++; \
- case 3: *dst ++ = *src ++; \
- case 2: *dst ++ = *src ++; \
+ case 6: *dst ++ = *src ++; ATTR_FALLTHROUGH; \
+ case 5: *dst ++ = *src ++; ATTR_FALLTHROUGH; \
+ case 4: *dst ++ = *src ++; ATTR_FALLTHROUGH; \
+ case 3: *dst ++ = *src ++; ATTR_FALLTHROUGH; \
+ case 2: *dst ++ = *src ++; ATTR_FALLTHROUGH; \
case 1: *dst ++ = *src ++; \
} \
} \
diff --git a/source/blender/blenlib/intern/task.c b/source/blender/blenlib/intern/task.c
index 297d0f0b310..e050f3148b8 100644
--- a/source/blender/blenlib/intern/task.c
+++ b/source/blender/blenlib/intern/task.c
@@ -52,7 +52,14 @@
*
* This allows thread to fetch next task without locking the whole queue.
*/
-#define LOCALQUEUE_SIZE 1
+#define LOCAL_QUEUE_SIZE 1
+
+/* Number of tasks which are allowed to be scheduled in a delayed manner.
+ *
+ * This allows to use less locks per graph node children schedule. More details
+ * could be found at TaskThreadLocalStorage::do_delayed_push.
+ */
+#define DELAYED_QUEUE_SIZE 4096
#ifndef NDEBUG
# define ASSERT_THREAD_ID(scheduler, thread_id) \
@@ -129,9 +136,28 @@ typedef struct TaskMemPoolStats {
#endif
typedef struct TaskThreadLocalStorage {
+ /* Memory pool for faster task allocation.
+ * The idea is to re-use memory of finished/discarded tasks by this thread.
+ */
TaskMemPool task_mempool;
+
+ /* Local queue keeps thread alive by keeping small amount of tasks ready
+ * to be picked up without causing global thread locks for synchronization.
+ */
int num_local_queue;
- Task *local_queue[LOCALQUEUE_SIZE];
+ Task *local_queue[LOCAL_QUEUE_SIZE];
+
+ /* Thread can be marked for delayed tasks push. This is helpful when it's
+ * know that lots of subsequent task pushed will happen from the same thread
+ * without "interrupting" for task execution.
+ *
+ * We try to accumulate as much tasks as possible in a local queue without
+ * any locks first, and then we push all of them into a scheduler's queue
+ * from within a single mutex lock.
+ */
+ bool do_delayed_push;
+ int num_delayed_queue;
+ Task *delayed_queue[DELAYED_QUEUE_SIZE];
} TaskThreadLocalStorage;
struct TaskPool {
@@ -162,6 +188,16 @@ struct TaskPool {
*/
int thread_id;
+ /* For the pools which are created from non-main thread which is not a
+ * scheduler worker thread we can't re-use any of scheduler's threads TLS
+ * and have to use our own one.
+ */
+ bool use_local_tls;
+ TaskThreadLocalStorage local_tls;
+#ifndef NDEBUG
+ pthread_t creator_thread_id;
+#endif
+
#ifdef DEBUG_STATS
TaskMemPoolStats *mempool_stats;
#endif
@@ -202,13 +238,25 @@ BLI_INLINE void task_data_free(Task *task, const int thread_id)
}
}
+BLI_INLINE void initialize_task_tls(TaskThreadLocalStorage *tls)
+{
+ memset(tls, 0, sizeof(TaskThreadLocalStorage));
+}
+
BLI_INLINE TaskThreadLocalStorage *get_task_tls(TaskPool *pool,
const int thread_id)
{
TaskScheduler *scheduler = pool->scheduler;
BLI_assert(thread_id >= 0);
BLI_assert(thread_id <= scheduler->num_threads);
+ if (pool->use_local_tls && thread_id == 0) {
+ BLI_assert(pool->thread_id == 0);
+ BLI_assert(!BLI_thread_is_main());
+ BLI_assert(pthread_equal(pthread_self(), pool->creator_thread_id));
+ return &pool->local_tls;
+ }
if (thread_id == 0) {
+ BLI_assert(BLI_thread_is_main());
return &scheduler->task_threads[pool->thread_id].tls;
}
return &scheduler->task_threads[thread_id].tls;
@@ -252,6 +300,9 @@ static void task_free(TaskPool *pool, Task *task, const int thread_id)
task_data_free(task, thread_id);
BLI_assert(thread_id >= 0);
BLI_assert(thread_id <= pool->scheduler->num_threads);
+ if (thread_id == 0) {
+ BLI_assert(pool->use_local_tls || BLI_thread_is_main());
+ }
TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id);
TaskMemPool *task_mempool = &tls->task_mempool;
if (task_mempool->num_tasks < MEMPOOL_SIZE - 1) {
@@ -353,6 +404,7 @@ static bool task_scheduler_thread_wait_pop(TaskScheduler *scheduler, Task **task
BLI_INLINE void handle_local_queue(TaskThreadLocalStorage *tls,
const int thread_id)
{
+ BLI_assert(!tls->do_delayed_push);
while (tls->num_local_queue > 0) {
/* We pop task from queue before handling it so handler of the task can
* push next job to the local queue.
@@ -366,6 +418,7 @@ BLI_INLINE void handle_local_queue(TaskThreadLocalStorage *tls,
local_task->run(local_pool, local_task->taskdata, thread_id);
task_free(local_pool, local_task, thread_id);
}
+ BLI_assert(!tls->do_delayed_push);
}
static void *task_scheduler_thread_run(void *thread_p)
@@ -383,7 +436,9 @@ static void *task_scheduler_thread_run(void *thread_p)
TaskPool *pool = task->pool;
/* run task */
+ BLI_assert(!tls->do_delayed_push);
task->run(pool, task->taskdata, thread_id);
+ BLI_assert(!tls->do_delayed_push);
/* delete task */
task_free(pool, task, thread_id);
@@ -424,9 +479,12 @@ TaskScheduler *BLI_task_scheduler_create(int num_threads)
num_threads = 1;
}
- scheduler->task_threads = MEM_callocN(sizeof(TaskThread) * (num_threads + 1),
+ scheduler->task_threads = MEM_mallocN(sizeof(TaskThread) * (num_threads + 1),
"TaskScheduler task threads");
+ /* Initialize TLS for main thread. */
+ initialize_task_tls(&scheduler->task_threads[0].tls);
+
pthread_key_create(&scheduler->tls_id_key, NULL);
/* launch threads that will be waiting for work */
@@ -440,6 +498,7 @@ TaskScheduler *BLI_task_scheduler_create(int num_threads)
TaskThread *thread = &scheduler->task_threads[i + 1];
thread->scheduler = scheduler;
thread->id = i + 1;
+ initialize_task_tls(&thread->tls);
if (pthread_create(&scheduler->threads[i], NULL, task_scheduler_thread_run, thread) != 0) {
fprintf(stderr, "TaskScheduler failed to launch thread %d/%d\n", i, num_threads);
@@ -518,6 +577,27 @@ static void task_scheduler_push(TaskScheduler *scheduler, Task *task, TaskPriori
BLI_mutex_unlock(&scheduler->queue_mutex);
}
+static void task_scheduler_push_all(TaskScheduler *scheduler,
+ TaskPool *pool,
+ Task **tasks,
+ int num_tasks)
+{
+ if (num_tasks == 0) {
+ return;
+ }
+
+ task_pool_num_increase(pool, num_tasks);
+
+ BLI_mutex_lock(&scheduler->queue_mutex);
+
+ for (int i = 0; i < num_tasks; i++) {
+ BLI_addhead(&scheduler->queue, tasks[i]);
+ }
+
+ BLI_condition_notify_all(&scheduler->queue_cond);
+ BLI_mutex_unlock(&scheduler->queue_mutex);
+}
+
static void task_scheduler_clear(TaskScheduler *scheduler, TaskPool *pool)
{
Task *task, *nexttask;
@@ -572,6 +652,7 @@ static TaskPool *task_pool_create_ex(TaskScheduler *scheduler,
pool->num_suspended = 0;
pool->suspended_queue.first = pool->suspended_queue.last = NULL;
pool->run_in_background = is_background;
+ pool->use_local_tls = false;
BLI_mutex_init(&pool->num_mutex);
BLI_condition_init(&pool->num_cond);
@@ -584,13 +665,18 @@ static TaskPool *task_pool_create_ex(TaskScheduler *scheduler,
}
else {
TaskThread *thread = pthread_getspecific(scheduler->tls_id_key);
- /* NOTE: It is possible that pool is created from non-main thread
- * which isn't a scheduler thread. In this case pthread's TLS will
- * be NULL and we can safely consider thread id 0 for the main
- * thread of this pool (the one which does wort_and_wait()).
- */
if (thread == NULL) {
+ /* NOTE: Task pool is created from non-main thread which is not
+ * managed by the task scheduler. We identify ourselves as thread ID
+ * 0 but we do not use scheduler's TLS storage and use our own
+ * instead to avoid any possible threading conflicts.
+ */
pool->thread_id = 0;
+ pool->use_local_tls = true;
+#ifndef NDEBUG
+ pool->creator_thread_id = pthread_self();
+#endif
+ initialize_task_tls(&pool->local_tls);
}
else {
pool->thread_id = thread->id;
@@ -670,43 +756,68 @@ void BLI_task_pool_free(TaskPool *pool)
MEM_freeN(pool->mempool_stats);
#endif
+ if (pool->use_local_tls) {
+ free_task_tls(&pool->local_tls);
+ }
+
MEM_freeN(pool);
BLI_end_threaded_malloc();
}
+BLI_INLINE bool task_can_use_local_queues(TaskPool *pool, int thread_id)
+{
+ return (thread_id != -1 && (thread_id != pool->thread_id || pool->do_work));
+}
+
static void task_pool_push(
TaskPool *pool, TaskRunFunction run, void *taskdata,
bool free_taskdata, TaskFreeFunction freedata, TaskPriority priority,
int thread_id)
{
+ /* Allocate task and fill it's properties. */
Task *task = task_alloc(pool, thread_id);
-
task->run = run;
task->taskdata = taskdata;
task->free_taskdata = free_taskdata;
task->freedata = freedata;
task->pool = pool;
-
+ /* For suspended pools we put everything yo a global queue first
+ * and exit as soon as possible.
+ *
+ * This tasks will be moved to actual execution when pool is
+ * activated by work_and_wait().
+ */
if (pool->is_suspended) {
BLI_addhead(&pool->suspended_queue, task);
atomic_fetch_and_add_z(&pool->num_suspended, 1);
return;
}
-
- if (thread_id != -1 &&
- (thread_id != pool->thread_id || pool->do_work))
- {
+ /* Populate to any local queue first, this is cheapest push ever. */
+ if (task_can_use_local_queues(pool, thread_id)) {
ASSERT_THREAD_ID(pool->scheduler, thread_id);
-
TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id);
- if (tls->num_local_queue < LOCALQUEUE_SIZE) {
+ /* Try to push to a local execution queue.
+ * These tasks will be picked up next.
+ */
+ if (tls->num_local_queue < LOCAL_QUEUE_SIZE) {
tls->local_queue[tls->num_local_queue] = task;
tls->num_local_queue++;
return;
}
+ /* If we are in the delayed tasks push mode, we push tasks to a
+ * temporary local queue first without any locks, and then move them
+ * to global execution queue with a single lock.
+ */
+ if (tls->do_delayed_push && tls->num_delayed_queue < DELAYED_QUEUE_SIZE) {
+ tls->delayed_queue[tls->num_delayed_queue] = task;
+ tls->num_delayed_queue++;
+ return;
+ }
}
-
+ /* Do push to a global execution ppol, slowest possible method,
+ * causes quite reasonable amount of threading overhead.
+ */
task_scheduler_push(pool->scheduler, task, priority);
}
@@ -777,7 +888,9 @@ void BLI_task_pool_work_and_wait(TaskPool *pool)
/* if found task, do it, otherwise wait until other tasks are done */
if (found_task) {
/* run task */
+ BLI_assert(!tls->do_delayed_push);
work_task->run(pool, work_task->taskdata, pool->thread_id);
+ BLI_assert(!tls->do_delayed_push);
/* delete task */
task_free(pool, task, pool->thread_id);
@@ -832,6 +945,30 @@ ThreadMutex *BLI_task_pool_user_mutex(TaskPool *pool)
return &pool->user_mutex;
}
+void BLI_task_pool_delayed_push_begin(TaskPool *pool, int thread_id)
+{
+ if (task_can_use_local_queues(pool, thread_id)) {
+ ASSERT_THREAD_ID(pool->scheduler, thread_id);
+ TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id);
+ tls->do_delayed_push = true;
+ }
+}
+
+void BLI_task_pool_delayed_push_end(TaskPool *pool, int thread_id)
+{
+ if (task_can_use_local_queues(pool, thread_id)) {
+ ASSERT_THREAD_ID(pool->scheduler, thread_id);
+ TaskThreadLocalStorage *tls = get_task_tls(pool, thread_id);
+ BLI_assert(tls->do_delayed_push);
+ task_scheduler_push_all(pool->scheduler,
+ pool,
+ tls->delayed_queue,
+ tls->num_delayed_queue);
+ tls->do_delayed_push = false;
+ tls->num_delayed_queue = 0;
+ }
+}
+
/* Parallel range routines */
/**
@@ -990,7 +1127,7 @@ static void task_parallel_range_ex(
atomic_fetch_and_add_uint32((uint32_t *)(&state.iter), 0);
if (use_userdata_chunk) {
- userdata_chunk_array = MALLOCA(userdata_chunk_size * num_tasks);
+ userdata_chunk_array = MALLOCA(userdata_chunk_size * num_tasks);
}
for (i = 0; i < num_tasks; i++) {
diff --git a/source/blender/blenlib/intern/threads.c b/source/blender/blenlib/intern/threads.c
index 77da3be0600..abf611d1245 100644
--- a/source/blender/blenlib/intern/threads.c
+++ b/source/blender/blenlib/intern/threads.c
@@ -813,6 +813,11 @@ void BLI_begin_threaded_malloc(void)
unsigned int level = atomic_fetch_and_add_u(&thread_levels, 1);
if (level == 0) {
MEM_set_lock_callback(BLI_lock_malloc_thread, BLI_unlock_malloc_thread);
+ /* There is a little chance that two threads will meed to acces to a
+ * scheduler which was not yet created from main thread. which could
+ * cause scheduler created multiple times.
+ */
+ BLI_task_scheduler_get();
}
}
diff --git a/source/blender/blenlib/intern/winstuff.c b/source/blender/blenlib/intern/winstuff.c
index 3b06b7df09a..d6834428376 100644
--- a/source/blender/blenlib/intern/winstuff.c
+++ b/source/blender/blenlib/intern/winstuff.c
@@ -160,8 +160,6 @@ void RegisterBlendExtension(void)
GetSystemDirectory(SysDir, FILE_MAXDIR);
#ifdef _WIN64
ThumbHandlerDLL = "BlendThumb64.dll";
-#elif defined(__MINGW32__)
- ThumbHandlerDLL = "BlendThumb.dll";
#else
IsWow64Process(GetCurrentProcess(), &IsWOW64);
if (IsWOW64 == true)
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c
index 09c88ac945a..f224f0b5633 100644
--- a/source/blender/blenloader/intern/readfile.c
+++ b/source/blender/blenloader/intern/readfile.c
@@ -129,6 +129,7 @@
#include "BKE_library_idmap.h"
#include "BKE_library_query.h"
#include "BKE_idcode.h"
+#include "BKE_idprop.h"
#include "BKE_material.h"
#include "BKE_main.h" // for Main
#include "BKE_mesh.h" // for ME_ defines (patching)
@@ -2001,7 +2002,7 @@ static void test_pointer_array(FileData *fd, void **mat)
/* ************ READ ID Properties *************** */
static void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData *fd);
-static void IDP_LibLinkProperty(IDProperty *prop, int switch_endian, FileData *fd);
+static void IDP_LibLinkProperty(IDProperty *prop, FileData *fd);
static void IDP_DirectLinkIDPArray(IDProperty *prop, int switch_endian, FileData *fd)
{
@@ -2106,8 +2107,19 @@ static void IDP_DirectLinkProperty(IDProperty *prop, int switch_endian, FileData
BLI_endian_switch_int32(&prop->data.val2);
BLI_endian_switch_int64((int64_t *)&prop->data.val);
}
-
break;
+ case IDP_INT:
+ case IDP_FLOAT:
+ case IDP_ID:
+ break; /* Nothing special to do here. */
+ default:
+ /* Unknown IDP type, nuke it (we cannot handle unknown types everywhere in code,
+ * IDP are way too polymorphic to do it safely. */
+ printf("%s: found unknown IDProperty type %d, reset to Integer one !\n", __func__, prop->type);
+ /* Note: we do not attempt to free unknown prop, we have no way to know how to do that! */
+ prop->type = IDP_INT;
+ prop->subtype = 0;
+ IDP_Int(prop) = 0;
}
}
@@ -2132,10 +2144,39 @@ static void _IDP_DirectLinkGroup_OrFree(IDProperty **prop, int switch_endian, Fi
}
}
-/* stub function */
-static void IDP_LibLinkProperty(IDProperty *UNUSED(prop), int UNUSED(switch_endian), FileData *UNUSED(fd))
+static void IDP_LibLinkProperty(IDProperty *prop, FileData *fd)
{
- /* Should we do something here, prop should be ensured to be non-NULL first... */
+ if (!prop)
+ return;
+
+ switch (prop->type) {
+ case IDP_ID: /* PointerProperty */
+ {
+ void *newaddr = newlibadr_us(fd, NULL, IDP_Id(prop));
+ if (IDP_Id(prop) && !newaddr && G.debug) {
+ printf("Error while loading \"%s\". Data not found in file!\n", prop->name);
+ }
+ prop->data.pointer = newaddr;
+ break;
+ }
+ case IDP_IDPARRAY: /* CollectionProperty */
+ {
+ IDProperty *idp_array = IDP_IDPArray(prop);
+ for (int i = 0; i < prop->len; i++) {
+ IDP_LibLinkProperty(&(idp_array[i]), fd);
+ }
+ break;
+ }
+ case IDP_GROUP: /* PointerProperty */
+ {
+ for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) {
+ IDP_LibLinkProperty(loop, fd);
+ }
+ break;
+ }
+ default:
+ break; /* Nothing to do for other IDProps. */
+ }
}
/* ************ READ IMAGE PREVIEW *************** */
@@ -2195,7 +2236,7 @@ static void lib_link_brush(FileData *fd, Main *main)
/* only link ID pointers */
for (Brush *brush = main->brush.first; brush; brush = brush->id.next) {
if (brush->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(brush->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(brush->id.properties, fd);
/* brush->(mask_)mtex.obj is ignored on purpose? */
brush->mtex.tex = newlibadr_us(fd, brush->id.lib, brush->mtex.tex);
@@ -2232,7 +2273,7 @@ static void lib_link_palette(FileData *fd, Main *main)
/* only link ID pointers */
for (Palette *palette = main->palettes.first; palette; palette = palette->id.next) {
if (palette->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(palette->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(palette->id.properties, fd);
palette->id.tag &= ~LIB_TAG_NEED_LINK;
}
@@ -2250,7 +2291,7 @@ static void lib_link_paint_curve(FileData *fd, Main *main)
/* only link ID pointers */
for (PaintCurve *pc = main->paintcurves.first; pc; pc = pc->id.next) {
if (pc->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(pc->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(pc->id.properties, fd);
pc->id.tag &= ~LIB_TAG_NEED_LINK;
}
@@ -2505,7 +2546,7 @@ static void lib_link_action(FileData *fd, Main *main)
{
for (bAction *act = main->action.first; act; act = act->id.next) {
if (act->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(act->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(act->id.properties, fd);
// XXX deprecated - old animation system <<<
for (bActionChannel *chan = act->chanbase.first; chan; chan = chan->next) {
@@ -2712,7 +2753,7 @@ static void lib_link_cachefiles(FileData *fd, Main *bmain)
/* only link ID pointers */
for (CacheFile *cache_file = bmain->cachefiles.first; cache_file; cache_file = cache_file->id.next) {
if (cache_file->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(cache_file->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(cache_file->id.properties, fd);
lib_link_animdata(fd, &cache_file->id, cache_file->adt);
cache_file->id.tag &= ~LIB_TAG_NEED_LINK;
@@ -2746,20 +2787,13 @@ static void direct_link_motionpath(FileData *fd, bMotionPath *mpath)
/* ************ READ NODE TREE *************** */
-static void lib_link_node_socket(FileData *fd, ID *UNUSED(id), bNodeSocket *sock)
-{
- /* Link ID Properties -- and copy this comment EXACTLY for easy finding
- * of library blocks that implement this.*/
- IDP_LibLinkProperty(sock->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
-}
-
/* Single node tree (also used for material/scene trees), ntree is not NULL */
static void lib_link_ntree(FileData *fd, ID *id, bNodeTree *ntree)
{
bNode *node;
bNodeSocket *sock;
- IDP_LibLinkProperty(ntree->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(ntree->id.properties, fd);
lib_link_animdata(fd, &ntree->id, ntree->adt);
ntree->gpd = newlibadr_us(fd, id->lib, ntree->gpd);
@@ -2767,27 +2801,23 @@ static void lib_link_ntree(FileData *fd, ID *id, bNodeTree *ntree)
for (node = ntree->nodes.first; node; node = node->next) {
/* Link ID Properties -- and copy this comment EXACTLY for easy finding
* of library blocks that implement this.*/
- IDP_LibLinkProperty(node->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(node->prop, fd);
node->id = newlibadr_us(fd, id->lib, node->id);
for (sock = node->inputs.first; sock; sock = sock->next) {
- IDP_LibLinkProperty(sock->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
- lib_link_node_socket(fd, id, sock);
+ IDP_LibLinkProperty(sock->prop, fd);
}
for (sock = node->outputs.first; sock; sock = sock->next) {
- IDP_LibLinkProperty(sock->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
- lib_link_node_socket(fd, id, sock);
+ IDP_LibLinkProperty(sock->prop, fd);
}
}
for (sock = ntree->inputs.first; sock; sock = sock->next) {
- IDP_LibLinkProperty(sock->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
- lib_link_node_socket(fd, id, sock);
+ IDP_LibLinkProperty(sock->prop, fd);
}
for (sock = ntree->outputs.first; sock; sock = sock->next) {
- IDP_LibLinkProperty(sock->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
- lib_link_node_socket(fd, id, sock);
+ IDP_LibLinkProperty(sock->prop, fd);
}
}
@@ -3090,7 +3120,7 @@ static void direct_link_nodetree(FileData *fd, bNodeTree *ntree)
else if (ntree->type==NTREE_COMPOSIT) {
if (ELEM(node->type, CMP_NODE_TIME, CMP_NODE_CURVE_VEC, CMP_NODE_CURVE_RGB, CMP_NODE_HUECORRECT))
direct_link_curvemapping(fd, node->storage);
- else if (ELEM(node->type, CMP_NODE_IMAGE, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
+ else if (ELEM(node->type, CMP_NODE_IMAGE, CMP_NODE_R_LAYERS, CMP_NODE_VIEWER, CMP_NODE_SPLITVIEWER))
((ImageUser *)node->storage)->ok = 1;
}
else if ( ntree->type==NTREE_TEXTURE) {
@@ -3292,6 +3322,8 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
pchan->bone = BLI_ghash_lookup(bone_hash, pchan->name);
+ IDP_LibLinkProperty(pchan->prop, fd);
+
pchan->custom = newlibadr_us(fd, arm->id.lib, pchan->custom);
if (UNLIKELY(pchan->bone == NULL)) {
rebuild = true;
@@ -3312,13 +3344,26 @@ static void lib_link_pose(FileData *fd, Main *bmain, Object *ob, bPose *pose)
}
}
+static void lib_link_bones(FileData *fd, Bone *bone)
+{
+ IDP_LibLinkProperty(bone->prop, fd);
+
+ for (Bone *curbone = bone->childbase.first; curbone; curbone = curbone->next) {
+ lib_link_bones(fd, curbone);
+ }
+}
+
static void lib_link_armature(FileData *fd, Main *main)
{
for (bArmature *arm = main->armature.first; arm; arm = arm->id.next) {
if (arm->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(arm->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(arm->id.properties, fd);
lib_link_animdata(fd, &arm->id, arm->adt);
+ for (Bone *curbone = arm->bonebase.first; curbone; curbone = curbone->next) {
+ lib_link_bones(fd, curbone);
+ }
+
arm->id.tag &= ~LIB_TAG_NEED_LINK;
}
}
@@ -3365,7 +3410,7 @@ static void lib_link_camera(FileData *fd, Main *main)
{
for (Camera *ca = main->camera.first; ca; ca = ca->id.next) {
if (ca->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(ca->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(ca->id.properties, fd);
lib_link_animdata(fd, &ca->id, ca->adt);
ca->ipo = newlibadr_us(fd, ca->id.lib, ca->ipo); // XXX deprecated - old animation system
@@ -3390,7 +3435,7 @@ static void lib_link_lamp(FileData *fd, Main *main)
{
for (Lamp *la = main->lamp.first; la; la = la->id.next) {
if (la->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(la->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(la->id.properties, fd);
lib_link_animdata(fd, &la->id, la->adt);
for (int a = 0; a < MAX_MTEX; a++) {
@@ -3455,7 +3500,7 @@ static void lib_link_key(FileData *fd, Main *main)
BLI_assert((key->id.tag & LIB_TAG_EXTERN) == 0);
if (key->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(key->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(key->id.properties, fd);
lib_link_animdata(fd, &key->id, key->adt);
key->ipo = newlibadr_us(fd, key->id.lib, key->ipo); // XXX deprecated - old animation system
@@ -3520,7 +3565,7 @@ static void lib_link_mball(FileData *fd, Main *main)
{
for (MetaBall *mb = main->mball.first; mb; mb = mb->id.next) {
if (mb->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(mb->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(mb->id.properties, fd);
lib_link_animdata(fd, &mb->id, mb->adt);
for (int a = 0; a < mb->totcol; a++) {
@@ -3556,7 +3601,7 @@ static void lib_link_world(FileData *fd, Main *main)
{
for (World *wrld = main->world.first; wrld; wrld = wrld->id.next) {
if (wrld->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(wrld->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(wrld->id.properties, fd);
lib_link_animdata(fd, &wrld->id, wrld->adt);
wrld->ipo = newlibadr_us(fd, wrld->id.lib, wrld->ipo); // XXX deprecated - old animation system
@@ -3607,7 +3652,7 @@ static void lib_link_vfont(FileData *fd, Main *main)
{
for (VFont *vf = main->vfont.first; vf; vf = vf->id.next) {
if (vf->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(vf->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(vf->id.properties, fd);
vf->id.tag &= ~LIB_TAG_NEED_LINK;
}
@@ -3627,7 +3672,7 @@ static void lib_link_text(FileData *fd, Main *main)
{
for (Text *text = main->text.first; text; text = text->id.next) {
if (text->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(text->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(text->id.properties, fd);
text->id.tag &= ~LIB_TAG_NEED_LINK;
}
@@ -3679,7 +3724,7 @@ static void lib_link_image(FileData *fd, Main *main)
{
for (Image *ima = main->image.first; ima; ima = ima->id.next) {
if (ima->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(ima->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(ima->id.properties, fd);
ima->id.tag &= ~LIB_TAG_NEED_LINK;
}
@@ -3746,7 +3791,7 @@ static void lib_link_curve(FileData *fd, Main *main)
{
for (Curve *cu = main->curve.first; cu; cu = cu->id.next) {
if (cu->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(cu->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(cu->id.properties, fd);
lib_link_animdata(fd, &cu->id, cu->adt);
for (int a = 0; a < cu->totcol; a++) {
@@ -3838,7 +3883,7 @@ static void lib_link_texture(FileData *fd, Main *main)
{
for (Tex *tex = main->tex.first; tex; tex = tex->id.next) {
if (tex->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(tex->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(tex->id.properties, fd);
lib_link_animdata(fd, &tex->id, tex->adt);
tex->ima = newlibadr_us(fd, tex->id.lib, tex->ima);
@@ -3916,12 +3961,12 @@ static void lib_link_material(FileData *fd, Main *main)
{
for (Material *ma = main->mat.first; ma; ma = ma->id.next) {
if (ma->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(ma->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(ma->id.properties, fd);
lib_link_animdata(fd, &ma->id, ma->adt);
/* Link ID Properties -- and copy this comment EXACTLY for easy finding
* of library blocks that implement this.*/
- IDP_LibLinkProperty(ma->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(ma->id.properties, fd);
ma->ipo = newlibadr_us(fd, ma->id.lib, ma->ipo); // XXX deprecated - old animation system
ma->group = newlibadr_us(fd, ma->id.lib, ma->group);
@@ -4060,7 +4105,7 @@ static void lib_link_particlesettings(FileData *fd, Main *main)
{
for (ParticleSettings *part = main->particle.first; part; part = part->id.next) {
if (part->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(part->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(part->id.properties, fd);
lib_link_animdata(fd, &part->id, part->adt);
part->ipo = newlibadr_us(fd, part->id.lib, part->ipo); // XXX deprecated - old animation system
@@ -4382,7 +4427,7 @@ static void lib_link_mesh(FileData *fd, Main *main)
/* Link ID Properties -- and copy this comment EXACTLY for easy finding
* of library blocks that implement this.*/
- IDP_LibLinkProperty(me->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(me->id.properties, fd);
lib_link_animdata(fd, &me->id, me->adt);
/* this check added for python created meshes */
@@ -4657,7 +4702,7 @@ static void lib_link_latt(FileData *fd, Main *main)
{
for (Lattice *lt = main->latt.first; lt; lt = lt->id.next) {
if (lt->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(lt->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(lt->id.properties, fd);
lib_link_animdata(fd, &lt->id, lt->adt);
lt->ipo = newlibadr_us(fd, lt->id.lib, lt->ipo); // XXX deprecated - old animation system
@@ -4707,7 +4752,7 @@ static void lib_link_object(FileData *fd, Main *main)
if (ob->id.tag & LIB_TAG_NEED_LINK) {
int a;
- IDP_LibLinkProperty(ob->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(ob->id.properties, fd);
lib_link_animdata(fd, &ob->id, ob->adt);
// XXX deprecated - old animation system <<<
@@ -5675,7 +5720,7 @@ static void lib_link_scene(FileData *fd, Main *main)
if (sce->id.tag & LIB_TAG_NEED_LINK) {
/* Link ID Properties -- and copy this comment EXACTLY for easy finding
* of library blocks that implement this.*/
- IDP_LibLinkProperty(sce->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(sce->id.properties, fd);
lib_link_animdata(fd, &sce->id, sce->adt);
lib_link_keyingsets(fd, &sce->id, &sce->keyingsets);
@@ -5728,6 +5773,8 @@ static void lib_link_scene(FileData *fd, Main *main)
Sequence *seq;
SEQ_BEGIN (sce->ed, seq)
{
+ IDP_LibLinkProperty(seq->prop, fd);
+
if (seq->ipo) seq->ipo = newlibadr_us(fd, sce->id.lib, seq->ipo); // XXX deprecated - old animation system
seq->scene_sound = NULL;
if (seq->scene) {
@@ -6049,9 +6096,13 @@ static void direct_link_scene(FileData *fd, Scene *sce)
seq->strip->transform = NULL;
}
if (seq->flag & SEQ_USE_PROXY) {
- seq->strip->proxy = newdataadr(
- fd, seq->strip->proxy);
- seq->strip->proxy->anim = NULL;
+ seq->strip->proxy = newdataadr(fd, seq->strip->proxy);
+ if (seq->strip->proxy) {
+ seq->strip->proxy->anim = NULL;
+ }
+ else {
+ BKE_sequencer_proxy_set(seq, true);
+ }
}
else {
seq->strip->proxy = NULL;
@@ -6126,6 +6177,11 @@ static void direct_link_scene(FileData *fd, Scene *sce)
link_list(fd, &(sce->r.layers));
link_list(fd, &(sce->r.views));
+
+ for (srl = sce->r.layers.first; srl; srl = srl->next) {
+ srl->prop = newdataadr(fd, srl->prop);
+ IDP_DirectLinkGroup_OrFree(&srl->prop, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ }
for (srl = sce->r.layers.first; srl; srl = srl->next) {
link_list(fd, &(srl->freestyleConfig.modules));
}
@@ -6258,7 +6314,7 @@ static void lib_link_gpencil(FileData *fd, Main *main)
{
for (bGPdata *gpd = main->gpencil.first; gpd; gpd = gpd->id.next) {
if (gpd->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(gpd->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(gpd->id.properties, fd);
lib_link_animdata(fd, &gpd->id, gpd->adt);
gpd->id.tag &= ~LIB_TAG_NEED_LINK;
@@ -6325,7 +6381,7 @@ static void lib_link_screen(FileData *fd, Main *main)
{
for (bScreen *sc = main->screen.first; sc; sc = sc->id.next) {
if (sc->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(sc->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(sc->id.properties, fd);
id_us_ensure_real(&sc->id);
sc->scene = newlibadr(fd, sc->id.lib, sc->scene);
@@ -7411,7 +7467,7 @@ static void lib_link_speaker(FileData *fd, Main *main)
{
for (Speaker *spk = main->speaker.first; spk; spk = spk->id.next) {
if (spk->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(spk->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(spk->id.properties, fd);
lib_link_animdata(fd, &spk->id, spk->adt);
spk->sound = newlibadr_us(fd, spk->id.lib, spk->sound);
@@ -7467,7 +7523,7 @@ static void lib_link_sound(FileData *fd, Main *main)
{
for (bSound *sound = main->sound.first; sound; sound = sound->id.next) {
if (sound->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(sound->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(sound->id.properties, fd);
sound->ipo = newlibadr_us(fd, sound->id.lib, sound->ipo); // XXX deprecated - old animation system
@@ -7490,7 +7546,7 @@ static void lib_link_group(FileData *fd, Main *main)
{
for (Group *group = main->group.first; group; group = group->id.next) {
if (group->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(group->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(group->id.properties, fd);
bool add_us = false;
@@ -7616,7 +7672,7 @@ static void lib_link_movieclip(FileData *fd, Main *main)
if (clip->id.tag & LIB_TAG_NEED_LINK) {
MovieTracking *tracking = &clip->tracking;
- IDP_LibLinkProperty(clip->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(clip->id.properties, fd);
lib_link_animdata(fd, &clip->id, clip->adt);
clip->gpd = newlibadr_us(fd, clip->id.lib, clip->gpd);
@@ -7703,7 +7759,7 @@ static void lib_link_mask(FileData *fd, Main *main)
{
for (Mask *mask = main->mask.first; mask; mask = mask->id.next) {
if (mask->id.tag & LIB_TAG_NEED_LINK) {
- IDP_LibLinkProperty(mask->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(mask->id.properties, fd);
lib_link_animdata(fd, &mask->id, mask->adt);
for (MaskLayer *masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
@@ -7738,7 +7794,7 @@ static void lib_link_linestyle(FileData *fd, Main *main)
if (linestyle->id.tag & LIB_TAG_NEED_LINK) {
LineStyleModifier *m;
- IDP_LibLinkProperty(linestyle->id.properties, (fd->flags & FD_FLAGS_SWITCH_ENDIAN), fd);
+ IDP_LibLinkProperty(linestyle->id.properties, fd);
lib_link_animdata(fd, &linestyle->id, linestyle->adt);
for (m = linestyle->color_modifiers.first; m; m = m->next) {
@@ -8633,7 +8689,8 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath)
/* in 2.50+ files, the file identifier for screens is patched, forward compatibility */
case ID_SCRN:
bhead->code = ID_SCR;
- /* deliberate pass on to default */
+ /* pass on to default */
+ ATTR_FALLTHROUGH;
default:
if (fd->skip_flags & BLO_READ_SKIP_DATA) {
bhead = blo_nextbhead(fd, bhead);
@@ -8905,6 +8962,31 @@ static void expand_constraint_channels(FileData *fd, Main *mainvar, ListBase *ch
}
}
+static void expand_idprops(FileData *fd, Main *mainvar, IDProperty *prop)
+{
+ if (!prop)
+ return;
+
+ switch (prop->type) {
+ case IDP_ID:
+ expand_doit(fd, mainvar, IDP_Id(prop));
+ break;
+ case IDP_IDPARRAY:
+ {
+ IDProperty *idp_array = IDP_IDPArray(prop);
+ for (int i = 0; i < prop->len; i++) {
+ expand_idprops(fd, mainvar, &idp_array[i]);
+ }
+ break;
+ }
+ case IDP_GROUP:
+ for (IDProperty *loop = prop->data.group.first; loop; loop = loop->next) {
+ expand_idprops(fd, mainvar, loop);
+ }
+ break;
+ }
+}
+
static void expand_fmodifiers(FileData *fd, Main *mainvar, ListBase *list)
{
FModifier *fcm;
@@ -9090,6 +9172,7 @@ static void expand_key(FileData *fd, Main *mainvar, Key *key)
static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree)
{
bNode *node;
+ bNodeSocket *sock;
if (ntree->adt)
expand_animdata(fd, mainvar, ntree->adt);
@@ -9098,10 +9181,22 @@ static void expand_nodetree(FileData *fd, Main *mainvar, bNodeTree *ntree)
expand_doit(fd, mainvar, ntree->gpd);
for (node = ntree->nodes.first; node; node = node->next) {
- if (node->id && node->type != CMP_NODE_R_LAYERS)
+ if (node->id && node->type != CMP_NODE_R_LAYERS) {
expand_doit(fd, mainvar, node->id);
+ }
+
+ expand_idprops(fd, mainvar, node->prop);
+
+ for (sock = node->inputs.first; sock; sock = sock->next)
+ expand_doit(fd, mainvar, sock->prop);
+ for (sock = node->outputs.first; sock; sock = sock->next)
+ expand_doit(fd, mainvar, sock->prop);
}
+ for (sock = ntree->inputs.first; sock; sock = sock->next)
+ expand_doit(fd, mainvar, sock->prop);
+ for (sock = ntree->outputs.first; sock; sock = sock->next)
+ expand_doit(fd, mainvar, sock->prop);
}
static void expand_texture(FileData *fd, Main *mainvar, Tex *tex)
@@ -9319,17 +9414,6 @@ static void expand_constraints(FileData *fd, Main *mainvar, ListBase *lb)
}
}
-#if 0 /* Disabled as it doesn't actually do anything except recurse... */
-static void expand_bones(FileData *fd, Main *mainvar, Bone *bone)
-{
- Bone *curBone;
-
- for (curBone = bone->childbase.first; curBone; curBone=curBone->next) {
- expand_bones(fd, mainvar, curBone);
- }
-}
-#endif
-
static void expand_pose(FileData *fd, Main *mainvar, bPose *pose)
{
bPoseChannel *chan;
@@ -9339,24 +9423,28 @@ static void expand_pose(FileData *fd, Main *mainvar, bPose *pose)
for (chan = pose->chanbase.first; chan; chan = chan->next) {
expand_constraints(fd, mainvar, &chan->constraints);
+ expand_idprops(fd, mainvar, chan->prop);
expand_doit(fd, mainvar, chan->custom);
}
}
+static void expand_bones(FileData *fd, Main *mainvar, Bone *bone)
+{
+ expand_idprops(fd, mainvar, bone->prop);
+
+ for (Bone *curBone = bone->childbase.first; curBone; curBone = curBone->next) {
+ expand_bones(fd, mainvar, curBone);
+ }
+}
+
static void expand_armature(FileData *fd, Main *mainvar, bArmature *arm)
-{
+{
if (arm->adt)
expand_animdata(fd, mainvar, arm->adt);
-
-#if 0 /* Disabled as this currently only recurses down the chain doing nothing */
- {
- Bone *curBone;
-
- for (curBone = arm->bonebase.first; curBone; curBone=curBone->next) {
- expand_bones(fd, mainvar, curBone);
- }
+
+ for (Bone *curBone = arm->bonebase.first; curBone; curBone = curBone->next) {
+ expand_bones(fd, mainvar, curBone);
}
-#endif
}
static void expand_object_expandModifiers(
@@ -9584,6 +9672,8 @@ static void expand_scene(FileData *fd, Main *mainvar, Scene *sce)
SEQ_BEGIN (sce->ed, seq)
{
+ expand_idprops(fd, mainvar, seq->prop);
+
if (seq->scene) expand_doit(fd, mainvar, seq->scene);
if (seq->scene_camera) expand_doit(fd, mainvar, seq->scene_camera);
if (seq->clip) expand_doit(fd, mainvar, seq->clip);
@@ -9741,6 +9831,8 @@ void BLO_expand_main(void *fdhandle, Main *mainvar)
id = lbarray[a]->first;
while (id) {
if (id->tag & LIB_TAG_NEED_EXPAND) {
+ expand_idprops(fd, mainvar, id->properties);
+
switch (GS(id->name)) {
case ID_OB:
expand_object(fd, mainvar, (Object *)id);
@@ -10067,7 +10159,7 @@ void BLO_library_link_copypaste(Main *mainl, BlendHandle *bh)
static ID *link_named_part_ex(
Main *mainl, FileData *fd, const short idcode, const char *name, const short flag,
- Scene *scene, View3D *v3d, const bool use_placeholders, const bool force_indirect)
+ Scene *scene, View3D *v3d, const bool use_placeholders, const bool force_indirect)
{
ID *id = link_named_part(mainl, fd, idcode, name, use_placeholders, force_indirect);
diff --git a/source/blender/blenloader/intern/versioning_260.c b/source/blender/blenloader/intern/versioning_260.c
index ab3d14af882..77542d8deb9 100644
--- a/source/blender/blenloader/intern/versioning_260.c
+++ b/source/blender/blenloader/intern/versioning_260.c
@@ -1000,7 +1000,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
{
/* convert extended ascii to utf-8 for text editor */
Text *text;
- for (text = main->text.first; text; text = text->id.next)
+ for (text = main->text.first; text; text = text->id.next) {
if (!(text->flags & TXT_ISEXT)) {
TextLine *tl;
@@ -1013,6 +1013,7 @@ void blo_do_versions_260(FileData *fd, Library *UNUSED(lib), Main *main)
text->curc = 0;
}
}
+ }
}
{
/* set new dynamic paint values */
diff --git a/source/blender/blenloader/intern/versioning_270.c b/source/blender/blenloader/intern/versioning_270.c
index d3f33cf725f..94d335870ca 100644
--- a/source/blender/blenloader/intern/versioning_270.c
+++ b/source/blender/blenloader/intern/versioning_270.c
@@ -80,6 +80,7 @@
#include "NOD_common.h"
#include "NOD_socket.h"
+#include "NOD_composite.h"
#include "readfile.h"
@@ -248,6 +249,41 @@ static void do_version_hue_sat_node(bNodeTree *ntree, bNode *node)
node->storage = NULL;
}
+static void do_versions_compositor_render_passes_storage(bNode *node)
+{
+ int pass_index = 0;
+ const char *sockname;
+ for (bNodeSocket *sock = node->outputs.first; sock && pass_index < 31; sock = sock->next, pass_index++) {
+ if (sock->storage == NULL) {
+ NodeImageLayer *sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer");
+ sock->storage = sockdata;
+ BLI_strncpy(sockdata->pass_name, node_cmp_rlayers_sock_to_pass(pass_index), sizeof(sockdata->pass_name));
+
+ if (pass_index == 0) sockname = "Image";
+ else if (pass_index == 1) sockname = "Alpha";
+ else sockname = node_cmp_rlayers_sock_to_pass(pass_index);
+ BLI_strncpy(sock->name, sockname, sizeof(sock->name));
+ }
+ }
+}
+
+static void do_versions_compositor_render_passes(bNodeTree *ntree)
+{
+ for (bNode *node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == CMP_NODE_R_LAYERS) {
+ /* First we make sure existing sockets have proper names.
+ * This is important because otherwise verification will
+ * drop links from sockets which were renamed.
+ */
+ do_versions_compositor_render_passes_storage(node);
+ /* Make sure new sockets are properly created. */
+ node_verify_socket_templates(ntree, node);
+ /* Make sure all possibly created sockets have proper storage. */
+ do_versions_compositor_render_passes_storage(node);
+ }
+ }
+}
+
void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
{
if (!MAIN_VERSION_ATLEAST(main, 270, 0)) {
@@ -1200,12 +1236,19 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
SEQ_BEGIN (scene->ed, seq)
{
- if (seq->type == SEQ_TYPE_TEXT) {
- TextVars *data = seq->effectdata;
- if (data->color[3] == 0.0f) {
- copy_v4_fl(data->color, 1.0f);
- data->shadow_color[3] = 1.0f;
- }
+ if (seq->type != SEQ_TYPE_TEXT) {
+ continue;
+ }
+
+ if (seq->effectdata == NULL) {
+ struct SeqEffectHandle effect_handle = BKE_sequence_get_effect(seq);
+ effect_handle.init(seq);
+ }
+
+ TextVars *data = seq->effectdata;
+ if (data->color[3] == 0.0f) {
+ copy_v4_fl(data->color, 1.0f);
+ data->shadow_color[3] = 1.0f;
}
}
SEQ_END
@@ -1259,7 +1302,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
for (Camera *camera = main->camera.first; camera != NULL; camera = camera->id.next) {
if (camera->stereo.pole_merge_angle_from == 0.0f &&
- camera->stereo.pole_merge_angle_to == 0.0f)
+ camera->stereo.pole_merge_angle_to == 0.0f)
{
camera->stereo.pole_merge_angle_from = DEG2RADF(60.0f);
camera->stereo.pole_merge_angle_to = DEG2RADF(75.0f);
@@ -1559,8 +1602,7 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
- /* To be added to next subversion bump! */
- {
+ if (!MAIN_VERSION_ATLEAST(main, 278, 5)) {
/* Mask primitive adding code was not initializing correctly id_type of its points' parent. */
for (Mask *mask = main->mask.first; mask; mask = mask->id.next) {
for (MaskLayer *mlayer = mask->masklayers.first; mlayer; mlayer = mlayer->next) {
@@ -1609,6 +1651,25 @@ void blo_do_versions_270(FileData *fd, Library *UNUSED(lib), Main *main)
}
}
}
+
+ FOREACH_NODETREE(main, ntree, id) {
+ if (ntree->type == NTREE_COMPOSIT) {
+ do_versions_compositor_render_passes(ntree);
+ }
+ } FOREACH_NODETREE_END
+ }
+
+ {
+ for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
+ if (scene->r.im_format.exr_codec == R_IMF_EXR_CODEC_DWAB) {
+ scene->r.im_format.exr_codec = R_IMF_EXR_CODEC_DWAA;
+ }
+ }
+
+ /* Fix related to VGroup modifiers creating named defgroup CD layers! See T51520. */
+ for (Mesh *me = main->mesh.first; me; me = me->id.next) {
+ CustomData_set_layer_name(&me->vdata, CD_MDEFORMVERT, 0, "");
+ }
}
}
diff --git a/source/blender/blenloader/intern/versioning_defaults.c b/source/blender/blenloader/intern/versioning_defaults.c
index e34f12b1cf9..e7e0054e7a1 100644
--- a/source/blender/blenloader/intern/versioning_defaults.c
+++ b/source/blender/blenloader/intern/versioning_defaults.c
@@ -242,13 +242,13 @@ void BLO_update_defaults_startup_blend(Main *bmain)
/* remove polish brush (flatten/contrast does the same) */
br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Polish");
if (br) {
- BKE_libblock_free(bmain, br);
+ BKE_libblock_delete(bmain, br);
}
/* remove brush brush (huh?) from some modes (draw brushes do the same) */
br = (Brush *)BKE_libblock_find_name_ex(bmain, ID_BR, "Brush");
if (br) {
- BKE_libblock_free(bmain, br);
+ BKE_libblock_delete(bmain, br);
}
/* remove draw brush from texpaint (draw brushes do the same) */
diff --git a/source/blender/blenloader/intern/versioning_legacy.c b/source/blender/blenloader/intern/versioning_legacy.c
index f2d42849bcc..c29ffbb76f2 100644
--- a/source/blender/blenloader/intern/versioning_legacy.c
+++ b/source/blender/blenloader/intern/versioning_legacy.c
@@ -2296,11 +2296,12 @@ void blo_do_versions_pre250(FileData *fd, Library *lib, Main *main)
/* during 2.41 images with this name were used for viewer node output, lets fix that */
if (main->versionfile == 241) {
Image *ima;
- for (ima = main->image.first; ima; ima = ima->id.next)
+ for (ima = main->image.first; ima; ima = ima->id.next) {
if (STREQ(ima->name, "Compositor")) {
strcpy(ima->id.name + 2, "Viewer Node");
strcpy(ima->name, "Viewer Node");
}
+ }
}
}
diff --git a/source/blender/blenloader/intern/writefile.c b/source/blender/blenloader/intern/writefile.c
index 57be237be6f..ee9665dc834 100644
--- a/source/blender/blenloader/intern/writefile.c
+++ b/source/blender/blenloader/intern/writefile.c
@@ -1052,7 +1052,7 @@ static void write_nodetree_nolib(WriteData *wd, bNodeTree *ntree)
writestruct(wd, DATA, NodeImageMultiFileSocket, 1, sock->storage);
}
}
- if (node->type == CMP_NODE_IMAGE) {
+ if (ELEM(node->type, CMP_NODE_IMAGE, CMP_NODE_R_LAYERS)) {
/* write extra socket info */
for (sock = node->outputs.first; sock; sock = sock->next) {
writestruct(wd, DATA, NodeImageLayer, 1, sock->storage);
@@ -1317,8 +1317,8 @@ static void write_particlesettings(WriteData *wd, ParticleSettings *part)
dw->index = 0;
if (part->dup_group) { /* can be NULL if lining fails or set to None */
for (GroupObject *go = part->dup_group->gobject.first;
- go && go->ob != dw->ob;
- go = go->next, dw->index++);
+ go && go->ob != dw->ob;
+ go = go->next, dw->index++);
}
}
writestruct(wd, DATA, ParticleDupliWeight, 1, dw);
@@ -2244,8 +2244,9 @@ static void write_mesh(WriteData *wd, Mesh *mesh)
* outside of save process itself.
* Maybe we can live with this, though?
*/
- mesh->totface = BKE_mesh_mpoly_to_mface(&mesh->fdata, &old_mesh->ldata, &old_mesh->pdata,
- mesh->totface, old_mesh->totloop, old_mesh->totpoly);
+ mesh->totface = BKE_mesh_mpoly_to_mface(
+ &mesh->fdata, &old_mesh->ldata, &old_mesh->pdata,
+ mesh->totface, old_mesh->totloop, old_mesh->totpoly);
BKE_mesh_update_customdata_pointers(mesh, false);
@@ -2654,8 +2655,8 @@ static void write_scene(WriteData *wd, Scene *sce)
}
if (seq->type == SEQ_TYPE_IMAGE) {
writestruct(wd, DATA, StripElem,
- MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem),
- strip->stripdata);
+ MEM_allocN_len(strip->stripdata) / sizeof(struct StripElem),
+ strip->stripdata);
}
else if (ELEM(seq->type, SEQ_TYPE_MOVIE, SEQ_TYPE_SOUND_RAM, SEQ_TYPE_SOUND_HD)) {
writestruct(wd, DATA, StripElem, 1, strip->stripdata);
@@ -2710,6 +2711,9 @@ static void write_scene(WriteData *wd, Scene *sce)
for (SceneRenderLayer *srl = sce->r.layers.first; srl; srl = srl->next) {
writestruct(wd, DATA, SceneRenderLayer, 1, srl);
+ if (srl->prop) {
+ IDP_WriteProperty(srl->prop, wd);
+ }
for (FreestyleModuleConfig *fmc = srl->freestyleConfig.modules.first; fmc; fmc = fmc->next) {
writestruct(wd, DATA, FreestyleModuleConfig, 1, fmc);
}
@@ -3362,13 +3366,13 @@ static void write_mask(WriteData *wd, Mask *mask)
}
for (masklay_shape = masklay->splines_shapes.first;
- masklay_shape;
- masklay_shape = masklay_shape->next)
+ masklay_shape;
+ masklay_shape = masklay_shape->next)
{
writestruct(wd, DATA, MaskLayerShape, 1, masklay_shape);
writedata(wd, DATA,
- masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE,
- masklay_shape->data);
+ masklay_shape->tot_vert * sizeof(float) * MASK_OBJECT_SHAPE_ELEM_SIZE,
+ masklay_shape->data);
}
}
}
@@ -3854,7 +3858,7 @@ static bool write_file_handle(
write_scene(wd, (Scene *)id);
break;
case ID_CU:
- write_curve(wd,(Curve *)id);
+ write_curve(wd, (Curve *)id);
break;
case ID_MB:
write_mball(wd, (MetaBall *)id);
diff --git a/source/blender/blentranslation/CMakeLists.txt b/source/blender/blentranslation/CMakeLists.txt
index a3e85344027..c0dce5b4f0d 100644
--- a/source/blender/blentranslation/CMakeLists.txt
+++ b/source/blender/blentranslation/CMakeLists.txt
@@ -60,3 +60,5 @@ if(WIN32)
endif()
blender_add_lib(bf_blentranslation "${SRC}" "${INC}" "${INC_SYS}")
+
+add_subdirectory(msgfmt)
diff --git a/source/blender/blentranslation/msgfmt/CMakeLists.txt b/source/blender/blentranslation/msgfmt/CMakeLists.txt
new file mode 100644
index 00000000000..d2cb6f5a03b
--- /dev/null
+++ b/source/blender/blentranslation/msgfmt/CMakeLists.txt
@@ -0,0 +1,50 @@
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# The Original Code is Copyright (C) 2017, Blender Foundation
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): Bastien Montagne.
+#
+# ***** END GPL LICENSE BLOCK *****
+
+# -----------------------------------------------------------------------------
+# Build msgfmt executable
+
+blender_include_dirs(
+ ../../../../intern/guardedalloc
+ ../../blenlib
+)
+
+set(SRC
+ msgfmt.c
+)
+
+add_cc_flags_custom_test(msgfmt)
+
+add_executable(msgfmt ${SRC})
+
+target_link_libraries(msgfmt bf_blenlib)
+target_link_libraries(msgfmt bf_intern_guardedalloc)
+
+if(WIN32)
+ target_link_libraries(msgfmt bf_intern_utfconv)
+endif()
+
+target_link_libraries(msgfmt ${ZLIB_LIBRARIES})
+target_link_libraries(msgfmt ${PLATFORM_LINKLIBS})
diff --git a/source/blender/blentranslation/msgfmt/msgfmt.c b/source/blender/blentranslation/msgfmt/msgfmt.c
new file mode 100644
index 00000000000..487d9fee7b4
--- /dev/null
+++ b/source/blender/blentranslation/msgfmt/msgfmt.c
@@ -0,0 +1,464 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2017 by Blender Foundation.
+ * All rights reserved.
+ *
+ * Contributor(s): Bastien Montagne
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/*
+ * Based on C++ version by Sergey Sharybin <sergey.vfx@gmail.com>.
+ * Based on Python script msgfmt.py from Python source code tree, which was written by
+ * Martin v. Löwis <loewis@informatik.hu-berlin.de>
+ *
+ * Generate binary message catalog from textual translation description.
+ *
+ * This program converts a textual Uniforum-style message catalog (.po file) into a binary GNU catalog (.mo file).
+ * This is essentially the same function as the GNU msgfmt program, however, it is a simpler implementation.
+ *
+ * Usage: msgfmt input.po output.po
+ */
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "BLI_utildefines.h"
+#include "BLI_dynstr.h"
+#include "BLI_fileops.h"
+#include "BLI_ghash.h"
+#include "BLI_linklist.h"
+#include "BLI_memarena.h"
+
+#include "MEM_guardedalloc.h"
+
+
+/* Stupid stub necessary because some BLI files includes winstuff.h, which uses G a bit... */
+#ifdef WIN32
+ typedef struct Global {
+ void *dummy;
+ } Global;
+
+ Global G;
+#endif
+
+
+/* We cannot use NULL char until ultimate step, would give nightmare to our C string processing...
+ * Using one of the UTF-8 invalid bytes (as per our BLI string_utf8.c) */
+#define NULLSEP_STR "\xff"
+#define NULLSEP_CHR '\xff'
+
+typedef enum {
+ SECTION_NONE = 0,
+ SECTION_CTX = 1,
+ SECTION_ID = 2,
+ SECTION_STR = 3,
+} eSectionType;
+
+typedef struct Message {
+ DynStr *ctxt;
+ DynStr *id;
+ DynStr *str;
+
+ bool is_fuzzy;
+} Message;
+
+static char *trim(char *str)
+{
+ const size_t len = strlen(str);
+ size_t i;
+
+ if (len == 0) {
+ return str;
+ }
+
+ for (i = 0; i < len && ELEM(str[0], ' ', '\t', '\n'); str++, i++);
+
+ char *end = &str[len - 1 - i];
+ for (i = len; i > 0 && ELEM(end[0], ' ', '\t', '\n'); end--, i--);
+ end[1] = '\0';
+
+ return str;
+}
+
+static char *unescape(char *str)
+{
+ char *curr, *next;
+ for (curr = next = str; next[0] != '\0'; curr++, next++) {
+ if (next[0] == '\\') {
+ switch (next[1]) {
+ case '\0':
+ /* Get rid of trailing escape char... */
+ curr--;
+ break;
+ case '\\':
+ *curr = '\\';
+ next++;
+ break;
+ case 'n':
+ *curr = '\n';
+ next++;
+ break;
+ case 't':
+ *curr = '\t';
+ next++;
+ break;
+ default:
+ /* Get rid of useless escape char. */
+ next++;
+ *curr = *next;
+ }
+ }
+ else if (curr != next) {
+ *curr = *next;
+ }
+ }
+ *curr = '\0';
+
+ if (str[0] == '"' && *(curr - 1) == '"') {
+ *(curr - 1) = '\0';
+ return str + 1;
+ }
+ return str;
+}
+
+static int qsort_str_cmp(const void *a, const void *b)
+{
+ return strcmp(*(const char **)a, *(const char **)b);
+}
+
+static char **get_keys_sorted(GHash *messages, const uint32_t num_keys)
+{
+ GHashIterator iter;
+
+ char **keys = MEM_mallocN(sizeof(*keys) * num_keys, __func__);
+ char **k = keys;
+
+ GHASH_ITER(iter, messages) {
+ *k = BLI_ghashIterator_getKey(&iter);
+ k++;
+ }
+
+ qsort(keys, num_keys, sizeof(*keys), qsort_str_cmp);
+
+ return keys;
+}
+
+BLI_INLINE size_t uint32_to_bytes(const int value, char *bytes) {
+ size_t i;
+ for (i = 0; i < sizeof(value); i++) {
+ bytes[i] = (char) ((value >> ((int)i * 8)) & 0xff);
+ }
+ return i;
+}
+
+BLI_INLINE size_t msg_to_bytes(char *msg, char *bytes, uint32_t size) {
+ /* Note that we also perform replacing of our NULLSEP placeholder by real NULL char... */
+ size_t i;
+ for (i = 0; i < size; i++, msg++, bytes++) {
+ *bytes = (*msg == NULLSEP_CHR) ? '\0' : *msg;
+ }
+ return i;
+}
+
+typedef struct Offset {
+ uint32_t key_offset, key_len, val_offset, val_len;
+} Offset;
+
+/* Return the generated binary output. */
+static char *generate(GHash *messages, size_t *r_output_size) {
+ const uint32_t num_keys = BLI_ghash_size(messages);
+
+ /* Get list of sorted keys. */
+ char **keys = get_keys_sorted(messages, num_keys);
+ char **vals = MEM_mallocN(sizeof(*vals) * num_keys, __func__);
+ uint32_t tot_keys_len = 0;
+ uint32_t tot_vals_len = 0;
+
+ Offset *offsets = MEM_mallocN(sizeof(*offsets) * num_keys, __func__);
+
+ for (int i = 0; i < num_keys; i++) {
+ Offset *off = &offsets[i];
+
+ vals[i] = BLI_ghash_lookup(messages, keys[i]);
+
+ /* For each string, we need size and file offset.
+ * Each string is NULL terminated; the NULL does not count into the size. */
+ off->key_offset = tot_keys_len;
+ off->key_len = (uint32_t)strlen(keys[i]);
+ tot_keys_len += off->key_len + 1;
+
+ off->val_offset = tot_vals_len;
+ off->val_len = (uint32_t)strlen(vals[i]);
+ tot_vals_len += off->val_len + 1;
+ }
+
+ /* The header is 7 32-bit unsigned integers. then comes the keys index table, then the values index table. */
+ const uint32_t idx_keystart = 7 * 4;
+ const uint32_t idx_valstart = idx_keystart + 8 * num_keys;
+ /* We don't use hash tables, so the keys start right after the index tables. */
+ const uint32_t keystart = idx_valstart + 8 * num_keys;
+ /* and the values start after the keys */
+ const uint32_t valstart = keystart + tot_keys_len;
+
+ /* Final buffer representing the binary MO file. */
+ *r_output_size = valstart + tot_vals_len;
+ char *output = MEM_mallocN(*r_output_size, __func__);
+ char *h = output;
+ char *ik = output + idx_keystart;
+ char *iv = output + idx_valstart;
+ char *k = output + keystart;
+ char *v = output + valstart;
+
+ h += uint32_to_bytes(0x950412de, h); /* Magic */
+ h += uint32_to_bytes(0x0, h); /* Version */
+ h += uint32_to_bytes(num_keys, h); /* Number of entries */
+ h += uint32_to_bytes(idx_keystart, h); /* Start of key index */
+ h += uint32_to_bytes(idx_valstart, h); /* Start of value index */
+ h += uint32_to_bytes(0, h); /* Size of hash table */
+ h += uint32_to_bytes(0, h); /* Offset of hash table */
+
+ BLI_assert(h == ik);
+
+ for (int i = 0; i < num_keys; i++) {
+ Offset *off = &offsets[i];
+
+ /* The index table first has the list of keys, then the list of values.
+ * Each entry has first the size of the string, then the file offset. */
+ ik += uint32_to_bytes(off->key_len, ik);
+ ik += uint32_to_bytes(off->key_offset + keystart, ik);
+ iv += uint32_to_bytes(off->val_len, iv);
+ iv += uint32_to_bytes(off->val_offset + valstart, iv);
+
+ k += msg_to_bytes(keys[i], k, off->key_len + 1);
+ v += msg_to_bytes(vals[i], v, off->val_len + 1);
+ }
+
+ BLI_assert(ik == output + idx_valstart);
+ BLI_assert(iv == output + keystart);
+ BLI_assert(k == output + valstart);
+
+ MEM_freeN(keys);
+ MEM_freeN(vals);
+ MEM_freeN(offsets);
+
+ return output;
+}
+
+/* Add a non-fuzzy translation to the dictionary. */
+static void add(GHash *messages, MemArena *memarena, const Message *msg)
+{
+ const size_t msgctxt_len = (size_t)BLI_dynstr_get_len(msg->ctxt);
+ const size_t msgid_len = (size_t)BLI_dynstr_get_len(msg->id);
+ const size_t msgstr_len = (size_t)BLI_dynstr_get_len(msg->str);
+ const size_t msgkey_len = msgid_len + ((msgctxt_len == 0) ? 0 : msgctxt_len + 1);
+
+ if (!msg->is_fuzzy && msgstr_len != 0) {
+ char *msgkey = BLI_memarena_alloc(memarena, sizeof(*msgkey) * (msgkey_len + 1));
+ char *msgstr = BLI_memarena_alloc(memarena, sizeof(*msgstr) * (msgstr_len + 1));
+
+ if (msgctxt_len != 0) {
+ BLI_dynstr_get_cstring_ex(msg->ctxt, msgkey);
+ msgkey[msgctxt_len] = '\x04'; /* Context/msgid separator */
+ BLI_dynstr_get_cstring_ex(msg->id, &msgkey[msgctxt_len + 1]);
+ }
+ else {
+ BLI_dynstr_get_cstring_ex(msg->id, msgkey);
+ }
+
+ BLI_dynstr_get_cstring_ex(msg->str, msgstr);
+
+ BLI_ghash_insert(messages, msgkey, msgstr);
+ }
+}
+
+
+static void clear(Message *msg)
+{
+ BLI_dynstr_clear(msg->ctxt);
+ BLI_dynstr_clear(msg->id);
+ BLI_dynstr_clear(msg->str);
+ msg->is_fuzzy = false;
+}
+
+static int make(const char *input_file_name, const char *output_file_name)
+{
+ GHash *messages = BLI_ghash_new(BLI_ghashutil_strhash_p_murmur, BLI_ghashutil_strcmp, __func__);
+ MemArena *msgs_memarena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+
+ const char *msgctxt_kw = "msgctxt";
+ const char *msgid_kw = "msgid";
+ const char *msgid_plural_kw = "msgid_plural";
+ const char *msgstr_kw = "msgstr";
+ const size_t msgctxt_len = strlen(msgctxt_kw);
+ const size_t msgid_len = strlen(msgid_kw);
+ const size_t msgid_plural_len = strlen(msgid_plural_kw);
+ const size_t msgstr_len = strlen(msgstr_kw);
+
+ /* Note: For now, we assume file encoding is always utf-8. */
+
+ eSectionType section = SECTION_NONE;
+ bool is_plural = false;
+
+ Message msg = {
+ .ctxt = BLI_dynstr_new_memarena(),
+ .id = BLI_dynstr_new_memarena(),
+ .str = BLI_dynstr_new_memarena(),
+ .is_fuzzy = false,
+ };
+
+ LinkNode *input_file_lines = BLI_file_read_as_lines(input_file_name);
+ LinkNode *ifl = input_file_lines;
+
+ /* Parse the catalog. */
+ for (int lno = 1; ifl; ifl = ifl->next, lno++) {
+ char *l = ifl->link;
+ const bool is_comment = (l[0] == '#');
+ /* If we get a comment line after a msgstr, this is a new entry. */
+ if (is_comment) {
+ if (section == SECTION_STR) {
+ add(messages, msgs_memarena, &msg);
+ clear(&msg);
+ section = SECTION_NONE;
+ }
+ /* Record a fuzzy mark. */
+ if (l[1] == ',' && strstr(l, "fuzzy") != NULL) {
+ msg.is_fuzzy = true;
+ }
+ /* Skip comments */
+ continue;
+ }
+ if (strstr(l, msgctxt_kw) == l) {
+ if (section == SECTION_STR) {
+ /* New message, output previous section. */
+ add(messages, msgs_memarena, &msg);
+ }
+ if (!ELEM(section, SECTION_NONE, SECTION_STR)) {
+ printf("msgctxt not at start of new message on %s:%d\n", input_file_name, lno);
+ return EXIT_FAILURE;
+ }
+ section = SECTION_CTX;
+ l = l + msgctxt_len;
+ clear(&msg);
+ }
+ else if (strstr(l, msgid_plural_kw) == l) {
+ /* This is a message with plural forms. */
+ if (section != SECTION_ID) {
+ printf("msgid_plural not preceeded by msgid on %s:%d\n", input_file_name, lno);
+ return EXIT_FAILURE;
+ }
+ l = l + msgid_plural_len;
+ BLI_dynstr_append(msg.id, NULLSEP_STR); /* separator of singular and plural */
+ is_plural = true;
+ }
+ else if (strstr(l, msgid_kw) == l) {
+ if (section == SECTION_STR) {
+ add(messages, msgs_memarena, &msg);
+ }
+ if (section != SECTION_CTX) {
+ clear(&msg);
+ }
+ section = SECTION_ID;
+ l = l + msgid_len;
+ is_plural = false;
+ }
+ else if (strstr(l, msgstr_kw) == l) {
+ l = l + msgstr_len;
+ // Now we are in a msgstr section
+ section = SECTION_STR;
+ if (l[0] == '[') {
+ if (!is_plural) {
+ printf("plural without msgid_plural on %s:%d\n", input_file_name, lno);
+ return EXIT_FAILURE;
+ }
+ if ((l = strchr(l, ']')) == NULL) {
+ printf("Syntax error on %s:%d\n", input_file_name, lno);
+ return EXIT_FAILURE;
+ }
+ if (BLI_dynstr_get_len(msg.str) != 0) {
+ BLI_dynstr_append(msg.str, NULLSEP_STR); /* Separator of the various plural forms. */
+ }
+ }
+ else {
+ if (is_plural) {
+ printf("indexed msgstr required for plural on %s:%d\n", input_file_name, lno);
+ return EXIT_FAILURE;
+ }
+ }
+ }
+ /* Skip empty lines. */
+ l = trim(l);
+ if (l[0] == '\0') {
+ if (section == SECTION_STR) {
+ add(messages, msgs_memarena, &msg);
+ clear(&msg);
+ }
+ section = SECTION_NONE;
+ continue;
+ }
+ l = unescape(l);
+ if (section == SECTION_CTX) {
+ BLI_dynstr_append(msg.ctxt, l);
+ }
+ else if (section == SECTION_ID) {
+ BLI_dynstr_append(msg.id, l);
+ }
+ else if (section == SECTION_STR) {
+ BLI_dynstr_append(msg.str, l);
+ }
+ else {
+ printf("Syntax error on %s:%d\n", input_file_name, lno);
+ return EXIT_FAILURE;
+ }
+ }
+ /* Add last entry */
+ if (section == SECTION_STR) {
+ add(messages, msgs_memarena, &msg);
+ }
+
+ BLI_dynstr_free(msg.ctxt);
+ BLI_dynstr_free(msg.id);
+ BLI_dynstr_free(msg.str);
+ BLI_file_free_lines(input_file_lines);
+
+ /* Compute output */
+ size_t output_size;
+ char *output = generate(messages, &output_size);
+
+ FILE *fp = BLI_fopen(output_file_name, "wb");
+ fwrite(output, 1, output_size, fp);
+ fclose(fp);
+
+ MEM_freeN(output);
+ BLI_ghash_free(messages, NULL, NULL);
+ BLI_memarena_free(msgs_memarena);
+
+ return EXIT_SUCCESS;
+}
+
+int main(int argc, char **argv) {
+ if (argc != 3) {
+ printf("Usage: %s <input.po> <output.mo>\n", argv[0]);
+ return EXIT_FAILURE;
+ }
+ const char *input_file = argv[1];
+ const char *output_file = argv[2];
+
+ return make(input_file, output_file);
+}
diff --git a/source/blender/bmesh/bmesh_class.h b/source/blender/bmesh/bmesh_class.h
index 104df625ee6..64a5cad812a 100644
--- a/source/blender/bmesh/bmesh_class.h
+++ b/source/blender/bmesh/bmesh_class.h
@@ -225,7 +225,7 @@ typedef struct BMesh {
/* operator api stuff (must be all NULL or all alloc'd) */
struct BLI_mempool *vtoolflagpool, *etoolflagpool, *ftoolflagpool;
- unsigned int use_toolflags : 1;
+ uint use_toolflags : 1;
int toolflag_index;
struct BMOperator *currentop;
@@ -382,7 +382,7 @@ typedef bool (*BMLoopFilterFunc)(const BMLoop *, void *user_data);
(assert(offset != -1), *((float *)((char *)(ele)->head.data + (offset))))
#define BM_ELEM_CD_GET_FLOAT_AS_UCHAR(ele, offset) \
- (assert(offset != -1), (unsigned char)(BM_ELEM_CD_GET_FLOAT(ele, offset) * 255.0f))
+ (assert(offset != -1), (uchar)(BM_ELEM_CD_GET_FLOAT(ele, offset) * 255.0f))
/*forward declarations*/
diff --git a/source/blender/bmesh/intern/bmesh_callback_generic.c b/source/blender/bmesh/intern/bmesh_callback_generic.c
index 913255bfb33..e9304e8536f 100644
--- a/source/blender/bmesh/intern/bmesh_callback_generic.c
+++ b/source/blender/bmesh/intern/bmesh_callback_generic.c
@@ -32,7 +32,7 @@
bool BM_elem_cb_check_hflag_ex(BMElem *ele, void *user_data)
{
- const unsigned int hflag_pair = GET_INT_FROM_POINTER(user_data);
+ const uint hflag_pair = GET_INT_FROM_POINTER(user_data);
const char hflag_p = (hflag_pair & 0xff);
const char hflag_n = (hflag_pair >> 8);
diff --git a/source/blender/bmesh/intern/bmesh_construct.c b/source/blender/bmesh/intern/bmesh_construct.c
index e46a31cb2e9..f8ecbe1756b 100644
--- a/source/blender/bmesh/intern/bmesh_construct.c
+++ b/source/blender/bmesh/intern/bmesh_construct.c
@@ -154,7 +154,7 @@ void BM_face_copy_shared(
if (l_other && l_other != l_iter) {
BMLoop *l_src[2];
BMLoop *l_dst[2] = {l_iter, l_iter->next};
- unsigned int j;
+ uint j;
if (l_other->v == l_iter->v) {
l_src[0] = l_other;
@@ -311,7 +311,7 @@ BMFace *BM_face_create_ngon_verts(
const bool calc_winding, const bool create_edges)
{
BMEdge **edge_arr = BLI_array_alloca(edge_arr, len);
- unsigned int winding[2] = {0, 0};
+ uint winding[2] = {0, 0};
int i, i_prev = len - 1;
BMVert *v_winding[2] = {vert_arr[i_prev], vert_arr[0]};
diff --git a/source/blender/bmesh/intern/bmesh_edgeloop.c b/source/blender/bmesh/intern/bmesh_edgeloop.c
index 5e1d9c3a98d..5780dc57d78 100644
--- a/source/blender/bmesh/intern/bmesh_edgeloop.c
+++ b/source/blender/bmesh/intern/bmesh_edgeloop.c
@@ -58,7 +58,7 @@ static int bm_vert_other_tag(
{
BMIter iter;
BMEdge *e, *e_next = NULL;
- unsigned int count = 0;
+ uint count = 0;
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
if (BM_elem_flag_test(e, BM_ELEM_INTERNAL_TAG)) {
diff --git a/source/blender/bmesh/intern/bmesh_iterators.h b/source/blender/bmesh/intern/bmesh_iterators.h
index 0551d824131..ab066682081 100644
--- a/source/blender/bmesh/intern/bmesh_iterators.h
+++ b/source/blender/bmesh/intern/bmesh_iterators.h
@@ -211,12 +211,12 @@ void *BMO_iter_as_arrayN(
int BM_iter_mesh_bitmap_from_filter(
const char itype, BMesh *bm,
- unsigned int *bitmap,
+ uint *bitmap,
bool (*test_fn)(BMElem *, void *user_data),
void *user_data);
int BM_iter_mesh_bitmap_from_filter_tessface(
BMesh *bm,
- unsigned int *bitmap,
+ uint *bitmap,
bool (*test_fn)(BMFace *, void *user_data),
void *user_data);
diff --git a/source/blender/bmesh/intern/bmesh_log.c b/source/blender/bmesh/intern/bmesh_log.c
index 2591c33fc73..1d16dbc1836 100644
--- a/source/blender/bmesh/intern/bmesh_log.c
+++ b/source/blender/bmesh/intern/bmesh_log.c
@@ -88,7 +88,7 @@ struct BMLog {
/* Mapping from unique IDs to vertices and faces
*
- * Each vertex and face in the log gets a unique unsigned integer
+ * Each vertex and face in the log gets a unique uinteger
* assigned. That ID is taken from the set managed by the
* unused_ids range tree.
*
@@ -120,7 +120,7 @@ typedef struct {
} BMLogVert;
typedef struct {
- unsigned int v_ids[3];
+ uint v_ids[3];
char hflag;
} BMLogFace;
@@ -131,14 +131,14 @@ typedef struct {
#define logkey_cmp BLI_ghashutil_intcmp
/* Get the vertex's unique ID from the log */
-static unsigned int bm_log_vert_id_get(BMLog *log, BMVert *v)
+static uint bm_log_vert_id_get(BMLog *log, BMVert *v)
{
BLI_assert(BLI_ghash_haskey(log->elem_to_id, v));
return GET_UINT_FROM_POINTER(BLI_ghash_lookup(log->elem_to_id, v));
}
/* Set the vertex's unique ID in the log */
-static void bm_log_vert_id_set(BMLog *log, BMVert *v, unsigned int id)
+static void bm_log_vert_id_set(BMLog *log, BMVert *v, uint id)
{
void *vid = SET_UINT_IN_POINTER(id);
@@ -147,7 +147,7 @@ static void bm_log_vert_id_set(BMLog *log, BMVert *v, unsigned int id)
}
/* Get a vertex from its unique ID */
-static BMVert *bm_log_vert_from_id(BMLog *log, unsigned int id)
+static BMVert *bm_log_vert_from_id(BMLog *log, uint id)
{
void *key = SET_UINT_IN_POINTER(id);
BLI_assert(BLI_ghash_haskey(log->id_to_elem, key));
@@ -155,14 +155,14 @@ static BMVert *bm_log_vert_from_id(BMLog *log, unsigned int id)
}
/* Get the face's unique ID from the log */
-static unsigned int bm_log_face_id_get(BMLog *log, BMFace *f)
+static uint bm_log_face_id_get(BMLog *log, BMFace *f)
{
BLI_assert(BLI_ghash_haskey(log->elem_to_id, f));
return GET_UINT_FROM_POINTER(BLI_ghash_lookup(log->elem_to_id, f));
}
/* Set the face's unique ID in the log */
-static void bm_log_face_id_set(BMLog *log, BMFace *f, unsigned int id)
+static void bm_log_face_id_set(BMLog *log, BMFace *f, uint id)
{
void *fid = SET_UINT_IN_POINTER(id);
@@ -171,7 +171,7 @@ static void bm_log_face_id_set(BMLog *log, BMFace *f, unsigned int id)
}
/* Get a face from its unique ID */
-static BMFace *bm_log_face_from_id(BMLog *log, unsigned int id)
+static BMFace *bm_log_face_from_id(BMLog *log, uint id)
{
void *key = SET_UINT_IN_POINTER(id);
BLI_assert(BLI_ghash_haskey(log->id_to_elem, key));
@@ -255,7 +255,7 @@ static void bm_log_verts_unmake(BMesh *bm, BMLog *log, GHash *verts)
GHASH_ITER (gh_iter, verts) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
- unsigned int id = GET_UINT_FROM_POINTER(key);
+ uint id = GET_UINT_FROM_POINTER(key);
BMVert *v = bm_log_vert_from_id(log, id);
/* Ensure the log has the final values of the vertex before
@@ -271,7 +271,7 @@ static void bm_log_faces_unmake(BMesh *bm, BMLog *log, GHash *faces)
GHashIterator gh_iter;
GHASH_ITER (gh_iter, faces) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
- unsigned int id = GET_UINT_FROM_POINTER(key);
+ uint id = GET_UINT_FROM_POINTER(key);
BMFace *f = bm_log_face_from_id(log, id);
BMEdge *e_tri[3];
BMLoop *l_iter;
@@ -333,7 +333,7 @@ static void bm_log_vert_values_swap(BMesh *bm, BMLog *log, GHash *verts)
GHASH_ITER (gh_iter, verts) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
BMLogVert *lv = BLI_ghashIterator_getValue(&gh_iter);
- unsigned int id = GET_UINT_FROM_POINTER(key);
+ uint id = GET_UINT_FROM_POINTER(key);
BMVert *v = bm_log_vert_from_id(log, id);
float mask;
short normal[3];
@@ -355,7 +355,7 @@ static void bm_log_face_values_swap(BMLog *log, GHash *faces)
GHASH_ITER (gh_iter, faces) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
BMLogFace *lf = BLI_ghashIterator_getValue(&gh_iter);
- unsigned int id = GET_UINT_FROM_POINTER(key);
+ uint id = GET_UINT_FROM_POINTER(key);
BMFace *f = bm_log_face_from_id(log, id);
SWAP(char, f->head.hflag, lf->hflag);
@@ -374,13 +374,13 @@ static void bm_log_assign_ids(BMesh *bm, BMLog *log)
/* Generate vertex IDs */
BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
- unsigned int id = range_tree_uint_take_any(log->unused_ids);
+ uint id = range_tree_uint_take_any(log->unused_ids);
bm_log_vert_id_set(log, v, id);
}
/* Generate face IDs */
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
- unsigned int id = range_tree_uint_take_any(log->unused_ids);
+ uint id = range_tree_uint_take_any(log->unused_ids);
bm_log_face_id_set(log, f, id);
}
}
@@ -425,7 +425,7 @@ static void bm_log_id_ghash_retake(RangeTreeUInt *unused_ids, GHash *id_ghash)
GHASH_ITER (gh_iter, id_ghash) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
- unsigned int id = GET_UINT_FROM_POINTER(key);
+ uint id = GET_UINT_FROM_POINTER(key);
range_tree_uint_retake(unused_ids, id);
}
@@ -433,8 +433,8 @@ static void bm_log_id_ghash_retake(RangeTreeUInt *unused_ids, GHash *id_ghash)
static int uint_compare(const void *a_v, const void *b_v)
{
- const unsigned int *a = a_v;
- const unsigned int *b = b_v;
+ const uint *a = a_v;
+ const uint *b = b_v;
return (*a) < (*b);
}
@@ -446,10 +446,10 @@ static int uint_compare(const void *a_v, const void *b_v)
* 10 -> 3
* 3 -> 1
*/
-static GHash *bm_log_compress_ids_to_indices(unsigned int *ids, unsigned int totid)
+static GHash *bm_log_compress_ids_to_indices(uint *ids, uint totid)
{
GHash *map = BLI_ghash_int_new_ex(__func__, totid);
- unsigned int i;
+ uint i;
qsort(ids, totid, sizeof(*ids), uint_compare);
@@ -469,7 +469,7 @@ static void bm_log_id_ghash_release(BMLog *log, GHash *id_ghash)
GHASH_ITER (gh_iter, id_ghash) {
void *key = BLI_ghashIterator_getKey(&gh_iter);
- unsigned int id = GET_UINT_FROM_POINTER(key);
+ uint id = GET_UINT_FROM_POINTER(key);
range_tree_uint_release(log->unused_ids, id);
}
}
@@ -480,7 +480,7 @@ static void bm_log_id_ghash_release(BMLog *log, GHash *id_ghash)
BMLog *BM_log_create(BMesh *bm)
{
BMLog *log = MEM_callocN(sizeof(*log), __func__);
- const unsigned int reserve_num = (unsigned int)(bm->totvert + bm->totface);
+ const uint reserve_num = (uint)(bm->totvert + bm->totface);
log->unused_ids = range_tree_uint_alloc(0, (unsigned)-1);
log->id_to_elem = BLI_ghash_new_ex(logkey_hash, logkey_cmp, __func__, reserve_num);
@@ -593,8 +593,8 @@ int BM_log_length(const BMLog *log)
/* Apply a consistent ordering to BMesh vertices */
void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
{
- unsigned int *varr;
- unsigned int *farr;
+ uint *varr;
+ uint *farr;
GHash *id_to_idx;
@@ -602,7 +602,7 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
BMVert *v;
BMFace *f;
- unsigned int i;
+ uint i;
/* Put all vertex IDs into an array */
varr = MEM_mallocN(sizeof(int) * (size_t)bm->totvert, __func__);
@@ -617,7 +617,7 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
}
/* Create BMVert index remap array */
- id_to_idx = bm_log_compress_ids_to_indices(varr, (unsigned int)bm->totvert);
+ id_to_idx = bm_log_compress_ids_to_indices(varr, (uint)bm->totvert);
BM_ITER_MESH_INDEX (v, &bm_iter, bm, BM_VERTS_OF_MESH, i) {
const unsigned id = bm_log_vert_id_get(log, v);
const void *key = SET_UINT_IN_POINTER(id);
@@ -627,7 +627,7 @@ void BM_log_mesh_elems_reorder(BMesh *bm, BMLog *log)
BLI_ghash_free(id_to_idx, NULL, NULL);
/* Create BMFace index remap array */
- id_to_idx = bm_log_compress_ids_to_indices(farr, (unsigned int)bm->totface);
+ id_to_idx = bm_log_compress_ids_to_indices(farr, (uint)bm->totface);
BM_ITER_MESH_INDEX (f, &bm_iter, bm, BM_FACES_OF_MESH, i) {
const unsigned id = bm_log_face_id_get(log, f);
const void *key = SET_UINT_IN_POINTER(id);
@@ -835,7 +835,7 @@ void BM_log_vert_before_modified(BMLog *log, BMVert *v, const int cd_vert_mask_o
{
BMLogEntry *entry = log->current_entry;
BMLogVert *lv;
- unsigned int v_id = bm_log_vert_id_get(log, v);
+ uint v_id = bm_log_vert_id_get(log, v);
void *key = SET_UINT_IN_POINTER(v_id);
void **val_p;
@@ -859,7 +859,7 @@ void BM_log_vert_before_modified(BMLog *log, BMVert *v, const int cd_vert_mask_o
void BM_log_vert_added(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
{
BMLogVert *lv;
- unsigned int v_id = range_tree_uint_take_any(log->unused_ids);
+ uint v_id = range_tree_uint_take_any(log->unused_ids);
void *key = SET_UINT_IN_POINTER(v_id);
bm_log_vert_id_set(log, v, v_id);
@@ -876,7 +876,7 @@ void BM_log_vert_added(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
void BM_log_face_modified(BMLog *log, BMFace *f)
{
BMLogFace *lf;
- unsigned int f_id = bm_log_face_id_get(log, f);
+ uint f_id = bm_log_face_id_get(log, f);
void *key = SET_UINT_IN_POINTER(f_id);
lf = bm_log_face_alloc(log, f);
@@ -892,7 +892,7 @@ void BM_log_face_modified(BMLog *log, BMFace *f)
void BM_log_face_added(BMLog *log, BMFace *f)
{
BMLogFace *lf;
- unsigned int f_id = range_tree_uint_take_any(log->unused_ids);
+ uint f_id = range_tree_uint_take_any(log->unused_ids);
void *key = SET_UINT_IN_POINTER(f_id);
/* Only triangles are supported for now */
@@ -922,7 +922,7 @@ void BM_log_face_added(BMLog *log, BMFace *f)
void BM_log_vert_removed(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
{
BMLogEntry *entry = log->current_entry;
- unsigned int v_id = bm_log_vert_id_get(log, v);
+ uint v_id = bm_log_vert_id_get(log, v);
void *key = SET_UINT_IN_POINTER(v_id);
/* if it has a key, it shouldn't be NULL */
@@ -963,7 +963,7 @@ void BM_log_vert_removed(BMLog *log, BMVert *v, const int cd_vert_mask_offset)
void BM_log_face_removed(BMLog *log, BMFace *f)
{
BMLogEntry *entry = log->current_entry;
- unsigned int f_id = bm_log_face_id_get(log, f);
+ uint f_id = bm_log_face_id_get(log, f);
void *key = SET_UINT_IN_POINTER(f_id);
/* if it has a key, it shouldn't be NULL */
@@ -991,11 +991,11 @@ void BM_log_all_added(BMesh *bm, BMLog *log)
/* avoid unnecessary resizing on initialization */
if (BLI_ghash_size(log->current_entry->added_verts) == 0) {
- BLI_ghash_reserve(log->current_entry->added_verts, (unsigned int)bm->totvert);
+ BLI_ghash_reserve(log->current_entry->added_verts, (uint)bm->totvert);
}
if (BLI_ghash_size(log->current_entry->added_faces) == 0) {
- BLI_ghash_reserve(log->current_entry->added_faces, (unsigned int)bm->totface);
+ BLI_ghash_reserve(log->current_entry->added_faces, (uint)bm->totface);
}
/* Log all vertices as newly created */
diff --git a/source/blender/bmesh/intern/bmesh_mesh.c b/source/blender/bmesh/intern/bmesh_mesh.c
index e9fb6a28154..d5d9e4abe2c 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.c
+++ b/source/blender/bmesh/intern/bmesh_mesh.c
@@ -635,7 +635,7 @@ static void bm_mesh_loops_calc_normals(
BM_elem_flag_disable(l_curr, BM_ELEM_TAG);
} while ((l_curr = l_curr->next) != l_first);
}
- bm->elem_index_dirty &= ~(BM_FACE|BM_LOOP);
+ bm->elem_index_dirty &= ~(BM_FACE | BM_LOOP);
/* We now know edges that can be smoothed (they are tagged), and edges that will be hard (they aren't).
* Now, time to generate the normals.
@@ -1527,9 +1527,9 @@ int BM_mesh_elem_count(BMesh *bm, const char htype)
*/
void BM_mesh_remap(
BMesh *bm,
- const unsigned int *vert_idx,
- const unsigned int *edge_idx,
- const unsigned int *face_idx)
+ const uint *vert_idx,
+ const uint *edge_idx,
+ const uint *face_idx)
{
/* Mapping old to new pointers. */
GHash *vptr_map = NULL, *eptr_map = NULL, *fptr_map = NULL;
@@ -1552,7 +1552,7 @@ void BM_mesh_remap(
if (vert_idx) {
BMVert **verts_pool, *verts_copy, **vep;
int i, totvert = bm->totvert;
- const unsigned int *new_idx;
+ const uint *new_idx;
/* Special case: Python uses custom - data layers to hold PyObject references.
* These have to be kept in - place, else the PyObject's we point to, wont point back to us. */
const int cd_vert_pyptr = CustomData_get_offset(&bm->vdata, CD_BM_ELEM_PYPTR);
@@ -1600,7 +1600,7 @@ void BM_mesh_remap(
if (edge_idx) {
BMEdge **edges_pool, *edges_copy, **edp;
int i, totedge = bm->totedge;
- const unsigned int *new_idx;
+ const uint *new_idx;
/* Special case: Python uses custom - data layers to hold PyObject references.
* These have to be kept in - place, else the PyObject's we point to, wont point back to us. */
const int cd_edge_pyptr = CustomData_get_offset(&bm->edata, CD_BM_ELEM_PYPTR);
@@ -1647,7 +1647,7 @@ void BM_mesh_remap(
if (face_idx) {
BMFace **faces_pool, *faces_copy, **fap;
int i, totface = bm->totface;
- const unsigned int *new_idx;
+ const uint *new_idx;
/* Special case: Python uses custom - data layers to hold PyObject references.
* These have to be kept in - place, else the PyObject's we point to, wont point back to us. */
const int cd_poly_pyptr = CustomData_get_offset(&bm->pdata, CD_BM_ELEM_PYPTR);
diff --git a/source/blender/bmesh/intern/bmesh_mesh.h b/source/blender/bmesh/intern/bmesh_mesh.h
index 6a9540c3b60..01f11f6f942 100644
--- a/source/blender/bmesh/intern/bmesh_mesh.h
+++ b/source/blender/bmesh/intern/bmesh_mesh.h
@@ -34,7 +34,7 @@ void BM_mesh_elem_toolflags_ensure(BMesh *bm);
void BM_mesh_elem_toolflags_clear(BMesh *bm);
struct BMeshCreateParams {
- unsigned int use_toolflags : 1;
+ uint use_toolflags : 1;
};
BMesh *BM_mesh_create(
@@ -88,9 +88,9 @@ int BM_mesh_elem_count(BMesh *bm, const char htype);
void BM_mesh_remap(
BMesh *bm,
- const unsigned int *vert_idx,
- const unsigned int *edge_idx,
- const unsigned int *face_idx);
+ const uint *vert_idx,
+ const uint *edge_idx,
+ const uint *face_idx);
void BM_mesh_rebuild(
BMesh *bm, const struct BMeshCreateParams *params,
diff --git a/source/blender/bmesh/intern/bmesh_mesh_conv.h b/source/blender/bmesh/intern/bmesh_mesh_conv.h
index 7cbfe2d9210..1974d364171 100644
--- a/source/blender/bmesh/intern/bmesh_mesh_conv.h
+++ b/source/blender/bmesh/intern/bmesh_mesh_conv.h
@@ -41,11 +41,11 @@ char BM_mesh_cd_flag_from_bmesh(BMesh *bm);
struct BMeshFromMeshParams {
- unsigned int calc_face_normal : 1;
+ uint calc_face_normal : 1;
/* add a vertex CD_SHAPE_KEYINDEX layer */
- unsigned int add_key_index : 1;
+ uint add_key_index : 1;
/* set vertex coordinates from the shapekey */
- unsigned int use_shapekey : 1;
+ uint use_shapekey : 1;
/* define the active shape key (index + 1) */
int active_shapekey;
};
@@ -55,7 +55,7 @@ void BM_mesh_bm_from_me(
ATTR_NONNULL(1, 3);
struct BMeshToMeshParams {
- unsigned int calc_tessface : 1;
+ uint calc_tessface : 1;
int64_t cd_mask_extra;
};
void BM_mesh_bm_to_me(
diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c b/source/blender/bmesh/intern/bmesh_opdefines.c
index 6b388a75436..a55df234264 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -1037,7 +1037,7 @@ static BMOpDefine bmo_extrude_face_region_def = {
/* slots_in */
{{"geom", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT | BM_EDGE | BM_FACE}}, /* edges and faces */
{"edges_exclude", BMO_OP_SLOT_MAPPING, {(int)BMO_OP_SLOT_SUBTYPE_MAP_EMPTY}},
- {"use_keep_orig", BMO_OP_SLOT_BOOL}, /* keep original geometry */
+ {"use_keep_orig", BMO_OP_SLOT_BOOL}, /* keep original geometry (requires ``geom`` to include edges). */
{"use_select_history", BMO_OP_SLOT_BOOL}, /* pass to duplicate */
{{'\0'}},
},
@@ -1741,6 +1741,8 @@ static BMOpDefine bmo_bevel_def = {
},
/* slots_out */
{{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}}, /* output faces */
+ {"edges.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* output edges */
+ {"verts.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_VERT}}, /* output verts */
{{'\0'}},
},
@@ -1912,7 +1914,6 @@ static BMOpDefine bmo_wireframe_def = {
{"use_even_offset", BMO_OP_SLOT_BOOL},
{"use_crease", BMO_OP_SLOT_BOOL},
{"crease_weight", BMO_OP_SLOT_FLT},
- {"thickness", BMO_OP_SLOT_FLT},
{"use_relative_offset", BMO_OP_SLOT_BOOL},
{"material_offset", BMO_OP_SLOT_INT},
{{'\0'}},
diff --git a/source/blender/bmesh/intern/bmesh_operators.c b/source/blender/bmesh/intern/bmesh_operators.c
index 706a7f74ed2..44445aae25a 100644
--- a/source/blender/bmesh/intern/bmesh_operators.c
+++ b/source/blender/bmesh/intern/bmesh_operators.c
@@ -128,7 +128,7 @@ void BMO_pop(BMesh *bm)
static void bmo_op_slots_init(const BMOSlotType *slot_types, BMOpSlot *slot_args)
{
BMOpSlot *slot;
- unsigned int i;
+ uint i;
for (i = 0; slot_types[i].type; i++) {
slot = &slot_args[i];
slot->slot_name = slot_types[i].name;
@@ -149,7 +149,7 @@ static void bmo_op_slots_init(const BMOSlotType *slot_types, BMOpSlot *slot_args
static void bmo_op_slots_free(const BMOSlotType *slot_types, BMOpSlot *slot_args)
{
BMOpSlot *slot;
- unsigned int i;
+ uint i;
for (i = 0; slot_types[i].type; i++) {
slot = &slot_args[i];
switch (slot->slot_type) {
@@ -311,9 +311,9 @@ void _bmo_slot_copy(
}
else {
/* check types */
- const unsigned int tot = slot_src->len;
- unsigned int i;
- unsigned int out = 0;
+ const uint tot = slot_src->len;
+ uint i;
+ uint out = 0;
BMElem **ele_src = (BMElem **)slot_src->data.buf;
for (i = 0; i < tot; i++, ele_src++) {
if ((*ele_src)->head.htype & dst_elem_flag) {
@@ -333,8 +333,8 @@ void _bmo_slot_copy(
}
else {
/* only copy compatible elements */
- const unsigned int tot = slot_src->len;
- unsigned int i;
+ const uint tot = slot_src->len;
+ uint i;
BMElem **ele_src = (BMElem **)slot_src->data.buf;
BMElem **ele_dst = (BMElem **)slot_dst->data.buf;
for (i = 0; i < tot; i++, ele_src++) {
@@ -1639,8 +1639,8 @@ static int bmo_name_to_slotcode_check(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], cons
int BMO_opcode_from_opname(const char *opname)
{
- const unsigned int tot = bmo_opdefines_total;
- unsigned int i;
+ const uint tot = bmo_opdefines_total;
+ uint i;
for (i = 0; i < tot; i++) {
if (STREQ(bmo_opdefines[i]->opname, opname)) {
return i;
diff --git a/source/blender/bmesh/intern/bmesh_operators.h b/source/blender/bmesh/intern/bmesh_operators.h
index 0a4fb1d56a4..b670f31ad9f 100644
--- a/source/blender/bmesh/intern/bmesh_operators.h
+++ b/source/blender/bmesh/intern/bmesh_operators.h
@@ -141,12 +141,19 @@ void BM_mesh_esubdivide(
const short use_only_quads,
const int seed);
-void BM_mesh_calc_uvs_grid(BMesh *bm, const unsigned int x_segments, const unsigned int y_segments, const short oflag);
-void BM_mesh_calc_uvs_sphere(BMesh *bm, const short oflag);
-void BM_mesh_calc_uvs_circle(BMesh *bm, float mat[4][4], const float radius, const short oflag);
+void BM_mesh_calc_uvs_grid(
+ BMesh *bm, const uint x_segments, const uint y_segments,
+ const short oflag, const int cd_loop_uv_offset);
+void BM_mesh_calc_uvs_sphere(
+ BMesh *bm,
+ const short oflag, const int cd_loop_uv_offset);
+void BM_mesh_calc_uvs_circle(
+ BMesh *bm, float mat[4][4], const float radius,
+ const short oflag, const int cd_loop_uv_offset);
void BM_mesh_calc_uvs_cone(
BMesh *bm, float mat[4][4],
- const float radius_top, const float radius_bottom, const int segments, const bool cap_ends, const short oflag);
+ const float radius_top, const float radius_bottom, const int segments, const bool cap_ends,
+ const short oflag, const int cd_loop_uv_offset);
void BM_mesh_calc_uvs_cube(BMesh *bm, const short oflag);
#include "intern/bmesh_operator_api_inline.h"
diff --git a/source/blender/bmesh/intern/bmesh_polygon.c b/source/blender/bmesh/intern/bmesh_polygon.c
index 78ee7589d23..a4621b45fe6 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.c
+++ b/source/blender/bmesh/intern/bmesh_polygon.c
@@ -132,7 +132,7 @@ static void bm_face_calc_poly_center_mean_vertex_cos(
*/
void BM_face_calc_tessellation(
const BMFace *f, const bool use_fixed_quad,
- BMLoop **r_loops, unsigned int (*r_index)[3])
+ BMLoop **r_loops, uint (*r_index)[3])
{
BMLoop *l_first = BM_FACE_FIRST_LOOP(f);
BMLoop *l_iter;
@@ -196,7 +196,7 @@ void BM_face_calc_point_in_face(const BMFace *f, float r_co[3])
* but without this we can't be sure the point is inside a concave face. */
const int tottri = f->len - 2;
BMLoop **loops = BLI_array_alloca(loops, f->len);
- unsigned int (*index)[3] = BLI_array_alloca(index, tottri);
+ uint (*index)[3] = BLI_array_alloca(index, tottri);
int j;
int j_best = 0; /* use as fallback when unset */
float area_best = -1.0f;
@@ -575,11 +575,11 @@ void BM_face_calc_center_mean_weighted(const BMFace *f, float r_cent[3])
* Rotates a polygon so that it's
* normal is pointing towards the mesh Z axis
*/
-void poly_rotate_plane(const float normal[3], float (*verts)[3], const unsigned int nverts)
+void poly_rotate_plane(const float normal[3], float (*verts)[3], const uint nverts)
{
float mat[3][3];
float co[3];
- unsigned int i;
+ uint i;
co[2] = 0.0f;
@@ -941,7 +941,7 @@ void BM_face_triangulate(
{
BMLoop **loops = BLI_array_alloca(loops, f->len);
- unsigned int (*tris)[3] = BLI_array_alloca(tris, f->len);
+ uint (*tris)[3] = BLI_array_alloca(tris, f->len);
const int totfilltri = f->len - 2;
const int last_tri = f->len - 3;
int i;
@@ -1425,7 +1425,7 @@ void BM_mesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptri
float axis_mat[3][3];
float (*projverts)[2];
- unsigned int (*tris)[3];
+ uint (*tris)[3];
const int totfilltri = efa->len - 2;
@@ -1451,7 +1451,7 @@ void BM_mesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptri
for (j = 0; j < totfilltri; j++) {
BMLoop **l_ptr = looptris[i++];
- unsigned int *tri = tris[j];
+ uint *tri = tris[j];
l_ptr[0] = l_arr[tri[0]];
l_ptr[1] = l_arr[tri[1]];
diff --git a/source/blender/bmesh/intern/bmesh_polygon.h b/source/blender/bmesh/intern/bmesh_polygon.h
index 1e50a504875..d944f3a8bc5 100644
--- a/source/blender/bmesh/intern/bmesh_polygon.h
+++ b/source/blender/bmesh/intern/bmesh_polygon.h
@@ -36,7 +36,7 @@ void BM_mesh_calc_tessellation(BMesh *bm, BMLoop *(*looptris)[3], int *r_looptr
void BM_face_calc_tessellation(
const BMFace *f, const bool use_fixed_quad,
- BMLoop **r_loops, unsigned int (*r_index)[3]);
+ BMLoop **r_loops, uint (*r_index)[3]);
void BM_face_calc_point_in_face(const BMFace *f, float r_co[3]);
float BM_face_calc_normal(const BMFace *f, float r_no[3]) ATTR_NONNULL();
float BM_face_calc_normal_vcos(
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
index 6ce7c100b0d..e515f9af63f 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.c
@@ -62,15 +62,16 @@
#define EDGE_NET _FLAG_WALK
/* tag verts we've visit */
#define VERT_VISIT _FLAG_WALK
+#define VERT_IN_QUEUE _FLAG_WALK_ALT
struct VertOrder {
float angle;
BMVert *v;
};
-static unsigned int bm_edge_flagged_radial_count(BMEdge *e)
+static uint bm_edge_flagged_radial_count(BMEdge *e)
{
- unsigned int count = 0;
+ uint count = 0;
BMLoop *l;
if ((l = e->l)) {
@@ -133,7 +134,7 @@ static bool bm_face_split_edgenet_find_loop_pair(
e = e_first = v_init->e;
do {
if (BM_ELEM_API_FLAG_TEST(e, EDGE_NET)) {
- const unsigned int count = bm_edge_flagged_radial_count(e);
+ const uint count = bm_edge_flagged_radial_count(e);
if (count == 1) {
BLI_SMALLSTACK_PUSH(edges_boundary, e);
edges_boundary_len++;
@@ -238,7 +239,7 @@ static bool bm_face_split_edgenet_find_loop_pair_exists(
e = e_first = v_init->e;
do {
if (BM_ELEM_API_FLAG_TEST(e, EDGE_NET)) {
- const unsigned int count = bm_edge_flagged_radial_count(e);
+ const uint count = bm_edge_flagged_radial_count(e);
if (count == 1) {
edges_boundary_len++;
}
@@ -274,7 +275,7 @@ static bool bm_face_split_edgenet_find_loop_pair_exists(
static bool bm_face_split_edgenet_find_loop_walk(
BMVert *v_init, const float face_normal[3],
/* cache to avoid realloc every time */
- struct VertOrder *edge_order, const unsigned int edge_order_len,
+ struct VertOrder *edge_order, const uint edge_order_len,
BMEdge *e_pair[2])
{
/* fast-path for the common case (avoid push-pop).
@@ -381,7 +382,7 @@ walk_nofork:
/* sort by angle if needed */
if (STACK_SIZE(edge_order) > 1) {
- unsigned int j;
+ uint j;
BMVert *v_prev = BM_edge_other_vert(v->e, v);
for (j = 0; j < STACK_SIZE(edge_order); j++) {
@@ -420,7 +421,7 @@ finally:
static bool bm_face_split_edgenet_find_loop(
BMVert *v_init, const float face_normal[3], float face_normal_matrix[3][3],
/* cache to avoid realloc every time */
- struct VertOrder *edge_order, const unsigned int edge_order_len,
+ struct VertOrder *edge_order, const uint edge_order_len,
BMVert **r_face_verts, int *r_face_verts_len)
{
BMEdge *e_pair[2];
@@ -434,7 +435,7 @@ static bool bm_face_split_edgenet_find_loop(
(bm_edge_flagged_radial_count(e_pair[1]) == 1));
if (bm_face_split_edgenet_find_loop_walk(v_init, face_normal, edge_order, edge_order_len, e_pair)) {
- unsigned int i = 0;
+ uint i = 0;
r_face_verts[i++] = v_init;
v = BM_edge_other_vert(e_pair[1], v_init);
@@ -474,7 +475,7 @@ bool BM_face_split_edgenet(
int i;
struct VertOrder *edge_order;
- const unsigned int edge_order_len = edge_net_len + 2;
+ const uint edge_order_len = edge_net_len + 2;
BMVert *v;
@@ -512,13 +513,21 @@ bool BM_face_split_edgenet(
} while ((l_iter = l_iter->next) != l_first);
#endif
+ /* Note: 'VERT_IN_QUEUE' is often not needed at all,
+ * however in rare cases verts are added multiple times to the queue,
+ * that on it's own is harmless but in _very_ rare cases,
+ * the queue will overflow its maximum size,
+ * so we better be strict about this! see: T51539 */
for (i = 0; i < edge_net_len; i++) {
BM_ELEM_API_FLAG_ENABLE(edge_net[i], EDGE_NET);
+ BM_ELEM_API_FLAG_DISABLE(edge_net[i]->v1, VERT_IN_QUEUE);
+ BM_ELEM_API_FLAG_DISABLE(edge_net[i]->v2, VERT_IN_QUEUE);
}
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
BM_ELEM_API_FLAG_ENABLE(l_iter->e, EDGE_NET);
+ BM_ELEM_API_FLAG_DISABLE(l_iter->v, VERT_IN_QUEUE);
} while ((l_iter = l_iter->next) != l_first);
float face_normal_matrix[3][3];
@@ -527,8 +536,10 @@ bool BM_face_split_edgenet(
/* any vert can be used to begin with */
STACK_PUSH(vert_queue, l_first->v);
+ BM_ELEM_API_FLAG_ENABLE(l_first->v, VERT_IN_QUEUE);
while ((v = STACK_POP(vert_queue))) {
+ BM_ELEM_API_FLAG_DISABLE(v, VERT_IN_QUEUE);
if (bm_face_split_edgenet_find_loop(
v, f->no, face_normal_matrix,
edge_order, edge_order_len, face_verts, &face_verts_len))
@@ -558,8 +569,12 @@ bool BM_face_split_edgenet(
* (verts between boundary and manifold edges) */
l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
do {
- if (bm_face_split_edgenet_find_loop_pair_exists(l_iter->v)) {
+ /* Avoid adding to queue multiple times (not common but happens). */
+ if (!BM_ELEM_API_FLAG_TEST(l_iter->v, VERT_IN_QUEUE) &&
+ bm_face_split_edgenet_find_loop_pair_exists(l_iter->v))
+ {
STACK_PUSH(vert_queue, l_iter->v);
+ BM_ELEM_API_FLAG_ENABLE(l_iter->v, VERT_IN_QUEUE);
}
} while ((l_iter = l_iter->next) != l_first);
}
@@ -721,13 +736,13 @@ BLI_INLINE bool edge_isect_verts_point_2d(
*/
struct EdgeGroupIsland {
LinkNode edge_links; /* keep first */
- unsigned int vert_len, edge_len;
+ uint vert_len, edge_len;
/* Set the following vars once we have >1 groups */
/* when when an edge in a previous group connects to this one,
* so theres no need to create one pointing back. */
- unsigned int has_prev_edge : 1;
+ uint has_prev_edge : 1;
/* verts in the group which has the lowest & highest values,
* the lower vertex is connected to the first edge */
@@ -758,7 +773,7 @@ struct Edges_VertVert_BVHTreeTest {
BMVert *v_origin;
BMVert *v_other;
- const unsigned int *vert_range;
+ const uint *vert_range;
};
struct Edges_VertRay_BVHTreeTest {
@@ -766,7 +781,7 @@ struct Edges_VertRay_BVHTreeTest {
BMVert *v_origin;
- const unsigned int *vert_range;
+ const uint *vert_range;
};
static void bvhtree_test_edges_isect_2d_vert_cb(
@@ -831,12 +846,12 @@ static void bvhtree_test_edges_isect_2d_ray_cb(
struct EdgeGroup_FindConnection_Args {
BVHTree *bvhtree;
BMEdge **edge_arr;
- unsigned int edge_arr_len;
+ uint edge_arr_len;
BMEdge **edge_arr_new;
- unsigned int edge_arr_new_len;
+ uint edge_arr_new_len;
- const unsigned int *vert_range;
+ const uint *vert_range;
};
static BMEdge *test_edges_isect_2d_vert(
@@ -869,7 +884,7 @@ static BMEdge *test_edges_isect_2d_vert(
/* check existing connections (no spatial optimization here since we're continually adding). */
if (LIKELY(index == -1)) {
float t_best = 1.0f;
- for (unsigned int i = 0; i < args->edge_arr_new_len; i++) {
+ for (uint i = 0; i < args->edge_arr_new_len; i++) {
float co_isect[2];
if (UNLIKELY(edge_isect_verts_point_2d(args->edge_arr_new[i], v_origin, v_other, co_isect))) {
const float t_test = line_point_factor_v2(co_isect, v_origin->co, v_other->co);
@@ -914,7 +929,7 @@ static BMEdge *test_edges_isect_2d_ray(
/* check existing connections (no spatial optimization here since we're continually adding). */
if (LIKELY(index != -1)) {
- for (unsigned int i = 0; i < args->edge_arr_new_len; i++) {
+ for (uint i = 0; i < args->edge_arr_new_len; i++) {
BMEdge *e = args->edge_arr_new[i];
float dist_new;
if (isect_ray_seg_v2(v_origin->co, dir, e->v1->co, e->v2->co, &dist_new, NULL)) {
@@ -1031,7 +1046,7 @@ static BMVert *bm_face_split_edgenet_partial_connect(BMesh *bm, BMVert *v_delimi
/* initial check - see if we have 3+ flagged edges attached to 'v_delimit'
* if not, we can early exit */
LinkNode *e_delimit_list = NULL;
- unsigned int e_delimit_list_len = 0;
+ uint e_delimit_list_len = 0;
#define EDGE_NOT_IN_STACK BM_ELEM_INTERNAL_TAG
#define VERT_NOT_IN_STACK BM_ELEM_INTERNAL_TAG
@@ -1169,10 +1184,10 @@ static bool bm_vert_partial_connect_check_overlap(
*/
bool BM_face_split_edgenet_connect_islands(
BMesh *bm,
- BMFace *f, BMEdge **edge_net_init, const unsigned int edge_net_init_len,
+ BMFace *f, BMEdge **edge_net_init, const uint edge_net_init_len,
bool use_partial_connect,
MemArena *mem_arena,
- BMEdge ***r_edge_net_new, unsigned int *r_edge_net_new_len)
+ BMEdge ***r_edge_net_new, uint *r_edge_net_new_len)
{
/* -------------------------------------------------------------------- */
/* This function has 2 main parts.
@@ -1186,7 +1201,7 @@ bool BM_face_split_edgenet_connect_islands(
* (avoid thrashing the area when the initial check isn't so intensive on the stack).
*/
- const unsigned int edge_arr_len = (unsigned int)edge_net_init_len + (unsigned int)f->len;
+ const uint edge_arr_len = (uint)edge_net_init_len + (uint)f->len;
BMEdge **edge_arr = BLI_array_alloca(edge_arr, edge_arr_len);
bool ok = false;
@@ -1197,7 +1212,7 @@ bool BM_face_split_edgenet_connect_islands(
#define VERT_NOT_IN_STACK BM_ELEM_INTERNAL_TAG
{
- unsigned int i = edge_net_init_len;
+ uint i = edge_net_init_len;
BMLoop *l_iter, *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f);
do {
@@ -1206,7 +1221,7 @@ bool BM_face_split_edgenet_connect_islands(
BLI_assert(i == edge_arr_len);
}
- for (unsigned int i = 0; i < edge_arr_len; i++) {
+ for (uint i = 0; i < edge_arr_len; i++) {
BM_elem_flag_enable(edge_arr[i], EDGE_NOT_IN_STACK);
BM_elem_flag_enable(edge_arr[i]->v1, VERT_NOT_IN_STACK);
BM_elem_flag_enable(edge_arr[i]->v2, VERT_NOT_IN_STACK);
@@ -1224,12 +1239,12 @@ bool BM_face_split_edgenet_connect_islands(
struct {
struct TempVertPair *list;
- unsigned int len;
+ uint len;
int *remap; /* temp -> orig mapping */
} temp_vert_pairs = {NULL};
if (use_partial_connect) {
- for (unsigned int i = 0; i < edge_net_init_len; i++) {
+ for (uint i = 0; i < edge_net_init_len; i++) {
for (unsigned j = 0; j < 2; j++) {
BMVert *v_delimit = (&edge_arr[i]->v1)[j];
BMVert *v_other;
@@ -1254,19 +1269,19 @@ bool BM_face_split_edgenet_connect_islands(
- unsigned int group_arr_len = 0;
+ uint group_arr_len = 0;
LinkNode *group_head = NULL;
{
/* scan 'edge_arr' backwards so the outer face boundary is handled first
* (since its likely to be the largest) */
- unsigned int edge_index = (edge_arr_len - 1);
- unsigned int edge_in_group_tot = 0;
+ uint edge_index = (edge_arr_len - 1);
+ uint edge_in_group_tot = 0;
BLI_SMALLSTACK_DECLARE(vstack, BMVert *);
while (true) {
LinkNode *edge_links = NULL;
- unsigned int unique_verts_in_group = 0, unique_edges_in_group = 0;
+ uint unique_verts_in_group = 0, unique_edges_in_group = 0;
/* list of groups */
BLI_assert(BM_elem_flag_test(edge_arr[edge_index]->v1, VERT_NOT_IN_STACK));
@@ -1333,7 +1348,7 @@ bool BM_face_split_edgenet_connect_islands(
#define VERT_IN_ARRAY BM_ELEM_INTERNAL_TAG
struct EdgeGroupIsland **group_arr = BLI_memarena_alloc(mem_arena, sizeof(*group_arr) * group_arr_len);
- unsigned int vert_arr_len = 0;
+ uint vert_arr_len = 0;
/* sort groups by lowest value vertex */
{
/* fill 'groups_arr' in reverse order so the boundary face is first */
@@ -1389,7 +1404,7 @@ bool BM_face_split_edgenet_connect_islands(
/* we don't know how many unique verts there are connecting the edges, so over-alloc */
BMVert **vert_arr = BLI_memarena_alloc(mem_arena, sizeof(*vert_arr) * vert_arr_len);
/* map vertex -> group index */
- unsigned int *verts_group_table = BLI_memarena_alloc(mem_arena, sizeof(*verts_group_table) * vert_arr_len);
+ uint *verts_group_table = BLI_memarena_alloc(mem_arena, sizeof(*verts_group_table) * vert_arr_len);
float (*vert_coords_backup)[3] = BLI_memarena_alloc(mem_arena, sizeof(*vert_coords_backup) * vert_arr_len);
@@ -1398,7 +1413,7 @@ bool BM_face_split_edgenet_connect_islands(
const float f_co_ref[3] = {UNPACK3(BM_FACE_FIRST_LOOP(f)->v->co)};
int v_index = 0; /* global vert index */
- for (unsigned int g_index = 0; g_index < group_arr_len; g_index++) {
+ for (uint g_index = 0; g_index < group_arr_len; g_index++) {
LinkNode *edge_links = group_arr[g_index]->edge_links.link;
do {
BMEdge *e = edge_links->link;
@@ -1436,7 +1451,7 @@ bool BM_face_split_edgenet_connect_islands(
/* Now create bvh tree*/
BVHTree *bvhtree = BLI_bvhtree_new(edge_arr_len, 0.0f, 8, 8);
- for (unsigned int i = 0; i < edge_arr_len; i++) {
+ for (uint i = 0; i < edge_arr_len; i++) {
const float e_cos[2][3] = {
{UNPACK2(edge_arr[i]->v1->co), 0.0f},
{UNPACK2(edge_arr[i]->v2->co), 0.0f},
@@ -1465,15 +1480,15 @@ bool BM_face_split_edgenet_connect_islands(
/* Create connections between groups */
/* may be an over-alloc, but not by much */
- unsigned int edge_net_new_len = (unsigned int)edge_net_init_len + ((group_arr_len - 1) * 2);
+ uint edge_net_new_len = (uint)edge_net_init_len + ((group_arr_len - 1) * 2);
BMEdge **edge_net_new = BLI_memarena_alloc(mem_arena, sizeof(*edge_net_new) * edge_net_new_len);
memcpy(edge_net_new, edge_net_init, sizeof(*edge_net_new) * (size_t)edge_net_init_len);
{
- unsigned int edge_net_new_index = edge_net_init_len;
+ uint edge_net_new_index = edge_net_init_len;
/* start-end of the verts in the current group */
- unsigned int vert_range[2];
+ uint vert_range[2];
vert_range[0] = 0;
vert_range[1] = group_arr[0]->vert_len;
@@ -1492,7 +1507,7 @@ bool BM_face_split_edgenet_connect_islands(
.vert_range = vert_range,
};
- for (unsigned int g_index = 1; g_index < group_arr_len; g_index++) {
+ for (uint g_index = 1; g_index < group_arr_len; g_index++) {
struct EdgeGroupIsland *g = group_arr[g_index];
/* the range of verts this group uses in 'verts_arr' (not uncluding the last index) */
@@ -1551,7 +1566,7 @@ bool BM_face_split_edgenet_connect_islands(
}
/* tell the 'next' group it doesn't need to create its own back-link */
- unsigned int g_index_other = verts_group_table[index_other];
+ uint g_index_other = verts_group_table[index_other];
group_arr[g_index_other]->has_prev_edge = true;
}
}
@@ -1567,7 +1582,7 @@ bool BM_face_split_edgenet_connect_islands(
*r_edge_net_new_len = edge_net_new_len;
ok = true;
- for (unsigned int i = 0; i < vert_arr_len; i++) {
+ for (uint i = 0; i < vert_arr_len; i++) {
copy_v3_v3(vert_arr[i]->co, vert_coords_backup[i]);
}
@@ -1600,7 +1615,7 @@ finally:
/* Remove edges which have become doubles since splicing vertices together,
* its less trouble then detecting future-doubles on edge-creation. */
- for (unsigned int i = edge_net_init_len; i < edge_net_new_len; i++) {
+ for (uint i = edge_net_init_len; i < edge_net_new_len; i++) {
while (BM_edge_find_double(edge_net_new[i])) {
BM_edge_kill(bm, edge_net_new[i]);
edge_net_new_len--;
@@ -1616,7 +1631,7 @@ finally:
#endif
- for (unsigned int i = 0; i < edge_arr_len; i++) {
+ for (uint i = 0; i < edge_arr_len; i++) {
BM_elem_flag_disable(edge_arr[i], EDGE_NOT_IN_STACK);
BM_elem_flag_disable(edge_arr[i]->v1, VERT_NOT_IN_STACK);
BM_elem_flag_disable(edge_arr[i]->v2, VERT_NOT_IN_STACK);
diff --git a/source/blender/bmesh/intern/bmesh_polygon_edgenet.h b/source/blender/bmesh/intern/bmesh_polygon_edgenet.h
index 72ae7695f0f..bf5cea59e30 100644
--- a/source/blender/bmesh/intern/bmesh_polygon_edgenet.h
+++ b/source/blender/bmesh/intern/bmesh_polygon_edgenet.h
@@ -32,10 +32,10 @@ bool BM_face_split_edgenet(
bool BM_face_split_edgenet_connect_islands(
BMesh *bm,
- BMFace *f, BMEdge **edge_net_init, const unsigned int edge_net_init_len,
+ BMFace *f, BMEdge **edge_net_init, const uint edge_net_init_len,
bool use_partial_connect,
struct MemArena *arena,
- BMEdge ***r_edge_net_new, unsigned int *r_edge_net_new_len)
+ BMEdge ***r_edge_net_new, uint *r_edge_net_new_len)
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2, 3, 6, 7, 8);
#endif /* __BMESH_POLYGON_EDGENET_H__ */
diff --git a/source/blender/bmesh/intern/bmesh_private.h b/source/blender/bmesh/intern/bmesh_private.h
index d8d297c9298..4161fbe90fb 100644
--- a/source/blender/bmesh/intern/bmesh_private.h
+++ b/source/blender/bmesh/intern/bmesh_private.h
@@ -73,7 +73,7 @@ enum {
};
#define BM_ELEM_API_FLAG_ENABLE(element, f) { ((element)->head.api_flag |= (f)); } (void)0
-#define BM_ELEM_API_FLAG_DISABLE(element, f) { ((element)->head.api_flag &= (unsigned char)~(f)); } (void)0
+#define BM_ELEM_API_FLAG_DISABLE(element, f) { ((element)->head.api_flag &= (uchar)~(f)); } (void)0
#define BM_ELEM_API_FLAG_TEST(element, f) ((element)->head.api_flag & (f))
#define BM_ELEM_API_FLAG_CLEAR(element) { ((element)->head.api_flag = 0); } (void)0
diff --git a/source/blender/bmesh/intern/bmesh_queries.c b/source/blender/bmesh/intern/bmesh_queries.c
index 7ca5640578a..668fb998254 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -1511,20 +1511,68 @@ float BM_loop_calc_face_angle(const BMLoop *l)
* Calculate the normal at this loop corner or fallback to the face normal on straight lines.
*
* \param l The loop to calculate the normal at
+ * \param epsilon: Value to avoid numeric errors (1e-5f works well).
* \param r_normal Resulting normal
*/
-void BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3])
+float BM_loop_calc_face_normal_safe_ex(const BMLoop *l, const float epsilon_sq, float r_normal[3])
{
- if (normal_tri_v3(r_normal,
- l->prev->v->co,
- l->v->co,
- l->next->v->co) != 0.0f)
- {
- /* pass */
+ /* Note: we cannot use result of normal_tri_v3 here to detect colinear vectors (vertex on a straight line)
+ * from zero value, because it does not normalize both vectors before making crossproduct.
+ * Instead of adding two costly normalize computations, just check ourselves for colinear case. */
+ /* Note: FEPSILON might need some finer tweaking at some point? Seems to be working OK for now though. */
+ float v1[3], v2[3], v_tmp[3];
+ sub_v3_v3v3(v1, l->prev->v->co, l->v->co);
+ sub_v3_v3v3(v2, l->next->v->co, l->v->co);
+
+ const float fac =
+ ((v2[0] == 0.0f) ?
+ ((v2[1] == 0.0f) ?
+ ((v2[2] == 0.0f) ? 0.0f : v1[2] / v2[2]) : v1[1] / v2[1]) : v1[0] / v2[0]);
+
+ mul_v3_v3fl(v_tmp, v2, fac);
+ sub_v3_v3(v_tmp, v1);
+ if (fac != 0.0f && !is_zero_v3(v1) && len_squared_v3(v_tmp) > epsilon_sq) {
+ /* Not co-linear, we can compute crossproduct and normalize it into normal. */
+ cross_v3_v3v3(r_normal, v1, v2);
+ return normalize_v3(r_normal);
}
else {
copy_v3_v3(r_normal, l->f->no);
+ return 0.0f;
+ }
+}
+
+/**
+ * #BM_loop_calc_face_normal_safe_ex with pre-defined sane epsilon.
+ *
+ * Since this doesn't scale baed on triangle size, fixed value works well.
+ */
+float BM_loop_calc_face_normal_safe(const BMLoop *l, float r_normal[3])
+{
+ return BM_loop_calc_face_normal_safe_ex(l, 1e-5f, r_normal);
+}
+
+/**
+ * \brief BM_loop_calc_face_normal
+ *
+ * Calculate the normal at this loop corner or fallback to the face normal on straight lines.
+ *
+ * \param l The loop to calculate the normal at
+ * \param r_normal Resulting normal
+ * \return The length of the cross product (double the area).
+ */
+float BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3])
+{
+ float v1[3], v2[3];
+ sub_v3_v3v3(v1, l->prev->v->co, l->v->co);
+ sub_v3_v3v3(v2, l->next->v->co, l->v->co);
+
+ cross_v3_v3v3(r_normal, v1, v2);
+ const float len = normalize_v3(r_normal);
+ if (UNLIKELY(len == 0.0f)) {
+ copy_v3_v3(r_normal, l->f->no);
}
+ return len;
}
/**
@@ -2326,7 +2374,7 @@ static void bm_mesh_calc_volume_face(const BMFace *f, float *r_vol)
{
const int tottri = f->len - 2;
BMLoop **loops = BLI_array_alloca(loops, f->len);
- unsigned int (*index)[3] = BLI_array_alloca(index, tottri);
+ uint (*index)[3] = BLI_array_alloca(index, tottri);
int j;
BM_face_calc_tessellation(f, false, loops, index);
@@ -2395,8 +2443,8 @@ int BM_mesh_calc_face_groups(
int group_curr = 0;
- unsigned int tot_faces = 0;
- unsigned int tot_touch = 0;
+ uint tot_faces = 0;
+ uint tot_touch = 0;
BMFace **stack;
STACK_DECLARE(stack);
@@ -2553,8 +2601,8 @@ int BM_mesh_calc_edge_groups(
int group_curr = 0;
- unsigned int tot_edges = 0;
- unsigned int tot_touch = 0;
+ uint tot_edges = 0;
+ uint tot_touch = 0;
BMEdge **stack;
STACK_DECLARE(stack);
diff --git a/source/blender/bmesh/intern/bmesh_queries.h b/source/blender/bmesh/intern/bmesh_queries.h
index 903fdc59cb8..83977fa8be0 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -113,7 +113,9 @@ BMLoop *BM_loop_find_prev_nodouble(BMLoop *l, BMLoop *l_stop, const float eps_sq
BMLoop *BM_loop_find_next_nodouble(BMLoop *l, BMLoop *l_stop, const float eps_sq);
float BM_loop_calc_face_angle(const BMLoop *l) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
-void BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3]) ATTR_NONNULL();
+float BM_loop_calc_face_normal(const BMLoop *l, float r_normal[3]) ATTR_NONNULL();
+float BM_loop_calc_face_normal_safe(const BMLoop *l, float r_normal[3]) ATTR_NONNULL();
+float BM_loop_calc_face_normal_safe_ex(const BMLoop *l, const float epsilon, float r_normal[3]) ATTR_NONNULL();
void BM_loop_calc_face_direction(const BMLoop *l, float r_normal[3]);
void BM_loop_calc_face_tangent(const BMLoop *l, float r_tangent[3]);
diff --git a/source/blender/bmesh/operators/bmo_bevel.c b/source/blender/bmesh/operators/bmo_bevel.c
index d5afb39d7b7..2ae87b64286 100644
--- a/source/blender/bmesh/operators/bmo_bevel.c
+++ b/source/blender/bmesh/operators/bmo_bevel.c
@@ -66,5 +66,7 @@ void bmo_bevel_exec(BMesh *bm, BMOperator *op)
BM_mesh_bevel(bm, offset, offset_type, seg, profile, vonly, false, clamp_overlap, NULL, -1, material, loop_slide);
BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "faces.out", BM_FACE, BM_ELEM_TAG);
+ BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "edges.out", BM_EDGE, BM_ELEM_TAG);
+ BMO_slot_buffer_from_enabled_hflag(bm, op, op->slots_out, "verts.out", BM_VERT, BM_ELEM_TAG);
}
}
diff --git a/source/blender/bmesh/operators/bmo_connect.c b/source/blender/bmesh/operators/bmo_connect.c
index 5c9cd8dc3fa..c5c4ac959a9 100644
--- a/source/blender/bmesh/operators/bmo_connect.c
+++ b/source/blender/bmesh/operators/bmo_connect.c
@@ -55,7 +55,7 @@ static int bm_face_connect_verts(BMesh *bm, BMFace *f, const bool check_degenera
BMLoop *l_tag_prev = NULL, *l_tag_first = NULL;
BMLoop *l_iter, *l_first;
- unsigned int i;
+ uint i;
STACK_INIT(loops_split, pair_split_max);
STACK_INIT(verts_pair, pair_split_max);
diff --git a/source/blender/bmesh/operators/bmo_connect_nonplanar.c b/source/blender/bmesh/operators/bmo_connect_nonplanar.c
index b8acc9d09b8..67590fe8ef9 100644
--- a/source/blender/bmesh/operators/bmo_connect_nonplanar.c
+++ b/source/blender/bmesh/operators/bmo_connect_nonplanar.c
@@ -67,8 +67,8 @@ static bool bm_face_split_find(BMesh *bm, BMFace *f, BMLoop *l_pair[2], float *r
{
BMLoop *l_iter, *l_first;
BMLoop **l_arr = BLI_array_alloca(l_arr, f->len);
- const unsigned int f_len = f->len;
- unsigned int i_a, i_b;
+ const uint f_len = f->len;
+ uint i_a, i_b;
bool found = false;
/* angle finding */
diff --git a/source/blender/bmesh/operators/bmo_connect_pair.c b/source/blender/bmesh/operators/bmo_connect_pair.c
index a73c86fd122..b474ad9fc7b 100644
--- a/source/blender/bmesh/operators/bmo_connect_pair.c
+++ b/source/blender/bmesh/operators/bmo_connect_pair.c
@@ -530,8 +530,8 @@ static void bm_vert_pair_to_matrix(BMVert *v_pair[2], float r_unit_mat[3][3])
float basis_nor_b[3];
/* align normal to direction */
- project_plane_v3_v3v3(basis_nor_a, v_pair[0]->no, basis_dir);
- project_plane_v3_v3v3(basis_nor_b, v_pair[1]->no, basis_dir);
+ project_plane_normalized_v3_v3v3(basis_nor_a, v_pair[0]->no, basis_dir);
+ project_plane_normalized_v3_v3v3(basis_nor_b, v_pair[1]->no, basis_dir);
/* don't normalize before combining so as normals approach the direction, they have less effect (T46784). */
@@ -569,7 +569,7 @@ static void bm_vert_pair_to_matrix(BMVert *v_pair[2], float r_unit_mat[3][3])
float angle_cos_test;
/* project basis dir onto the normal to find its closest angle */
- project_plane_v3_v3v3(basis_dir_proj, basis_dir, l->f->no);
+ project_plane_normalized_v3_v3v3(basis_dir_proj, basis_dir, l->f->no);
if (normalize_v3(basis_dir_proj) > eps) {
angle_cos_test = dot_v3v3(basis_dir_proj, basis_dir);
@@ -586,7 +586,7 @@ static void bm_vert_pair_to_matrix(BMVert *v_pair[2], float r_unit_mat[3][3])
* note: we could add the directions,
* but this more often gives 45d rotated matrix, so just use the best one. */
copy_v3_v3(basis_nor, axis_pair[axis_pair[0].angle_cos < axis_pair[1].angle_cos].nor);
- project_plane_v3_v3v3(basis_nor, basis_nor, basis_dir);
+ project_plane_normalized_v3_v3v3(basis_nor, basis_nor, basis_dir);
cross_v3_v3v3(basis_tmp, basis_dir, basis_nor);
diff --git a/source/blender/bmesh/operators/bmo_create.c b/source/blender/bmesh/operators/bmo_create.c
index a980baf8626..fa08d009d40 100644
--- a/source/blender/bmesh/operators/bmo_create.c
+++ b/source/blender/bmesh/operators/bmo_create.c
@@ -74,13 +74,13 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
BMVert *verts[2];
BMEdge *e;
- BMO_iter_as_array(op->slots_in, "geom", BM_VERT, (void **)verts, 2);
-
- /* create edge */
- e = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE);
- BMO_edge_flag_enable(bm, e, ELE_OUT);
- tote += 1;
- BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT);
+ if (BMO_iter_as_array(op->slots_in, "geom", BM_VERT, (void **)verts, 2) == 2) {
+ /* create edge */
+ e = BM_edge_create(bm, verts[0], verts[1], NULL, BM_CREATE_NO_DOUBLE);
+ BMO_edge_flag_enable(bm, e, ELE_OUT);
+ tote += 1;
+ BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "edges.out", BM_EDGE, ELE_OUT);
+ }
return;
}
@@ -283,13 +283,13 @@ void bmo_contextual_create_exec(BMesh *bm, BMOperator *op)
*/
if (totv > 2) {
/* TODO, some of these vertes may be connected by edges,
- * this connectivity could be used rather then treating
+ * this connectivity could be used rather than treating
* them as a bunch of isolated verts. */
BMVert **vert_arr = MEM_mallocN(sizeof(BMVert *) * totv, __func__);
BMFace *f;
- BMO_iter_as_array(op->slots_in, "geom", BM_VERT, (void **)vert_arr, totv);
+ totv = BMO_iter_as_array(op->slots_in, "geom", BM_VERT, (void **)vert_arr, totv);
BM_verts_sort_radial_plane(vert_arr, totv);
diff --git a/source/blender/bmesh/operators/bmo_dissolve.c b/source/blender/bmesh/operators/bmo_dissolve.c
index 6e3a8a1473d..2df8e73c2b8 100644
--- a/source/blender/bmesh/operators/bmo_dissolve.c
+++ b/source/blender/bmesh/operators/bmo_dissolve.c
@@ -309,7 +309,7 @@ void bmo_dissolve_edges_exec(BMesh *bm, BMOperator *op)
BMO_ITER (e, &eiter, op->slots_in, "edges", BM_EDGE) {
BMFace *f_pair[2];
if (BM_edge_face_pair(e, &f_pair[0], &f_pair[1])) {
- unsigned int j;
+ uint j;
for (j = 0; j < 2; j++) {
BMLoop *l_first, *l_iter;
l_iter = l_first = BM_FACE_FIRST_LOOP(f_pair[j]);
diff --git a/source/blender/bmesh/operators/bmo_dupe.c b/source/blender/bmesh/operators/bmo_dupe.c
index 8048add84d4..e35c1f3b66c 100644
--- a/source/blender/bmesh/operators/bmo_dupe.c
+++ b/source/blender/bmesh/operators/bmo_dupe.c
@@ -83,7 +83,7 @@ static BMEdge *bmo_edge_copy(
{
BMEdge *e_dst;
BMVert *e_dst_v1, *e_dst_v2;
- unsigned int rlen;
+ uint rlen;
/* see if any of the neighboring faces are
* not being duplicated. in that case,
diff --git a/source/blender/bmesh/operators/bmo_fill_attribute.c b/source/blender/bmesh/operators/bmo_fill_attribute.c
index 233ed746ed4..dcf2570dff4 100644
--- a/source/blender/bmesh/operators/bmo_fill_attribute.c
+++ b/source/blender/bmesh/operators/bmo_fill_attribute.c
@@ -91,7 +91,7 @@ static void bm_face_copy_shared_all(
/**
* Flood fill attributes.
*/
-static unsigned int bmesh_face_attribute_fill(
+static uint bmesh_face_attribute_fill(
BMesh *bm,
const bool use_normals, const bool use_data)
{
@@ -102,7 +102,7 @@ static unsigned int bmesh_face_attribute_fill(
BMIter iter;
BMLoop *l;
- unsigned int face_tot = 0;
+ uint face_tot = 0;
BLI_LINKSTACK_INIT(loop_queue_prev);
diff --git a/source/blender/bmesh/operators/bmo_fill_grid.c b/source/blender/bmesh/operators/bmo_fill_grid.c
index 04ae915b707..dc4ebf50754 100644
--- a/source/blender/bmesh/operators/bmo_fill_grid.c
+++ b/source/blender/bmesh/operators/bmo_fill_grid.c
@@ -187,15 +187,15 @@ static void bm_loop_interp_from_grid_boundary_2(BMesh *bm, BMLoop *l, BMLoop *l_
* Avoids calling #barycentric_weights_v2_quad often by caching weights into an array.
*/
static void barycentric_weights_v2_grid_cache(
- const unsigned int xtot, const unsigned int ytot,
+ const uint xtot, const uint ytot,
float (*weight_table)[4])
{
float x_step = 1.0f / (float)(xtot - 1);
float y_step = 1.0f / (float)(ytot - 1);
- unsigned int i = 0;
+ uint i = 0;
float xy_fl[2];
- unsigned int x, y;
+ uint x, y;
for (y = 0; y < ytot; y++) {
xy_fl[1] = y_step * (float)y;
for (x = 0; x < xtot; x++) {
@@ -219,13 +219,13 @@ static void barycentric_weights_v2_grid_cache(
* \param v_grid 2d array of verts, all boundary verts must be set, we fill in the middle.
*/
static void bm_grid_fill_array(
- BMesh *bm, BMVert **v_grid, const unsigned int xtot, unsigned const int ytot,
+ BMesh *bm, BMVert **v_grid, const uint xtot, unsigned const int ytot,
const short mat_nr, const bool use_smooth,
const bool use_flip, const bool use_interp_simple)
{
const bool use_vert_interp = CustomData_has_interp(&bm->vdata);
const bool use_loop_interp = CustomData_has_interp(&bm->ldata);
- unsigned int x, y;
+ uint x, y;
/* for use_loop_interp */
BMLoop *((*larr_x_a)[2]), *((*larr_x_b)[2]), *((*larr_y_a)[2]), *((*larr_y_b)[2]);
@@ -393,7 +393,7 @@ static void bm_grid_fill_array(
BMLoop *l_quad[4];
BMLoop *l_bound[4];
BMLoop *l_tmp;
- unsigned int x_side, y_side, i;
+ uint x_side, y_side, i;
char interp_from;
@@ -496,12 +496,12 @@ static void bm_grid_fill(
{
#define USE_FLIP_DETECT
- const unsigned int xtot = (unsigned int)BM_edgeloop_length_get(estore_a);
- const unsigned int ytot = (unsigned int)BM_edgeloop_length_get(estore_rail_a);
+ const uint xtot = (uint)BM_edgeloop_length_get(estore_a);
+ const uint ytot = (uint)BM_edgeloop_length_get(estore_rail_a);
//BMVert *v;
- unsigned int i;
+ uint i;
#ifdef DEBUG
- unsigned int x, y;
+ uint x, y;
#endif
LinkData *el;
bool use_flip = false;
diff --git a/source/blender/bmesh/operators/bmo_fill_holes.c b/source/blender/bmesh/operators/bmo_fill_holes.c
index eadfbdb1aa8..869994a98b9 100644
--- a/source/blender/bmesh/operators/bmo_fill_holes.c
+++ b/source/blender/bmesh/operators/bmo_fill_holes.c
@@ -36,7 +36,7 @@
void bmo_holes_fill_exec(BMesh *bm, BMOperator *op)
{
BMOperator op_attr;
- const unsigned int sides = BMO_slot_int_get(op->slots_in, "sides");
+ const uint sides = BMO_slot_int_get(op->slots_in, "sides");
BM_mesh_elem_hflag_disable_all(bm, BM_EDGE | BM_FACE, BM_ELEM_TAG, false);
diff --git a/source/blender/bmesh/operators/bmo_inset.c b/source/blender/bmesh/operators/bmo_inset.c
index f0796e425fa..a64c6d74a93 100644
--- a/source/blender/bmesh/operators/bmo_inset.c
+++ b/source/blender/bmesh/operators/bmo_inset.c
@@ -275,7 +275,7 @@ static void bmo_face_inset_individual(
BMLoop *l_iter, *l_first;
BMLoop *l_other;
- unsigned int i;
+ uint i;
float e_length_prev;
l_first = BM_FACE_FIRST_LOOP(f);
diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c b/source/blender/bmesh/operators/bmo_join_triangles.c
index 655fb346976..69198ff35ab 100644
--- a/source/blender/bmesh/operators/bmo_join_triangles.c
+++ b/source/blender/bmesh/operators/bmo_join_triangles.c
@@ -132,11 +132,11 @@ struct DelimitData_CD {
};
struct DelimitData {
- unsigned int do_seam : 1;
- unsigned int do_sharp : 1;
- unsigned int do_mat : 1;
- unsigned int do_angle_face : 1;
- unsigned int do_angle_shape : 1;
+ uint do_seam : 1;
+ uint do_sharp : 1;
+ uint do_mat : 1;
+ uint do_angle_face : 1;
+ uint do_angle_shape : 1;
float angle_face;
float angle_face__cos;
@@ -272,7 +272,7 @@ void bmo_join_triangles_exec(BMesh *bm, BMOperator *op)
/* data: edge-to-join, sort_value: error weight */
struct SortPointerByFloat *jedges;
unsigned i, totedge;
- unsigned int totedge_tag = 0;
+ uint totedge_tag = 0;
struct DelimitData delimit_data = {0};
diff --git a/source/blender/bmesh/operators/bmo_primitive.c b/source/blender/bmesh/operators/bmo_primitive.c
index e5c3ff7a088..d8f83d786b4 100644
--- a/source/blender/bmesh/operators/bmo_primitive.c
+++ b/source/blender/bmesh/operators/bmo_primitive.c
@@ -760,11 +760,13 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
BMOpSlot *slot_verts_out = BMO_slot_get(op->slots_out, "verts.out");
const float dia = BMO_slot_float_get(op->slots_in, "size");
- const unsigned int xtot = max_ii(2, BMO_slot_int_get(op->slots_in, "x_segments"));
- const unsigned int ytot = max_ii(2, BMO_slot_int_get(op->slots_in, "y_segments"));
+ const uint xtot = max_ii(2, BMO_slot_int_get(op->slots_in, "x_segments"));
+ const uint ytot = max_ii(2, BMO_slot_int_get(op->slots_in, "y_segments"));
const float xtot_inv2 = 2.0f / (xtot - 1);
const float ytot_inv2 = 2.0f / (ytot - 1);
- const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs");
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
BMVert **varr;
BMVert *vquad[4];
@@ -772,7 +774,7 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
float mat[4][4];
float vec[3], tvec[3];
- unsigned int x, y, i;
+ uint x, y, i;
BMO_slot_mat4_get(op->slots_in, "matrix", mat);
@@ -814,7 +816,7 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
#undef XY
if (calc_uvs) {
- BM_mesh_calc_uvs_grid(bm, xtot, ytot, FACE_MARK);
+ BM_mesh_calc_uvs_grid(bm, xtot, ytot, FACE_MARK, cd_loop_uv_offset);
}
}
@@ -826,7 +828,9 @@ void bmo_create_grid_exec(BMesh *bm, BMOperator *op)
* \param y_segments The y-resolution of the grid
* \param oflag The flag to check faces with.
*/
-void BM_mesh_calc_uvs_grid(BMesh *bm, const unsigned int x_segments, const unsigned int y_segments, const short oflag)
+void BM_mesh_calc_uvs_grid(
+ BMesh *bm, const uint x_segments, const uint y_segments,
+ const short oflag, const int cd_loop_uv_offset)
{
BMFace *f;
BMLoop *l;
@@ -835,9 +839,7 @@ void BM_mesh_calc_uvs_grid(BMesh *bm, const unsigned int x_segments, const unsig
const float dx = 1.0f / (float)(x_segments - 1);
const float dy = 1.0f / (float)(y_segments - 1);
float x = 0.0f;
- float y = 0.0f;
-
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ float y = dy;
int loop_index;
@@ -852,16 +854,16 @@ void BM_mesh_calc_uvs_grid(BMesh *bm, const unsigned int x_segments, const unsig
switch (loop_index) {
case 0:
- x += dx;
+ y -= dy;
break;
case 1:
- y += dy;
+ x += dx;
break;
case 2:
- x -= dx;
+ y += dy;
break;
case 3:
- y -= dy;
+ x -= dx;
break;
default:
break;
@@ -884,7 +886,9 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
const float dia = BMO_slot_float_get(op->slots_in, "diameter");
const int seg = BMO_slot_int_get(op->slots_in, "u_segments");
const int tot = BMO_slot_int_get(op->slots_in, "v_segments");
- const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs");
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
BMOperator bmop, prevop;
BMVert *eve, *preveve;
@@ -982,7 +986,7 @@ void bmo_create_uvsphere_exec(BMesh *bm, BMOperator *op)
}
}
- BM_mesh_calc_uvs_sphere(bm, FACE_MARK);
+ BM_mesh_calc_uvs_sphere(bm, FACE_MARK, cd_loop_uv_offset);
}
/* and now do imat */
@@ -1000,7 +1004,9 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
const float dia = BMO_slot_float_get(op->slots_in, "diameter");
const float dia_div = dia / 200.0f;
const int subdiv = BMO_slot_int_get(op->slots_in, "subdivisions");
- const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs");
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
BMVert *eva[12];
BMVert *v;
@@ -1026,7 +1032,6 @@ void bmo_create_icosphere_exec(BMesh *bm, BMOperator *op)
}
int uvi = 0;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
for (a = 0; a < 20; a++) {
BMFace *f;
BMVert *v1, *v2, *v3;
@@ -1157,13 +1162,13 @@ static void bm_mesh_calc_uvs_sphere_face(BMFace *f, const int cd_loop_uv_offset)
* \param bm The BMesh to operate on
* \param oflag The flag to check faces with.
*/
-void BM_mesh_calc_uvs_sphere(BMesh *bm, const short oflag)
+void BM_mesh_calc_uvs_sphere(
+ BMesh *bm,
+ const short oflag, const int cd_loop_uv_offset)
{
BMFace *f;
BMIter iter;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
-
BLI_assert(cd_loop_uv_offset != -1); /* caller is responsible for giving us UVs */
BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
@@ -1206,7 +1211,9 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op)
int i;
BMO_slot_mat4_get(op->slots_in, "matrix", mat);
- const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs");
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
for (i = 0; i < monkeynv; i++) {
float v[3];
@@ -1234,7 +1241,6 @@ void bmo_create_monkey_exec(BMesh *bm, BMOperator *op)
}
int uvi = 0;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
for (i = 0; i < monkeynf; i++) {
BMFace *f_new_a = BM_face_create_quad_tri(bm,
tv[monkeyf[i][0] + i - monkeyo],
@@ -1283,7 +1289,9 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
const int segs = BMO_slot_int_get(op->slots_in, "segments");
const bool cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends");
const bool cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris");
- const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs");
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
BMVert *v1, *lastv1 = NULL, *cent1, *firstv1 = NULL;
float vec[3], mat[4][4], phi, phid;
@@ -1343,7 +1351,7 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
BMO_face_flag_enable(bm, f, FACE_NEW);
if (calc_uvs) {
- BM_mesh_calc_uvs_circle(bm, mat, dia, FACE_NEW);
+ BM_mesh_calc_uvs_circle(bm, mat, dia, FACE_NEW, cd_loop_uv_offset);
}
}
@@ -1362,14 +1370,14 @@ void bmo_create_circle_exec(BMesh *bm, BMOperator *op)
* \param radius The size of the circle.
* \param oflag The flag to check faces with.
*/
-void BM_mesh_calc_uvs_circle(BMesh *bm, float mat[4][4], const float radius, const short oflag)
+void BM_mesh_calc_uvs_circle(
+ BMesh *bm, float mat[4][4], const float radius,
+ const short oflag, const int cd_loop_uv_offset)
{
BMFace *f;
BMLoop *l;
BMIter fiter, liter;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
-
const float uv_scale = 0.5f / radius;
const float uv_center = 0.5f;
@@ -1409,7 +1417,9 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
int segs = BMO_slot_int_get(op->slots_in, "segments");
const bool cap_ends = BMO_slot_bool_get(op->slots_in, "cap_ends");
const bool cap_tris = BMO_slot_bool_get(op->slots_in, "cap_tris");
- const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs");
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
int a;
if (!segs)
@@ -1506,7 +1516,7 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
}
if (calc_uvs) {
- BM_mesh_calc_uvs_cone(bm, mat, dia2, dia1, segs, cap_ends, FACE_MARK);
+ BM_mesh_calc_uvs_cone(bm, mat, dia2, dia1, segs, cap_ends, FACE_MARK, cd_loop_uv_offset);
}
if (!cap_tris) {
@@ -1530,12 +1540,12 @@ void bmo_create_cone_exec(BMesh *bm, BMOperator *op)
*/
void BM_mesh_calc_uvs_cone(
BMesh *bm, float mat[4][4],
- const float radius_top, const float radius_bottom, const int segments, const bool cap_ends, const short oflag)
+ const float radius_top, const float radius_bottom, const int segments, const bool cap_ends,
+ const short oflag, const int cd_loop_uv_offset)
{
BMFace *f;
BMLoop *l;
BMIter fiter, liter;
- const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
const float uv_width = 1.0f / (float)segments;
const float uv_height = cap_ends ? 0.5f : 1.0f;
@@ -1627,8 +1637,10 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op)
BMVert *verts[8];
float mat[4][4];
float off = BMO_slot_float_get(op->slots_in, "size") / 2.0f;
- const bool calc_uvs = BMO_slot_bool_get(op->slots_in, "calc_uvs");
- int i, x, y, z;
+
+ const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_MLOOPUV);
+ const bool calc_uvs = (cd_loop_uv_offset != -1) && BMO_slot_bool_get(op->slots_in, "calc_uvs");
+
/* rotation order set to match 'BM_mesh_calc_uvs_cube' */
const char faces[6][4] = {
{0, 1, 3, 2},
@@ -1642,11 +1654,11 @@ void bmo_create_cube_exec(BMesh *bm, BMOperator *op)
BMO_slot_mat4_get(op->slots_in, "matrix", mat);
if (!off) off = 0.5f;
- i = 0;
+ int i = 0;
- for (x = -1; x < 2; x += 2) {
- for (y = -1; y < 2; y += 2) {
- for (z = -1; z < 2; z += 2) {
+ for (int x = -1; x < 2; x += 2) {
+ for (int y = -1; y < 2; y += 2) {
+ for (int z = -1; z < 2; z += 2) {
float vec[3] = {(float)x * off, (float)y * off, (float)z * off};
mul_m4_v3(mat, vec);
verts[i] = BM_vert_create(bm, vec, NULL, BM_CREATE_NOP);
diff --git a/source/blender/bmesh/operators/bmo_removedoubles.c b/source/blender/bmesh/operators/bmo_removedoubles.c
index 0ad8247e539..7d19d90807a 100644
--- a/source/blender/bmesh/operators/bmo_removedoubles.c
+++ b/source/blender/bmesh/operators/bmo_removedoubles.c
@@ -153,7 +153,7 @@ static BMFace *remdoubles_createface(BMesh *bm, BMFace *f, BMOpSlot *slot_target
finally:
{
- unsigned int i;
+ uint i;
for (i = 0; i < STACK_SIZE(verts); i++) {
BMO_vert_flag_disable(bm, verts[i], VERT_IN_FACE);
}
@@ -165,7 +165,7 @@ finally:
BLI_assert(f_new != f);
if (f_new) {
- unsigned int i = 0;
+ uint i = 0;
BMLoop *l_iter, *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(f_new);
do {
@@ -440,20 +440,24 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
edge_stack = BLI_stack_new(sizeof(BMEdge *), __func__);
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
- float min[3], max[3], center[3];
+ float center[3];
+ int count = 0;
BMVert *v_tar;
+ zero_v3(center);
+
if (!BMO_edge_flag_test(bm, e, EDGE_MARK))
continue;
BLI_assert(BLI_stack_is_empty(edge_stack));
- INIT_MINMAX(min, max);
for (e = BMW_begin(&walker, e->v1); e; e = BMW_step(&walker)) {
BLI_stack_push(edge_stack, &e);
- minmax_v3v3_v3(min, max, e->v1->co);
- minmax_v3v3_v3(min, max, e->v2->co);
+ add_v3_v3(center, e->v1->co);
+ add_v3_v3(center, e->v2->co);
+
+ count += 2;
/* prevent adding to slot_targetmap multiple times */
BM_elem_flag_disable(e->v1, BM_ELEM_TAG);
@@ -461,15 +465,14 @@ void bmo_collapse_exec(BMesh *bm, BMOperator *op)
}
if (!BLI_stack_is_empty(edge_stack)) {
-
- mid_v3_v3v3(center, min, max);
+ mul_v3_fl(center, 1.0f / count);
/* snap edges to a point. for initial testing purposes anyway */
e = *(BMEdge **)BLI_stack_peek(edge_stack);
v_tar = e->v1;
while (!BLI_stack_is_empty(edge_stack)) {
- unsigned int j;
+ uint j;
BLI_stack_pop(edge_stack, &e);
for (j = 0; j < 2; j++) {
diff --git a/source/blender/bmesh/operators/bmo_smooth_laplacian.c b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
index 1a83bafc074..2a7b85ac8fd 100644
--- a/source/blender/bmesh/operators/bmo_smooth_laplacian.c
+++ b/source/blender/bmesh/operators/bmo_smooth_laplacian.c
@@ -172,7 +172,7 @@ static void init_laplacian_matrix(LaplacianSystem *sys)
float w1, w2, w3, w4;
int i, j;
bool has_4_vert;
- unsigned int idv1, idv2, idv3, idv4, idv[4];
+ uint idv1, idv2, idv3, idv4, idv[4];
BMEdge *e;
BMFace *f;
BMIter eiter;
@@ -289,7 +289,7 @@ static void fill_laplacian_matrix(LaplacianSystem *sys)
float w2, w3, w4;
int i, j;
bool has_4_vert;
- unsigned int idv1, idv2, idv3, idv4, idv[4];
+ uint idv1, idv2, idv3, idv4, idv[4];
BMEdge *e;
BMFace *f;
@@ -420,7 +420,7 @@ static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez
float leni, lene;
float vini, vend;
float *vi1, *vi2, ve1[3], ve2[3];
- unsigned int idv1, idv2;
+ uint idv1, idv2;
BMOIter siter;
BMVert *v;
BMEdge *e;
diff --git a/source/blender/bmesh/operators/bmo_subdivide_edgering.c b/source/blender/bmesh/operators/bmo_subdivide_edgering.c
index ce031e1c230..94b60a51f68 100644
--- a/source/blender/bmesh/operators/bmo_subdivide_edgering.c
+++ b/source/blender/bmesh/operators/bmo_subdivide_edgering.c
@@ -66,7 +66,7 @@
/* Specialized Utility Funcs */
#ifndef NDEBUG
-static unsigned int bm_verts_tag_count(BMesh *bm)
+static uint bm_verts_tag_count(BMesh *bm)
{
int count = 0;
BMIter iter;
@@ -390,9 +390,9 @@ static void bm_vert_calc_surface_tangent(BMesh *bm, BMVert *v, float r_no[3])
* Tag faces connected to an edge loop as FACE_SHARED
* if all vertices are VERT_SHARED.
*/
-static void bm_faces_share_tag_flush(BMesh *bm, BMEdge **e_arr, const unsigned int e_arr_len)
+static void bm_faces_share_tag_flush(BMesh *bm, BMEdge **e_arr, const uint e_arr_len)
{
- unsigned int i;
+ uint i;
for (i = 0; i < e_arr_len; i++) {
BMEdge *e = e_arr[i];
@@ -412,9 +412,9 @@ static void bm_faces_share_tag_flush(BMesh *bm, BMEdge **e_arr, const unsigned i
/**
* Un-Tag faces connected to an edge loop, clearing FACE_SHARED
*/
-static void bm_faces_share_tag_clear(BMesh *bm, BMEdge **e_arr_iter, const unsigned int e_arr_len_iter)
+static void bm_faces_share_tag_clear(BMesh *bm, BMEdge **e_arr_iter, const uint e_arr_len_iter)
{
- unsigned int i;
+ uint i;
for (i = 0; i < e_arr_len_iter; i++) {
BMEdge *e = e_arr_iter[i];
@@ -454,16 +454,16 @@ static LoopPairStore *bm_edgering_pair_store_create(
LoopPairStore *lpair = MEM_mallocN(sizeof(*lpair), __func__);
if (interp_mode == SUBD_RING_INTERP_SURF) {
- const unsigned int len_a = BM_edgeloop_length_get(el_store_a);
- const unsigned int len_b = BM_edgeloop_length_get(el_store_b);
- const unsigned int e_arr_a_len = len_a - (BM_edgeloop_is_closed(el_store_a) ? 0 : 1);
- const unsigned int e_arr_b_len = len_b - (BM_edgeloop_is_closed(el_store_b) ? 0 : 1);
+ const uint len_a = BM_edgeloop_length_get(el_store_a);
+ const uint len_b = BM_edgeloop_length_get(el_store_b);
+ const uint e_arr_a_len = len_a - (BM_edgeloop_is_closed(el_store_a) ? 0 : 1);
+ const uint e_arr_b_len = len_b - (BM_edgeloop_is_closed(el_store_b) ? 0 : 1);
BMEdge **e_arr_a = BLI_array_alloca(e_arr_a, e_arr_a_len);
BMEdge **e_arr_b = BLI_array_alloca(e_arr_b, e_arr_b_len);
- unsigned int i;
+ uint i;
struct BMEdgeLoopStore *el_store_pair[2] = {el_store_a, el_store_b};
- unsigned int side_index;
+ uint side_index;
float (*nors_pair[2])[3];
GHash *nors_gh_pair[2];
@@ -768,8 +768,8 @@ static void bm_edgering_pair_interpolate(
bm_vert_calc_surface_tangent(bm, v_b, no_b);
#else
{
- const unsigned int index_a = GET_UINT_FROM_POINTER(BLI_ghash_lookup(lpair->nors_gh_a, v_a));
- const unsigned int index_b = GET_UINT_FROM_POINTER(BLI_ghash_lookup(lpair->nors_gh_b, v_b));
+ const uint index_a = GET_UINT_FROM_POINTER(BLI_ghash_lookup(lpair->nors_gh_a, v_a));
+ const uint index_b = GET_UINT_FROM_POINTER(BLI_ghash_lookup(lpair->nors_gh_b, v_b));
BLI_assert(BLI_ghash_haskey(lpair->nors_gh_a, v_a));
BLI_assert(BLI_ghash_haskey(lpair->nors_gh_b, v_b));
diff --git a/source/blender/bmesh/operators/bmo_triangulate.c b/source/blender/bmesh/operators/bmo_triangulate.c
index 6bd3174d27a..4e8bace59e0 100644
--- a/source/blender/bmesh/operators/bmo_triangulate.c
+++ b/source/blender/bmesh/operators/bmo_triangulate.c
@@ -77,7 +77,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
GHash *sf_vert_map;
float normal[3];
const int scanfill_flag = BLI_SCANFILL_CALC_HOLES | BLI_SCANFILL_CALC_POLYS | BLI_SCANFILL_CALC_LOOSE;
- unsigned int nors_tot;
+ uint nors_tot;
bool calc_winding = false;
sf_vert_map = BLI_ghash_ptr_new_ex(__func__, BMO_slot_buffer_count(op->slots_in, "edges"));
@@ -89,7 +89,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
ScanFillVert *sf_verts[2];
BMVert **e_verts = &e->v1;
- unsigned int i;
+ uint i;
BMO_edge_flag_enable(bm, e, EDGE_MARK);
@@ -115,7 +115,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
* Since we don't know winding, just accumulate */
ScanFillVert *sf_vert;
struct SortNormal *nors;
- unsigned int i;
+ uint i;
bool is_degenerate = true;
nors = MEM_mallocN(sizeof(*nors) * nors_tot, __func__);
@@ -124,7 +124,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
BMVert *v = sf_vert->tmp.p;
BMIter eiter;
BMEdge *e_pair[2];
- unsigned int e_index = 0;
+ uint e_index = 0;
nors[i].value = -1.0f;
@@ -199,7 +199,7 @@ void bmo_triangle_fill_exec(BMesh *bm, BMOperator *op)
int winding_votes = 0;
for (sf_tri = sf_ctx.fillfacebase.first; sf_tri; sf_tri = sf_tri->next) {
BMVert *v_tri[3] = {sf_tri->v1->tmp.p, sf_tri->v2->tmp.p, sf_tri->v3->tmp.p};
- unsigned int i, i_prev;
+ uint i, i_prev;
for (i = 0, i_prev = 2; i < 3; i_prev = i++) {
e = BM_edge_exists(v_tri[i], v_tri[i_prev]);
diff --git a/source/blender/bmesh/tools/bmesh_beautify.c b/source/blender/bmesh/tools/bmesh_beautify.c
index 3e3a6547b75..f08f21a2c88 100644
--- a/source/blender/bmesh/tools/bmesh_beautify.c
+++ b/source/blender/bmesh/tools/bmesh_beautify.c
@@ -62,7 +62,7 @@ typedef struct EdRotState {
#if 0
/* use BLI_ghashutil_inthash_v4 direct */
-static unsigned int erot_gsetutil_hash(const void *ptr)
+static uint erot_gsetutil_hash(const void *ptr)
{
const EdRotState *e_state = (const EdRotState *)ptr;
return BLI_ghashutil_inthash_v4(&e_state->v1);
@@ -368,7 +368,7 @@ void BM_mesh_beautify_fill(
TIMEIT_START(beautify_fill);
#endif
- eheap = BLI_heap_new_ex((unsigned int)edge_array_len);
+ eheap = BLI_heap_new_ex((uint)edge_array_len);
eheap_table = MEM_mallocN(sizeof(HeapNode *) * (size_t)edge_array_len, __func__);
/* build heap */
diff --git a/source/blender/bmesh/tools/bmesh_bevel.c b/source/blender/bmesh/tools/bmesh_bevel.c
index 05169a2a976..6673c5d25cf 100644
--- a/source/blender/bmesh/tools/bmesh_bevel.c
+++ b/source/blender/bmesh/tools/bmesh_bevel.c
@@ -205,6 +205,38 @@ static int bev_debug_flags = 0;
#define DEBUG_OLD_PROJ_TO_PERP_PLANE (bev_debug_flags & 2)
#define DEBUG_OLD_FLAT_MID (bev_debug_flags & 4)
+/* this flag values will get set on geom we want to return in 'out' slots for edges and verts */
+#define EDGE_OUT 4
+#define VERT_OUT 8
+
+/* If we're called from the modifier, tool flags aren't available, but don't need output geometry */
+static void flag_out_edge(BMesh *bm, BMEdge *bme)
+{
+ if (bm->use_toolflags)
+ BMO_edge_flag_enable(bm, bme, EDGE_OUT);
+}
+
+static void flag_out_vert(BMesh *bm, BMVert *bmv)
+{
+ if (bm->use_toolflags)
+ BMO_vert_flag_enable(bm, bmv, VERT_OUT);
+}
+
+static void disable_flag_out_edge(BMesh *bm, BMEdge *bme)
+{
+ if (bm->use_toolflags)
+ BMO_edge_flag_disable(bm, bme, EDGE_OUT);
+}
+
+/* Are d1 and d2 parallel or nearly so? */
+static bool nearly_parallel(const float d1[3], const float d2[3])
+{
+ float ang;
+
+ ang = angle_v3v3(d1, d2);
+ return (fabsf(ang) < BEVEL_EPSILON_ANG) || (fabsf(ang - M_PI) < BEVEL_EPSILON_ANG);
+}
+
/* Make a new BoundVert of the given kind, insert it at the end of the circular linked
* list with entry point bv->boundstart, and return it. */
static BoundVert *add_new_bound_vert(MemArena *mem_arena, VMesh *vm, const float co[3])
@@ -253,6 +285,7 @@ static void create_mesh_bmvert(BMesh *bm, VMesh *vm, int i, int j, int k, BMVert
NewVert *nv = mesh_vert(vm, i, j, k);
nv->v = BM_vert_create(bm, nv->co, eg, BM_CREATE_NOP);
BM_elem_flag_disable(nv->v, BM_ELEM_TAG);
+ flag_out_vert(bm, nv->v);
}
static void copy_mesh_vert(
@@ -495,9 +528,12 @@ static BMFace *bev_create_ngon(
}
/* not essential for bevels own internal logic,
- * this is done so the operator can select newly created faces */
+ * this is done so the operator can select newly created geometry */
if (f) {
BM_elem_flag_enable(f, BM_ELEM_TAG);
+ BM_ITER_ELEM(bme, &iter, f, BM_EDGES_OF_FACE) {
+ flag_out_edge(bm, bme);
+ }
}
if (mat_nr >= 0)
@@ -916,8 +952,12 @@ static bool offset_meet_edge(EdgeHalf *e1, EdgeHalf *e2, BMVert *v, float meetc
return false;
}
cross_v3_v3v3(fno, dir1, dir2);
- if (dot_v3v3(fno, v->no) < 0.0f)
+ if (dot_v3v3(fno, v->no) < 0.0f) {
ang = 2.0f * (float)M_PI - ang; /* angle is reflex */
+ if (r_angle)
+ *r_angle = ang;
+ return false;
+ }
if (r_angle)
*r_angle = ang;
@@ -1055,7 +1095,7 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv)
{
EdgeHalf *e;
Profile *pro;
- float co1[3], co2[3], co3[3], d1[3], d2[3], l;
+ float co1[3], co2[3], co3[3], d1[3], d2[3];
bool do_linear_interp;
copy_v3_v3(co1, bndv->nv.co);
@@ -1093,8 +1133,8 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv)
normalize_v3(d1);
normalize_v3(d2);
cross_v3_v3v3(pro->plane_no, d1, d2);
- l = normalize_v3(pro->plane_no);
- if (l <= BEVEL_EPSILON_BIG) {
+ normalize_v3(pro->plane_no);
+ if (nearly_parallel(d1, d2)) {
/* co1 - midco -co2 are collinear.
* Should be case that beveled edge is coplanar with two boundary verts.
* We want to move the profile to that common plane, if possible.
@@ -1126,17 +1166,24 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv)
sub_v3_v3v3(d4, e->next->e->v1->co, e->next->e->v2->co);
normalize_v3(d3);
normalize_v3(d4);
- add_v3_v3v3(co3, co1, d3);
- add_v3_v3v3(co4, co2, d4);
- isect_kind = isect_line_line_v3(co1, co3, co2, co4, meetco, isect2);
- if (isect_kind != 0) {
- copy_v3_v3(pro->midco, meetco);
- }
- else {
+ if (nearly_parallel(d3, d4)) {
/* offset lines are collinear - want linear interpolation */
mid_v3_v3v3(pro->midco, co1, co2);
do_linear_interp = true;
}
+ else {
+ add_v3_v3v3(co3, co1, d3);
+ add_v3_v3v3(co4, co2, d4);
+ isect_kind = isect_line_line_v3(co1, co3, co2, co4, meetco, isect2);
+ if (isect_kind != 0) {
+ copy_v3_v3(pro->midco, meetco);
+ }
+ else {
+ /* offset lines don't intersect - want linear interpolation */
+ mid_v3_v3v3(pro->midco, co1, co2);
+ do_linear_interp = true;
+ }
+ }
}
}
copy_v3_v3(pro->cob, co2);
@@ -1145,8 +1192,8 @@ static void set_profile_params(BevelParams *bp, BevVert *bv, BoundVert *bndv)
sub_v3_v3v3(d2, pro->midco, co2);
normalize_v3(d2);
cross_v3_v3v3(pro->plane_no, d1, d2);
- l = normalize_v3(pro->plane_no);
- if (l <= BEVEL_EPSILON_BIG) {
+ normalize_v3(pro->plane_no);
+ if (nearly_parallel(d1, d2)) {
/* whole profile is collinear with edge: just interpolate */
do_linear_interp = true;
}
@@ -2295,7 +2342,7 @@ static int interp_range(const float *frac, int n, const float f, float *r_rest)
/* Interpolate given vmesh to make one with target nseg border vertices on the profiles */
static VMesh *interp_vmesh(BevelParams *bp, VMesh *vm0, int nseg)
{
- int n, ns0, nseg2, odd, i, j, k, j0, k0, k0prev;
+ int n, ns0, nseg2, odd, i, j, k, j0, k0, k0prev, j0inc, k0inc;
float *prev_frac, *frac, *new_frac, *prev_new_frac;
float f, restj, restk, restkprev;
float quad[4][3], co[3], center[3];
@@ -2339,10 +2386,12 @@ static VMesh *interp_vmesh(BevelParams *bp, VMesh *vm0, int nseg)
copy_v3_v3(co, mesh_vert_canon(vm0, i, j0, k0)->co);
}
else {
+ j0inc = (restj < BEVEL_EPSILON || j0 == ns0) ? 0 : 1;
+ k0inc = (restk < BEVEL_EPSILON || k0 == ns0) ? 0 : 1;
copy_v3_v3(quad[0], mesh_vert_canon(vm0, i, j0, k0)->co);
- copy_v3_v3(quad[1], mesh_vert_canon(vm0, i, j0, k0 + 1)->co);
- copy_v3_v3(quad[2], mesh_vert_canon(vm0, i, j0 + 1, k0 + 1)->co);
- copy_v3_v3(quad[3], mesh_vert_canon(vm0, i, j0 + 1, k0)->co);
+ copy_v3_v3(quad[1], mesh_vert_canon(vm0, i, j0, k0 + k0inc)->co);
+ copy_v3_v3(quad[2], mesh_vert_canon(vm0, i, j0 + j0inc, k0 + k0inc)->co);
+ copy_v3_v3(quad[3], mesh_vert_canon(vm0, i, j0 + j0inc, k0)->co);
interp_bilinear_quad_v3(quad, restk, restj, co);
}
copy_v3_v3(mesh_vert(vm1, i, j, k)->co, co);
@@ -3191,6 +3240,7 @@ static void bevel_build_trifan(BevelParams *bp, BMesh *bm, BevVert *bv)
BMFace *f_new;
BLI_assert(v_fan == l_fan->v);
f_new = BM_face_split(bm, f, l_fan, l_fan->next->next, &l_new, NULL, false);
+ flag_out_edge(bm, l_new->e);
if (f_new->len > f->len) {
f = f_new;
@@ -3237,6 +3287,7 @@ static void bevel_build_quadstrip(BevelParams *bp, BMesh *bm, BevVert *bv)
else {
BM_face_split(bm, f, l_a, l_b, &l_new, NULL, false);
f = l_new->f;
+ flag_out_edge(bm, l_new->e);
/* walk around the new face to get the next verts to split */
l_a = l_new->prev;
@@ -3256,7 +3307,7 @@ static void bevel_vert_two_edges(BevelParams *bp, BMesh *bm, BevVert *bv)
{
VMesh *vm = bv->vmesh;
BMVert *v1, *v2;
- BMEdge *e_eg;
+ BMEdge *e_eg, *bme;
Profile *pro;
float co[3];
BoundVert *bndv;
@@ -3298,7 +3349,9 @@ static void bevel_vert_two_edges(BevelParams *bp, BMesh *bm, BevVert *bv)
v1 = mesh_vert(vm, 0, 0, k)->v;
v2 = mesh_vert(vm, 0, 0, k + 1)->v;
BLI_assert(v1 != NULL && v2 != NULL);
- BM_edge_create(bm, v1, v2, e_eg, BM_CREATE_NO_DOUBLE);
+ bme = BM_edge_create(bm, v1, v2, e_eg, BM_CREATE_NO_DOUBLE);
+ if (bme)
+ flag_out_edge(bm, bme);
}
}
}
@@ -3879,7 +3932,7 @@ static BevVert *bevel_vert_construct(BMesh *bm, BevelParams *bp, BMVert *v)
/* Face f has at least one beveled vertex. Rebuild f */
static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
{
- BMIter liter;
+ BMIter liter, eiter, fiter;
BMLoop *l, *lprev;
BevVert *bv;
BoundVert *v, *vstart, *vend;
@@ -3887,10 +3940,10 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
VMesh *vm;
int i, k, n;
bool do_rebuild = false;
- bool go_ccw, corner3special;
+ bool go_ccw, corner3special, keep;
BMVert *bmv;
BMEdge *bme, *bme_new, *bme_prev;
- BMFace *f_new;
+ BMFace *f_new, *f_other;
BMVert **vv = NULL;
BMVert **vv_fix = NULL;
BMEdge **ee = NULL;
@@ -4028,9 +4081,21 @@ static bool bev_rebuild_polygon(BMesh *bm, BevelParams *bp, BMFace *f)
}
}
- /* don't select newly created boundary faces... */
+ /* don't select newly or return created boundary faces... */
if (f_new) {
BM_elem_flag_disable(f_new, BM_ELEM_TAG);
+ /* Also don't want new edges that aren't part of a new bevel face */
+ BM_ITER_ELEM(bme, &eiter, f_new, BM_EDGES_OF_FACE) {
+ keep = false;
+ BM_ITER_ELEM(f_other, &fiter, bme, BM_FACES_OF_EDGE) {
+ if (BM_elem_flag_test(f_other, BM_ELEM_TAG)) {
+ keep = true;
+ break;
+ }
+ }
+ if (!keep)
+ disable_flag_out_edge(bm, bme);
+ }
}
}
@@ -4112,8 +4177,9 @@ static void bevel_reattach_wires(BMesh *bm, BevelParams *bp, BMVert *v)
}
}
} while ((bndv = bndv->next) != bv->vmesh->boundstart);
- if (vclosest)
+ if (vclosest) {
BM_edge_create(bm, vclosest, votherclosest, e, BM_CREATE_NO_DOUBLE);
+ }
}
}
@@ -4517,9 +4583,9 @@ static float bevel_limit_offset(BMesh *bm, BevelParams *bp)
/**
* - Currently only bevels BM_ELEM_TAG'd verts and edges.
*
- * - Newly created faces are BM_ELEM_TAG'd too,
- * the caller needs to ensure this is cleared before calling
- * if its going to use this face tag.
+ * - Newly created faces, edges, and verts are BM_ELEM_TAG'd too,
+ * the caller needs to ensure these are cleared before calling
+ * if its going to use this tag.
*
* - If limit_offset is set, adjusts offset down if necessary
* to avoid geometry collisions.
@@ -4611,6 +4677,20 @@ void BM_mesh_bevel(
}
}
+ /* When called from operator (as opposed to modifier), bm->use_toolflags
+ * will be set, and we to transfer the oflags to BM_ELEM_TAGs */
+ if (bm->use_toolflags) {
+ BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
+ if (BMO_vert_flag_test(bm, v, VERT_OUT))
+ BM_elem_flag_enable(v, BM_ELEM_TAG);
+ }
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BMO_edge_flag_test(bm, e, EDGE_OUT)) {
+ BM_elem_flag_enable(e, BM_ELEM_TAG);
+ }
+ }
+ }
+
/* primary free */
BLI_ghash_free(bp.vert_hash, NULL, NULL);
BLI_memarena_free(bp.mem_arena);
diff --git a/source/blender/bmesh/tools/bmesh_bisect_plane.c b/source/blender/bmesh/tools/bmesh_bisect_plane.c
index 828c50c39fd..676a8de94c8 100644
--- a/source/blender/bmesh/tools/bmesh_bisect_plane.c
+++ b/source/blender/bmesh/tools/bmesh_bisect_plane.c
@@ -74,7 +74,7 @@ static short plane_point_test_v3(const float plane[4], const float co[3], const
#define BM_VERT_DIST(v) ((v)->no[0]) /* Distance from the plane. */
#define BM_VERT_SORTVAL(v) ((v)->no[1]) /* Temp value for sorting. */
#define BM_VERT_LOOPINDEX(v) /* The verts index within a face (temp var) */ \
- (*((unsigned int *)(&(v)->no[2])))
+ (*((uint *)(&(v)->no[2])))
/**
* Hide flag access
@@ -113,7 +113,7 @@ static int bm_vert_sortval_cb(const void *v_a_v, const void *v_b_v)
static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], const short oflag_center, const short oflag_new)
{
/* unlikely more than 2 verts are needed */
- const unsigned int f_len_orig = (unsigned int)f->len;
+ const uint f_len_orig = (uint)f->len;
BMVert **vert_split_arr = BLI_array_alloca(vert_split_arr, f_len_orig);
STACK_DECLARE(vert_split_arr);
BMLoop *l_iter, *l_first;
@@ -171,7 +171,7 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con
STACK_DECLARE(face_split_arr);
float sort_dir[3];
- unsigned int i;
+ uint i;
/* ---- */
@@ -246,7 +246,7 @@ static void bm_face_bisect_verts(BMesh *bm, BMFace *f, const float plane[4], con
if (is_inside) {
BMLoop *l_a, *l_b;
bool found = false;
- unsigned int j;
+ uint j;
for (j = 0; j < STACK_SIZE(face_split_arr); j++) {
/* would be nice to avoid loop lookup here,
@@ -311,8 +311,8 @@ void BM_mesh_bisect_plane(
const bool use_snap_center, const bool use_tag,
const short oflag_center, const short oflag_new, const float eps)
{
- unsigned int einput_len;
- unsigned int i;
+ uint einput_len;
+ uint i;
BMEdge **edges_arr = MEM_mallocN(sizeof(*edges_arr) * (size_t)bm->totedge, __func__);
BLI_LINKSTACK_DECLARE(face_stack, BMFace *);
@@ -345,7 +345,7 @@ void BM_mesh_bisect_plane(
}
else {
BMEdge *e;
- einput_len = (unsigned int)bm->totedge;
+ einput_len = (uint)bm->totedge;
BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
edge_is_cut_enable(e);
edges_arr[i] = e;
@@ -425,7 +425,7 @@ void BM_mesh_bisect_plane(
else if (side[0] == 0 || side[1] == 0) {
/* check if either edge verts are aligned,
* if so - tag and push all faces that use it into the stack */
- unsigned int j;
+ uint j;
BM_ITER_ELEM_INDEX (v, &iter, e, BM_VERTS_OF_EDGE, j) {
if (side[j] == 0) {
if (vert_is_center_test(v) == 0) {
diff --git a/source/blender/bmesh/tools/bmesh_decimate_collapse.c b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
index 372d341f223..c417131d588 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_collapse.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_collapse.c
@@ -180,7 +180,7 @@ static bool bm_edge_collapse_is_degenerate_flip(BMEdge *e, const float optimize_
{
BMIter liter;
BMLoop *l;
- unsigned int i;
+ uint i;
for (i = 0; i < 2; i++) {
/* loop over both verts */
@@ -367,7 +367,7 @@ static void bm_decim_build_edge_cost(
{
BMIter iter;
BMEdge *e;
- unsigned int i;
+ uint i;
BM_ITER_MESH_INDEX (e, &iter, bm, BM_EDGES_OF_MESH, i) {
eheap_table[i] = NULL; /* keep sanity check happy */
@@ -418,12 +418,12 @@ static bool bm_edge_symmetry_check_cb(void *user_data, int index, const float UN
return false;
}
-static int *bm_edge_symmetry_map(BMesh *bm, unsigned int symmetry_axis, float limit)
+static int *bm_edge_symmetry_map(BMesh *bm, uint symmetry_axis, float limit)
{
struct KD_Symmetry_Data sym_data;
BMIter iter;
BMEdge *e, **etable;
- unsigned int i;
+ uint i;
int *edge_symmetry_map;
const float limit_sq = SQUARE(limit);
KDTree *tree;
diff --git a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
index 92300ae66a2..f0ac6c673c9 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_unsubdivide.c
@@ -43,10 +43,10 @@ static bool bm_vert_dissolve_fan_test(BMVert *v)
BMVert *varr[4];
- unsigned int tot_edge = 0;
- unsigned int tot_edge_boundary = 0;
- unsigned int tot_edge_manifold = 0;
- unsigned int tot_edge_wire = 0;
+ uint tot_edge = 0;
+ uint tot_edge_boundary = 0;
+ uint tot_edge_manifold = 0;
+ uint tot_edge_wire = 0;
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
if (BM_edge_is_boundary(e)) {
@@ -97,11 +97,11 @@ static bool bm_vert_dissolve_fan(BMesh *bm, BMVert *v)
BMIter iter;
BMEdge *e;
- unsigned int tot_loop = 0;
- unsigned int tot_edge = 0;
- unsigned int tot_edge_boundary = 0;
- unsigned int tot_edge_manifold = 0;
- unsigned int tot_edge_wire = 0;
+ uint tot_loop = 0;
+ uint tot_edge = 0;
+ uint tot_edge_boundary = 0;
+ uint tot_edge_manifold = 0;
+ uint tot_edge_wire = 0;
BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
if (BM_edge_is_boundary(e)) {
@@ -143,7 +143,7 @@ static bool bm_vert_dissolve_fan(BMesh *bm, BMVert *v)
if (tot_loop) {
BMLoop *f_loop[4];
- unsigned int i;
+ uint i;
/* ensure there are exactly tot_loop loops */
BLI_assert(BM_iter_at_index(bm, BM_LOOPS_OF_VERT, v, tot_loop) == NULL);
@@ -192,8 +192,8 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool
BMIter iter;
- const unsigned int offset = 0;
- const unsigned int nth = 2;
+ const uint offset = 0;
+ const uint nth = 2;
int iter_step;
@@ -229,8 +229,8 @@ void BM_mesh_decimate_unsubdivide_ex(BMesh *bm, const int iterations, const bool
#ifdef USE_WALKER
BMWalker walker;
#else
- unsigned int depth = 1;
- unsigned int i;
+ uint depth = 1;
+ uint i;
#endif
BMVert *v_first = NULL;
diff --git a/source/blender/bmesh/tools/bmesh_edgenet.c b/source/blender/bmesh/tools/bmesh_edgenet.c
index 2a1946df7ae..193a032b46e 100644
--- a/source/blender/bmesh/tools/bmesh_edgenet.c
+++ b/source/blender/bmesh/tools/bmesh_edgenet.c
@@ -100,13 +100,13 @@ static BMEdge *bm_edgenet_edge_get_next(
*
* This function returns half a loop, the caller needs to run twice to get both sides.
*/
-static unsigned int bm_edgenet_path_from_pass(
+static uint bm_edgenet_path_from_pass(
BMVert *v, LinkNode **v_ls,
VertNetInfo *vnet_info, BLI_mempool *path_pool)
{
VertNetInfo *vn = &vnet_info[BM_elem_index_get(v)];
const int pass = vn->pass;
- unsigned int v_ls_tot = 0;
+ uint v_ls_tot = 0;
do {
BLI_linklist_prepend_pool(v_ls, v, path_pool);
@@ -127,10 +127,10 @@ static bool bm_edgenet_path_check_overlap(
VertNetInfo *vnet_info)
{
/* vert order doesn't matter */
- unsigned int v_ls_tot = 0;
+ uint v_ls_tot = 0;
LinkNode *v_ls = NULL;
BMVert *v_pair[2] = {v1, v2};
- unsigned int i;
+ uint i;
for (i = 0; i < 2; i++) {
BMVert *v = v_pair[i];
@@ -162,7 +162,7 @@ static bool bm_edgenet_path_check_overlap(
* Create a face from the path.
*/
static BMFace *bm_edgenet_face_from_path(
- BMesh *bm, LinkNode *path, const unsigned int path_len)
+ BMesh *bm, LinkNode *path, const uint path_len)
{
BMFace *f;
LinkNode *v_lnk;
@@ -205,8 +205,8 @@ static BMEdge *bm_edgenet_path_step(
BMEdge *e;
BMIter iter;
- unsigned int tot;
- unsigned int v_ls_tot;
+ uint tot;
+ uint v_ls_tot;
begin:
@@ -277,8 +277,8 @@ begin:
* \return A linked list of verts.
*/
static LinkNode *bm_edgenet_path_calc(
- BMEdge *e, const int pass_nr, const unsigned int path_cost_max,
- unsigned int *r_path_len, unsigned int *r_path_cost,
+ BMEdge *e, const int pass_nr, const uint path_cost_max,
+ uint *r_path_len, uint *r_path_cost,
VertNetInfo *vnet_info, BLI_mempool *path_pool)
{
VertNetInfo *vn_1, *vn_2;
@@ -288,7 +288,7 @@ static LinkNode *bm_edgenet_path_calc(
LinkNode *v_ls_prev = NULL;
LinkNode *v_ls_next = NULL;
- unsigned int path_cost_accum = 0;
+ uint path_cost_accum = 0;
BLI_assert(bm_edge_step_ok(e));
@@ -331,7 +331,7 @@ static LinkNode *bm_edgenet_path_calc(
if (e_found) {
LinkNode *path = NULL;
- unsigned int path_len;
+ uint path_len;
BLI_linklist_free_pool(v_ls_next, NULL, path_pool);
BLI_linklist_free_pool(v_ls_prev, NULL, path_pool);
@@ -376,12 +376,12 @@ static LinkNode *bm_edgenet_path_calc(
* _don't_ have a better option.
*/
static LinkNode *bm_edgenet_path_calc_best(
- BMEdge *e, int *pass_nr, unsigned int path_cost_max,
- unsigned int *r_path_len, unsigned int *r_path_cost,
+ BMEdge *e, int *pass_nr, uint path_cost_max,
+ uint *r_path_len, uint *r_path_cost,
VertNetInfo *vnet_info, BLI_mempool *path_pool)
{
LinkNode *path;
- unsigned int path_cost;
+ uint path_cost;
path = bm_edgenet_path_calc(e, *pass_nr, path_cost_max,
r_path_len, &path_cost,
@@ -399,8 +399,8 @@ static LinkNode *bm_edgenet_path_calc_best(
/* Check every edge to see if any can give a better path.
* This avoids very strange/long paths from being created. */
- const unsigned int path_len = *r_path_len;
- unsigned int i, i_prev;
+ const uint path_len = *r_path_len;
+ uint i, i_prev;
BMVert **vert_arr = BLI_array_alloca(vert_arr, path_len);
LinkNode *v_lnk;
@@ -413,8 +413,8 @@ static LinkNode *bm_edgenet_path_calc_best(
BMEdge *e_other = BM_edge_exists(vert_arr[i], vert_arr[i_prev]);
if (e_other != e) {
LinkNode *path_test;
- unsigned int path_len_test;
- unsigned int path_cost_test;
+ uint path_len_test;
+ uint path_cost_test;
path_test = bm_edgenet_path_calc(e_other, *pass_nr, path_cost,
&path_len_test, &path_cost_test,
@@ -471,8 +471,8 @@ void BM_mesh_edgenet(
while (true) {
LinkNode *path = NULL;
- unsigned int path_len;
- unsigned int path_cost;
+ uint path_len;
+ uint path_cost;
e = bm_edgenet_edge_get_next(bm, &edge_queue, edge_queue_pool);
if (e == NULL) {
diff --git a/source/blender/bmesh/tools/bmesh_edgesplit.c b/source/blender/bmesh/tools/bmesh_edgesplit.c
index a59a5c43c82..3a844a0b8d9 100644
--- a/source/blender/bmesh/tools/bmesh_edgesplit.c
+++ b/source/blender/bmesh/tools/bmesh_edgesplit.c
@@ -96,7 +96,7 @@ void BM_mesh_edgesplit(
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_elem_flag_test(e, BM_ELEM_TAG)) {
- unsigned int i;
+ uint i;
for (i = 0; i < 2; i++) {
BMVert *v = ((&e->v1)[i]);
if (BM_elem_flag_test(v, BM_ELEM_TAG)) {
diff --git a/source/blender/bmesh/tools/bmesh_intersect.c b/source/blender/bmesh/tools/bmesh_intersect.c
index 2cb82d0fc02..b9408492cc1 100644
--- a/source/blender/bmesh/tools/bmesh_intersect.c
+++ b/source/blender/bmesh/tools/bmesh_intersect.c
@@ -152,7 +152,7 @@ struct ISectState {
*/
struct LinkBase {
LinkNode *list;
- unsigned int list_len;
+ uint list_len;
};
static bool ghash_insert_link(
@@ -193,7 +193,7 @@ struct vert_sort_t {
static void edge_verts_sort(const float co[3], struct LinkBase *v_ls_base)
{
/* not optimal but list will be typically < 5 */
- unsigned int i;
+ uint i;
struct vert_sort_t *vert_sort = BLI_array_alloca(vert_sort, v_ls_base->list_len);
LinkNode *node;
@@ -246,8 +246,8 @@ static void face_edges_split(
bool use_island_connect,
MemArena *mem_arena_edgenet)
{
- unsigned int i;
- unsigned int edge_arr_len = e_ls_base->list_len;
+ uint i;
+ uint edge_arr_len = e_ls_base->list_len;
BMEdge **edge_arr = BLI_array_alloca(edge_arr, edge_arr_len);
LinkNode *node;
BLI_assert(f->head.htype == BM_FACE);
@@ -263,7 +263,7 @@ static void face_edges_split(
#ifdef USE_NET_ISLAND_CONNECT
if (use_island_connect) {
- unsigned int edge_arr_holes_len;
+ uint edge_arr_holes_len;
BMEdge **edge_arr_holes;
if (BM_face_split_edgenet_connect_islands(
bm, f,
@@ -305,14 +305,14 @@ static enum ISectType intersect_line_tri(
const struct ISectEpsilon *e)
{
float p_dir[3];
- unsigned int i_t0;
+ uint i_t0;
float fac;
sub_v3_v3v3(p_dir, p0, p1);
normalize_v3(p_dir);
for (i_t0 = 0; i_t0 < 3; i_t0++) {
- const unsigned int i_t1 = (i_t0 + 1) % 3;
+ const uint i_t1 = (i_t0 + 1) % 3;
float te_dir[3];
sub_v3_v3v3(te_dir, t_cos[i_t0], t_cos[i_t1]);
@@ -375,7 +375,7 @@ static BMVert *bm_isect_edge_tri(
{
BMesh *bm = s->bm;
int k_arr[IX_TOT][4];
- unsigned int i;
+ uint i;
const int ti[3] = {UNPACK3_EX(BM_elem_index_get, t, )};
float ix[3];
@@ -470,7 +470,7 @@ static BMVert *bm_isect_edge_tri(
}
if ((*r_side >= IX_EDGE_TRI_EDGE0) && (*r_side <= IX_EDGE_TRI_EDGE2)) {
- i = (unsigned int)(*r_side - IX_EDGE_TRI_EDGE0);
+ i = (uint)(*r_side - IX_EDGE_TRI_EDGE0);
e = BM_edge_exists(t[i], t[(i + 1) % 3]);
if (e) {
edge_verts_add(s, e, iv, false);
@@ -537,7 +537,7 @@ static void bm_isect_tri_tri(
const float *f_b_cos[3] = {UNPACK3_EX(, fv_b, ->co)};
float f_a_nor[3];
float f_b_nor[3];
- unsigned int i;
+ uint i;
/* should be enough but may need to bump */
@@ -578,9 +578,9 @@ static void bm_isect_tri_tri(
/* first check in any verts are touching
* (any case where we wont create new verts)
*/
- unsigned int i_a;
+ uint i_a;
for (i_a = 0; i_a < 3; i_a++) {
- unsigned int i_b;
+ uint i_b;
for (i_b = 0; i_b < 3; i_b++) {
if (len_squared_v3v3(fv_a[i_a]->co, fv_b[i_b]->co) <= s->epsilon.eps2x_sq) {
#ifdef USE_DUMP
@@ -603,12 +603,12 @@ static void bm_isect_tri_tri(
/* vert-edge
* --------- */
{
- unsigned int i_a;
+ uint i_a;
for (i_a = 0; i_a < 3; i_a++) {
if (BM_ELEM_API_FLAG_TEST(fv_a[i_a], VERT_VISIT_A) == 0) {
- unsigned int i_b_e0;
+ uint i_b_e0;
for (i_b_e0 = 0; i_b_e0 < 3; i_b_e0++) {
- unsigned int i_b_e1 = (i_b_e0 + 1) % 3;
+ uint i_b_e1 = (i_b_e0 + 1) % 3;
if (BM_ELEM_API_FLAG_TEST(fv_b[i_b_e0], VERT_VISIT_B) ||
BM_ELEM_API_FLAG_TEST(fv_b[i_b_e1], VERT_VISIT_B))
@@ -644,12 +644,12 @@ static void bm_isect_tri_tri(
}
{
- unsigned int i_b;
+ uint i_b;
for (i_b = 0; i_b < 3; i_b++) {
if (BM_ELEM_API_FLAG_TEST(fv_b[i_b], VERT_VISIT_B) == 0) {
- unsigned int i_a_e0;
+ uint i_a_e0;
for (i_a_e0 = 0; i_a_e0 < 3; i_a_e0++) {
- unsigned int i_a_e1 = (i_a_e0 + 1) % 3;
+ uint i_a_e1 = (i_a_e0 + 1) % 3;
if (BM_ELEM_API_FLAG_TEST(fv_a[i_a_e0], VERT_VISIT_A) ||
BM_ELEM_API_FLAG_TEST(fv_a[i_a_e1], VERT_VISIT_A))
@@ -689,7 +689,7 @@ static void bm_isect_tri_tri(
{
float t_scale[3][3];
- unsigned int i_a;
+ uint i_a;
copy_v3_v3(t_scale[0], fv_b[0]->co);
copy_v3_v3(t_scale[1], fv_b[1]->co);
@@ -717,7 +717,7 @@ static void bm_isect_tri_tri(
{
float t_scale[3][3];
- unsigned int i_b;
+ uint i_b;
copy_v3_v3(t_scale[0], fv_a[0]->co);
copy_v3_v3(t_scale[1], fv_a[1]->co);
@@ -757,8 +757,8 @@ static void bm_isect_tri_tri(
/* edge-tri & edge-edge
* -------------------- */
{
- for (unsigned int i_a_e0 = 0; i_a_e0 < 3; i_a_e0++) {
- unsigned int i_a_e1 = (i_a_e0 + 1) % 3;
+ for (uint i_a_e0 = 0; i_a_e0 < 3; i_a_e0++) {
+ uint i_a_e1 = (i_a_e0 + 1) % 3;
enum ISectType side;
BMVert *iv;
@@ -778,8 +778,8 @@ static void bm_isect_tri_tri(
}
}
- for (unsigned int i_b_e0 = 0; i_b_e0 < 3; i_b_e0++) {
- unsigned int i_b_e1 = (i_b_e0 + 1) % 3;
+ for (uint i_b_e0 = 0; i_b_e0 < 3; i_b_e0++) {
+ uint i_b_e1 = (i_b_e0 + 1) % 3;
enum ISectType side;
BMVert *iv;
@@ -956,7 +956,7 @@ static int isect_bvhtree_point_v3(
const float *depth_arr = z_buffer.data;
float depth_last = depth_arr[0];
- for (unsigned int i = 1; i < z_buffer.count; i++) {
+ for (uint i = 1; i < z_buffer.count; i++) {
if (depth_arr[i] - depth_last > eps) {
depth_last = depth_arr[i];
num_isect++;
@@ -1000,7 +1000,7 @@ bool BM_mesh_intersect(
#ifdef USE_BVH
BVHTree *tree_a, *tree_b;
- unsigned int tree_overlap_tot;
+ uint tree_overlap_tot;
BVHTreeOverlap *overlap;
#else
int i_a, i_b;
@@ -1117,7 +1117,7 @@ bool BM_mesh_intersect(
overlap = BLI_bvhtree_overlap(tree_b, tree_a, &tree_overlap_tot, NULL, NULL);
if (overlap) {
- unsigned int i;
+ uint i;
for (i = 0; i < tree_overlap_tot; i++) {
#ifdef USE_DUMP
@@ -1390,7 +1390,7 @@ bool BM_mesh_intersect(
GHASH_ITER (gh_iter, s.face_edges) {
struct LinkBase *e_ls_base = BLI_ghashIterator_getValue(&gh_iter);
LinkNode **node_prev_p;
- unsigned int i;
+ uint i;
node_prev_p = &e_ls_base->list;
for (i = 0, node = e_ls_base->list; node; i++, node = node->next) {
@@ -1455,7 +1455,7 @@ bool BM_mesh_intersect(
}
{
- unsigned int i;
+ uint i;
for (i = 0; i < STACK_SIZE(splice_ls); i++) {
if (!BLI_gset_haskey(verts_invalid, splice_ls[i][0]) &&
!BLI_gset_haskey(verts_invalid, splice_ls[i][1]))
@@ -1610,7 +1610,7 @@ bool BM_mesh_intersect(
#ifdef USE_BOOLEAN_RAYCAST_DRAW
{
- unsigned int colors[4] = {0x00000000, 0xffffffff, 0xff000000, 0x0000ff};
+ uint colors[4] = {0x00000000, 0xffffffff, 0xff000000, 0x0000ff};
float co_other[3] = {UNPACK3(co)};
co_other[0] += 1000.0f;
bl_debug_color_set(colors[(hits & 1) == 1]);
diff --git a/source/blender/bmesh/tools/bmesh_path.h b/source/blender/bmesh/tools/bmesh_path.h
index b6de5e0e4e0..fbdd2296121 100644
--- a/source/blender/bmesh/tools/bmesh_path.h
+++ b/source/blender/bmesh/tools/bmesh_path.h
@@ -28,8 +28,8 @@
*/
struct BMCalcPathParams {
- unsigned int use_topology_distance : 1;
- unsigned int use_step_face : 1;
+ uint use_topology_distance : 1;
+ uint use_step_face : 1;
};
struct LinkNode *BM_mesh_calc_path_vert(
diff --git a/source/blender/bmesh/tools/bmesh_region_match.c b/source/blender/bmesh/tools/bmesh_region_match.c
index a6860a6614a..2abf8f2c46e 100644
--- a/source/blender/bmesh/tools/bmesh_region_match.c
+++ b/source/blender/bmesh/tools/bmesh_region_match.c
@@ -114,7 +114,7 @@ typedef struct UUIDWalk {
GHash *faces_from_uuid; /* UUID -> UUIDFaceStepItem */
UUID_Int *rehash_store;
- unsigned int rehash_store_len;
+ uint rehash_store_len;
} cache;
} UUIDWalk;
@@ -136,7 +136,7 @@ typedef struct UUIDFaceStepItem {
uintptr_t uuid;
LinkNode *list;
- unsigned int list_len;
+ uint list_len;
} UUIDFaceStepItem;
BLI_INLINE bool bm_uuidwalk_face_test(
@@ -178,10 +178,10 @@ BLI_INLINE bool bm_uuidwalk_face_lookup(
}
}
-static unsigned int ghashutil_bmelem_indexhash(const void *key)
+static uint ghashutil_bmelem_indexhash(const void *key)
{
const BMElem *ele = key;
- return (unsigned int)BM_elem_index_get(ele);
+ return (uint)BM_elem_index_get(ele);
}
static bool ghashutil_bmelem_indexcmp(const void *a, const void *b)
@@ -192,14 +192,14 @@ static bool ghashutil_bmelem_indexcmp(const void *a, const void *b)
static GHash *ghash_bmelem_new_ex(
const char *info,
- const unsigned int nentries_reserve)
+ const uint nentries_reserve)
{
return BLI_ghash_new_ex(ghashutil_bmelem_indexhash, ghashutil_bmelem_indexcmp, info, nentries_reserve);
}
static GSet *gset_bmelem_new_ex(
const char *info,
- const unsigned int nentries_reserve)
+ const uint nentries_reserve)
{
return BLI_gset_new_ex(ghashutil_bmelem_indexhash, ghashutil_bmelem_indexcmp, info, nentries_reserve);
}
@@ -218,8 +218,8 @@ static GSet *gset_bmelem_new(const char *info)
static void bm_uuidwalk_init(
UUIDWalk *uuidwalk,
- const unsigned int faces_src_region_len,
- const unsigned int verts_src_region_len)
+ const uint faces_src_region_len,
+ const uint verts_src_region_len)
{
BLI_listbase_clear(&uuidwalk->faces_step);
@@ -307,7 +307,7 @@ static UUID_Int bm_uuidwalk_calc_vert_uuid(
/* vert -> other */
{
- unsigned int tot = 0;
+ uint tot = 0;
BMIter eiter;
BMEdge *e;
BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
@@ -323,7 +323,7 @@ static UUID_Int bm_uuidwalk_calc_vert_uuid(
/* faces */
{
- unsigned int tot = 0;
+ uint tot = 0;
BMIter iter;
BMFace *f;
@@ -357,7 +357,7 @@ static UUID_Int bm_uuidwalk_calc_face_uuid(
UUID_Int uuid;
- uuid = uuidwalk->pass * (unsigned int)f->len * PRIME_FACE_LARGE;
+ uuid = uuidwalk->pass * (uint)f->len * PRIME_FACE_LARGE;
/* face-verts */
{
@@ -399,7 +399,7 @@ static UUID_Int bm_uuidwalk_calc_face_uuid(
}
static void bm_uuidwalk_rehash_reserve(
- UUIDWalk *uuidwalk, unsigned int rehash_store_len_new)
+ UUIDWalk *uuidwalk, uint rehash_store_len_new)
{
if (UNLIKELY(rehash_store_len_new > uuidwalk->cache.rehash_store_len)) {
/* avoid re-allocs */
@@ -419,9 +419,9 @@ static void bm_uuidwalk_rehash(
{
GHashIterator gh_iter;
UUID_Int *uuid_store;
- unsigned int i;
+ uint i;
- unsigned int rehash_store_len_new = MAX2(BLI_ghash_size(uuidwalk->verts_uuid),
+ uint rehash_store_len_new = MAX2(BLI_ghash_size(uuidwalk->verts_uuid),
BLI_ghash_size(uuidwalk->faces_uuid));
bm_uuidwalk_rehash_reserve(uuidwalk, rehash_store_len_new);
@@ -454,12 +454,12 @@ static void bm_uuidwalk_rehash(
static void bm_uuidwalk_rehash_facelinks(
UUIDWalk *uuidwalk,
- LinkNode *faces, const unsigned int faces_len,
+ LinkNode *faces, const uint faces_len,
const bool is_init)
{
UUID_Int *uuid_store;
LinkNode *f_link;
- unsigned int i;
+ uint i;
bm_uuidwalk_rehash_reserve(uuidwalk, faces_len);
uuid_store = uuidwalk->cache.rehash_store;
@@ -502,7 +502,7 @@ static bool bm_vert_is_uuid_connect(
}
static void bm_uuidwalk_pass_add(
- UUIDWalk *uuidwalk, LinkNode *faces_pass, const unsigned int faces_pass_len)
+ UUIDWalk *uuidwalk, LinkNode *faces_pass, const uint faces_pass_len)
{
GHashIterator gh_iter;
GHash *verts_uuid_pass;
@@ -511,7 +511,7 @@ static void bm_uuidwalk_pass_add(
UUIDFaceStep *fstep;
- BLI_assert(faces_pass_len == (unsigned int)BLI_linklist_count(faces_pass));
+ BLI_assert(faces_pass_len == (uint)BLI_linklist_count(faces_pass));
/* rehash faces now all their verts have been added */
bm_uuidwalk_rehash_facelinks(uuidwalk, faces_pass, faces_pass_len, true);
@@ -588,13 +588,13 @@ static int bm_face_len_cmp(const void *v1, const void *v2)
else return 0;
}
-static unsigned int bm_uuidwalk_init_from_edge(
+static uint bm_uuidwalk_init_from_edge(
UUIDWalk *uuidwalk, BMEdge *e)
{
BMLoop *l_iter = e->l;
- unsigned int f_arr_len = (unsigned int)BM_edge_face_count(e);
+ uint f_arr_len = (uint)BM_edge_face_count(e);
BMFace **f_arr = BLI_array_alloca(f_arr, f_arr_len);
- unsigned int fstep_num = 0, i = 0;
+ uint fstep_num = 0, i = 0;
do {
BMFace *f = l_iter->f;
@@ -619,7 +619,7 @@ static unsigned int bm_uuidwalk_init_from_edge(
* elsewhere using LinkNode's makes more sense */
for (i = 0; i < f_arr_len; ) {
LinkNode *faces_pass = NULL;
- const unsigned int i_init = i;
+ const uint i_init = i;
const int f_len = f_arr[i]->len;
do {
@@ -750,9 +750,9 @@ static BMFace **bm_mesh_region_match_pair(
UUIDWalk *w_src, UUIDWalk *w_dst,
#endif
BMEdge *e_src, BMEdge *e_dst,
- const unsigned int faces_src_region_len,
- const unsigned int verts_src_region_len,
- unsigned int *r_faces_result_len)
+ const uint faces_src_region_len,
+ const uint verts_src_region_len,
+ uint *r_faces_result_len)
{
#ifndef USE_WALKER_REUSE
UUIDWalk w_src_, w_dst_;
@@ -877,8 +877,8 @@ static BMFace **bm_mesh_region_match_pair(
if (found) {
GHashIterator gh_iter;
- const unsigned int faces_result_len = BLI_ghash_size(w_dst->faces_uuid);
- unsigned int i;
+ const uint faces_result_len = BLI_ghash_size(w_dst->faces_uuid);
+ uint i;
faces_result = MEM_mallocN(sizeof(*faces_result) * (faces_result_len + 1), __func__);
GHASH_ITER_INDEX (gh_iter, w_dst->faces_uuid, i) {
@@ -909,12 +909,12 @@ finally:
* Tag as visited, avoid re-use.
*/
static void bm_face_array_visit(
- BMFace **faces, const unsigned int faces_len,
- unsigned int *r_verts_len,
+ BMFace **faces, const uint faces_len,
+ uint *r_verts_len,
bool visit_faces)
{
- unsigned int verts_len = 0;
- unsigned int i;
+ uint verts_len = 0;
+ uint i;
for (i = 0; i < faces_len; i++) {
BMFace *f = faces[i];
BMLoop *l_iter, *l_first;
@@ -1081,9 +1081,9 @@ static SUID_Int bm_face_region_vert_pass_id(GHash *gh, BMVert *v)
* This is only called once on the source region (no need to be highly optimized).
*/
static BMEdge *bm_face_region_pivot_edge_find(
- BMFace **faces_region, unsigned int faces_region_len,
- unsigned int verts_region_len,
- unsigned int *r_depth)
+ BMFace **faces_region, uint faces_region_len,
+ uint verts_region_len,
+ uint *r_depth)
{
/* note, keep deterministic where possible (geometry order independent)
* this function assumed all visit faces & edges are tagged */
@@ -1092,7 +1092,7 @@ static BMEdge *bm_face_region_pivot_edge_find(
BLI_LINKSTACK_DECLARE(vert_queue_next, BMVert *);
GHash *gh = BLI_ghash_ptr_new(__func__);
- unsigned int i;
+ uint i;
BMEdge *e_pivot = NULL;
/* pick any non-boundary edge (not ideal) */
@@ -1101,7 +1101,7 @@ static BMEdge *bm_face_region_pivot_edge_find(
SUID_Int pass = 0;
/* total verts in 'gs' we have visited - aka - not v_init_none */
- unsigned int vert_queue_used = 0;
+ uint vert_queue_used = 0;
BLI_LINKSTACK_INIT(vert_queue_prev);
BLI_LINKSTACK_INIT(vert_queue_next);
@@ -1115,7 +1115,7 @@ static BMEdge *bm_face_region_pivot_edge_find(
do {
BMEdge *e = l_iter->e;
if (bm_edge_is_region_boundary(e)) {
- unsigned int j;
+ uint j;
for (j = 0; j < 2; j++) {
void **val_p;
if (!BLI_ghash_ensure_p(gh, (&e->v1)[j], &val_p)) {
@@ -1251,7 +1251,7 @@ static BMEdge *bm_face_region_pivot_edge_find(
pass = 0;
}
- *r_depth = (unsigned int)pass;
+ *r_depth = (uint)pass;
return e_pivot;
}
@@ -1286,7 +1286,7 @@ static UUIDFashMatch bm_vert_fasthash_single(BMVert *v)
e_num += 1;
do {
f_num += 1;
- l_num += (unsigned int)l_iter->f->len;
+ l_num += (uint)l_iter->f->len;
} while ((l_iter = l_iter->radial_next) != e->l);
}
}
@@ -1301,16 +1301,16 @@ static UUIDFashMatch bm_vert_fasthash_single(BMVert *v)
}
static UUIDFashMatch *bm_vert_fasthash_create(
- BMesh *bm, const unsigned int depth)
+ BMesh *bm, const uint depth)
{
UUIDFashMatch *id_prev;
UUIDFashMatch *id_curr;
- unsigned int pass, i;
+ uint pass, i;
BMVert *v;
BMIter iter;
- id_prev = MEM_mallocN(sizeof(*id_prev) * (unsigned int)bm->totvert, __func__);
- id_curr = MEM_mallocN(sizeof(*id_curr) * (unsigned int)bm->totvert, __func__);
+ id_prev = MEM_mallocN(sizeof(*id_prev) * (uint)bm->totvert, __func__);
+ id_curr = MEM_mallocN(sizeof(*id_curr) * (uint)bm->totvert, __func__);
BM_ITER_MESH_INDEX (v, &iter, bm, BM_VERTS_OF_MESH, i) {
id_prev[i] = bm_vert_fasthash_single(v);
@@ -1319,7 +1319,7 @@ static UUIDFashMatch *bm_vert_fasthash_create(
for (pass = 0; pass < depth; pass++) {
BMEdge *e;
- memcpy(id_curr, id_prev, sizeof(*id_prev) * (unsigned int)bm->totvert);
+ memcpy(id_curr, id_prev, sizeof(*id_prev) * (uint)bm->totvert);
BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
if (BM_edge_is_wire(e) == false) {
@@ -1379,16 +1379,16 @@ static void bm_vert_fasthash_destroy(
*/
int BM_mesh_region_match(
BMesh *bm,
- BMFace **faces_region, unsigned int faces_region_len,
+ BMFace **faces_region, uint faces_region_len,
ListBase *r_face_regions)
{
BMEdge *e_src;
BMEdge *e_dst;
BMIter iter;
- unsigned int verts_region_len = 0;
- unsigned int faces_result_len = 0;
+ uint verts_region_len = 0;
+ uint faces_result_len = 0;
/* number of steps from e_src to a boundary vert */
- unsigned int depth;
+ uint depth;
#ifdef USE_WALKER_REUSE
@@ -1457,7 +1457,7 @@ int BM_mesh_region_match(
BM_ITER_MESH (e_dst, &iter, bm, BM_EDGES_OF_MESH) {
BMFace **faces_result;
- unsigned int faces_result_len_out;
+ uint faces_result_len_out;
if (BM_elem_flag_test(e_dst, BM_ELEM_TAG) || BM_edge_is_wire(e_dst)) {
continue;
diff --git a/source/blender/bmesh/tools/bmesh_region_match.h b/source/blender/bmesh/tools/bmesh_region_match.h
index edf8369b070..8ef138629b8 100644
--- a/source/blender/bmesh/tools/bmesh_region_match.h
+++ b/source/blender/bmesh/tools/bmesh_region_match.h
@@ -27,7 +27,7 @@
int BM_mesh_region_match(
BMesh *bm,
- BMFace **faces_region, unsigned int faces_region_len,
+ BMFace **faces_region, uint faces_region_len,
ListBase *r_face_regions);
#endif /* __BMESH_REGION_MATCH_H__ */
diff --git a/source/blender/bmesh/tools/bmesh_separate.c b/source/blender/bmesh/tools/bmesh_separate.c
index ff28ed4c156..287b4125330 100644
--- a/source/blender/bmesh/tools/bmesh_separate.c
+++ b/source/blender/bmesh/tools/bmesh_separate.c
@@ -58,8 +58,8 @@ void BM_mesh_separate_faces(
BMFace *f;
BMIter iter;
- unsigned int faces_a_len = 0;
- unsigned int faces_b_len = 0;
+ uint faces_a_len = 0;
+ uint faces_b_len = 0;
{
int i_a = 0;
int i_b = bm->totface;
@@ -77,7 +77,7 @@ void BM_mesh_separate_faces(
BM_mesh_elem_hflag_enable_all(bm, BM_VERT, BM_ELEM_TAG, false);
/* Disable vert tag on faces_b */
- for (unsigned int i = 0; i < faces_b_len; i++) {
+ for (uint i = 0; i < faces_b_len; i++) {
BMLoop *l_iter, *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(faces_b[i]);
do {
@@ -89,7 +89,7 @@ void BM_mesh_separate_faces(
BLI_buffer_declare_static(BMLoop **, loop_split, 0, 128);
/* Check shared verts ('faces_a' tag and disable) */
- for (unsigned int i = 0; i < faces_a_len; i++) {
+ for (uint i = 0; i < faces_a_len; i++) {
BMLoop *l_iter, *l_first;
l_iter = l_first = BM_FACE_FIRST_LOOP(faces_a[i]);
do {
diff --git a/source/blender/collada/AnimationExporter.cpp b/source/blender/collada/AnimationExporter.cpp
index 3bff20e846b..b3d512204be 100644
--- a/source/blender/collada/AnimationExporter.cpp
+++ b/source/blender/collada/AnimationExporter.cpp
@@ -530,7 +530,7 @@ void AnimationExporter::dae_baked_animation(std::vector<float> &fra, Object *ob_
addSampler(sampler);
- std::string target = translate_id(bone_name) + "/transform";
+ std::string target = get_joint_id(bone, ob_arm) + "/transform";
addChannel(COLLADABU::URI(empty, sampler_id), target);
closeAnimation();
diff --git a/source/blender/collada/ArmatureExporter.cpp b/source/blender/collada/ArmatureExporter.cpp
index 9348f3b3285..d2495a8cb9f 100644
--- a/source/blender/collada/ArmatureExporter.cpp
+++ b/source/blender/collada/ArmatureExporter.cpp
@@ -116,7 +116,10 @@ bool ArmatureExporter::add_instance_controller(Object *ob)
write_bone_URLs(ins, ob_arm, bone);
}
- InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob, this->export_settings->active_uv_only);
+ InstanceWriter::add_material_bindings(ins.getBindMaterial(),
+ ob,
+ this->export_settings->active_uv_only,
+ this->export_settings->export_texture_type);
ins.add();
return true;
diff --git a/source/blender/collada/ControllerExporter.cpp b/source/blender/collada/ControllerExporter.cpp
index 1c2642e8313..5cd5e6d271a 100644
--- a/source/blender/collada/ControllerExporter.cpp
+++ b/source/blender/collada/ControllerExporter.cpp
@@ -98,7 +98,10 @@ bool ControllerExporter::add_instance_controller(Object *ob)
write_bone_URLs(ins, ob_arm, bone);
}
- InstanceWriter::add_material_bindings(ins.getBindMaterial(), ob, this->export_settings->active_uv_only);
+ InstanceWriter::add_material_bindings(ins.getBindMaterial(),
+ ob,
+ this->export_settings->active_uv_only,
+ this->export_settings->export_texture_type);
ins.add();
return true;
diff --git a/source/blender/collada/DocumentExporter.cpp b/source/blender/collada/DocumentExporter.cpp
index bd32e989ae3..634071bc90f 100644
--- a/source/blender/collada/DocumentExporter.cpp
+++ b/source/blender/collada/DocumentExporter.cpp
@@ -138,7 +138,8 @@ extern bool bc_has_object_type(LinkNode *export_set, short obtype);
char *bc_CustomData_get_layer_name(const struct CustomData *data, int type, int n)
{
int layer_index = CustomData_get_layer_index(data, type);
- if (layer_index < 0) return NULL;
+ if (layer_index < 0)
+ return NULL;
return data->layers[layer_index + n].name;
}
@@ -147,9 +148,10 @@ char *bc_CustomData_get_active_layer_name(const CustomData *data, int type)
{
/* get the layer index of the active layer of type */
int layer_index = CustomData_get_active_layer_index(data, type);
- if (layer_index < 0) return NULL;
+ if (layer_index < 1)
+ return NULL;
- return data->layers[layer_index].name;
+ return bc_CustomData_get_layer_name(data, type, layer_index-1);
}
DocumentExporter::DocumentExporter(const ExportSettings *export_settings) : export_settings(export_settings) {
diff --git a/source/blender/collada/DocumentImporter.cpp b/source/blender/collada/DocumentImporter.cpp
index 226f319cefd..435eaa0208a 100644
--- a/source/blender/collada/DocumentImporter.cpp
+++ b/source/blender/collada/DocumentImporter.cpp
@@ -388,9 +388,7 @@ Object *DocumentImporter::create_camera_object(COLLADAFW::InstanceCamera *camera
Camera *cam = uid_camera_map[cam_uid];
Camera *old_cam = (Camera *)ob->data;
ob->data = cam;
- id_us_min(&old_cam->id);
- if (old_cam->id.us == 0)
- BKE_libblock_free(G.main, old_cam);
+ BKE_libblock_free_us(G.main, old_cam);
return ob;
}
@@ -406,9 +404,7 @@ Object *DocumentImporter::create_lamp_object(COLLADAFW::InstanceLight *lamp, Sce
Lamp *la = uid_lamp_map[lamp_uid];
Lamp *old_lamp = (Lamp *)ob->data;
ob->data = la;
- id_us_min(&old_lamp->id);
- if (old_lamp->id.us == 0)
- BKE_libblock_free(G.main, old_lamp);
+ BKE_libblock_free_us(G.main, old_lamp);
return ob;
}
diff --git a/source/blender/collada/EffectExporter.cpp b/source/blender/collada/EffectExporter.cpp
index 76b51148509..2bf0859b0f0 100644
--- a/source/blender/collada/EffectExporter.cpp
+++ b/source/blender/collada/EffectExporter.cpp
@@ -27,7 +27,6 @@
#include <map>
-#include <set>
#include "COLLADASWEffectProfile.h"
#include "COLLADAFWColorOrTexture.h"
@@ -49,21 +48,10 @@ extern "C" {
#include "BKE_material.h"
}
-// OB_MESH is assumed
-static std::string getActiveUVLayerName(Object *ob)
-{
- Mesh *me = (Mesh *)ob->data;
-
- int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
- if (num_layers)
- return std::string(bc_CustomData_get_active_layer_name(&me->fdata, CD_MTFACE));
-
- return "";
-}
-
EffectsExporter::EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryEffects(sw), export_settings(export_settings) {
}
+
bool EffectsExporter::hasEffects(Scene *sce)
{
Base *base = (Base *)sce->base.first;
@@ -86,13 +74,49 @@ bool EffectsExporter::hasEffects(Scene *sce)
void EffectsExporter::exportEffects(Scene *sce)
{
- if (hasEffects(sce)) {
- this->scene = sce;
- openLibrary();
- MaterialFunctor mf;
- mf.forEachMaterialInExportSet<EffectsExporter>(sce, *this, this->export_settings->export_set);
-
- closeLibrary();
+ this->scene = sce;
+
+ if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT) {
+ if (hasEffects(sce)) {
+ MaterialFunctor mf;
+ openLibrary();
+ mf.forEachMaterialInExportSet<EffectsExporter>(sce, *this, this->export_settings->export_set);
+ closeLibrary();
+ }
+ }
+ else {
+ std::set<Object *> uv_textured_obs = bc_getUVTexturedObjects(sce, !this->export_settings->active_uv_only);
+ std::set<Image *> uv_images = bc_getUVImages(sce, !this->export_settings->active_uv_only);
+ if (uv_images.size() > 0) {
+ openLibrary();
+ std::set<Image *>::iterator uv_images_iter;
+ for (uv_images_iter = uv_images.begin();
+ uv_images_iter != uv_images.end();
+ uv_images_iter++) {
+
+ Image *ima = *uv_images_iter;
+ std::string key(id_name(ima));
+ key = translate_id(key);
+ COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D,
+ key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX,
+ key + COLLADASW::Sampler::SURFACE_SID_SUFFIX);
+ sampler.setImageId(key);
+
+ openEffect(key + "-effect");
+ COLLADASW::EffectProfile ep(mSW);
+ ep.setProfileType(COLLADASW::EffectProfile::COMMON);
+ ep.setShaderType(COLLADASW::EffectProfile::PHONG);
+ ep.setDiffuse(createTexture(ima, key, &sampler), false, "diffuse");
+ COLLADASW::ColorOrTexture cot = getcol(0, 0, 0, 1.0f);
+ ep.setSpecular(cot, false, "specular");
+ ep.openProfile();
+ ep.addProfileElements();
+ ep.addExtraTechniques(mSW);
+ ep.closeProfile();
+ closeEffect();
+ }
+ closeLibrary();
+ }
}
}
@@ -176,8 +200,7 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
{
// create a list of indices to textures of type TEX_IMAGE
std::vector<int> tex_indices;
- if (this->export_settings->include_material_textures)
- createTextureIndices(ma, tex_indices);
+ createTextureIndices(ma, tex_indices);
openEffect(translate_id(id_name(ma)) + "-effect");
@@ -311,61 +334,9 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
}
}
- int active_uv_layer = -1;
- std::set<Image *> uv_textures;
- if (ob->type == OB_MESH && ob->totcol && this->export_settings->include_uv_textures) {
- bool active_uv_only = this->export_settings->active_uv_only;
- Mesh *me = (Mesh *) ob->data;
- active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
-
- BKE_mesh_tessface_ensure(me);
- for (int i = 0; i < me->pdata.totlayer; i++) {
- if (!active_uv_only || active_uv_layer == i)
- {
- if (me->pdata.layers[i].type == CD_MTEXPOLY) {
- MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
- MPoly *mpoly = me->mpoly;
- for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) {
-
- Material *mat = give_current_material(ob, mpoly->mat_nr + 1);
- if (mat != ma)
- continue;
-
- Image *ima = txface->tpage;
- if (ima == NULL)
- continue;
-
-
- bool not_in_list = uv_textures.find(ima)==uv_textures.end();
- if (not_in_list) {
- std::string name = id_name(ima);
- std::string key(name);
- key = translate_id(key);
-
- // create only one <sampler>/<surface> pair for each unique image
- if (im_samp_map.find(key) == im_samp_map.end()) {
- //<newparam> <sampler> <source>
- COLLADASW::Sampler sampler(COLLADASW::Sampler::SAMPLER_TYPE_2D,
- key + COLLADASW::Sampler::SAMPLER_SID_SUFFIX,
- key + COLLADASW::Sampler::SURFACE_SID_SUFFIX);
- sampler.setImageId(key);
- samplers[a] = sampler;
- samp_surf[b] = &samplers[a];
- im_samp_map[key] = b;
- b++;
- a++;
- uv_textures.insert(ima);
- }
- }
- }
- }
- }
- }
- }
-
// used as fallback when MTex->uvname is "" (this is pretty common)
// it is indeed the correct value to use in that case
- std::string active_uv(getActiveUVLayerName(ob));
+ std::string active_uv(bc_get_active_uvlayer_name(ob));
// write textures
// XXX very slow
@@ -385,19 +356,6 @@ void EffectsExporter::operator()(Material *ma, Object *ob)
writeTextures(ep, key, sampler, t, ima, uvname);
}
- std::set<Image *>::iterator uv_t_iter;
- int idx;
- for (idx = 0, uv_t_iter = uv_textures.begin(); uv_t_iter != uv_textures.end(); uv_t_iter++, idx++ ) {
- if (active_uv_layer>-1 && idx==active_uv_layer) {
- Image *ima = *uv_t_iter;
- std::string key(id_name(ima));
- key = translate_id(key);
- int i = im_samp_map[key];
- COLLADASW::Sampler *sampler = (COLLADASW::Sampler *)samp_surf[i];
- ep.setDiffuse(createTexture(ima, active_uv, sampler), false, "diffuse");
- }
- }
-
// performs the actual writing
ep.addProfileElements();
bool twoSided = false;
diff --git a/source/blender/collada/EffectExporter.h b/source/blender/collada/EffectExporter.h
index d20cbfdfe0b..7d45a085777 100644
--- a/source/blender/collada/EffectExporter.h
+++ b/source/blender/collada/EffectExporter.h
@@ -48,7 +48,6 @@ class EffectsExporter: COLLADASW::LibraryEffects
public:
EffectsExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings);
void exportEffects(Scene *sce);
-
void operator()(Material *ma, Object *ob);
COLLADASW::ColorOrTexture createTexture(Image *ima,
diff --git a/source/blender/collada/ErrorHandler.cpp b/source/blender/collada/ErrorHandler.cpp
index 98aa85f8a9b..32aa5636e08 100644
--- a/source/blender/collada/ErrorHandler.cpp
+++ b/source/blender/collada/ErrorHandler.cpp
@@ -49,7 +49,7 @@ ErrorHandler::~ErrorHandler()
//--------------------------------------------------------------------
bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error)
{
- bool isError = true;
+ bool isError = false;
if (error->getErrorClass() == COLLADASaxFWL::IError::ERROR_SAXPARSER) {
COLLADASaxFWL::SaxParserError *saxParserError = (COLLADASaxFWL::SaxParserError *) error;
@@ -81,10 +81,7 @@ bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error)
* Accept non critical errors as warnings (i.e. texture not found)
* This makes the importer more graceful, so it now imports what makes sense.
*/
- if (saxFWLError->getSeverity() == COLLADASaxFWL::IError::SEVERITY_ERROR_NONCRITICAL) {
- isError = false;
- }
-
+ isError = (saxFWLError->getSeverity() != COLLADASaxFWL::IError::SEVERITY_ERROR_NONCRITICAL);
std::cout << "Sax FWL Error: " << saxFWLError->getErrorMessage() << std::endl;
}
else {
@@ -93,5 +90,5 @@ bool ErrorHandler::handleError(const COLLADASaxFWL::IError *error)
mError |= isError;
- return false; // let OpenCollada decide when to abort
+ return isError; // let OpenCollada decide when to abort
}
diff --git a/source/blender/collada/ExportSettings.h b/source/blender/collada/ExportSettings.h
index de91f68a492..6d90edd2f67 100644
--- a/source/blender/collada/ExportSettings.h
+++ b/source/blender/collada/ExportSettings.h
@@ -28,7 +28,6 @@
#define __EXPORTSETTINGS_H__
#include "collada.h"
-#include "collada.h"
struct ExportSettings {
public:
@@ -42,8 +41,7 @@ public:
bool deform_bones_only;
bool active_uv_only;
- bool include_uv_textures;
- bool include_material_textures;
+ BC_export_texture_type export_texture_type;
bool use_texture_copies;
bool triangulate;
diff --git a/source/blender/collada/GeometryExporter.cpp b/source/blender/collada/GeometryExporter.cpp
index 7c7c57f3305..b8b1ff7fd95 100644
--- a/source/blender/collada/GeometryExporter.cpp
+++ b/source/blender/collada/GeometryExporter.cpp
@@ -52,6 +52,7 @@ extern "C" {
#include "collada_internal.h"
#include "collada_utils.h"
+
// TODO: optimize UV sets by making indexed list with duplicates removed
GeometryExporter::GeometryExporter(COLLADASW::StreamWriter *sw, const ExportSettings *export_settings) : COLLADASW::LibraryGeometries(sw), export_settings(export_settings)
{
@@ -134,13 +135,22 @@ void GeometryExporter::operator()(Object *ob)
// Only create Polylists if number of faces > 0
if (me->totface > 0) {
// XXX slow
- if (ob->totcol) {
- for (int a = 0; a < ob->totcol; a++) {
- createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind);
+ std::set<Image *> uv_images = bc_getUVImages(ob, !this->export_settings->active_uv_only);
+ if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT || uv_images.size() == 0) {
+ if (ob->totcol) {
+ for (int a = 0; a < ob->totcol; a++) {
+ createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind);
+ }
+ }
+ else {
+ int i = 0;
+ createPolylist(i, has_uvs, has_color, ob, me, geom_id, norind);
}
}
else {
- createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind);
+ bool all_uv_layers = !this->export_settings->active_uv_only;
+ std::set<Image *> uv_images = bc_getUVImages(ob, all_uv_layers);
+ createPolylists(uv_images, has_uvs, has_color, ob, me, geom_id, norind);
}
}
@@ -220,13 +230,15 @@ void GeometryExporter::export_key_mesh(Object *ob, Mesh *me, KeyBlock *kb)
//createLooseEdgeList(ob, me, geom_id, norind);
// XXX slow
- if (ob->totcol) {
+ if (ob->totcol && this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT) {
for (int a = 0; a < ob->totcol; a++) {
createPolylist(a, has_uvs, has_color, ob, me, geom_id, norind);
}
}
else {
- createPolylist(0, has_uvs, has_color, ob, me, geom_id, norind);
+ bool all_uv_layers = !this->export_settings->active_uv_only;
+ std::set<Image *> uv_images = bc_getUVImages(ob, all_uv_layers);
+ createPolylists(uv_images, has_uvs, has_color, ob, me, geom_id, norind);
}
closeMesh();
@@ -295,7 +307,44 @@ std::string GeometryExporter::makeVertexColorSourceId(std::string& geom_id, char
return result;
}
-// powerful because it handles both cases when there is material and when there's not
+static void prepareToAppendValues(bool is_triangulated, COLLADASW::PrimitivesBase *facelist, std::vector<unsigned long> &vcount_list)
+{
+ // performs the actual writing
+ if (is_triangulated) {
+ ((COLLADASW::Triangles *)facelist)->prepareToAppendValues();
+ }
+ else {
+ // sets <vcount>
+ facelist->setVCountList(vcount_list);
+ ((COLLADASW::Polylist *)facelist)-> prepareToAppendValues();
+ }
+}
+
+static void finishList(bool is_triangulated, COLLADASW::PrimitivesBase *facelist)
+{
+ if (is_triangulated) {
+ ((COLLADASW::Triangles *)facelist)->finish();
+ }
+ else {
+ ((COLLADASW::Polylist *)facelist)->finish();
+ }
+}
+
+COLLADASW::PrimitivesBase *getFacelist(bool is_triangulated, COLLADASW::StreamWriter *mSW)
+{
+ COLLADASW::PrimitivesBase *facelist;
+
+ if (is_triangulated)
+ {
+ facelist = new COLLADASW::Triangles(mSW);
+ }
+ else {
+ facelist = new COLLADASW::Polylist(mSW);
+ }
+ return facelist;
+}
+
+// Export meshes with Materials
void GeometryExporter::createPolylist(short material_index,
bool has_uvs,
bool has_color,
@@ -313,7 +362,7 @@ void GeometryExporter::createPolylist(short material_index,
int i;
int faces_in_polylist = 0;
std::vector<unsigned long> vcount_list;
-
+ bool is_triangulated = true;
// count faces with this material
for (i = 0; i < totpolys; i++) {
MPoly *p = &mpolys[i];
@@ -321,6 +370,9 @@ void GeometryExporter::createPolylist(short material_index,
if (p->mat_nr == material_index) {
faces_in_polylist++;
vcount_list.push_back(p->totloop);
+ if (p->totloop != 3) {
+ is_triangulated = false;
+ }
}
}
@@ -331,20 +383,21 @@ void GeometryExporter::createPolylist(short material_index,
}
Material *ma = ob->totcol ? give_current_material(ob, material_index + 1) : NULL;
- COLLADASW::Polylist polylist(mSW);
+ COLLADASW::PrimitivesBase *facelist = getFacelist(is_triangulated, mSW);
+
// sets count attribute in <polylist>
- polylist.setCount(faces_in_polylist);
+ facelist->setCount(faces_in_polylist);
// sets material name
if (ma) {
std::string material_id = get_material_id(ma);
std::ostringstream ostr;
ostr << translate_id(material_id);
- polylist.setMaterial(ostr.str());
+ facelist->setMaterial(ostr.str());
}
- COLLADASW::InputList &til = polylist.getInputList();
+ COLLADASW::InputList &til = facelist->getInputList();
// creates <input> in <polylist> for vertices
COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0);
@@ -360,13 +413,21 @@ void GeometryExporter::createPolylist(short material_index,
int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE)-1;
for (i = 0; i < num_layers; i++) {
if (!this->export_settings->active_uv_only || i == active_uv_index) {
-
- // char *name = CustomData_get_layer_name(&me->fdata, CD_MTFACE, i);
+
+ std::string uv_name(bc_get_uvlayer_name(me, i));
+ std::string effective_id = geom_id; // (uv_name == "") ? geom_id : uv_name;
+ std::string layer_id = makeTexcoordSourceId(
+ effective_id,
+ i, this->export_settings->active_uv_only);
+
+ /* Note: the third parameter denotes the offset of TEXCOORD in polylist elements
+ For now this is always 2 (This may change sometime/maybe)
+ */
COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD,
- makeUrl(makeTexcoordSourceId(geom_id, i, this->export_settings->active_uv_only)),
- 2, // this is only until we have optimized UV sets
- (this->export_settings->active_uv_only) ? 0 : i // only_active_uv exported -> we have only one set
- );
+ makeUrl(layer_id),
+ 2, // this is only until we have optimized UV sets
+ (this->export_settings->active_uv_only) ? 0 : i // only_active_uv exported -> we have only one set
+ );
til.push_back(input3);
}
}
@@ -387,12 +448,10 @@ void GeometryExporter::createPolylist(short material_index,
}
}
- // sets <vcount>
- polylist.setVCountList(vcount_list);
// performs the actual writing
- polylist.prepareToAppendValues();
-
+ prepareToAppendValues(is_triangulated, facelist, vcount_list);
+
// <p>
int texindex = 0;
for (i = 0; i < totpolys; i++) {
@@ -404,22 +463,202 @@ void GeometryExporter::createPolylist(short material_index,
BCPolygonNormalsIndices normal_indices = norind[i];
for (int j = 0; j < loop_count; j++) {
- polylist.appendValues(l[j].v);
- polylist.appendValues(normal_indices[j]);
+ facelist->appendValues(l[j].v);
+ facelist->appendValues(normal_indices[j]);
if (has_uvs)
- polylist.appendValues(texindex + j);
+ facelist->appendValues(texindex + j);
if (has_color)
- polylist.appendValues(texindex + j);
+ facelist->appendValues(texindex + j);
}
}
texindex += loop_count;
}
-
- polylist.finish();
+
+ finishList(is_triangulated, facelist);
+ delete facelist;
+}
+
+void GeometryExporter::createPolylists(std::set<Image *> uv_images,
+ bool has_uvs,
+ bool has_color,
+ Object *ob,
+ Mesh *me,
+ std::string& geom_id,
+ std::vector<BCPolygonNormalsIndices>& norind)
+{
+ std::set<Image *>::iterator uv_images_iter;
+ for (uv_images_iter = uv_images.begin();
+ uv_images_iter != uv_images.end();
+ uv_images_iter++) {
+
+ Image *ima = *uv_images_iter;
+ std::string imageid(id_name(ima));
+ createPolylist(imageid, has_uvs,
+ has_color,
+ ob,
+ me,
+ geom_id,
+ norind);
+ }
+
+ /* We msut add an additional collector for the case when
+ * some parts of the object are not textured at all.
+ * The next call creates a polylist for all untextured polygons
+ */
+
+ createPolylist("", has_uvs,
+ has_color,
+ ob,
+ me,
+ geom_id,
+ norind);
+
}
+/* ===========================================================================
+ * Export Meshes with UV Textures (export as materials, see also in
+ * effectExporter and MaterialExporter)
+ *
+ * If imageid is the empty string, then collect only untextured polygons
+ * =========================================================================== */
+void GeometryExporter::createPolylist(std::string imageid,
+ bool has_uvs,
+ bool has_color,
+ Object *ob,
+ Mesh *me,
+ std::string& geom_id,
+ std::vector<BCPolygonNormalsIndices>& norind)
+{
+
+ MPoly *mpolys = me->mpoly;
+ MLoop *mloops = me->mloop;
+ MTexPoly *mtpolys = me->mtpoly;
+
+ int totpolys = me->totpoly;
+
+ // <vcount>
+ int i;
+ int faces_in_polylist = 0;
+ std::vector<unsigned long> vcount_list;
+ bool is_triangulated = true;
+ // count faces with this material
+ for (i = 0; i < totpolys; i++) {
+ MTexPoly *tp = &mtpolys[i];
+ MPoly *p = &mpolys[i];
+
+ std::string tpageid = (tp->tpage) ? id_name(tp->tpage):"";
+ if (tpageid == imageid) {
+ faces_in_polylist++;
+ vcount_list.push_back(p->totloop);
+ if (p->totloop != 3) {
+ is_triangulated = false;
+ }
+ }
+ }
+
+ // no faces using this imageid
+ if (faces_in_polylist == 0) {
+ if (imageid != "")
+ fprintf(stderr, "%s: Image %s is not used.\n", id_name(ob).c_str(), imageid.c_str());
+ return;
+ }
+
+ COLLADASW::PrimitivesBase *facelist = getFacelist(is_triangulated, mSW);
+
+ // sets count attribute in <polylist>
+ facelist->setCount(faces_in_polylist);
+
+ if (imageid != "") {
+ // sets material name
+ std::string material_id = get_material_id_from_id(imageid);
+ std::ostringstream ostr;
+ ostr << translate_id(material_id);
+ facelist->setMaterial(ostr.str());
+ }
+ COLLADASW::InputList &til = facelist->getInputList();
+
+ // creates <input> in <polylist> for vertices
+ COLLADASW::Input input1(COLLADASW::InputSemantic::VERTEX, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::VERTEX), 0);
+
+ // creates <input> in <polylist> for normals
+ COLLADASW::Input input2(COLLADASW::InputSemantic::NORMAL, getUrlBySemantics(geom_id, COLLADASW::InputSemantic::NORMAL), 1);
+
+ til.push_back(input1);
+ til.push_back(input2);
+
+ // if mesh has uv coords writes <input> for TEXCOORD
+ int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
+ int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) - 1;
+ for (i = 0; i < num_layers; i++) {
+ if (!this->export_settings->active_uv_only || i == active_uv_index) {
+
+ std::string uv_name(bc_get_uvlayer_name(me, i));
+ std::string effective_id = geom_id; // (uv_name == "") ? geom_id : uv_name;
+ std::string layer_id = makeTexcoordSourceId(
+ effective_id,
+ i, this->export_settings->active_uv_only);
+
+ /* Note: the third parameter denotes the offset of TEXCOORD in polylist elements
+ For now this is always 2 (This may change sometime/maybe)
+ */
+ COLLADASW::Input input3(COLLADASW::InputSemantic::TEXCOORD,
+ makeUrl(layer_id),
+ 2, // this is only until we have optimized UV sets
+ (this->export_settings->active_uv_only) ? 0 : i // only_active_uv exported -> we have only one set
+ );
+ til.push_back(input3);
+ }
+ }
+
+ int totlayer_mcol = CustomData_number_of_layers(&me->ldata, CD_MLOOPCOL);
+ if (totlayer_mcol > 0) {
+ int map_index = 0;
+
+ for (int a = 0; a < totlayer_mcol; a++) {
+ char *layer_name = bc_CustomData_get_layer_name(&me->ldata, CD_MLOOPCOL, a);
+ COLLADASW::Input input4(COLLADASW::InputSemantic::COLOR,
+ makeUrl(makeVertexColorSourceId(geom_id, layer_name)),
+ (has_uvs) ? 3 : 2, // all color layers have same index order
+ map_index // set number equals color map index
+ );
+ til.push_back(input4);
+ map_index++;
+ }
+ }
+
+ // performs the actual writing
+ prepareToAppendValues(is_triangulated, facelist, vcount_list);
+
+ // <p>
+ int texindex = 0;
+ for (i = 0; i < totpolys; i++) {
+ MTexPoly *tp = &mtpolys[i];
+ MPoly *p = &mpolys[i];
+ int loop_count = p->totloop;
+ std::string tpageid = (tp->tpage) ? id_name(tp->tpage) : "";
+ if (tpageid == imageid) {
+ MLoop *l = &mloops[p->loopstart];
+ BCPolygonNormalsIndices normal_indices = norind[i];
+
+ for (int j = 0; j < loop_count; j++) {
+ facelist->appendValues(l[j].v);
+ facelist->appendValues(normal_indices[j]);
+ if (has_uvs)
+ facelist->appendValues(texindex + j);
+
+ if (has_color)
+ facelist->appendValues(texindex + j);
+ }
+ }
+
+ texindex += loop_count;
+ }
+
+ finishList(is_triangulated, facelist);
+ delete facelist;
+}
// creates <source> for positions
void GeometryExporter::createVertsSource(std::string geom_id, Mesh *me)
@@ -537,7 +776,13 @@ void GeometryExporter::createTexcoordsSource(std::string geom_id, Mesh *me)
MLoopUV *mloops = (MLoopUV *)CustomData_get_layer_n(&me->ldata, CD_MLOOPUV, a);
COLLADASW::FloatSourceF source(mSW);
- std::string layer_id = makeTexcoordSourceId(geom_id, a, this->export_settings->active_uv_only);
+ std::string active_uv_name(bc_get_active_uvlayer_name(me));
+ std::string effective_id = geom_id; // (active_uv_name == "") ? geom_id : active_uv_name;
+ std::string layer_id = makeTexcoordSourceId(
+ effective_id,
+ a,
+ this->export_settings->active_uv_only );
+
source.setId(layer_id);
source.setArrayId(layer_id + ARRAY_ID_SUFFIX);
diff --git a/source/blender/collada/GeometryExporter.h b/source/blender/collada/GeometryExporter.h
index 69d1067e6f4..890304f4568 100644
--- a/source/blender/collada/GeometryExporter.h
+++ b/source/blender/collada/GeometryExporter.h
@@ -85,15 +85,33 @@ public:
Mesh *me,
std::string& geom_id);
- // powerful because it handles both cases when there is material and when there's not
+ // Create polylists for meshes with Materials
void createPolylist(short material_index,
- bool has_uvs,
- bool has_color,
- Object *ob,
- Mesh *me,
- std::string& geom_id,
- std::vector<BCPolygonNormalsIndices>& norind);
-
+ bool has_uvs,
+ bool has_color,
+ Object *ob,
+ Mesh *me,
+ std::string& geom_id,
+ std::vector<BCPolygonNormalsIndices>& norind);
+
+ // Create polylists for meshes with UV Textures
+ void createPolylists(std::set<Image *> uv_images,
+ bool has_uvs,
+ bool has_color,
+ Object *ob,
+ Mesh *me,
+ std::string& geom_id,
+ std::vector<BCPolygonNormalsIndices>& norind);
+
+ // Create polylists for meshes with UV Textures
+ void createPolylist(std::string imageid,
+ bool has_uvs,
+ bool has_color,
+ Object *ob,
+ Mesh *me,
+ std::string& geom_id,
+ std::vector<BCPolygonNormalsIndices>& norind);
+
// creates <source> for positions
void createVertsSource(std::string geom_id, Mesh *me);
diff --git a/source/blender/collada/ImageExporter.cpp b/source/blender/collada/ImageExporter.cpp
index aac41e2e93c..93be7de6236 100644
--- a/source/blender/collada/ImageExporter.cpp
+++ b/source/blender/collada/ImageExporter.cpp
@@ -55,9 +55,9 @@ ImagesExporter::ImagesExporter(COLLADASW::StreamWriter *sw, const ExportSettings
void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
{
- std::string name(id_name(image));
- std::string translated_name(translate_id(name));
- bool not_yet_exported = find(mImages.begin(), mImages.end(), translated_name) == mImages.end();
+ std::string id(id_name(image));
+ std::string translated_id(translate_id(id));
+ bool not_yet_exported = find(mImages.begin(), mImages.end(), translated_id) == mImages.end();
if (not_yet_exported) {
@@ -88,7 +88,7 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
// make absolute destination path
- BLI_strncpy(export_file, name.c_str(), sizeof(export_file));
+ BLI_strncpy(export_file, id.c_str(), sizeof(export_file));
BKE_image_path_ensure_ext_from_imformat(export_file, &imageFormat);
BLI_join_dirfile(export_path, sizeof(export_path), export_dir, export_file);
@@ -143,10 +143,11 @@ void ImagesExporter::export_UV_Image(Image *image, bool use_copies)
}
}
- COLLADASW::Image img(COLLADABU::URI(COLLADABU::URI::nativePathToUri(export_path)), translated_name, translated_name); /* set name also to mNameNC. This helps other viewers import files exported from Blender better */
+ /* set name also to mNameNC. This helps other viewers import files exported from Blender better */
+ COLLADASW::Image img(COLLADABU::URI(COLLADABU::URI::nativePathToUri(export_path)), translated_id, translated_id);
img.add(mSW);
fprintf(stdout, "Collada export: Added image: %s\n", export_file);
- mImages.push_back(translated_name);
+ mImages.push_back(translated_id);
BKE_image_release_ibuf(image, imbuf, NULL);
}
@@ -161,7 +162,7 @@ void ImagesExporter::export_UV_Images()
for (node = this->export_settings->export_set; node; node = node->next) {
Object *ob = (Object *)node->link;
- if (ob->type == OB_MESH && ob->totcol) {
+ if (ob->type == OB_MESH) {
Mesh *me = (Mesh *) ob->data;
BKE_mesh_tessface_ensure(me);
int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
@@ -189,7 +190,13 @@ void ImagesExporter::export_UV_Images()
}
}
-
+/* ============================================================
+ * Check if there are any images to be exported
+ * Returns true as soon as an object is detected that
+ * either has an UV Texture assigned, or has a material
+ * assigned that uses an Image Texture.
+ * ============================================================
+ */
bool ImagesExporter::hasImages(Scene *sce)
{
LinkNode *node;
@@ -232,11 +239,10 @@ void ImagesExporter::exportImages(Scene *sce)
openLibrary();
MaterialFunctor mf;
- if (this->export_settings->include_material_textures) {
+ if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT) {
mf.forEachMaterialInExportSet<ImagesExporter>(sce, *this, this->export_settings->export_set);
}
-
- if (this->export_settings->include_uv_textures) {
+ else {
export_UV_Images();
}
diff --git a/source/blender/collada/InstanceWriter.cpp b/source/blender/collada/InstanceWriter.cpp
index 71371d280df..de1a4075462 100644
--- a/source/blender/collada/InstanceWriter.cpp
+++ b/source/blender/collada/InstanceWriter.cpp
@@ -32,43 +32,76 @@
#include "COLLADASWInstanceMaterial.h"
extern "C" {
- #include "BKE_customdata.h"
- #include "BKE_material.h"
- #include "DNA_mesh_types.h"
+#include "BKE_customdata.h"
+#include "BKE_material.h"
+#include "DNA_mesh_types.h"
}
#include "InstanceWriter.h"
#include "collada_internal.h"
#include "collada_utils.h"
-void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only)
+void InstanceWriter::add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only, BC_export_texture_type export_texture_type)
{
- for (int a = 0; a < ob->totcol; a++) {
- Material *ma = give_current_material(ob, a + 1);
-
- COLLADASW::InstanceMaterialList& iml = bind_material.getInstanceMaterialList();
+ bool all_uv_layers = !active_uv_only;
+ COLLADASW::InstanceMaterialList& iml = bind_material.getInstanceMaterialList();
- if (ma) {
- std::string matid(get_material_id(ma));
- matid = translate_id(matid);
+ if (export_texture_type == BC_TEXTURE_TYPE_UV)
+ {
+ std::set<Image *> uv_images = bc_getUVImages(ob, all_uv_layers);
+ std::set<Image *>::iterator uv_images_iter;
+ for (uv_images_iter = uv_images.begin();
+ uv_images_iter != uv_images.end();
+ uv_images_iter++) {
+ Image *ima = *uv_images_iter;
+ std::string matid(id_name(ima));
+ matid = get_material_id_from_id(matid);
std::ostringstream ostr;
ostr << matid;
COLLADASW::InstanceMaterial im(ostr.str(), COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid));
-
+
// create <bind_vertex_input> for each uv map
Mesh *me = (Mesh *)ob->data;
int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
-
+
int map_index = 0;
- int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) -1;
+ int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) - 1;
for (int b = 0; b < totlayer; b++) {
if (!active_uv_only || b == active_uv_index) {
char *name = bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, b);
im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++));
}
}
-
+
iml.push_back(im);
}
}
+
+ else {
+ for (int a = 0; a < ob->totcol; a++) {
+ Material *ma = give_current_material(ob, a + 1);
+ if (ma) {
+ std::string matid(get_material_id(ma));
+ matid = translate_id(matid);
+ std::ostringstream ostr;
+ ostr << matid;
+ COLLADASW::InstanceMaterial im(ostr.str(), COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, matid));
+
+ // create <bind_vertex_input> for each uv map
+ Mesh *me = (Mesh *)ob->data;
+ int totlayer = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
+
+ int map_index = 0;
+ int active_uv_index = CustomData_get_active_layer_index(&me->fdata, CD_MTFACE) - 1;
+ for (int b = 0; b < totlayer; b++) {
+ if (!active_uv_only || b == active_uv_index) {
+ char *name = bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, b);
+ im.push_back(COLLADASW::BindVertexInput(name, "TEXCOORD", map_index++));
+ }
+ }
+
+ iml.push_back(im);
+ }
+ }
+ }
}
diff --git a/source/blender/collada/InstanceWriter.h b/source/blender/collada/InstanceWriter.h
index 49ddf091b1c..a46027325a2 100644
--- a/source/blender/collada/InstanceWriter.h
+++ b/source/blender/collada/InstanceWriter.h
@@ -31,11 +31,12 @@
#include "COLLADASWBindMaterial.h"
#include "DNA_object_types.h"
+#include "collada.h"
class InstanceWriter
{
protected:
- void add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only);
+ void add_material_bindings(COLLADASW::BindMaterial& bind_material, Object *ob, bool active_uv_only, BC_export_texture_type export_texture_type);
};
#endif
diff --git a/source/blender/collada/MaterialExporter.cpp b/source/blender/collada/MaterialExporter.cpp
index 4aece997f72..6e6cc24be20 100644
--- a/source/blender/collada/MaterialExporter.cpp
+++ b/source/blender/collada/MaterialExporter.cpp
@@ -38,14 +38,39 @@ MaterialsExporter::MaterialsExporter(COLLADASW::StreamWriter *sw, const ExportSe
void MaterialsExporter::exportMaterials(Scene *sce)
{
- if (hasMaterials(sce)) {
- openLibrary();
+ if (this->export_settings->export_texture_type == BC_TEXTURE_TYPE_MAT)
+ {
+ if (hasMaterials(sce)) {
+ openLibrary();
- MaterialFunctor mf;
- mf.forEachMaterialInExportSet<MaterialsExporter>(sce, *this, this->export_settings->export_set);
+ MaterialFunctor mf;
+ mf.forEachMaterialInExportSet<MaterialsExporter>(sce, *this, this->export_settings->export_set);
- closeLibrary();
+ closeLibrary();
+ }
}
+
+ else {
+ std::set<Image *> uv_images = bc_getUVImages(sce, !this->export_settings->active_uv_only);
+ if (uv_images.size() > 0) {
+ openLibrary();
+ std::set<Image *>::iterator uv_images_iter;
+ for (uv_images_iter = uv_images.begin();
+ uv_images_iter != uv_images.end();
+ uv_images_iter++) {
+
+ Image *ima = *uv_images_iter;
+ std::string matid(id_name(ima));
+
+ openMaterial(get_material_id_from_id(matid), translate_id(matid));
+ std::string efid = translate_id(matid) + "-effect";
+ addInstanceEffect(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, efid));
+ closeMaterial();
+ }
+ closeLibrary();
+ }
+ }
+
}
bool MaterialsExporter::hasMaterials(Scene *sce)
diff --git a/source/blender/collada/MeshImporter.cpp b/source/blender/collada/MeshImporter.cpp
index 8f3bf88af65..6ca53c64299 100644
--- a/source/blender/collada/MeshImporter.cpp
+++ b/source/blender/collada/MeshImporter.cpp
@@ -27,7 +27,7 @@
#include <algorithm>
-#if !defined(WIN32) || defined(FREE_WINDOWS)
+#if !defined(WIN32)
#include <iostream>
#endif
@@ -1173,8 +1173,9 @@ Object *MeshImporter::create_mesh_object(COLLADAFW::Node *node, COLLADAFW::Insta
BKE_mesh_assign_object(ob, new_mesh);
BKE_mesh_calc_normals(new_mesh);
- if (old_mesh->id.us == 0) BKE_libblock_free(G.main, old_mesh);
-
+ id_us_plus(&old_mesh->id); /* Because BKE_mesh_assign_object would have already decreased it... */
+ BKE_libblock_free_us(G.main, old_mesh);
+
char layername[100];
layername[0] = '\0';
MTFace *texture_face = NULL;
diff --git a/source/blender/collada/SceneExporter.cpp b/source/blender/collada/SceneExporter.cpp
index 30cd6ddf197..73945539931 100644
--- a/source/blender/collada/SceneExporter.cpp
+++ b/source/blender/collada/SceneExporter.cpp
@@ -151,7 +151,10 @@ void SceneExporter::writeNodes(Object *ob, Scene *sce)
COLLADASW::InstanceGeometry instGeom(mSW);
instGeom.setUrl(COLLADASW::URI(COLLADABU::Utils::EMPTY_STRING, get_geometry_id(ob, this->export_settings->use_object_instantiation)));
instGeom.setName(translate_id(id_name(ob)));
- InstanceWriter::add_material_bindings(instGeom.getBindMaterial(), ob, this->export_settings->active_uv_only);
+ InstanceWriter::add_material_bindings(instGeom.getBindMaterial(),
+ ob,
+ this->export_settings->active_uv_only,
+ this->export_settings->export_texture_type);
instGeom.add();
}
diff --git a/source/blender/collada/SkinInfo.cpp b/source/blender/collada/SkinInfo.cpp
index 71875d6274a..c48c060dc95 100644
--- a/source/blender/collada/SkinInfo.cpp
+++ b/source/blender/collada/SkinInfo.cpp
@@ -27,7 +27,7 @@
#include <algorithm>
-#if !defined(WIN32) || defined(FREE_WINDOWS)
+#if !defined(WIN32)
#include <stdint.h>
#endif
diff --git a/source/blender/collada/collada.cpp b/source/blender/collada/collada.cpp
index bfe3180909b..024bc4a4a5c 100644
--- a/source/blender/collada/collada.cpp
+++ b/source/blender/collada/collada.cpp
@@ -80,8 +80,7 @@ int collada_export(Scene *sce,
int deform_bones_only,
int active_uv_only,
- int include_uv_textures,
- int include_material_textures,
+ BC_export_texture_type export_texture_type,
int use_texture_copies,
int triangulate,
@@ -106,8 +105,7 @@ int collada_export(Scene *sce,
export_settings.deform_bones_only = deform_bones_only != 0;
export_settings.active_uv_only = active_uv_only != 0;
- export_settings.include_uv_textures = include_uv_textures != 0;
- export_settings.include_material_textures= include_material_textures != 0;
+ export_settings.export_texture_type = export_texture_type;
export_settings.use_texture_copies = use_texture_copies != 0;
export_settings.triangulate = triangulate != 0;
diff --git a/source/blender/collada/collada.h b/source/blender/collada/collada.h
index 8035af59c8b..d31f5a8ba62 100644
--- a/source/blender/collada/collada.h
+++ b/source/blender/collada/collada.h
@@ -46,6 +46,11 @@ typedef enum BC_export_transformation_type {
BC_TRANSFORMATION_TYPE_TRANSROTLOC
} BC_export_transformation_type;
+typedef enum BC_export_texture_type {
+ BC_TEXTURE_TYPE_MAT,
+ BC_TEXTURE_TYPE_UV
+} BC_export_texture_type;
+
struct bContext;
struct Scene;
@@ -74,8 +79,7 @@ int collada_export(struct Scene *sce,
int deform_bones_only,
int active_uv_only,
- int include_uv_textures,
- int include_material_textures,
+ BC_export_texture_type export_texture_type,
int use_texture_copies,
int triangulate,
@@ -84,9 +88,9 @@ int collada_export(struct Scene *sce,
int sort_by_name,
BC_export_transformation_type export_transformation_type,
- int open_sim,
- int limit_precision,
- int keep_bind_info);
+ int open_sim,
+ int limit_precision,
+ int keep_bind_info);
#ifdef __cplusplus
}
diff --git a/source/blender/collada/collada_internal.cpp b/source/blender/collada/collada_internal.cpp
index 6ebde6bd773..8974acb3460 100644
--- a/source/blender/collada/collada_internal.cpp
+++ b/source/blender/collada/collada_internal.cpp
@@ -344,7 +344,13 @@ std::string get_camera_id(Object *ob)
std::string get_material_id(Material *mat)
{
- return translate_id(id_name(mat)) + "-material";
+ std::string id = id_name(mat);
+ return get_material_id_from_id(id);
+}
+
+std::string get_material_id_from_id(std::string id)
+{
+ return translate_id(id) + "-material";
}
std::string get_morph_id(Object *ob)
diff --git a/source/blender/collada/collada_internal.h b/source/blender/collada/collada_internal.h
index 1c7aa160f57..5f3fa34edc1 100644
--- a/source/blender/collada/collada_internal.h
+++ b/source/blender/collada/collada_internal.h
@@ -103,6 +103,7 @@ extern std::string get_joint_sid(Bone *bone, Object *ob_arm);
extern std::string get_camera_id(Object *ob);
extern std::string get_material_id(Material *mat);
+extern std::string get_material_id_from_id(std::string id);
extern std::string get_morph_id(Object *ob);
diff --git a/source/blender/collada/collada_utils.cpp b/source/blender/collada/collada_utils.cpp
index ac4395e1430..b09732f9102 100644
--- a/source/blender/collada/collada_utils.cpp
+++ b/source/blender/collada/collada_utils.cpp
@@ -32,6 +32,8 @@
#include "COLLADAFWMeshPrimitive.h"
#include "COLLADAFWMeshVertexData.h"
+#include <set>
+
extern "C" {
#include "DNA_modifier_types.h"
#include "DNA_customdata_types.h"
@@ -831,4 +833,160 @@ void bc_sanitize_mat(float mat[4][4], int precision)
for (int i = 0; i < 4; i++)
for (int j = 0; j < 4; j++)
mat[i][j] = double_round(mat[i][j], precision);
+}
+
+/*
+* Returns name of Active UV Layer or empty String if no active UV Layer defined.
+* Assuming the Object is of type MESH
+*/
+std::string bc_get_active_uvlayer_name(Object *ob)
+{
+ Mesh *me = (Mesh *)ob->data;
+ return bc_get_active_uvlayer_name(me);
+}
+
+/*
+ * Returns name of Active UV Layer or empty String if no active UV Layer defined
+ */
+std::string bc_get_active_uvlayer_name(Mesh *me)
+{
+ int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
+ if (num_layers) {
+ return std::string(bc_CustomData_get_active_layer_name(&me->fdata, CD_MTFACE));
+ }
+ return "";
+}
+
+/*
+ * Returns UV Layer name or empty string if layer index is out of range
+ */
+std::string bc_get_uvlayer_name(Mesh *me, int layer)
+{
+ int num_layers = CustomData_number_of_layers(&me->fdata, CD_MTFACE);
+ if (num_layers && layer < num_layers) {
+ return std::string(bc_CustomData_get_layer_name(&me->fdata, CD_MTFACE, layer));
+ }
+ return "";
+}
+
+/**********************************************************************
+*
+* Return the list of Mesh objects with assigned UVtextures and Images
+* Note: We need to create artificaial materials for each of them
+*
+***********************************************************************/
+std::set<Object *> bc_getUVTexturedObjects(Scene *sce, bool all_uv_layers)
+{
+ std::set <Object *> UVObjects;
+ Base *base = (Base *)sce->base.first;
+
+ while (base) {
+ Object *ob = base->object;
+ bool has_uvimage = false;
+ if (ob->type == OB_MESH) {
+ Mesh *me = (Mesh *)ob->data;
+ int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
+
+ for (int i = 0; i < me->pdata.totlayer && !has_uvimage; i++) {
+ if (all_uv_layers || active_uv_layer == i)
+ {
+ if (me->pdata.layers[i].type == CD_MTEXPOLY) {
+ MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
+ MPoly *mpoly = me->mpoly;
+ for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) {
+
+ Image *ima = txface->tpage;
+ if (ima != NULL) {
+ has_uvimage = true;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (has_uvimage) {
+ UVObjects.insert(ob);
+ }
+ }
+ base = base->next;
+ }
+ return UVObjects;
+}
+
+/**********************************************************************
+*
+* Return the list of UV Texture images from all exported Mesh Items
+* Note: We need to create one artificial material for each Image.
+*
+***********************************************************************/
+std::set<Image *> bc_getUVImages(Scene *sce, bool all_uv_layers)
+{
+ std::set <Image *> UVImages;
+ Base *base = (Base *)sce->base.first;
+
+ while (base) {
+ Object *ob = base->object;
+ bool has_uvimage = false;
+ if (ob->type == OB_MESH) {
+ Mesh *me = (Mesh *)ob->data;
+ int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
+
+ for (int i = 0; i < me->pdata.totlayer && !has_uvimage; i++) {
+ if (all_uv_layers || active_uv_layer == i)
+ {
+ if (me->pdata.layers[i].type == CD_MTEXPOLY) {
+ MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
+ MPoly *mpoly = me->mpoly;
+ for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) {
+
+ Image *ima = txface->tpage;
+ if (ima != NULL) {
+ if (UVImages.find(ima) == UVImages.end())
+ UVImages.insert(ima);
+ }
+ }
+ }
+ }
+ }
+ }
+ base = base->next;
+ }
+ return UVImages;
+}
+
+/**********************************************************************
+*
+* Return the list of UV Texture images for the given Object
+* Note: We need to create one artificial material for each Image.
+*
+***********************************************************************/
+std::set<Image *> bc_getUVImages(Object *ob, bool all_uv_layers)
+{
+ std::set <Image *> UVImages;
+
+ bool has_uvimage = false;
+ if (ob->type == OB_MESH) {
+ Mesh *me = (Mesh *)ob->data;
+ int active_uv_layer = CustomData_get_active_layer_index(&me->pdata, CD_MTEXPOLY);
+
+ for (int i = 0; i < me->pdata.totlayer && !has_uvimage; i++) {
+ if (all_uv_layers || active_uv_layer == i)
+ {
+ if (me->pdata.layers[i].type == CD_MTEXPOLY) {
+ MTexPoly *txface = (MTexPoly *)me->pdata.layers[i].data;
+ MPoly *mpoly = me->mpoly;
+ for (int j = 0; j < me->totpoly; j++, mpoly++, txface++) {
+
+ Image *ima = txface->tpage;
+ if (ima != NULL) {
+ if (UVImages.find(ima) == UVImages.end())
+ UVImages.insert(ima);
+ }
+ }
+ }
+ }
+ }
+ }
+ return UVImages;
} \ No newline at end of file
diff --git a/source/blender/collada/collada_utils.h b/source/blender/collada/collada_utils.h
index 38c0bd5096a..5447c39e902 100644
--- a/source/blender/collada/collada_utils.h
+++ b/source/blender/collada/collada_utils.h
@@ -34,6 +34,7 @@
#include <vector>
#include <map>
+#include <set>
#include <algorithm>
extern "C" {
@@ -80,6 +81,7 @@ extern void bc_set_mark(Object *ob);
extern char *bc_CustomData_get_layer_name(const CustomData *data, int type, int n);
extern char *bc_CustomData_get_active_layer_name(const CustomData *data, int type);
+extern char *bc_CustomData_get_layer_name(const CustomData *data, int layer_index, int type);
extern void bc_bubble_sort_by_Object_name(LinkNode *export_set);
extern bool bc_is_root_bone(Bone *aBone, bool deform_bones_only);
@@ -109,6 +111,14 @@ extern bool bc_get_property_matrix(Bone *bone, std::string key, float mat[4][4])
extern void bc_create_restpose_mat(const ExportSettings *export_settings, Bone *bone, float to_mat[4][4], float world[4][4], bool use_local_space);
+extern std::string bc_get_active_uvlayer_name(Object *ob);
+extern std::string bc_get_active_uvlayer_name(Mesh *me);
+extern std::string bc_get_uvlayer_name(Mesh *me, int layer);
+
+extern std::set<Image *> bc_getUVImages(Scene *sce, bool all_uv_layers);
+extern std::set<Image *> bc_getUVImages(Object *ob, bool all_uv_layers);
+extern std::set<Object *> bc_getUVTexturedObjects(Scene *sce, bool all_uv_layers);
+
class BCPolygonNormalsIndices
{
std::vector<unsigned int> normal_indices;
diff --git a/source/blender/compositor/CMakeLists.txt b/source/blender/compositor/CMakeLists.txt
index 3180e7e4154..3e1dd83112a 100644
--- a/source/blender/compositor/CMakeLists.txt
+++ b/source/blender/compositor/CMakeLists.txt
@@ -551,8 +551,4 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-if(WITH_CYCLES AND WITH_CYCLES_DEBUG)
- add_definitions(-DWITH_CYCLES_DEBUG)
-endif()
-
blender_add_lib(bf_compositor "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/compositor/COM_compositor.h b/source/blender/compositor/COM_compositor.h
index a5d7704a708..3b24f9c69a2 100644
--- a/source/blender/compositor/COM_compositor.h
+++ b/source/blender/compositor/COM_compositor.h
@@ -331,19 +331,6 @@ void COM_deinitialize(void);
*/
// void COM_clearCaches(void); // NOT YET WRITTEN
-/**
- * @brief Return a list of highlighted bnodes pointers.
- * @return
- */
-void COM_startReadHighlights(void);
-
-/**
- * @brief check if a bnode is highlighted
- * @param bnode
- * @return
- */
-int COM_isHighlightedbNode(bNode *bnode);
-
#ifdef __cplusplus
}
#endif
diff --git a/source/blender/compositor/intern/COM_WorkScheduler.cpp b/source/blender/compositor/intern/COM_WorkScheduler.cpp
index 39147f3ab84..68f934008a4 100644
--- a/source/blender/compositor/intern/COM_WorkScheduler.cpp
+++ b/source/blender/compositor/intern/COM_WorkScheduler.cpp
@@ -75,82 +75,6 @@ static bool g_openclInitialized = false;
#endif
#endif
-#define MAX_HIGHLIGHT 8
-static bool g_highlightInitialized = false;
-extern "C" {
-static int g_highlightIndex;
-static void **g_highlightedNodes;
-static void **g_highlightedNodesRead;
-
-/* XXX highlighting disabled for now
- * This requires pointers back to DNA data (bNodeTree/bNode) in operations, which is bad!
- * Instead IF we want to keep this feature it should use a weak reference such as bNodeInstanceKey
- */
-#if 0
-#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
-#define HIGHLIGHT(wp) \
-{ \
- ExecutionGroup *group = wp->getExecutionGroup(); \
- if (group->isComplex()) { \
- NodeOperation *operation = group->getOutputOperation(); \
- if (operation->isWriteBufferOperation()) { \
- WriteBufferOperation *writeOperation = (WriteBufferOperation *)operation; \
- NodeOperation *complexOperation = writeOperation->getInput(); \
- bNode *node = complexOperation->getbNode(); \
- if (node) { \
- if (node->original) { \
- node = node->original; \
- } \
- if (g_highlightInitialized && g_highlightedNodes) { \
- if (g_highlightIndex < MAX_HIGHLIGHT) { \
- g_highlightedNodes[g_highlightIndex++] = node; \
- } \
- } \
- } \
- } \
- } \
-}
-#endif /* COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE */
-#else
-# if COM_CURRENT_THREADING_MODEL != COM_TM_NOTHREAD
-#define HIGHLIGHT(wp) {}
-# endif
-#endif
-
-void COM_startReadHighlights()
-{
- if (!g_highlightInitialized) {
- return;
- }
-
- if (g_highlightedNodesRead) {
- MEM_freeN(g_highlightedNodesRead);
- }
-
- g_highlightedNodesRead = g_highlightedNodes;
- g_highlightedNodes = (void **)MEM_callocN(sizeof(void *) * MAX_HIGHLIGHT, __func__);
- g_highlightIndex = 0;
-}
-
-int COM_isHighlightedbNode(bNode *bnode)
-{
- if (!g_highlightInitialized) {
- return false;
- }
-
- if (!g_highlightedNodesRead) {
- return false;
- }
-
- for (int i = 0; i < MAX_HIGHLIGHT; i++) {
- void *p = g_highlightedNodesRead[i];
- if (!p) return false;
- if (p == bnode) return true;
- }
- return false;
-}
-} // end extern "C"
-
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
void *WorkScheduler::thread_execute_cpu(void *data)
{
@@ -158,7 +82,6 @@ void *WorkScheduler::thread_execute_cpu(void *data)
WorkPackage *work;
BLI_thread_local_set(g_thread_device, device);
while ((work = (WorkPackage *)BLI_thread_queue_pop(g_cpuqueue))) {
- HIGHLIGHT(work);
device->execute(work);
delete work;
}
@@ -172,7 +95,6 @@ void *WorkScheduler::thread_execute_gpu(void *data)
WorkPackage *work;
while ((work = (WorkPackage *)BLI_thread_queue_pop(g_gpuqueue))) {
- HIGHLIGHT(work);
device->execute(work);
delete work;
}
@@ -289,19 +211,6 @@ static void CL_CALLBACK clContextError(const char *errinfo,
void WorkScheduler::initialize(bool use_opencl, int num_cpu_threads)
{
- /* initialize highlighting */
- if (!g_highlightInitialized) {
- if (g_highlightedNodesRead) MEM_freeN(g_highlightedNodesRead);
- if (g_highlightedNodes) MEM_freeN(g_highlightedNodes);
-
- g_highlightedNodesRead = NULL;
- g_highlightedNodes = NULL;
-
- COM_startReadHighlights();
-
- g_highlightInitialized = true;
- }
-
#if COM_CURRENT_THREADING_MODEL == COM_TM_QUEUE
/* deinitialize if number of threads doesn't match */
if (g_cpudevices.size() != num_cpu_threads) {
@@ -439,20 +348,6 @@ void WorkScheduler::deinitialize()
}
#endif
#endif
-
- /* deinitialize highlighting */
- if (g_highlightInitialized) {
- g_highlightInitialized = false;
- if (g_highlightedNodes) {
- MEM_freeN(g_highlightedNodes);
- g_highlightedNodes = NULL;
- }
-
- if (g_highlightedNodesRead) {
- MEM_freeN(g_highlightedNodesRead);
- g_highlightedNodesRead = NULL;
- }
- }
}
int WorkScheduler::current_thread_id()
diff --git a/source/blender/compositor/nodes/COM_BrightnessNode.cpp b/source/blender/compositor/nodes/COM_BrightnessNode.cpp
index 053f286c66e..6729571fac0 100644
--- a/source/blender/compositor/nodes/COM_BrightnessNode.cpp
+++ b/source/blender/compositor/nodes/COM_BrightnessNode.cpp
@@ -31,7 +31,9 @@ BrightnessNode::BrightnessNode(bNode *editorNode) : Node(editorNode)
void BrightnessNode::convertToOperations(NodeConverter &converter, const CompositorContext &/*context*/) const
{
+ bNode *bnode = this->getbNode();
BrightnessOperation *operation = new BrightnessOperation();
+ operation->setUsePremultiply((bnode->custom1 & 1) != 0);
converter.addOperation(operation);
converter.mapInputSocket(getInputSocket(0), operation->getInputSocket(0));
diff --git a/source/blender/compositor/nodes/COM_ImageNode.cpp b/source/blender/compositor/nodes/COM_ImageNode.cpp
index facd422c217..81891d853d2 100644
--- a/source/blender/compositor/nodes/COM_ImageNode.cpp
+++ b/source/blender/compositor/nodes/COM_ImageNode.cpp
@@ -95,17 +95,14 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo
NodeOperation *operation = NULL;
socket = this->getOutputSocket(index);
bNodeSocket *bnodeSocket = socket->getbNodeSocket();
- RenderPass *rpass = (RenderPass *)BLI_findstring(&rl->passes, bnodeSocket->identifier, offsetof(RenderPass, internal_name));
+ NodeImageLayer *storage = (NodeImageLayer *)bnodeSocket->storage;
+ RenderPass *rpass = (RenderPass *)BLI_findstring(&rl->passes, storage->pass_name, offsetof(RenderPass, name));
int view = 0;
- /* Passes in the file can differ from passes stored in sockets (#36755).
- * Look up the correct file pass using the socket identifier instead.
- */
-#if 0
- NodeImageLayer *storage = (NodeImageLayer *)bnodeSocket->storage;*/
- int passindex = storage->pass_index;*/
- RenderPass *rpass = (RenderPass *)BLI_findlink(&rl->passes, passindex);
-#endif
+ if (STREQ(storage->pass_name, RE_PASSNAME_COMBINED) && STREQ(bnodeSocket->name, "Alpha")) {
+ /* Alpha output is already handled with the associated combined output. */
+ continue;
+ }
/* returns the image view to use for the current active view */
if (BLI_listbase_count_ex(&image->rr->views, 2) > 1) {
@@ -147,17 +144,25 @@ void ImageNode::convertToOperations(NodeConverter &converter, const CompositorCo
if (index == 0 && operation) {
converter.addPreview(operation->getOutputSocket());
}
- if (rpass->passtype == SCE_PASS_COMBINED) {
- BLI_assert(operation != NULL);
- BLI_assert(index < numberOfOutputs - 1);
- NodeOutput *outputSocket = this->getOutputSocket(index + 1);
- SeparateChannelOperation *separate_operation;
- separate_operation = new SeparateChannelOperation();
- separate_operation->setChannel(3);
- converter.addOperation(separate_operation);
- converter.addLink(operation->getOutputSocket(), separate_operation->getInputSocket(0));
- converter.mapOutputSocket(outputSocket, separate_operation->getOutputSocket());
- index++;
+ if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) {
+ for (int alphaIndex = 0; alphaIndex < numberOfOutputs; alphaIndex++) {
+ NodeOutput *alphaSocket = this->getOutputSocket(alphaIndex);
+ bNodeSocket *bnodeAlphaSocket = alphaSocket->getbNodeSocket();
+ if (!STREQ(bnodeAlphaSocket->name, "Alpha")) {
+ continue;
+ }
+ NodeImageLayer *alphaStorage = (NodeImageLayer *)bnodeSocket->storage;
+ if (!STREQ(alphaStorage->pass_name, RE_PASSNAME_COMBINED)) {
+ continue;
+ }
+ SeparateChannelOperation *separate_operation;
+ separate_operation = new SeparateChannelOperation();
+ separate_operation->setChannel(3);
+ converter.addOperation(separate_operation);
+ converter.addLink(operation->getOutputSocket(), separate_operation->getInputSocket(0));
+ converter.mapOutputSocket(alphaSocket, separate_operation->getOutputSocket());
+ break;
+ }
}
}
diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp
index 842edcf35c9..75128de2d84 100644
--- a/source/blender/compositor/nodes/COM_RenderLayersNode.cpp
+++ b/source/blender/compositor/nodes/COM_RenderLayersNode.cpp
@@ -27,76 +27,61 @@
#include "COM_ScaleOperation.h"
#include "COM_SetValueOperation.h"
-#ifdef WITH_CYCLES_DEBUG
-# include "RE_pipeline.h"
-#endif
-
RenderLayersNode::RenderLayersNode(bNode *editorNode) : Node(editorNode)
{
/* pass */
}
void RenderLayersNode::testSocketLink(NodeConverter &converter, const CompositorContext &context,
- int outputSocketNumber, RenderLayersBaseProg *operation) const
+ NodeOutput *output, RenderLayersProg *operation,
+ Scene *scene, int layerId, bool is_preview) const
{
- NodeOutput *outputSocket = this->getOutputSocket(outputSocketNumber);
- Scene *scene = (Scene *)this->getbNode()->id;
- short layerId = this->getbNode()->custom1;
-
operation->setScene(scene);
operation->setLayerId(layerId);
operation->setRenderData(context.getRenderData());
operation->setViewName(context.getViewName());
- converter.mapOutputSocket(outputSocket, operation->getOutputSocket());
+ converter.mapOutputSocket(output, operation->getOutputSocket());
converter.addOperation(operation);
- if (outputSocketNumber == 0) /* only for image socket */
+ if (is_preview) /* only for image socket */
converter.addPreview(operation->getOutputSocket());
}
void RenderLayersNode::convertToOperations(NodeConverter &converter, const CompositorContext &context) const
{
- testSocketLink(converter, context, 0, new RenderLayersColorProg());
- testSocketLink(converter, context, 1, new RenderLayersAlphaProg());
- testSocketLink(converter, context, 2, new RenderLayersDepthProg());
- testSocketLink(converter, context, 3, new RenderLayersNormalOperation());
- testSocketLink(converter, context, 4, new RenderLayersUVOperation());
- testSocketLink(converter, context, 5, new RenderLayersSpeedOperation());
- testSocketLink(converter, context, 6, new RenderLayersColorOperation());
- testSocketLink(converter, context, 7, new RenderLayersDiffuseOperation());
- testSocketLink(converter, context, 8, new RenderLayersSpecularOperation());
- testSocketLink(converter, context, 9, new RenderLayersShadowOperation());
- testSocketLink(converter, context, 10, new RenderLayersAOOperation());
- testSocketLink(converter, context, 11, new RenderLayersReflectionOperation());
- testSocketLink(converter, context, 12, new RenderLayersRefractionOperation());
- testSocketLink(converter, context, 13, new RenderLayersIndirectOperation());
- testSocketLink(converter, context, 14, new RenderLayersObjectIndexOperation());
- testSocketLink(converter, context, 15, new RenderLayersMaterialIndexOperation());
- testSocketLink(converter, context, 16, new RenderLayersMistOperation());
- testSocketLink(converter, context, 17, new RenderLayersEmitOperation());
- testSocketLink(converter, context, 18, new RenderLayersEnvironmentOperation());
+ Scene *scene = (Scene *)this->getbNode()->id;
+ short layerId = this->getbNode()->custom1;
+ Render *re = (scene) ? RE_GetRender(scene->id.name) : NULL;
+ int numberOfOutputs = this->getNumberOfOutputSockets();
- // cycles passes
- testSocketLink(converter, context, 19, new RenderLayersCyclesOperation(SCE_PASS_DIFFUSE_DIRECT));
- testSocketLink(converter, context, 20, new RenderLayersCyclesOperation(SCE_PASS_DIFFUSE_INDIRECT));
- testSocketLink(converter, context, 21, new RenderLayersCyclesOperation(SCE_PASS_DIFFUSE_COLOR));
- testSocketLink(converter, context, 22, new RenderLayersCyclesOperation(SCE_PASS_GLOSSY_DIRECT));
- testSocketLink(converter, context, 23, new RenderLayersCyclesOperation(SCE_PASS_GLOSSY_INDIRECT));
- testSocketLink(converter, context, 24, new RenderLayersCyclesOperation(SCE_PASS_GLOSSY_COLOR));
- testSocketLink(converter, context, 25, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_DIRECT));
- testSocketLink(converter, context, 26, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_INDIRECT));
- testSocketLink(converter, context, 27, new RenderLayersCyclesOperation(SCE_PASS_TRANSM_COLOR));
- testSocketLink(converter, context, 28, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_DIRECT));
- testSocketLink(converter, context, 29, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_INDIRECT));
- testSocketLink(converter, context, 30, new RenderLayersCyclesOperation(SCE_PASS_SUBSURFACE_COLOR));
-
-#ifdef WITH_CYCLES_DEBUG
- {
- Scene *scene = (Scene *)this->getbNode()->id;
- Render *re = RE_GetRender(scene->id.name);
- int debug_pass_type = ((re != NULL) ? RE_debug_pass_type_get(re) : scene->r.debug_pass_type);
- testSocketLink(converter, context, 31, new RenderLayersCyclesDebugOperation(SCE_PASS_DEBUG, debug_pass_type));
+ if (re) {
+ RenderResult *rr = RE_AcquireResultRead(re);
+ if (rr) {
+ SceneRenderLayer *srl = (SceneRenderLayer *)BLI_findlink(&scene->r.layers, layerId);
+ if (srl) {
+ RenderLayer *rl = RE_GetRenderLayer(rr, srl->name);
+ if (rl) {
+ for (int i = 0; i < numberOfOutputs; i++) {
+ NodeOutput *output = this->getOutputSocket(i);
+ NodeImageLayer *storage = (NodeImageLayer*) output->getbNodeSocket()->storage;
+ RenderPass *rpass = (RenderPass*) BLI_findstring(&rl->passes, storage->pass_name, offsetof(RenderPass, name));
+ if (rpass) {
+ if (STREQ(rpass->name, RE_PASSNAME_COMBINED) && STREQ(output->getbNodeSocket()->name, "Alpha")) {
+ testSocketLink(converter, context, output, new RenderLayersAlphaProg(rpass->name, COM_DT_VALUE, rpass->channels), scene, layerId, false);
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_Z)) {
+ testSocketLink(converter, context, output, new RenderLayersDepthProg(rpass->name, COM_DT_VALUE, rpass->channels), scene, layerId, false);
+ }
+ else {
+ DataType type = ((rpass->channels == 4)? COM_DT_COLOR : ((rpass->channels == 3)? COM_DT_VECTOR : COM_DT_VALUE));
+ testSocketLink(converter, context, output, new RenderLayersProg(rpass->name, type, rpass->channels), scene, layerId, STREQ(output->getbNodeSocket()->name, "Image"));
+ }
+ }
+ }
+ }
+ }
+ }
+ RE_ReleaseResult(re);
}
-#endif
}
diff --git a/source/blender/compositor/nodes/COM_RenderLayersNode.h b/source/blender/compositor/nodes/COM_RenderLayersNode.h
index 5863cbb390c..1f733a9f4bb 100644
--- a/source/blender/compositor/nodes/COM_RenderLayersNode.h
+++ b/source/blender/compositor/nodes/COM_RenderLayersNode.h
@@ -33,5 +33,11 @@ public:
RenderLayersNode(bNode *editorNode);
void convertToOperations(NodeConverter &converter, const CompositorContext &context) const;
private:
- void testSocketLink(NodeConverter &converter, const CompositorContext &context, int outputSocketNumber, RenderLayersBaseProg *operation) const;
+ void testSocketLink(NodeConverter &converter,
+ const CompositorContext &context,
+ NodeOutput *output,
+ RenderLayersProg *operation,
+ Scene *scene,
+ int layerId,
+ bool is_preview) const;
};
diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.cpp b/source/blender/compositor/operations/COM_BrightnessOperation.cpp
index 33e35c3fe3b..c7ba86b66bc 100644
--- a/source/blender/compositor/operations/COM_BrightnessOperation.cpp
+++ b/source/blender/compositor/operations/COM_BrightnessOperation.cpp
@@ -29,7 +29,14 @@ BrightnessOperation::BrightnessOperation() : NodeOperation()
this->addInputSocket(COM_DT_VALUE);
this->addOutputSocket(COM_DT_COLOR);
this->m_inputProgram = NULL;
+ this->m_use_premultiply = false;
}
+
+void BrightnessOperation::setUsePremultiply(bool use_premultiply)
+{
+ this->m_use_premultiply = use_premultiply;
+}
+
void BrightnessOperation::initExecution()
{
this->m_inputProgram = this->getInputSocketReader(0);
@@ -64,11 +71,16 @@ void BrightnessOperation::executePixelSampled(float output[4], float x, float y,
delta *= -1;
b = a * (brightness + delta);
}
-
+ if (this->m_use_premultiply) {
+ premul_to_straight_v4(inputValue);
+ }
output[0] = a * inputValue[0] + b;
output[1] = a * inputValue[1] + b;
output[2] = a * inputValue[2] + b;
output[3] = inputValue[3];
+ if (this->m_use_premultiply) {
+ straight_to_premul_v4(output);
+ }
}
void BrightnessOperation::deinitExecution()
diff --git a/source/blender/compositor/operations/COM_BrightnessOperation.h b/source/blender/compositor/operations/COM_BrightnessOperation.h
index 22086ae11e8..ff492f2b102 100644
--- a/source/blender/compositor/operations/COM_BrightnessOperation.h
+++ b/source/blender/compositor/operations/COM_BrightnessOperation.h
@@ -34,6 +34,8 @@ private:
SocketReader *m_inputBrightnessProgram;
SocketReader *m_inputContrastProgram;
+ bool m_use_premultiply;
+
public:
BrightnessOperation();
@@ -52,5 +54,6 @@ public:
*/
void deinitExecution();
+ void setUsePremultiply(bool use_premultiply);
};
#endif
diff --git a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp
index 325ef83a529..aa58c0571cf 100644
--- a/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp
+++ b/source/blender/compositor/operations/COM_DifferenceMatteOperation.cpp
@@ -65,11 +65,11 @@ void DifferenceMatteOperation::executePixelSampled(float output[4], float x, flo
difference = difference / 3.0f;
/* make 100% transparent */
- if (difference < tolerance) {
+ if (difference <= tolerance) {
output[0] = 0.0f;
}
/*in the falloff region, make partially transparent */
- else if (difference < falloff + tolerance) {
+ else if (difference <= falloff + tolerance) {
difference = difference - tolerance;
alpha = difference / falloff;
/*only change if more transparent than before */
diff --git a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp
index 57aa3a1bac2..94f407dad86 100644
--- a/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp
+++ b/source/blender/compositor/operations/COM_GlareSimpleStarOperation.cpp
@@ -65,10 +65,10 @@ void GlareSimpleStarOperation::generateGlare(float *data, MemoryBuffer *inputTil
}
}
// // B
- for (y = tbuf1->getHeight() - 1 && (!breaked); y >= 0; y--) {
+ for (y = this->getHeight() - 1; y >= 0 && (!breaked); y--) {
ym = y - i;
yp = y + i;
- for (x = tbuf1->getWidth() - 1; x >= 0; x--) {
+ for (x = this->getWidth() - 1; x >= 0; x--) {
xm = x - i;
xp = x + i;
tbuf1->read(c, x, y);
diff --git a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp
index fb8730c9fa0..d6affa6eee9 100644
--- a/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp
+++ b/source/blender/compositor/operations/COM_PlaneCornerPinOperation.cpp
@@ -29,8 +29,6 @@
#include "BLI_math_color.h"
extern "C" {
-# include "BLI_jitter.h"
-
# include "BKE_node.h"
}
diff --git a/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp b/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp
index a56aa0cbaa6..070b7562b2d 100644
--- a/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp
+++ b/source/blender/compositor/operations/COM_PlaneTrackOperation.cpp
@@ -29,8 +29,6 @@
#include "BLI_math_color.h"
extern "C" {
-# include "BLI_jitter.h"
-
# include "BKE_movieclip.h"
# include "BKE_node.h"
# include "BKE_tracking.h"
diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.cpp b/source/blender/compositor/operations/COM_RenderLayersProg.cpp
index 099208ce600..f2f1b211a97 100644
--- a/source/blender/compositor/operations/COM_RenderLayersProg.cpp
+++ b/source/blender/compositor/operations/COM_RenderLayersProg.cpp
@@ -34,17 +34,18 @@ extern "C" {
/* ******** Render Layers Base Prog ******** */
-RenderLayersBaseProg::RenderLayersBaseProg(int renderpass, int elementsize) : NodeOperation()
+RenderLayersProg::RenderLayersProg(const char *passName, DataType type, int elementsize) : NodeOperation(), m_passName(passName)
{
- this->m_renderpass = renderpass;
this->setScene(NULL);
this->m_inputBuffer = NULL;
this->m_elementsize = elementsize;
this->m_rd = NULL;
+
+ this->addOutputSocket(type);
}
-void RenderLayersBaseProg::initExecution()
+void RenderLayersProg::initExecution()
{
Scene *scene = this->getScene();
Render *re = (scene) ? RE_GetRender(scene->id.name) : NULL;
@@ -59,10 +60,7 @@ void RenderLayersBaseProg::initExecution()
RenderLayer *rl = RE_GetRenderLayer(rr, srl->name);
if (rl) {
- this->m_inputBuffer = RE_RenderLayerGetPass(rl, this->m_renderpass, this->m_viewName);
- if (this->m_inputBuffer == NULL && this->m_renderpass == SCE_PASS_COMBINED) {
- this->m_inputBuffer = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, this->m_viewName);
- }
+ this->m_inputBuffer = RE_RenderLayerGetPass(rl, this->m_passName.c_str(), this->m_viewName);
}
}
}
@@ -72,7 +70,7 @@ void RenderLayersBaseProg::initExecution()
}
}
-void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, PixelSampler sampler)
+void RenderLayersProg::doInterpolation(float output[4], float x, float y, PixelSampler sampler)
{
unsigned int offset;
int width = this->getWidth(), height = this->getHeight();
@@ -111,7 +109,7 @@ void RenderLayersBaseProg::doInterpolation(float output[4], float x, float y, Pi
}
}
-void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
+void RenderLayersProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
#if 0
const RenderData *rd = this->m_rd;
@@ -173,12 +171,12 @@ void RenderLayersBaseProg::executePixelSampled(float output[4], float x, float y
}
}
-void RenderLayersBaseProg::deinitExecution()
+void RenderLayersProg::deinitExecution()
{
this->m_inputBuffer = NULL;
}
-void RenderLayersBaseProg::determineResolution(unsigned int resolution[2], unsigned int /*preferredResolution*/[2])
+void RenderLayersProg::determineResolution(unsigned int resolution[2], unsigned int /*preferredResolution*/[2])
{
Scene *sce = this->getScene();
Render *re = (sce) ? RE_GetRender(sce->id.name) : NULL;
@@ -207,13 +205,6 @@ void RenderLayersBaseProg::determineResolution(unsigned int resolution[2], unsig
}
/* ******** Render Layers AO Operation ******** */
-
-RenderLayersAOOperation::RenderLayersAOOperation() : RenderLayersBaseProg(SCE_PASS_AO, 3)
-{
- this->addOutputSocket(COM_DT_COLOR);
-}
-
-
void RenderLayersAOOperation::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
float *inputBuffer = this->getInputBuffer();
@@ -227,12 +218,6 @@ void RenderLayersAOOperation::executePixelSampled(float output[4], float x, floa
}
/* ******** Render Layers Alpha Operation ******** */
-
-RenderLayersAlphaProg::RenderLayersAlphaProg() : RenderLayersBaseProg(SCE_PASS_COMBINED, 4)
-{
- this->addOutputSocket(COM_DT_VALUE);
-}
-
void RenderLayersAlphaProg::executePixelSampled(float output[4], float x, float y, PixelSampler sampler)
{
float *inputBuffer = this->getInputBuffer();
@@ -247,27 +232,7 @@ void RenderLayersAlphaProg::executePixelSampled(float output[4], float x, float
}
}
-/* ******** Render Layers Color Operation ******** */
-
-RenderLayersColorOperation::RenderLayersColorOperation() : RenderLayersBaseProg(SCE_PASS_RGBA, 4)
-{
- this->addOutputSocket(COM_DT_COLOR);
-}
-
-/* ******** Render Layers Cycles Operation ******** */
-
-RenderLayersCyclesOperation::RenderLayersCyclesOperation(int pass) : RenderLayersBaseProg(pass, 3)
-{
- this->addOutputSocket(COM_DT_VECTOR);
-}
-
/* ******** Render Layers Depth Operation ******** */
-
-RenderLayersDepthProg::RenderLayersDepthProg() : RenderLayersBaseProg(SCE_PASS_Z, 1)
-{
- this->addOutputSocket(COM_DT_VALUE);
-}
-
void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float y, PixelSampler /*sampler*/)
{
int ix = x;
@@ -281,135 +246,4 @@ void RenderLayersDepthProg::executePixelSampled(float output[4], float x, float
unsigned int offset = (iy * this->getWidth() + ix);
output[0] = inputBuffer[offset];
}
-}
-
-/* ******** Render Layers Diffuse Operation ******** */
-
-RenderLayersDiffuseOperation::RenderLayersDiffuseOperation() : RenderLayersBaseProg(SCE_PASS_DIFFUSE, 3)
-{
- this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Emit Operation ******** */
-
-RenderLayersEmitOperation::RenderLayersEmitOperation() : RenderLayersBaseProg(SCE_PASS_EMIT, 3)
-{
- this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Environment Operation ******** */
-
-RenderLayersEnvironmentOperation::RenderLayersEnvironmentOperation() : RenderLayersBaseProg(SCE_PASS_ENVIRONMENT, 3)
-{
- this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Image Operation ******** */
-
-RenderLayersColorProg::RenderLayersColorProg() : RenderLayersBaseProg(SCE_PASS_COMBINED, 4)
-{
- this->addOutputSocket(COM_DT_COLOR);
-}
-
-/* ******** Render Layers Indirect Operation ******** */
-
-RenderLayersIndirectOperation::RenderLayersIndirectOperation() : RenderLayersBaseProg(SCE_PASS_INDIRECT, 3)
-{
- this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Material Index Operation ******** */
-
-RenderLayersMaterialIndexOperation::RenderLayersMaterialIndexOperation() : RenderLayersBaseProg(SCE_PASS_INDEXMA, 1)
-{
- this->addOutputSocket(COM_DT_VALUE);
-}
-
-/* ******** Render Layers Mist Operation ******** */
-
-RenderLayersMistOperation::RenderLayersMistOperation() : RenderLayersBaseProg(SCE_PASS_MIST, 1)
-{
- this->addOutputSocket(COM_DT_VALUE);
-}
-
-/* ******** Render Layers Normal Operation ******** */
-
-RenderLayersNormalOperation::RenderLayersNormalOperation() : RenderLayersBaseProg(SCE_PASS_NORMAL, 3)
-{
- this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Object Index Operation ******** */
-
-RenderLayersObjectIndexOperation::RenderLayersObjectIndexOperation() : RenderLayersBaseProg(SCE_PASS_INDEXOB, 1)
-{
- this->addOutputSocket(COM_DT_VALUE);
-}
-
-/* ******** Render Layers Reflection Operation ******** */
-
-RenderLayersReflectionOperation::RenderLayersReflectionOperation() : RenderLayersBaseProg(SCE_PASS_REFLECT, 3)
-{
- this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Refraction Operation ******** */
-
-RenderLayersRefractionOperation::RenderLayersRefractionOperation() : RenderLayersBaseProg(SCE_PASS_REFRACT, 3)
-{
- this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Shadow Operation ******** */
-
-RenderLayersShadowOperation::RenderLayersShadowOperation() : RenderLayersBaseProg(SCE_PASS_SHADOW, 3)
-{
- this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Specular Operation ******** */
-
-RenderLayersSpecularOperation::RenderLayersSpecularOperation() : RenderLayersBaseProg(SCE_PASS_SPEC, 3)
-{
- this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Render Layers Speed Operation ******** */
-
-RenderLayersSpeedOperation::RenderLayersSpeedOperation() : RenderLayersBaseProg(SCE_PASS_VECTOR, 4)
-{
- this->addOutputSocket(COM_DT_COLOR);
-}
-
-/* ******** Render Layers UV Operation ******** */
-
-RenderLayersUVOperation::RenderLayersUVOperation() : RenderLayersBaseProg(SCE_PASS_UV, 3)
-{
- this->addOutputSocket(COM_DT_VECTOR);
-}
-
-/* ******** Debug Render Layers Cycles Operation ******** */
-
-#ifdef WITH_CYCLES_DEBUG
-
-RenderLayersCyclesDebugOperation::RenderLayersCyclesDebugOperation(
- int pass,
- int debug_pass_type)
- : RenderLayersBaseProg(pass, RE_debug_pass_num_channels_get(debug_pass_type))
-{
- switch (m_elementsize) {
- case 1:
- this->addOutputSocket(COM_DT_VALUE);
- break;
- case 3:
- this->addOutputSocket(COM_DT_VECTOR);
- break;
- case 4:
- this->addOutputSocket(COM_DT_COLOR);
- break;
- default:
- BLI_assert(!"Unkown debug pass type element size.");
- }
-}
-
-#endif
+} \ No newline at end of file
diff --git a/source/blender/compositor/operations/COM_RenderLayersProg.h b/source/blender/compositor/operations/COM_RenderLayersProg.h
index 89eb2a6954d..1be15906770 100644
--- a/source/blender/compositor/operations/COM_RenderLayersProg.h
+++ b/source/blender/compositor/operations/COM_RenderLayersProg.h
@@ -40,7 +40,7 @@ extern "C" {
*
* @todo: rename to operation.
*/
-class RenderLayersBaseProg : public NodeOperation {
+class RenderLayersProg : public NodeOperation {
protected:
/**
* Reference to the scene object.
@@ -65,7 +65,7 @@ protected:
/**
* renderpass where this operation needs to get its data from
*/
- int m_renderpass;
+ std::string m_passName;
int m_elementsize;
@@ -73,11 +73,6 @@ protected:
* @brief render data used for active rendering
*/
const RenderData *m_rd;
-
- /**
- * Constructor
- */
- RenderLayersBaseProg(int renderpass, int elementsize);
/**
* Determine the output resolution. The resolution is retrieved from the Renderer
@@ -92,6 +87,10 @@ protected:
void doInterpolation(float output[4], float x, float y, PixelSampler sampler);
public:
/**
+ * Constructor
+ */
+ RenderLayersProg(const char *passName, DataType type, int elementsize);
+ /**
* setter for the scene field. Will be called from
* @see RenderLayerNode to set the actual scene where
* the data will be retrieved from.
@@ -108,116 +107,25 @@ public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-class RenderLayersAOOperation : public RenderLayersBaseProg {
+class RenderLayersAOOperation : public RenderLayersProg {
public:
- RenderLayersAOOperation();
+ RenderLayersAOOperation(const char *passName, DataType type, int elementsize)
+ : RenderLayersProg(passName, type, elementsize) {}
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-class RenderLayersAlphaProg : public RenderLayersBaseProg {
+class RenderLayersAlphaProg : public RenderLayersProg {
public:
- RenderLayersAlphaProg();
+ RenderLayersAlphaProg(const char *passName, DataType type, int elementsize)
+ : RenderLayersProg(passName, type, elementsize) {}
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-class RenderLayersColorOperation : public RenderLayersBaseProg {
-public:
- RenderLayersColorOperation();
-};
-
-class RenderLayersCyclesOperation : public RenderLayersBaseProg {
-public:
- RenderLayersCyclesOperation(int pass);
-};
-
-class RenderLayersDepthProg : public RenderLayersBaseProg {
+class RenderLayersDepthProg : public RenderLayersProg {
public:
- RenderLayersDepthProg();
+ RenderLayersDepthProg(const char *passName, DataType type, int elementsize)
+ : RenderLayersProg(passName, type, elementsize) {}
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
};
-class RenderLayersDiffuseOperation : public RenderLayersBaseProg {
-public:
- RenderLayersDiffuseOperation();
-};
-
-class RenderLayersEmitOperation : public RenderLayersBaseProg {
-public:
- RenderLayersEmitOperation();
-};
-
-class RenderLayersEnvironmentOperation : public RenderLayersBaseProg {
-public:
- RenderLayersEnvironmentOperation();
-};
-
-/// @todo rename to image operation
-class RenderLayersColorProg : public RenderLayersBaseProg {
-public:
- RenderLayersColorProg();
-};
-
-class RenderLayersIndirectOperation : public RenderLayersBaseProg {
-public:
- RenderLayersIndirectOperation();
-};
-
-class RenderLayersMaterialIndexOperation : public RenderLayersBaseProg {
-public:
- RenderLayersMaterialIndexOperation();
-};
-
-class RenderLayersMistOperation : public RenderLayersBaseProg {
-public:
- RenderLayersMistOperation();
-};
-
-class RenderLayersNormalOperation : public RenderLayersBaseProg {
-public:
- RenderLayersNormalOperation();
-};
-
-class RenderLayersObjectIndexOperation : public RenderLayersBaseProg {
-public:
- RenderLayersObjectIndexOperation();
-};
-
-class RenderLayersReflectionOperation : public RenderLayersBaseProg {
-public:
- RenderLayersReflectionOperation();
-};
-
-class RenderLayersRefractionOperation : public RenderLayersBaseProg {
-public:
- RenderLayersRefractionOperation();
-};
-
-class RenderLayersShadowOperation : public RenderLayersBaseProg {
-public:
- RenderLayersShadowOperation();
-};
-
-class RenderLayersSpecularOperation : public RenderLayersBaseProg {
-public:
- RenderLayersSpecularOperation();
-};
-
-class RenderLayersSpeedOperation : public RenderLayersBaseProg {
-public:
- RenderLayersSpeedOperation();
-};
-
-class RenderLayersUVOperation : public RenderLayersBaseProg {
-public:
- RenderLayersUVOperation();
-};
-
-#ifdef WITH_CYCLES_DEBUG
-class RenderLayersCyclesDebugOperation : public RenderLayersBaseProg {
-public:
- RenderLayersCyclesDebugOperation(int pass,
- int debug_pass_type);
-};
-#endif
-
#endif
diff --git a/source/blender/compositor/operations/COM_TextureOperation.cpp b/source/blender/compositor/operations/COM_TextureOperation.cpp
index 6bfd8ae3888..d0c72935b16 100644
--- a/source/blender/compositor/operations/COM_TextureOperation.cpp
+++ b/source/blender/compositor/operations/COM_TextureOperation.cpp
@@ -41,6 +41,7 @@ TextureBaseOperation::TextureBaseOperation() : NodeOperation()
this->m_rd = NULL;
this->m_pool = NULL;
this->m_sceneColorManage = false;
+ setComplex(true);
}
TextureOperation::TextureOperation() : TextureBaseOperation()
{
@@ -155,31 +156,3 @@ void TextureBaseOperation::executePixelSampled(float output[4], float x, float y
output[0] = output[1] = output[2] = output[3];
}
}
-
-MemoryBuffer *TextureBaseOperation::createMemoryBuffer(rcti * /*rect2*/)
-{
- int height = getHeight();
- int width = getWidth();
- DataType datatype = this->getOutputSocket()->getDataType();
- int add = 4;
- if (datatype == COM_DT_VALUE) {
- add = 1;
- }
-
- rcti rect;
- rect.xmin = 0;
- rect.ymin = 0;
- rect.xmax = width;
- rect.ymax = height;
- MemoryBuffer *result = new MemoryBuffer(datatype, &rect);
-
- float *data = result->getBuffer();
-
- for (int y = 0; y < height; y++) {
- for (int x = 0; x < width; x++, data += add) {
- this->executePixelSampled(data, x, y, COM_PS_NEAREST);
- }
- }
-
- return result;
-}
diff --git a/source/blender/compositor/operations/COM_TextureOperation.h b/source/blender/compositor/operations/COM_TextureOperation.h
index 4cc203b54a2..59ff58a7289 100644
--- a/source/blender/compositor/operations/COM_TextureOperation.h
+++ b/source/blender/compositor/operations/COM_TextureOperation.h
@@ -59,8 +59,6 @@ protected:
* Constructor
*/
TextureBaseOperation();
-
- MemoryBuffer *createMemoryBuffer(rcti *rect2);
public:
void executePixelSampled(float output[4], float x, float y, PixelSampler sampler);
diff --git a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp
index 1ec52571be8..9ff0bf9ce12 100644
--- a/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp
+++ b/source/blender/compositor/operations/COM_VariableSizeBokehBlurOperation.cpp
@@ -286,9 +286,9 @@ void InverseSearchRadiusOperation::initExecution()
this->m_inputRadius = this->getInputSocketReader(0);
}
-voi *InverseSearchRadiusOperation::initializeTileData(rcti *rect)
+void *InverseSearchRadiusOperation::initializeTileData(rcti *rect)
{
- MemoryBuffer * data = new MemoryBuffer(NULL, rect);
+ MemoryBuffer * data = new MemoryBuffer(COM_DT_COLOR, rect);
float *buffer = data->getBuffer();
int x, y;
int width = this->m_inputRadius->getWidth();
@@ -343,7 +343,7 @@ voi *InverseSearchRadiusOperation::initializeTileData(rcti *rect)
void InverseSearchRadiusOperation::executePixelChunk(float output[4], int x, int y, void *data)
{
MemoryBuffer *buffer = (MemoryBuffer *)data;
- buffer->readNoCheck(color, x, y);
+ buffer->readNoCheck(output, x, y);
}
void InverseSearchRadiusOperation::deinitializeTileData(rcti *rect, void *data)
diff --git a/source/blender/depsgraph/CMakeLists.txt b/source/blender/depsgraph/CMakeLists.txt
index e635256cda6..33a7628c68d 100644
--- a/source/blender/depsgraph/CMakeLists.txt
+++ b/source/blender/depsgraph/CMakeLists.txt
@@ -87,8 +87,8 @@ set(SRC
intern/depsgraph_intern.h
intern/depsgraph_types.h
+ util/deg_util_foreach.h
util/deg_util_function.h
- util/deg_util_hash.h
)
if(WITH_CXX11)
diff --git a/source/blender/depsgraph/DEG_depsgraph_build.h b/source/blender/depsgraph/DEG_depsgraph_build.h
index fdc86540171..b65d921cfd1 100644
--- a/source/blender/depsgraph/DEG_depsgraph_build.h
+++ b/source/blender/depsgraph/DEG_depsgraph_build.h
@@ -153,7 +153,8 @@ void DEG_add_object_cache_relation(struct DepsNodeHandle *handle,
eDepsObjectComponentType component,
const char *description);
-/* TODO(sergey): Remove once all geometry update is granular. */
+
+struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *handle);
void DEG_add_special_eval_flag(struct Depsgraph *graph, struct ID *id, short flag);
/* Utility functions for physics modifiers */
diff --git a/source/blender/depsgraph/intern/builder/deg_builder.cc b/source/blender/depsgraph/intern/builder/deg_builder.cc
index 7f62eb122db..086fd0c1144 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder.cc
@@ -30,15 +30,13 @@
#include "intern/builder/deg_builder.h"
-// TODO(sergey): Use own wrapper over STD.
-#include <stack>
-
#include "DNA_anim_types.h"
#include "DNA_object_types.h"
#include "DNA_ID.h"
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
+#include "BLI_stack.h"
#include "intern/depsgraph.h"
#include "intern/depsgraph_types.h"
@@ -71,50 +69,52 @@ static bool check_object_needs_evaluation(Object *object)
void deg_graph_build_flush_layers(Depsgraph *graph)
{
- std::stack<OperationDepsNode *> stack;
+ BLI_Stack *stack = BLI_stack_new(sizeof(OperationDepsNode*),
+ "DEG flush layers stack");
foreach (OperationDepsNode *node, graph->operations) {
IDDepsNode *id_node = node->owner->owner;
node->done = 0;
node->num_links_pending = 0;
foreach (DepsRelation *rel, node->outlinks) {
- if ((rel->from->type == DEPSNODE_TYPE_OPERATION) &&
+ if ((rel->from->type == DEG_NODE_TYPE_OPERATION) &&
(rel->flag & DEPSREL_FLAG_CYCLIC) == 0)
{
++node->num_links_pending;
}
}
if (node->num_links_pending == 0) {
- stack.push(node);
+ BLI_stack_push(stack, &node);
node->done = 1;
}
node->owner->layers = id_node->layers;
id_node->id->tag |= LIB_TAG_DOIT;
}
- while (!stack.empty()) {
- OperationDepsNode *node = stack.top();
- stack.pop();
+ while (!BLI_stack_is_empty(stack)) {
+ OperationDepsNode *node;
+ BLI_stack_pop(stack, &node);
/* Flush layers to parents. */
foreach (DepsRelation *rel, node->inlinks) {
- if (rel->from->type == DEPSNODE_TYPE_OPERATION) {
+ if (rel->from->type == DEG_NODE_TYPE_OPERATION) {
OperationDepsNode *from = (OperationDepsNode *)rel->from;
from->owner->layers |= node->owner->layers;
}
}
/* Schedule parent nodes. */
foreach (DepsRelation *rel, node->inlinks) {
- if (rel->from->type == DEPSNODE_TYPE_OPERATION) {
+ if (rel->from->type == DEG_NODE_TYPE_OPERATION) {
OperationDepsNode *from = (OperationDepsNode *)rel->from;
if ((rel->flag & DEPSREL_FLAG_CYCLIC) == 0) {
BLI_assert(from->num_links_pending > 0);
--from->num_links_pending;
}
if (from->num_links_pending == 0 && from->done == 0) {
- stack.push(from);
+ BLI_stack_push(stack, &from);
from->done = 1;
}
}
}
}
+ BLI_stack_free(stack);
}
void deg_graph_build_finalize(Depsgraph *graph)
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
index 9b37aaa12ff..3eed0697b5e 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_cycle.cc
@@ -32,11 +32,9 @@
// TOO(sergey): Use some wrappers over those?
#include <cstdio>
#include <cstdlib>
-#include <stack>
-extern "C" {
#include "BLI_utildefines.h"
-}
+#include "BLI_stack.h"
#include "util/deg_util_foreach.h"
@@ -48,12 +46,6 @@ extern "C" {
namespace DEG {
-struct StackEntry {
- OperationDepsNode *node;
- StackEntry *from;
- DepsRelation *via_relation;
-};
-
void deg_graph_detect_cycles(Depsgraph *graph)
{
enum {
@@ -65,11 +57,19 @@ void deg_graph_detect_cycles(Depsgraph *graph)
NODE_IN_STACK = 2,
};
- std::stack<StackEntry> traversal_stack;
+ struct StackEntry {
+ OperationDepsNode *node;
+ StackEntry *from;
+ DepsRelation *via_relation;
+ };
+
+ BLI_Stack *traversal_stack = BLI_stack_new(sizeof(StackEntry),
+ "DEG detect cycles stack");
+
foreach (OperationDepsNode *node, graph->operations) {
bool has_inlinks = false;
foreach (DepsRelation *rel, node->inlinks) {
- if (rel->from->type == DEPSNODE_TYPE_OPERATION) {
+ if (rel->from->type == DEG_NODE_TYPE_OPERATION) {
has_inlinks = true;
}
}
@@ -78,7 +78,7 @@ void deg_graph_detect_cycles(Depsgraph *graph)
entry.node = node;
entry.from = NULL;
entry.via_relation = NULL;
- traversal_stack.push(entry);
+ BLI_stack_push(traversal_stack, &entry);
node->tag = NODE_IN_STACK;
}
else {
@@ -87,13 +87,13 @@ void deg_graph_detect_cycles(Depsgraph *graph)
node->done = 0;
}
- while (!traversal_stack.empty()) {
- StackEntry& entry = traversal_stack.top();
- OperationDepsNode *node = entry.node;
+ while (!BLI_stack_is_empty(traversal_stack)) {
+ StackEntry *entry = (StackEntry *)BLI_stack_peek(traversal_stack);
+ OperationDepsNode *node = entry->node;
bool all_child_traversed = true;
for (int i = node->done; i < node->outlinks.size(); ++i) {
DepsRelation *rel = node->outlinks[i];
- if (rel->to->type == DEPSNODE_TYPE_OPERATION) {
+ if (rel->to->type == DEG_NODE_TYPE_OPERATION) {
OperationDepsNode *to = (OperationDepsNode *)rel->to;
if (to->tag == NODE_IN_STACK) {
printf("Dependency cycle detected:\n");
@@ -102,7 +102,7 @@ void deg_graph_detect_cycles(Depsgraph *graph)
node->full_identifier().c_str(),
rel->name);
- StackEntry *current = &entry;
+ StackEntry *current = entry;
while (current->node != to) {
BLI_assert(current != NULL);
printf(" '%s' depends on '%s' through '%s'\n",
@@ -117,9 +117,9 @@ void deg_graph_detect_cycles(Depsgraph *graph)
else if (to->tag == NODE_NOT_VISITED) {
StackEntry new_entry;
new_entry.node = to;
- new_entry.from = &entry;
+ new_entry.from = entry;
new_entry.via_relation = rel;
- traversal_stack.push(new_entry);
+ BLI_stack_push(traversal_stack, &new_entry);
to->tag = NODE_IN_STACK;
all_child_traversed = false;
node->done = i;
@@ -129,9 +129,11 @@ void deg_graph_detect_cycles(Depsgraph *graph)
}
if (all_child_traversed) {
node->tag = NODE_VISITED;
- traversal_stack.pop();
+ BLI_stack_discard(traversal_stack);
}
}
+
+ BLI_stack_free(traversal_stack);
}
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
index 7bcaee61fe0..a90f8ff02b6 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.cc
@@ -37,11 +37,11 @@
#include "MEM_guardedalloc.h"
-extern "C" {
#include "BLI_blenlib.h"
#include "BLI_string.h"
#include "BLI_utildefines.h"
+extern "C" {
#include "DNA_action_types.h"
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
@@ -94,13 +94,13 @@ extern "C" {
#include "BKE_tracking.h"
#include "BKE_world.h"
-#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_build.h"
-
#include "RNA_access.h"
#include "RNA_types.h"
} /* extern "C" */
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+
#include "intern/builder/deg_builder.h"
#include "intern/nodes/deg_node.h"
#include "intern/nodes/deg_node_component.h"
@@ -160,55 +160,14 @@ DepsgraphNodeBuilder::~DepsgraphNodeBuilder()
{
}
-RootDepsNode *DepsgraphNodeBuilder::add_root_node()
-{
- return m_graph->add_root_node();
-}
-
IDDepsNode *DepsgraphNodeBuilder::add_id_node(ID *id)
{
return m_graph->add_id_node(id, id->name);
}
-TimeSourceDepsNode *DepsgraphNodeBuilder::add_time_source(ID *id)
+TimeSourceDepsNode *DepsgraphNodeBuilder::add_time_source()
{
- /* determine which node to attach timesource to */
- if (id) {
-#if 0 /* XXX TODO */
- /* get ID node */
- IDDepsNode id_node = m_graph->find_id_node(id);
-
- /* depends on what this is... */
- switch (GS(id->name)) {
- case ID_SCE: /* Scene - Usually sequencer strip causing time remapping... */
- {
- // TODO...
- }
- break;
-
- case ID_GR: /* Group */
- {
- // TODO...
- }
- break;
-
- // XXX: time source...
-
- default: /* Unhandled */
- printf("%s(): Unhandled ID - %s \n", __func__, id->name);
- break;
- }
-#endif
- }
- else {
- /* root-node */
- RootDepsNode *root_node = m_graph->root_node;
- if (root_node) {
- return root_node->add_time_source("Time Source");
- }
- }
-
- return NULL;
+ return m_graph->add_time_source();
}
ComponentDepsNode *DepsgraphNodeBuilder::add_component_node(
@@ -224,8 +183,7 @@ ComponentDepsNode *DepsgraphNodeBuilder::add_component_node(
OperationDepsNode *DepsgraphNodeBuilder::add_operation_node(
ComponentDepsNode *comp_node,
- eDepsOperation_Type optype,
- DepsEvalOperationCb op,
+ const DepsEvalOperationCb& op,
eDepsOperation_Code opcode,
const char *name,
int name_tag)
@@ -234,7 +192,7 @@ OperationDepsNode *DepsgraphNodeBuilder::add_operation_node(
name,
name_tag);
if (op_node == NULL) {
- op_node = comp_node->add_operation(optype, op, opcode, name, name_tag);
+ op_node = comp_node->add_operation(op, opcode, name, name_tag);
m_graph->operations.push_back(op_node);
}
else {
@@ -252,21 +210,19 @@ OperationDepsNode *DepsgraphNodeBuilder::add_operation_node(
ID *id,
eDepsNode_Type comp_type,
const char *comp_name,
- eDepsOperation_Type optype,
- DepsEvalOperationCb op,
+ const DepsEvalOperationCb& op,
eDepsOperation_Code opcode,
const char *name,
int name_tag)
{
ComponentDepsNode *comp_node = add_component_node(id, comp_type, comp_name);
- return add_operation_node(comp_node, optype, op, opcode, name, name_tag);
+ return add_operation_node(comp_node, op, opcode, name, name_tag);
}
OperationDepsNode *DepsgraphNodeBuilder::add_operation_node(
ID *id,
eDepsNode_Type comp_type,
- eDepsOperation_Type optype,
- DepsEvalOperationCb op,
+ const DepsEvalOperationCb& op,
eDepsOperation_Code opcode,
const char *name,
int name_tag)
@@ -274,7 +230,6 @@ OperationDepsNode *DepsgraphNodeBuilder::add_operation_node(
return add_operation_node(id,
comp_type,
"",
- optype,
op,
opcode,
name,
@@ -352,41 +307,6 @@ void DepsgraphNodeBuilder::build_group(Scene *scene,
}
}
-SubgraphDepsNode *DepsgraphNodeBuilder::build_subgraph(Group *group)
-{
- /* sanity checks */
- if (!group)
- return NULL;
-
- /* create new subgraph's data */
- Depsgraph *subgraph = reinterpret_cast<Depsgraph *>(DEG_graph_new());
-
- DepsgraphNodeBuilder subgraph_builder(m_bmain, subgraph);
-
- /* add group objects */
- LINKLIST_FOREACH (GroupObject *, go, &group->gobject) {
- /*Object *ob = go->ob;*/
-
- /* Each "group object" is effectively a separate instance of the
- * underlying object data. When the group is evaluated, the transform
- * results and/or some other attributes end up getting overridden by
- * the group.
- */
- }
-
- /* Create a node for representing subgraph. */
- SubgraphDepsNode *subgraph_node = m_graph->add_subgraph_node(&group->id);
- subgraph_node->graph = subgraph;
-
- /* Make a copy of the data this node will need? */
- /* XXX: do we do this now, or later? */
- /* TODO: need API function which queries graph's ID's hash, and duplicates
- * those blocks thoroughly with all outside links removed.
- */
-
- return subgraph_node;
-}
-
void DepsgraphNodeBuilder::build_object(Scene *scene, Base *base, Object *ob)
{
const bool has_object = (ob->id.tag & LIB_TAG_DOIT);
@@ -427,7 +347,6 @@ void DepsgraphNodeBuilder::build_object(Scene *scene, Base *base, Object *ob)
BuilderWalkUserData data;
data.builder = this;
data.scene = scene;
- modifiers_foreachObjectLink(ob, modifier_walk, &data);
BKE_constraints_id_loop(&ob->constraints, constraint_walk, &data);
}
@@ -513,15 +432,18 @@ void DepsgraphNodeBuilder::build_object(Scene *scene, Base *base, Object *ob)
void DepsgraphNodeBuilder::build_object_transform(Scene *scene, Object *ob)
{
+ OperationDepsNode *op_node;
+
/* local transforms (from transform channels - loc/rot/scale + deltas) */
- add_operation_node(&ob->id, DEPSNODE_TYPE_TRANSFORM,
- DEPSOP_TYPE_INIT, function_bind(BKE_object_eval_local_transform, _1, scene, ob),
- DEG_OPCODE_TRANSFORM_LOCAL);
+ op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
+ function_bind(BKE_object_eval_local_transform, _1, scene, ob),
+ DEG_OPCODE_TRANSFORM_LOCAL);
+ op_node->set_as_entry();
/* object parent */
if (ob->parent) {
- add_operation_node(&ob->id, DEPSNODE_TYPE_TRANSFORM,
- DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_parent, _1, scene, ob),
+ add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
+ function_bind(BKE_object_eval_parent, _1, scene, ob),
DEG_OPCODE_TRANSFORM_PARENT);
}
@@ -537,14 +459,15 @@ void DepsgraphNodeBuilder::build_object_transform(Scene *scene, Object *ob)
*
* TODO(sergey): Get rid of this node.
*/
- add_operation_node(&ob->id, DEPSNODE_TYPE_TRANSFORM,
- DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_uber_transform, _1, scene, ob),
+ add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
+ function_bind(BKE_object_eval_uber_transform, _1, scene, ob),
DEG_OPCODE_OBJECT_UBEREVAL);
/* object transform is done */
- add_operation_node(&ob->id, DEPSNODE_TYPE_TRANSFORM,
- DEPSOP_TYPE_POST, function_bind(BKE_object_eval_done, _1, ob),
- DEG_OPCODE_TRANSFORM_FINAL);
+ op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
+ function_bind(BKE_object_eval_done, _1, ob),
+ DEG_OPCODE_TRANSFORM_FINAL);
+ op_node->set_as_exit();
}
/**
@@ -567,8 +490,8 @@ void DepsgraphNodeBuilder::build_object_transform(Scene *scene, Object *ob)
void DepsgraphNodeBuilder::build_object_constraints(Scene *scene, Object *ob)
{
/* create node for constraint stack */
- add_operation_node(&ob->id, DEPSNODE_TYPE_TRANSFORM,
- DEPSOP_TYPE_EXEC, function_bind(BKE_object_eval_constraints, _1, scene, ob),
+ add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
+ function_bind(BKE_object_eval_constraints, _1, scene, ob),
DEG_OPCODE_TRANSFORM_CONSTRAINTS);
}
@@ -590,8 +513,8 @@ void DepsgraphNodeBuilder::build_animdata(ID *id)
/* actions and NLA - as a single unit for now, as it gets complicated to schedule otherwise */
if ((adt->action) || (adt->nla_tracks.first)) {
/* create the node */
- add_operation_node(id, DEPSNODE_TYPE_ANIMATION,
- DEPSOP_TYPE_EXEC, function_bind(BKE_animsys_eval_animdata, _1, id),
+ add_operation_node(id, DEG_NODE_TYPE_ANIMATION,
+ function_bind(BKE_animsys_eval_animdata, _1, id),
DEG_OPCODE_ANIMATION, id->name);
// TODO: for each channel affected, we might also want to add some support for running RNA update callbacks on them
@@ -621,18 +544,17 @@ OperationDepsNode *DepsgraphNodeBuilder::build_driver(ID *id, FCurve *fcu)
* and use some tagging magic instead.
*/
OperationDepsNode *driver_op = find_operation_node(id,
- DEPSNODE_TYPE_PARAMETERS,
+ DEG_NODE_TYPE_PARAMETERS,
DEG_OPCODE_DRIVER,
- fcu->rna_path,
+ fcu->rna_path ? fcu->rna_path : "",
fcu->array_index);
if (driver_op == NULL) {
driver_op = add_operation_node(id,
- DEPSNODE_TYPE_PARAMETERS,
- DEPSOP_TYPE_EXEC,
+ DEG_NODE_TYPE_PARAMETERS,
function_bind(BKE_animsys_eval_driver, _1, id, fcu),
DEG_OPCODE_DRIVER,
- fcu->rna_path,
+ fcu->rna_path ? fcu->rna_path : "",
fcu->array_index);
}
@@ -653,12 +575,13 @@ void DepsgraphNodeBuilder::build_world(World *world)
return;
}
- /* world itself */
- add_id_node(world_id); /* world shading/params? */
-
build_animdata(world_id);
- /* TODO: other settings? */
+ /* world itself */
+ add_component_node(world_id, DEG_NODE_TYPE_PARAMETERS);
+
+ add_operation_node(world_id, DEG_NODE_TYPE_PARAMETERS, NULL,
+ DEG_OPCODE_PLACEHOLDER, "Parameters Eval");
/* textures */
build_texture_stack(world->mtex);
@@ -693,14 +616,14 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
/* XXX: is this the right component, or do we want to use another one instead? */
/* init/rebuild operation */
- /*OperationDepsNode *init_node =*/ add_operation_node(&scene->id, DEPSNODE_TYPE_TRANSFORM,
- DEPSOP_TYPE_REBUILD, function_bind(BKE_rigidbody_rebuild_sim, _1, scene),
+ /*OperationDepsNode *init_node =*/ add_operation_node(&scene->id, DEG_NODE_TYPE_TRANSFORM,
+ function_bind(BKE_rigidbody_rebuild_sim, _1, scene),
DEG_OPCODE_RIGIDBODY_REBUILD);
/* do-sim operation */
// XXX: what happens if we need to split into several groups?
- OperationDepsNode *sim_node = add_operation_node(&scene->id, DEPSNODE_TYPE_TRANSFORM,
- DEPSOP_TYPE_SIM, function_bind(BKE_rigidbody_eval_simulation, _1, scene),
+ OperationDepsNode *sim_node = add_operation_node(&scene->id, DEG_NODE_TYPE_TRANSFORM,
+ function_bind(BKE_rigidbody_eval_simulation, _1, scene),
DEG_OPCODE_RIGIDBODY_SIM);
/* XXX: For now, the sim node is the only one that really matters here. If any other
@@ -720,8 +643,8 @@ void DepsgraphNodeBuilder::build_rigidbody(Scene *scene)
/* 2) create operation for flushing results */
/* object's transform component - where the rigidbody operation lives */
- add_operation_node(&ob->id, DEPSNODE_TYPE_TRANSFORM,
- DEPSOP_TYPE_EXEC, function_bind(BKE_rigidbody_object_sync_transforms, _1, scene, ob),
+ add_operation_node(&ob->id, DEG_NODE_TYPE_TRANSFORM,
+ function_bind(BKE_rigidbody_object_sync_transforms, _1, scene, ob),
DEG_OPCODE_TRANSFORM_RIGIDBODY);
}
}
@@ -746,7 +669,14 @@ void DepsgraphNodeBuilder::build_particles(Scene *scene, Object *ob)
/* component for all particle systems */
ComponentDepsNode *psys_comp =
- add_component_node(&ob->id, DEPSNODE_TYPE_EVAL_PARTICLES);
+ add_component_node(&ob->id, DEG_NODE_TYPE_EVAL_PARTICLES);
+
+ add_operation_node(psys_comp,
+ function_bind(BKE_particle_system_eval_init,
+ _1,
+ scene,
+ ob),
+ DEG_OPCODE_PSYS_EVAL_INIT);
/* particle systems */
LINKLIST_FOREACH (ParticleSystem *, psys, &ob->particlesystem) {
@@ -759,12 +689,7 @@ void DepsgraphNodeBuilder::build_particles(Scene *scene, Object *ob)
/* this particle system */
// TODO: for now, this will just be a placeholder "ubereval" node
add_operation_node(psys_comp,
- DEPSOP_TYPE_EXEC,
- function_bind(BKE_particle_system_eval,
- _1,
- scene,
- ob,
- psys),
+ NULL,
DEG_OPCODE_PSYS_EVAL,
psys->name);
}
@@ -776,9 +701,8 @@ void DepsgraphNodeBuilder::build_particles(Scene *scene, Object *ob)
void DepsgraphNodeBuilder::build_cloth(Scene *scene, Object *object)
{
ComponentDepsNode *cache_comp = add_component_node(&object->id,
- DEPSNODE_TYPE_CACHE);
+ DEG_NODE_TYPE_CACHE);
add_operation_node(cache_comp,
- DEPSOP_TYPE_EXEC,
function_bind(BKE_object_eval_cloth,
_1,
scene,
@@ -792,7 +716,7 @@ void DepsgraphNodeBuilder::build_shapekeys(Key *key)
{
build_animdata(&key->id);
- add_operation_node(&key->id, DEPSNODE_TYPE_GEOMETRY, DEPSOP_TYPE_EXEC, NULL,
+ add_operation_node(&key->id, DEG_NODE_TYPE_GEOMETRY, NULL,
DEG_OPCODE_PLACEHOLDER, "Shapekey Eval");
}
@@ -801,18 +725,19 @@ void DepsgraphNodeBuilder::build_shapekeys(Key *key)
void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
{
ID *obdata = (ID *)ob->data;
+ OperationDepsNode *op_node;
/* TODO(sergey): This way using this object's properties as driver target
* works fine.
*
* Does this depend on other nodes?
*/
- add_operation_node(&ob->id,
- DEPSNODE_TYPE_PARAMETERS,
- DEPSOP_TYPE_POST,
- NULL,
- DEG_OPCODE_PLACEHOLDER,
- "Parameters Eval");
+ op_node = add_operation_node(&ob->id,
+ DEG_NODE_TYPE_PARAMETERS,
+ NULL,
+ DEG_OPCODE_PLACEHOLDER,
+ "Parameters Eval");
+ op_node->set_as_exit();
/* Temporary uber-update node, which does everything.
* It is for the being we're porting old dependencies into the new system.
@@ -821,51 +746,34 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
*
* TODO(sergey): Get rid of this node.
*/
- add_operation_node(&ob->id,
- DEPSNODE_TYPE_GEOMETRY,
- DEPSOP_TYPE_POST,
- function_bind(BKE_object_eval_uber_data, _1, scene, ob),
- DEG_OPCODE_GEOMETRY_UBEREVAL);
-
- add_operation_node(&ob->id,
- DEPSNODE_TYPE_GEOMETRY,
- DEPSOP_TYPE_INIT,
- NULL,
- DEG_OPCODE_PLACEHOLDER,
- "Eval Init");
+ op_node = add_operation_node(&ob->id,
+ DEG_NODE_TYPE_GEOMETRY,
+ function_bind(BKE_object_eval_uber_data, _1, scene, ob),
+ DEG_OPCODE_GEOMETRY_UBEREVAL);
+ op_node->set_as_exit();
+
+ op_node = add_operation_node(&ob->id,
+ DEG_NODE_TYPE_GEOMETRY,
+ NULL,
+ DEG_OPCODE_PLACEHOLDER,
+ "Eval Init");
+ op_node->set_as_entry();
// TODO: "Done" operation
- /* Modifiers */
+ /* Cloyth modifier. */
LINKLIST_FOREACH (ModifierData *, md, &ob->modifiers) {
- add_operation_node(&ob->id,
- DEPSNODE_TYPE_GEOMETRY,
- DEPSOP_TYPE_EXEC,
- function_bind(BKE_object_eval_modifier,
- _1,
- scene,
- ob,
- md),
- DEG_OPCODE_GEOMETRY_MODIFIER,
- md->name);
if (md->type == eModifierType_Cloth) {
build_cloth(scene, ob);
}
}
/* materials */
- if (ob->totcol != 0) {
- for (int a = 1; a <= ob->totcol; a++) {
- Material *ma = give_current_material(ob, a);
- if (ma != NULL) {
- build_material(ma);
- }
+ for (int a = 1; a <= ob->totcol; a++) {
+ Material *ma = give_current_material(ob, a);
+ if (ma != NULL) {
+ build_material(ma);
}
- add_operation_node(&ob->id,
- DEPSNODE_TYPE_SHADING,
- DEPSOP_TYPE_EXEC,
- NULL,
- DEG_OPCODE_PLACEHOLDER, "Material Update");
}
/* geometry collision */
@@ -894,14 +802,14 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
//Mesh *me = (Mesh *)ob->data;
/* evaluation operations */
- add_operation_node(obdata,
- DEPSNODE_TYPE_GEOMETRY,
- DEPSOP_TYPE_INIT,
- function_bind(BKE_mesh_eval_geometry,
- _1,
- (Mesh *)obdata),
- DEG_OPCODE_PLACEHOLDER,
- "Geometry Eval");
+ op_node = add_operation_node(obdata,
+ DEG_NODE_TYPE_GEOMETRY,
+ function_bind(BKE_mesh_eval_geometry,
+ _1,
+ (Mesh *)obdata),
+ DEG_OPCODE_PLACEHOLDER,
+ "Geometry Eval");
+ op_node->set_as_entry();
break;
}
@@ -913,14 +821,14 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
if (mom == ob) {
/* metaball evaluation operations */
/* NOTE: only the motherball gets evaluated! */
- add_operation_node(obdata,
- DEPSNODE_TYPE_GEOMETRY,
- DEPSOP_TYPE_INIT,
- function_bind(BKE_mball_eval_geometry,
- _1,
- (MetaBall *)obdata),
- DEG_OPCODE_PLACEHOLDER,
- "Geometry Eval");
+ op_node = add_operation_node(obdata,
+ DEG_NODE_TYPE_GEOMETRY,
+ function_bind(BKE_mball_eval_geometry,
+ _1,
+ (MetaBall *)obdata),
+ DEG_OPCODE_PLACEHOLDER,
+ "Geometry Eval");
+ op_node->set_as_entry();
}
break;
}
@@ -931,20 +839,19 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
{
/* Curve/nurms evaluation operations. */
/* - calculate curve geometry (including path) */
- add_operation_node(obdata,
- DEPSNODE_TYPE_GEOMETRY,
- DEPSOP_TYPE_INIT,
- function_bind(BKE_curve_eval_geometry,
- _1,
- (Curve *)obdata),
- DEG_OPCODE_PLACEHOLDER,
- "Geometry Eval");
+ op_node = add_operation_node(obdata,
+ DEG_NODE_TYPE_GEOMETRY,
+ function_bind(BKE_curve_eval_geometry,
+ _1,
+ (Curve *)obdata),
+ DEG_OPCODE_PLACEHOLDER,
+ "Geometry Eval");
+ op_node->set_as_entry();
/* Calculate curve path - this is used by constraints, etc. */
if (ELEM(ob->type, OB_CURVE, OB_FONT)) {
add_operation_node(obdata,
- DEPSNODE_TYPE_GEOMETRY,
- DEPSOP_TYPE_EXEC,
+ DEG_NODE_TYPE_GEOMETRY,
function_bind(BKE_curve_eval_path,
_1,
(Curve *)obdata),
@@ -971,24 +878,24 @@ void DepsgraphNodeBuilder::build_obdata_geom(Scene *scene, Object *ob)
case OB_LATTICE:
{
/* Lattice evaluation operations. */
- add_operation_node(obdata,
- DEPSNODE_TYPE_GEOMETRY,
- DEPSOP_TYPE_INIT,
- function_bind(BKE_lattice_eval_geometry,
- _1,
- (Lattice *)obdata),
- DEG_OPCODE_PLACEHOLDER,
- "Geometry Eval");
+ op_node = add_operation_node(obdata,
+ DEG_NODE_TYPE_GEOMETRY,
+ function_bind(BKE_lattice_eval_geometry,
+ _1,
+ (Lattice *)obdata),
+ DEG_OPCODE_PLACEHOLDER,
+ "Geometry Eval");
+ op_node->set_as_entry();
break;
}
}
- add_operation_node(obdata, DEPSNODE_TYPE_GEOMETRY,
- DEPSOP_TYPE_POST, NULL,
- DEG_OPCODE_PLACEHOLDER, "Eval Done");
+ op_node = add_operation_node(obdata, DEG_NODE_TYPE_GEOMETRY, NULL,
+ DEG_OPCODE_PLACEHOLDER, "Eval Done");
+ op_node->set_as_exit();
/* Parameters for driver sources. */
- add_operation_node(obdata, DEPSNODE_TYPE_PARAMETERS, DEPSOP_TYPE_EXEC, NULL,
+ add_operation_node(obdata, DEG_NODE_TYPE_PARAMETERS, NULL,
DEG_OPCODE_PLACEHOLDER, "Parameters Eval");
}
@@ -1004,15 +911,13 @@ void DepsgraphNodeBuilder::build_camera(Object *ob)
build_animdata(&cam->id);
- add_operation_node(camera_id, DEPSNODE_TYPE_PARAMETERS, DEPSOP_TYPE_EXEC, NULL,
+ add_operation_node(camera_id, DEG_NODE_TYPE_PARAMETERS, NULL,
DEG_OPCODE_PLACEHOLDER, "Parameters Eval");
if (cam->dof_ob != NULL) {
/* TODO(sergey): For now parametrs are on object level. */
- add_operation_node(&ob->id, DEPSNODE_TYPE_PARAMETERS,
- DEPSOP_TYPE_EXEC, NULL,
- DEG_OPCODE_PLACEHOLDER,
- "Camera DOF");
+ add_operation_node(&ob->id, DEG_NODE_TYPE_PARAMETERS, NULL,
+ DEG_OPCODE_PLACEHOLDER, "Camera DOF");
}
}
@@ -1028,10 +933,10 @@ void DepsgraphNodeBuilder::build_lamp(Object *ob)
build_animdata(&la->id);
/* node for obdata */
- add_component_node(lamp_id, DEPSNODE_TYPE_PARAMETERS);
+ add_component_node(lamp_id, DEG_NODE_TYPE_PARAMETERS);
/* TODO(sergey): Is it really how we're supposed to work with drivers? */
- add_operation_node(lamp_id, DEPSNODE_TYPE_PARAMETERS, DEPSOP_TYPE_EXEC, NULL,
+ add_operation_node(lamp_id, DEG_NODE_TYPE_PARAMETERS, NULL,
DEG_OPCODE_PLACEHOLDER, "Parameters Eval");
/* lamp's nodetree */
@@ -1050,12 +955,14 @@ void DepsgraphNodeBuilder::build_nodetree(bNodeTree *ntree)
/* nodetree itself */
ID *ntree_id = &ntree->id;
+ OperationDepsNode *op_node;
build_animdata(ntree_id);
/* Parameters for drivers. */
- add_operation_node(ntree_id, DEPSNODE_TYPE_PARAMETERS, DEPSOP_TYPE_POST, NULL,
- DEG_OPCODE_PLACEHOLDER, "Parameters Eval");
+ op_node = add_operation_node(ntree_id, DEG_NODE_TYPE_PARAMETERS, NULL,
+ DEG_OPCODE_PLACEHOLDER, "Parameters Eval");
+ op_node->set_as_exit();
/* nodetree's nodes... */
LINKLIST_FOREACH (bNode *, bnode, &ntree->nodes) {
@@ -1094,8 +1001,7 @@ void DepsgraphNodeBuilder::build_material(Material *ma)
/* material itself */
add_id_node(ma_id);
- add_operation_node(ma_id, DEPSNODE_TYPE_SHADING,
- DEPSOP_TYPE_EXEC, NULL,
+ add_operation_node(ma_id, DEG_NODE_TYPE_SHADING, NULL,
DEG_OPCODE_PLACEHOLDER, "Material Update");
/* material animation */
@@ -1151,8 +1057,7 @@ void DepsgraphNodeBuilder::build_image(Image *image) {
add_id_node(image_id);
/* Placeholder so we can add relations and tag ID node for update. */
add_operation_node(image_id,
- DEPSNODE_TYPE_PARAMETERS,
- DEPSOP_TYPE_EXEC,
+ DEG_NODE_TYPE_PARAMETERS,
NULL,
DEG_OPCODE_PLACEHOLDER,
"Image Eval");
@@ -1163,10 +1068,10 @@ void DepsgraphNodeBuilder::build_compositor(Scene *scene)
/* For now, just a plain wrapper? */
// TODO: create compositing component?
// XXX: component type undefined!
- //graph->get_node(&scene->id, NULL, DEPSNODE_TYPE_COMPOSITING, NULL);
+ //graph->get_node(&scene->id, NULL, DEG_NODE_TYPE_COMPOSITING, NULL);
/* for now, nodetrees are just parameters; compositing occurs in internals of renderer... */
- add_component_node(&scene->id, DEPSNODE_TYPE_PARAMETERS);
+ add_component_node(&scene->id, DEG_NODE_TYPE_PARAMETERS);
build_nodetree(scene->nodetree);
}
@@ -1188,9 +1093,8 @@ void DepsgraphNodeBuilder::build_cachefile(CacheFile *cache_file)
{
ID *cache_file_id = &cache_file->id;
- add_component_node(cache_file_id, DEPSNODE_TYPE_CACHE);
- add_operation_node(cache_file_id, DEPSNODE_TYPE_CACHE,
- DEPSOP_TYPE_EXEC, NULL,
+ add_component_node(cache_file_id, DEG_NODE_TYPE_CACHE);
+ add_operation_node(cache_file_id, DEG_NODE_TYPE_CACHE, NULL,
DEG_OPCODE_PLACEHOLDER, "Cache File Update");
add_id_node(cache_file_id);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
index 10b586342dd..a54b1c76c77 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes.h
@@ -61,8 +61,6 @@ namespace DEG {
struct Depsgraph;
struct DepsNode;
-struct RootDepsNode;
-struct SubgraphDepsNode;
struct IDDepsNode;
struct TimeSourceDepsNode;
struct ComponentDepsNode;
@@ -74,32 +72,28 @@ struct DepsgraphNodeBuilder {
void begin_build(Main *bmain);
- RootDepsNode *add_root_node();
IDDepsNode *add_id_node(ID *id);
- TimeSourceDepsNode *add_time_source(ID *id);
+ TimeSourceDepsNode *add_time_source();
ComponentDepsNode *add_component_node(ID *id,
eDepsNode_Type comp_type,
const char *comp_name = "");
OperationDepsNode *add_operation_node(ComponentDepsNode *comp_node,
- eDepsOperation_Type optype,
- DepsEvalOperationCb op,
+ const DepsEvalOperationCb& op,
eDepsOperation_Code opcode,
const char *name = "",
int name_tag = -1);
OperationDepsNode *add_operation_node(ID *id,
eDepsNode_Type comp_type,
const char *comp_name,
- eDepsOperation_Type optype,
- DepsEvalOperationCb op,
+ const DepsEvalOperationCb& op,
eDepsOperation_Code opcode,
const char *name = "",
int name_tag = -1);
OperationDepsNode *add_operation_node(ID *id,
eDepsNode_Type comp_type,
- eDepsOperation_Type optype,
- DepsEvalOperationCb op,
+ const DepsEvalOperationCb& op,
eDepsOperation_Code opcode,
const char *name = "",
int name_tag = -1);
@@ -125,12 +119,11 @@ struct DepsgraphNodeBuilder {
int name_tag = -1);
void build_scene(Main *bmain, Scene *scene);
- SubgraphDepsNode *build_subgraph(Group *group);
void build_group(Scene *scene, Base *base, Group *group);
void build_object(Scene *scene, Base *base, Object *ob);
void build_object_transform(Scene *scene, Object *ob);
void build_object_constraints(Scene *scene, Object *ob);
- void build_pose_constraints(Object *ob, bPoseChannel *pchan);
+ void build_pose_constraints(Scene *scene, Object *ob, bPoseChannel *pchan);
void build_rigidbody(Scene *scene);
void build_particles(Scene *scene, Object *ob);
void build_cloth(Scene *scene, Object *object);
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
index f2437ce1fac..fe7ccaa7fc0 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_rig.cc
@@ -37,11 +37,11 @@
#include "MEM_guardedalloc.h"
-extern "C" {
+#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_string.h"
-#include "BLI_utildefines.h"
+extern "C" {
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
#include "DNA_constraint_types.h"
@@ -49,10 +49,10 @@ extern "C" {
#include "BKE_action.h"
#include "BKE_armature.h"
+} /* extern "C" */
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
-} /* extern "C" */
#include "intern/builder/deg_builder.h"
#include "intern/nodes/deg_node.h"
@@ -64,11 +64,11 @@ extern "C" {
namespace DEG {
-void DepsgraphNodeBuilder::build_pose_constraints(Object *ob, bPoseChannel *pchan)
+void DepsgraphNodeBuilder::build_pose_constraints(Scene *scene, Object *ob, bPoseChannel *pchan)
{
/* create node for constraint stack */
- add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
- DEPSOP_TYPE_EXEC, function_bind(BKE_pose_constraints_evaluate, _1, ob, pchan),
+ add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name,
+ function_bind(BKE_pose_constraints_evaluate, _1, scene, ob, pchan),
DEG_OPCODE_BONE_CONSTRAINTS);
}
@@ -80,15 +80,15 @@ void DepsgraphNodeBuilder::build_ik_pose(Scene *scene, Object *ob, bPoseChannel
/* Find the chain's root. */
bPoseChannel *rootchan = BKE_armature_ik_solver_find_root(pchan, data);
- if (has_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name,
+ if (has_operation_node(&ob->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name,
DEG_OPCODE_POSE_IK_SOLVER))
{
return;
}
/* Operation node for evaluating/running IK Solver. */
- add_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name,
- DEPSOP_TYPE_SIM, function_bind(BKE_pose_iktree_evaluate, _1, scene, ob, rootchan),
+ add_operation_node(&ob->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name,
+ function_bind(BKE_pose_iktree_evaluate, _1, scene, ob, rootchan),
DEG_OPCODE_POSE_IK_SOLVER);
}
@@ -103,8 +103,8 @@ void DepsgraphNodeBuilder::build_splineik_pose(Scene *scene, Object *ob, bPoseCh
/* Operation node for evaluating/running Spline IK Solver.
* Store the "root bone" of this chain in the solver, so it knows where to start.
*/
- add_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name,
- DEPSOP_TYPE_SIM, function_bind(BKE_pose_splineik_evaluate, _1, scene, ob, rootchan),
+ add_operation_node(&ob->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name,
+ function_bind(BKE_pose_splineik_evaluate, _1, scene, ob, rootchan),
DEG_OPCODE_POSE_SPLINE_IK_SOLVER);
}
@@ -112,6 +112,7 @@ void DepsgraphNodeBuilder::build_splineik_pose(Scene *scene, Object *ob, bPoseCh
void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *ob)
{
bArmature *arm = (bArmature *)ob->data;
+ OperationDepsNode *op_node;
/* animation and/or drivers linking posebones to base-armature used to define them
* NOTE: AnimData here is really used to control animated deform properties,
@@ -124,8 +125,7 @@ void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *ob)
/* Make sure pose is up-to-date with armature updates. */
add_operation_node(&arm->id,
- DEPSNODE_TYPE_PARAMETERS,
- DEPSOP_TYPE_EXEC,
+ DEG_NODE_TYPE_PARAMETERS,
NULL,
DEG_OPCODE_PLACEHOLDER,
"Armature Eval");
@@ -174,34 +174,41 @@ void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *ob)
*/
/* pose eval context */
- add_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE,
- DEPSOP_TYPE_INIT, function_bind(BKE_pose_eval_init, _1, scene, ob, ob->pose), DEG_OPCODE_POSE_INIT);
-
- add_operation_node(&ob->id, DEPSNODE_TYPE_EVAL_POSE,
- DEPSOP_TYPE_POST, function_bind(BKE_pose_eval_flush, _1, scene, ob, ob->pose), DEG_OPCODE_POSE_DONE);
+ op_node = add_operation_node(&ob->id,
+ DEG_NODE_TYPE_EVAL_POSE,
+ function_bind(BKE_pose_eval_init, _1, scene, ob, ob->pose),
+ DEG_OPCODE_POSE_INIT);
+ op_node->set_as_entry();
+
+ op_node = add_operation_node(&ob->id,
+ DEG_NODE_TYPE_EVAL_POSE,
+ function_bind(BKE_pose_eval_flush, _1, scene, ob, ob->pose),
+ DEG_OPCODE_POSE_DONE);
+ op_node->set_as_exit();
/* bones */
LINKLIST_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
/* node for bone eval */
- add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
- DEPSOP_TYPE_INIT, NULL, // XXX: BKE_pose_eval_bone_local
- DEG_OPCODE_BONE_LOCAL);
+ op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, NULL,
+ DEG_OPCODE_BONE_LOCAL);
+ op_node->set_as_entry();
- add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
- DEPSOP_TYPE_EXEC, function_bind(BKE_pose_eval_bone, _1, scene, ob, pchan), // XXX: BKE_pose_eval_bone_pose
+ add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name,
+ function_bind(BKE_pose_eval_bone, _1, scene, ob, pchan),
DEG_OPCODE_BONE_POSE_PARENT);
- add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
- DEPSOP_TYPE_OUT, NULL, /* NOTE: dedicated noop for easier relationship construction */
+ add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name,
+ NULL, /* NOTE: dedicated noop for easier relationship construction */
DEG_OPCODE_BONE_READY);
- add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
- DEPSOP_TYPE_POST, function_bind(BKE_pose_bone_done, _1, pchan),
- DEG_OPCODE_BONE_DONE);
+ op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name,
+ function_bind(BKE_pose_bone_done, _1, pchan),
+ DEG_OPCODE_BONE_DONE);
+ op_node->set_as_exit();
/* constraints */
if (pchan->constraints.first != NULL) {
- build_pose_constraints(ob, pchan);
+ build_pose_constraints(scene, ob, pchan);
}
/**
@@ -235,6 +242,8 @@ void DepsgraphNodeBuilder::build_rig(Scene *scene, Object *ob)
void DepsgraphNodeBuilder::build_proxy_rig(Object *ob)
{
ID *obdata = (ID *)ob->data;
+ OperationDepsNode *op_node;
+
build_animdata(obdata);
BLI_assert(ob->pose != NULL);
@@ -245,31 +254,28 @@ void DepsgraphNodeBuilder::build_proxy_rig(Object *ob)
BKE_pose_update_constraint_flags(ob->pose);
}
- add_operation_node(&ob->id,
- DEPSNODE_TYPE_EVAL_POSE,
- DEPSOP_TYPE_INIT,
- function_bind(BKE_pose_eval_proxy_copy, _1, ob),
- DEG_OPCODE_POSE_INIT);
+ op_node = add_operation_node(&ob->id,
+ DEG_NODE_TYPE_EVAL_POSE,
+ function_bind(BKE_pose_eval_proxy_copy, _1, ob),
+ DEG_OPCODE_POSE_INIT);
+ op_node->set_as_entry();
LINKLIST_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
- add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
- DEPSOP_TYPE_INIT, NULL,
- DEG_OPCODE_BONE_LOCAL);
+ op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name,
+ NULL, DEG_OPCODE_BONE_LOCAL);
+ op_node->set_as_entry();
- add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
- DEPSOP_TYPE_EXEC, NULL,
- DEG_OPCODE_BONE_READY);
+ add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name,
+ NULL, DEG_OPCODE_BONE_READY);
- add_operation_node(&ob->id, DEPSNODE_TYPE_BONE, pchan->name,
- DEPSOP_TYPE_POST, NULL,
- DEG_OPCODE_BONE_DONE);
+ op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_BONE, pchan->name,
+ NULL, DEG_OPCODE_BONE_DONE);
+ op_node->set_as_exit();
}
- add_operation_node(&ob->id,
- DEPSNODE_TYPE_EVAL_POSE,
- DEPSOP_TYPE_POST,
- NULL,
- DEG_OPCODE_POSE_DONE);
+ op_node = add_operation_node(&ob->id, DEG_NODE_TYPE_EVAL_POSE,
+ NULL, DEG_OPCODE_POSE_DONE);
+ op_node->set_as_exit();
}
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
index 7dd694cb570..3249867e416 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_nodes_scene.cc
@@ -37,21 +37,21 @@
#include "MEM_guardedalloc.h"
-extern "C" {
+#include "BLI_utildefines.h"
#include "BLI_blenlib.h"
#include "BLI_string.h"
-#include "BLI_utildefines.h"
+extern "C" {
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BKE_main.h"
#include "BKE_node.h"
+} /* extern "C" */
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
-} /* extern "C" */
#include "intern/builder/deg_builder.h"
#include "intern/nodes/deg_node.h"
@@ -69,7 +69,7 @@ void DepsgraphNodeBuilder::build_scene(Main *bmain, Scene *scene)
add_id_node(&scene->id);
/* timesource */
- add_time_source(NULL);
+ add_time_source();
/* build subgraph for set, and link this in... */
// XXX: depending on how this goes, that scene itself could probably store its
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc
index f870a33fb68..59eb7ed8cf1 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_pchanmap.cc
@@ -33,10 +33,8 @@
#include <stdio.h>
#include <string.h>
-extern "C" {
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
-}
namespace DEG {
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
index 7f2c6d8d9a1..a1abcb96411 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.cc
@@ -38,10 +38,10 @@
#include "MEM_guardedalloc.h"
-extern "C" {
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_blenlib.h"
+extern "C" {
#include "DNA_action_types.h"
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
@@ -92,13 +92,13 @@ extern "C" {
#include "BKE_tracking.h"
#include "BKE_world.h"
-#include "DEG_depsgraph.h"
-#include "DEG_depsgraph_build.h"
-
#include "RNA_access.h"
#include "RNA_types.h"
} /* extern "C" */
+#include "DEG_depsgraph.h"
+#include "DEG_depsgraph_build.h"
+
#include "intern/builder/deg_builder.h"
#include "intern/builder/deg_builder_pchanmap.h"
@@ -113,6 +113,41 @@ extern "C" {
namespace DEG {
+namespace {
+
+struct BuilderWalkUserData {
+ DepsgraphRelationBuilder *builder;
+ Main *bmain;
+ Scene *scene;
+};
+
+static void modifier_walk(void *user_data,
+ struct Object * /*ob*/,
+ struct Object **obpoin,
+ int /*cb_flag*/)
+{
+ BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
+ if (*obpoin) {
+ data->builder->build_object(data->bmain, data->scene, *obpoin);
+ }
+}
+
+void constraint_walk(bConstraint * /*con*/,
+ ID **idpoin,
+ bool /*is_reference*/,
+ void *user_data)
+{
+ BuilderWalkUserData *data = (BuilderWalkUserData *)user_data;
+ if (*idpoin) {
+ ID *id = *idpoin;
+ if (GS(id->name) == ID_OB) {
+ data->builder->build_object(data->bmain, data->scene, (Object *)id);
+ }
+ }
+}
+
+} /* namespace */
+
/* ***************** */
/* Relations Builder */
@@ -163,13 +198,6 @@ DepsgraphRelationBuilder::DepsgraphRelationBuilder(Depsgraph *graph) :
{
}
-RootDepsNode *DepsgraphRelationBuilder::find_node(const RootKey &key) const
-{
- (void)key;
- BLI_assert(!"Doesn't seem to be correct");
- return m_graph->root_node;
-}
-
TimeSourceDepsNode *DepsgraphRelationBuilder::find_node(
const TimeSourceKey &key) const
{
@@ -178,7 +206,7 @@ TimeSourceDepsNode *DepsgraphRelationBuilder::find_node(
return NULL;
}
else {
- return m_graph->root_node->time_source;
+ return m_graph->time_source;
}
}
@@ -247,7 +275,7 @@ void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc,
const char *description)
{
if (timesrc && node_to) {
- m_graph->add_new_relation(timesrc, node_to, DEPSREL_TYPE_TIME, description);
+ m_graph->add_new_relation(timesrc, node_to, description);
}
else {
DEG_DEBUG_PRINTF("add_time_relation(%p = %s, %p = %s, %s) Failed\n",
@@ -260,17 +288,16 @@ void DepsgraphRelationBuilder::add_time_relation(TimeSourceDepsNode *timesrc,
void DepsgraphRelationBuilder::add_operation_relation(
OperationDepsNode *node_from,
OperationDepsNode *node_to,
- eDepsRelation_Type type,
const char *description)
{
if (node_from && node_to) {
- m_graph->add_new_relation(node_from, node_to, type, description);
+ m_graph->add_new_relation(node_from, node_to, description);
}
else {
- DEG_DEBUG_PRINTF("add_operation_relation(%p = %s, %p = %s, %d, %s) Failed\n",
+ DEG_DEBUG_PRINTF("add_operation_relation(%p = %s, %p = %s, %s) Failed\n",
node_from, (node_from) ? node_from->identifier().c_str() : "<None>",
node_to, (node_to) ? node_to->identifier().c_str() : "<None>",
- type, description);
+ description);
}
}
@@ -283,11 +310,11 @@ void DepsgraphRelationBuilder::add_collision_relations(const OperationKey &key,
{
Object *ob1 = collobjs[i];
- ComponentKey trf_key(&ob1->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(trf_key, key, DEPSREL_TYPE_STANDARD, name);
+ ComponentKey trf_key(&ob1->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(trf_key, key, name);
- ComponentKey coll_key(&ob1->id, DEPSNODE_TYPE_GEOMETRY);
- add_relation(coll_key, key, DEPSREL_TYPE_STANDARD, name);
+ ComponentKey coll_key(&ob1->id, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(coll_key, key, name);
}
if (collobjs)
@@ -301,31 +328,31 @@ void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key,
if (effectors) {
for (EffectorCache *eff = (EffectorCache *)effectors->first; eff; eff = eff->next) {
if (eff->ob != ob) {
- ComponentKey eff_key(&eff->ob->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, name);
+ ComponentKey eff_key(&eff->ob->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(eff_key, key, name);
}
if (eff->psys) {
if (eff->ob != ob) {
- ComponentKey eff_key(&eff->ob->id, DEPSNODE_TYPE_EVAL_PARTICLES);
- add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, name);
+ ComponentKey eff_key(&eff->ob->id, DEG_NODE_TYPE_EVAL_PARTICLES);
+ add_relation(eff_key, key, name);
/* TODO: remove this when/if EVAL_PARTICLES is sufficient for up to date particles */
- ComponentKey mod_key(&eff->ob->id, DEPSNODE_TYPE_GEOMETRY);
- add_relation(mod_key, key, DEPSREL_TYPE_STANDARD, name);
+ ComponentKey mod_key(&eff->ob->id, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(mod_key, key, name);
}
else if (eff->psys != psys) {
- OperationKey eff_key(&eff->ob->id, DEPSNODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, eff->psys->name);
- add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, name);
+ OperationKey eff_key(&eff->ob->id, DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, eff->psys->name);
+ add_relation(eff_key, key, name);
}
}
if (eff->pd->forcefield == PFIELD_SMOKEFLOW && eff->pd->f_source) {
- ComponentKey trf_key(&eff->pd->f_source->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(trf_key, key, DEPSREL_TYPE_STANDARD, "Smoke Force Domain");
+ ComponentKey trf_key(&eff->pd->f_source->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(trf_key, key, "Smoke Force Domain");
- ComponentKey eff_key(&eff->pd->f_source->id, DEPSNODE_TYPE_GEOMETRY);
- add_relation(eff_key, key, DEPSREL_TYPE_STANDARD, "Smoke Force Domain");
+ ComponentKey eff_key(&eff->pd->f_source->id, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(eff_key, key, "Smoke Force Domain");
}
if (add_absorption && (eff->pd->flag & PFIELD_VISIBILITY)) {
@@ -337,6 +364,11 @@ void DepsgraphRelationBuilder::add_forcefield_relations(const OperationKey &key,
pdEndEffectors(&effectors);
}
+Depsgraph *DepsgraphRelationBuilder::getGraph()
+{
+ return m_graph;
+}
+
/* **** Functions to build relations between entities **** */
void DepsgraphRelationBuilder::begin_build(Main *bmain)
@@ -363,17 +395,14 @@ void DepsgraphRelationBuilder::build_group(Main *bmain,
ID *group_id = &group->id;
bool group_done = (group_id->tag & LIB_TAG_DOIT) != 0;
OperationKey object_local_transform_key(&object->id,
- DEPSNODE_TYPE_TRANSFORM,
+ DEG_NODE_TYPE_TRANSFORM,
DEG_OPCODE_TRANSFORM_LOCAL);
LINKLIST_FOREACH (GroupObject *, go, &group->gobject) {
if (!group_done) {
build_object(bmain, scene, go->ob);
}
- ComponentKey dupli_transform_key(&go->ob->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(dupli_transform_key,
- object_local_transform_key,
- DEPSREL_TYPE_TRANSFORM,
- "Dupligroup");
+ ComponentKey dupli_transform_key(&go->ob->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(dupli_transform_key, object_local_transform_key, "Dupligroup");
}
group_id->tag |= LIB_TAG_DOIT;
}
@@ -387,13 +416,13 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o
/* Object Transforms */
eDepsOperation_Code base_op = (ob->parent) ? DEG_OPCODE_TRANSFORM_PARENT : DEG_OPCODE_TRANSFORM_LOCAL;
- OperationKey base_op_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, base_op);
+ OperationKey base_op_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, base_op);
- OperationKey local_transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL);
- OperationKey parent_transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_PARENT);
- OperationKey final_transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL);
+ OperationKey local_transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL);
+ OperationKey parent_transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_PARENT);
+ OperationKey final_transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL);
- OperationKey ob_ubereval_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_OBJECT_UBEREVAL);
+ OperationKey ob_ubereval_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_OBJECT_UBEREVAL);
/* parenting */
if (ob->parent != NULL) {
@@ -401,16 +430,28 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o
build_object_parent(ob);
/* local -> parent */
- add_relation(local_transform_key,
- parent_transform_key,
- DEPSREL_TYPE_COMPONENT_ORDER,
- "[ObLocal -> ObParent]");
+ add_relation(local_transform_key, parent_transform_key, "[ObLocal -> ObParent]");
+ }
+
+ if (ob->modifiers.first != NULL) {
+ BuilderWalkUserData data;
+ data.builder = this;
+ data.bmain = bmain;
+ data.scene = scene;
+ modifiers_foreachObjectLink(ob, modifier_walk, &data);
+ }
+ if (ob->constraints.first != NULL) {
+ BuilderWalkUserData data;
+ data.builder = this;
+ data.bmain = bmain;
+ data.scene = scene;
+ BKE_constraints_id_loop(&ob->constraints, constraint_walk, &data);
}
/* object constraints */
if (ob->constraints.first != NULL) {
OperationKey constraint_key(&ob->id,
- DEPSNODE_TYPE_TRANSFORM,
+ DEG_NODE_TYPE_TRANSFORM,
DEG_OPCODE_TRANSFORM_CONSTRAINTS);
/* constraint relations */
@@ -418,30 +459,18 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o
// XXX: this is broken
build_constraints(scene,
&ob->id,
- DEPSNODE_TYPE_TRANSFORM,
+ DEG_NODE_TYPE_TRANSFORM,
"",
&ob->constraints,
NULL);
/* operation order */
- add_relation(base_op_key,
- constraint_key,
- DEPSREL_TYPE_COMPONENT_ORDER,
- "[ObBase-> Constraint Stack]");
- add_relation(constraint_key,
- final_transform_key,
- DEPSREL_TYPE_COMPONENT_ORDER,
- "[ObConstraints -> Done]");
+ add_relation(base_op_key, constraint_key, "[ObBase-> Constraint Stack]");
+ add_relation(constraint_key, final_transform_key, "[ObConstraints -> Done]");
// XXX
- add_relation(constraint_key,
- ob_ubereval_key,
- DEPSREL_TYPE_COMPONENT_ORDER,
- "Temp Ubereval");
- add_relation(ob_ubereval_key,
- final_transform_key,
- DEPSREL_TYPE_COMPONENT_ORDER,
- "Temp Ubereval");
+ add_relation(constraint_key, ob_ubereval_key, "Temp Ubereval");
+ add_relation(ob_ubereval_key, final_transform_key, "Temp Ubereval");
}
else {
/* NOTE: Keep an eye here, we skip some relations here to "streamline"
@@ -452,31 +481,20 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o
/* Rigid body will hook up another node inbetween, so skip
* relation here to avoid transitive relation.
*/
- add_relation(base_op_key,
- ob_ubereval_key,
- DEPSREL_TYPE_COMPONENT_ORDER,
- "Temp Ubereval");
+ add_relation(base_op_key, ob_ubereval_key, "Temp Ubereval");
}
- add_relation(ob_ubereval_key,
- final_transform_key,
- DEPSREL_TYPE_COMPONENT_ORDER,
- "Temp Ubereval");
+ add_relation(ob_ubereval_key, final_transform_key, "Temp Ubereval");
}
-
/* AnimData */
build_animdata(&ob->id);
// XXX: This should be hooked up by the build_animdata code
if (needs_animdata_node(&ob->id)) {
- ComponentKey adt_key(&ob->id, DEPSNODE_TYPE_ANIMATION);
- add_relation(adt_key,
- local_transform_key,
- DEPSREL_TYPE_OPERATION,
- "Object Animation");
+ ComponentKey adt_key(&ob->id, DEG_NODE_TYPE_ANIMATION);
+ add_relation(adt_key, local_transform_key, "Object Animation");
}
-
/* object data */
if (ob->data) {
ID *obdata_id = (ID *)ob->data;
@@ -517,12 +535,9 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o
Key *key = BKE_key_from_object(ob);
if (key != NULL) {
- ComponentKey geometry_key((ID *)ob->data, DEPSNODE_TYPE_GEOMETRY);
- ComponentKey key_key(&key->id, DEPSNODE_TYPE_GEOMETRY);
- add_relation(key_key,
- geometry_key,
- DEPSREL_TYPE_GEOMETRY_EVAL,
- "Shapekeys");
+ ComponentKey geometry_key((ID *)ob->data, DEG_NODE_TYPE_GEOMETRY);
+ ComponentKey key_key(&key->id, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(key_key, geometry_key, "Shapekeys");
}
}
@@ -543,9 +558,9 @@ void DepsgraphRelationBuilder::build_object(Main *bmain, Scene *scene, Object *o
/* TODO(sergey): This is an inverted relation, matches old depsgraph
* behavior and need to be investigated if it still need to be inverted.
*/
- ComponentKey ob_pose_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE);
- ComponentKey proxy_pose_key(&ob->proxy->id, DEPSNODE_TYPE_EVAL_POSE);
- add_relation(ob_pose_key, proxy_pose_key, DEPSREL_TYPE_TRANSFORM, "Proxy");
+ ComponentKey ob_pose_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE);
+ ComponentKey proxy_pose_key(&ob->proxy->id, DEG_NODE_TYPE_EVAL_POSE);
+ add_relation(ob_pose_key, proxy_pose_key, "Proxy");
}
/* Object dupligroup. */
@@ -561,23 +576,23 @@ void DepsgraphRelationBuilder::build_object_parent(Object *ob)
*/
// XXX: @sergey - it would be good if we got that backwards flushing working
// when tagging for updates.
- //OperationKey ob_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_PARENT);
- ComponentKey ob_key(&ob->id, DEPSNODE_TYPE_TRANSFORM);
+ //OperationKey ob_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_PARENT);
+ ComponentKey ob_key(&ob->id, DEG_NODE_TYPE_TRANSFORM);
/* type-specific links */
switch (ob->partype) {
case PARSKEL: /* Armature Deform (Virtual Modifier) */
{
- ComponentKey parent_key(&ob->parent->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(parent_key, ob_key, DEPSREL_TYPE_STANDARD, "Armature Deform Parent");
+ ComponentKey parent_key(&ob->parent->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(parent_key, ob_key, "Armature Deform Parent");
break;
}
case PARVERT1: /* Vertex Parent */
case PARVERT3:
{
- ComponentKey parent_key(&ob->parent->id, DEPSNODE_TYPE_GEOMETRY);
- add_relation(parent_key, ob_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Vertex Parent");
+ ComponentKey parent_key(&ob->parent->id, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(parent_key, ob_key, "Vertex Parent");
/* XXX not sure what this is for or how you could be done properly - lukas */
OperationDepsNode *parent_node = find_operation_node(parent_key);
@@ -585,27 +600,21 @@ void DepsgraphRelationBuilder::build_object_parent(Object *ob)
parent_node->customdata_mask |= CD_MASK_ORIGINDEX;
}
- ComponentKey transform_key(&ob->parent->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(transform_key, ob_key, DEPSREL_TYPE_TRANSFORM, "Vertex Parent TFM");
+ ComponentKey transform_key(&ob->parent->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(transform_key, ob_key, "Vertex Parent TFM");
break;
}
case PARBONE: /* Bone Parent */
{
ComponentKey parent_bone_key(&ob->parent->id,
- DEPSNODE_TYPE_BONE,
+ DEG_NODE_TYPE_BONE,
ob->parsubstr);
OperationKey parent_transform_key(&ob->parent->id,
- DEPSNODE_TYPE_TRANSFORM,
+ DEG_NODE_TYPE_TRANSFORM,
DEG_OPCODE_TRANSFORM_FINAL);
- add_relation(parent_bone_key,
- ob_key,
- DEPSREL_TYPE_TRANSFORM,
- "Bone Parent");
- add_relation(parent_transform_key,
- ob_key,
- DEPSREL_TYPE_TRANSFORM,
- "Armature Parent");
+ add_relation(parent_bone_key, ob_key, "Bone Parent");
+ add_relation(parent_transform_key, ob_key, "Armature Parent");
break;
}
@@ -614,33 +623,33 @@ void DepsgraphRelationBuilder::build_object_parent(Object *ob)
if (ob->parent->type == OB_LATTICE) {
/* Lattice Deform Parent - Virtual Modifier */
// XXX: no virtual modifiers should be left!
- ComponentKey parent_key(&ob->parent->id, DEPSNODE_TYPE_TRANSFORM);
- ComponentKey geom_key(&ob->parent->id, DEPSNODE_TYPE_GEOMETRY);
+ ComponentKey parent_key(&ob->parent->id, DEG_NODE_TYPE_TRANSFORM);
+ ComponentKey geom_key(&ob->parent->id, DEG_NODE_TYPE_GEOMETRY);
- add_relation(parent_key, ob_key, DEPSREL_TYPE_STANDARD, "Lattice Deform Parent");
- add_relation(geom_key, ob_key, DEPSREL_TYPE_STANDARD, "Lattice Deform Parent Geom");
+ add_relation(parent_key, ob_key, "Lattice Deform Parent");
+ add_relation(geom_key, ob_key, "Lattice Deform Parent Geom");
}
else if (ob->parent->type == OB_CURVE) {
Curve *cu = (Curve *)ob->parent->data;
if (cu->flag & CU_PATH) {
/* Follow Path */
- ComponentKey parent_key(&ob->parent->id, DEPSNODE_TYPE_GEOMETRY);
- add_relation(parent_key, ob_key, DEPSREL_TYPE_TRANSFORM, "Curve Follow Parent");
+ ComponentKey parent_key(&ob->parent->id, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(parent_key, ob_key, "Curve Follow Parent");
- ComponentKey transform_key(&ob->parent->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(transform_key, ob_key, DEPSREL_TYPE_TRANSFORM, "Curve Follow TFM");
+ ComponentKey transform_key(&ob->parent->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(transform_key, ob_key, "Curve Follow TFM");
}
else {
/* Standard Parent */
- ComponentKey parent_key(&ob->parent->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(parent_key, ob_key, DEPSREL_TYPE_TRANSFORM, "Curve Parent");
+ ComponentKey parent_key(&ob->parent->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(parent_key, ob_key, "Curve Parent");
}
}
else {
/* Standard Parent */
- ComponentKey parent_key(&ob->parent->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(parent_key, ob_key, DEPSREL_TYPE_TRANSFORM, "Parent");
+ ComponentKey parent_key(&ob->parent->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(parent_key, ob_key, "Parent");
}
break;
}
@@ -656,7 +665,7 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode
ListBase *constraints, RootPChanMap *root_map)
{
OperationKey constraint_op_key(id, component_type, component_subdata,
- (component_type == DEPSNODE_TYPE_BONE) ? DEG_OPCODE_BONE_CONSTRAINTS : DEG_OPCODE_TRANSFORM_CONSTRAINTS);
+ (component_type == DEG_NODE_TYPE_BONE) ? DEG_OPCODE_BONE_CONSTRAINTS : DEG_OPCODE_TRANSFORM_CONSTRAINTS);
/* add dependencies for each constraint in turn */
for (bConstraint *con = (bConstraint *)constraints->first; con; con = con->next) {
@@ -679,8 +688,8 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode
if (data->depth_ob) {
// DAG_RL_DATA_OB | DAG_RL_OB_OB
- ComponentKey depth_key(&data->depth_ob->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(depth_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name);
+ ComponentKey depth_key(&data->depth_ob->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(depth_key, constraint_op_key, cti->name);
}
}
else if (cti->type == CONSTRAINT_TYPE_OBJECTSOLVER) {
@@ -689,24 +698,24 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode
if (depends_on_camera && scene->camera) {
// DAG_RL_DATA_OB | DAG_RL_OB_OB
- ComponentKey camera_key(&scene->camera->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(camera_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name);
+ ComponentKey camera_key(&scene->camera->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(camera_key, constraint_op_key, cti->name);
}
/* TODO(sergey): This is more a TimeSource -> MovieClip -> Constraint dependency chain. */
TimeSourceKey time_src_key;
- add_relation(time_src_key, constraint_op_key, DEPSREL_TYPE_TIME, "[TimeSrc -> Animation]");
+ add_relation(time_src_key, constraint_op_key, "[TimeSrc -> Animation]");
}
else if (cti->type == CONSTRAINT_TYPE_TRANSFORM_CACHE) {
/* TODO(kevin): This is more a TimeSource -> CacheFile -> Constraint dependency chain. */
TimeSourceKey time_src_key;
- add_relation(time_src_key, constraint_op_key, DEPSREL_TYPE_TIME, "[TimeSrc -> Animation]");
+ add_relation(time_src_key, constraint_op_key, "[TimeSrc -> Animation]");
bTransformCacheConstraint *data = (bTransformCacheConstraint *)con->data;
if (data->cache_file) {
- ComponentKey cache_key(&data->cache_file->id, DEPSNODE_TYPE_CACHE);
- add_relation(cache_key, constraint_op_key, DEPSREL_TYPE_CACHE, cti->name);
+ ComponentKey cache_key(&data->cache_file->id, DEG_NODE_TYPE_CACHE);
+ add_relation(cache_key, constraint_op_key, cti->name);
}
}
else if (cti->get_constraint_targets) {
@@ -723,8 +732,8 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode
}
else if (ELEM(con->type, CONSTRAINT_TYPE_FOLLOWPATH, CONSTRAINT_TYPE_CLAMPTO)) {
/* these constraints require path geometry data... */
- ComponentKey target_key(&ct->tar->id, DEPSNODE_TYPE_GEOMETRY);
- add_relation(target_key, constraint_op_key, DEPSREL_TYPE_GEOMETRY_EVAL, cti->name); // XXX: type = geom_transform
+ ComponentKey target_key(&ct->tar->id, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(target_key, constraint_op_key, cti->name); // XXX: type = geom_transform
// TODO: path dependency
}
else if ((ct->tar->type == OB_ARMATURE) && (ct->subtarget[0])) {
@@ -743,20 +752,20 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode
target_key_opcode = DEG_OPCODE_BONE_DONE;
}
- OperationKey target_key(&ct->tar->id, DEPSNODE_TYPE_BONE, ct->subtarget, target_key_opcode);
- add_relation(target_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name);
+ OperationKey target_key(&ct->tar->id, DEG_NODE_TYPE_BONE, ct->subtarget, target_key_opcode);
+ add_relation(target_key, constraint_op_key, cti->name);
}
else {
/* different armature - we can safely use the result of that */
- OperationKey target_key(&ct->tar->id, DEPSNODE_TYPE_BONE, ct->subtarget, DEG_OPCODE_BONE_DONE);
- add_relation(target_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name);
+ OperationKey target_key(&ct->tar->id, DEG_NODE_TYPE_BONE, ct->subtarget, DEG_OPCODE_BONE_DONE);
+ add_relation(target_key, constraint_op_key, cti->name);
}
}
else if (ELEM(ct->tar->type, OB_MESH, OB_LATTICE) && (ct->subtarget[0])) {
/* vertex group */
/* NOTE: for now, we don't need to represent vertex groups separately... */
- ComponentKey target_key(&ct->tar->id, DEPSNODE_TYPE_GEOMETRY);
- add_relation(target_key, constraint_op_key, DEPSREL_TYPE_GEOMETRY_EVAL, cti->name);
+ ComponentKey target_key(&ct->tar->id, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(target_key, constraint_op_key, cti->name);
if (ct->tar->type == OB_MESH) {
OperationDepsNode *node2 = find_operation_node(target_key);
@@ -767,12 +776,12 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode
}
else if (con->type == CONSTRAINT_TYPE_SHRINKWRAP) {
/* Constraints which requires the target object surface. */
- ComponentKey target_key(&ct->tar->id, DEPSNODE_TYPE_GEOMETRY);
- add_relation(target_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name);
+ ComponentKey target_key(&ct->tar->id, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(target_key, constraint_op_key, cti->name);
/* NOTE: obdata eval now doesn't necessarily depend on the object's transform... */
- ComponentKey target_transform_key(&ct->tar->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(target_transform_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name);
+ ComponentKey target_transform_key(&ct->tar->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(target_transform_key, constraint_op_key, cti->name);
}
else {
/* standard object relation */
@@ -784,19 +793,19 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode
* - If however it is a real self targetting case, just make it depend on the
* previous constraint (or the pre-constraint state)...
*/
- if ((ct->tar->type == OB_ARMATURE) && (component_type == DEPSNODE_TYPE_BONE)) {
- OperationKey target_key(&ct->tar->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL);
- add_relation(target_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name);
+ if ((ct->tar->type == OB_ARMATURE) && (component_type == DEG_NODE_TYPE_BONE)) {
+ OperationKey target_key(&ct->tar->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL);
+ add_relation(target_key, constraint_op_key, cti->name);
}
else {
- OperationKey target_key(&ct->tar->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL);
- add_relation(target_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name);
+ OperationKey target_key(&ct->tar->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL);
+ add_relation(target_key, constraint_op_key, cti->name);
}
}
else {
/* normal object dependency */
- OperationKey target_key(&ct->tar->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL);
- add_relation(target_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name);
+ OperationKey target_key(&ct->tar->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL);
+ add_relation(target_key, constraint_op_key, cti->name);
}
}
@@ -810,8 +819,8 @@ void DepsgraphRelationBuilder::build_constraints(Scene *scene, ID *id, eDepsNode
CONSTRAINT_TYPE_TRANSLIKE))
{
/* TODO(sergey): Add used space check. */
- ComponentKey target_transform_key(&ct->tar->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(target_transform_key, constraint_op_key, DEPSREL_TYPE_TRANSFORM, cti->name);
+ ComponentKey target_transform_key(&ct->tar->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(target_transform_key, constraint_op_key, cti->name);
}
}
@@ -829,13 +838,13 @@ void DepsgraphRelationBuilder::build_animdata(ID *id)
if (adt == NULL)
return;
- ComponentKey adt_key(id, DEPSNODE_TYPE_ANIMATION);
+ ComponentKey adt_key(id, DEG_NODE_TYPE_ANIMATION);
/* animation */
if (adt->action || adt->nla_tracks.first) {
/* wire up dependency to time source */
TimeSourceKey time_src_key;
- add_relation(time_src_key, adt_key, DEPSREL_TYPE_TIME, "[TimeSrc -> Animation]");
+ add_relation(time_src_key, adt_key, "[TimeSrc -> Animation]");
// XXX: Hook up specific update callbacks for special properties which may need it...
@@ -845,9 +854,9 @@ void DepsgraphRelationBuilder::build_animdata(ID *id)
/* drivers */
LINKLIST_FOREACH (FCurve *, fcu, &adt->drivers) {
OperationKey driver_key(id,
- DEPSNODE_TYPE_PARAMETERS,
+ DEG_NODE_TYPE_PARAMETERS,
DEG_OPCODE_DRIVER,
- fcu->rna_path,
+ fcu->rna_path ? fcu->rna_path : "",
fcu->array_index);
/* create the driver's relations to targets */
@@ -869,7 +878,8 @@ void DepsgraphRelationBuilder::build_animdata(ID *id)
FCurve *fcu_prev = NULL;
LINKLIST_FOREACH (FCurve *, fcu_candidate, &adt->drivers) {
/* Writing to different RNA paths is */
- if (!STREQ(fcu_candidate->rna_path, fcu->rna_path)) {
+ const char *rna_path = fcu->rna_path ? fcu->rna_path : "";
+ if (!STREQ(fcu_candidate->rna_path, rna_path)) {
continue;
}
/* We only do relation from previous fcurve to previous one. */
@@ -885,26 +895,22 @@ void DepsgraphRelationBuilder::build_animdata(ID *id)
}
if (fcu_prev != NULL) {
OperationKey prev_driver_key(id,
- DEPSNODE_TYPE_PARAMETERS,
+ DEG_NODE_TYPE_PARAMETERS,
DEG_OPCODE_DRIVER,
- fcu_prev->rna_path,
+ fcu_prev->rna_path ? fcu_prev->rna_path : "",
fcu_prev->array_index);
OperationKey driver_key(id,
- DEPSNODE_TYPE_PARAMETERS,
+ DEG_NODE_TYPE_PARAMETERS,
DEG_OPCODE_DRIVER,
- fcu->rna_path,
+ fcu->rna_path ? fcu->rna_path : "",
fcu->array_index);
- add_relation(prev_driver_key,
- driver_key,
- DEPSREL_TYPE_OPERATION,
- "[Driver Order]");
+ add_relation(prev_driver_key, driver_key, "[Driver Order]");
}
}
/* prevent driver from occurring before own animation... */
if (adt->action || adt->nla_tracks.first) {
- add_relation(adt_key, driver_key, DEPSREL_TYPE_OPERATION,
- "[AnimData Before Drivers]");
+ add_relation(adt_key, driver_key, "[AnimData Before Drivers]");
}
}
}
@@ -913,26 +919,28 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
{
ChannelDriver *driver = fcu->driver;
OperationKey driver_key(id,
- DEPSNODE_TYPE_PARAMETERS,
+ DEG_NODE_TYPE_PARAMETERS,
DEG_OPCODE_DRIVER,
- fcu->rna_path,
+ fcu->rna_path ? fcu->rna_path : "",
fcu->array_index);
bPoseChannel *pchan = NULL;
+ const char *rna_path = fcu->rna_path ? fcu->rna_path : "";
+
/* create dependency between driver and data affected by it */
/* - direct property relationship... */
//RNAPathKey affected_key(id, fcu->rna_path);
- //add_relation(driver_key, affected_key, DEPSREL_TYPE_DRIVER, "[Driver -> Data] DepsRel");
+ //add_relation(driver_key, affected_key, "[Driver -> Data] DepsRel");
/* driver -> data components (for interleaved evaluation - bones/constraints/modifiers) */
// XXX: this probably should probably be moved out into a separate function
- if (strstr(fcu->rna_path, "pose.bones[") != NULL) {
+ if (strstr(rna_path, "pose.bones[") != NULL) {
/* interleaved drivers during bone eval */
// TODO: ideally, if this is for a constraint, it goes to said constraint
Object *ob = (Object *)id;
char *bone_name;
- bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
+ bone_name = BLI_str_quoted_substrN(rna_path, "pose.bones[");
pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
if (bone_name) {
@@ -941,21 +949,21 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
}
if (pchan) {
- OperationKey bone_key(id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
- add_relation(driver_key, bone_key, DEPSREL_TYPE_DRIVER, "[Driver -> Bone]");
+ OperationKey bone_key(id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
+ add_relation(driver_key, bone_key, "[Driver -> Bone]");
}
else {
fprintf(stderr,
"Couldn't find bone name for driver path - '%s'\n",
- fcu->rna_path);
+ rna_path);
}
}
- else if (GS(id->name) == ID_AR && strstr(fcu->rna_path, "bones[")) {
+ else if (GS(id->name) == ID_AR && strstr(rna_path, "bones[")) {
/* drivers on armature-level bone settings (i.e. bbone stuff),
* which will affect the evaluation of corresponding pose bones
*/
IDDepsNode *arm_node = m_graph->find_id_node(id);
- char *bone_name = BLI_str_quoted_substrN(fcu->rna_path, "bones[");
+ char *bone_name = BLI_str_quoted_substrN(rna_path, "bones[");
if (arm_node && bone_name) {
/* find objects which use this, and make their eval callbacks depend on this */
@@ -968,8 +976,8 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, bone_name); // NOTE: ob->pose may be NULL
if (pchan) {
- OperationKey bone_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
- add_relation(driver_key, bone_key, DEPSREL_TYPE_DRIVER, "[Arm Bone -> Driver -> Bone]");
+ OperationKey bone_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
+ add_relation(driver_key, bone_key, "[Arm Bone -> Driver -> Bone]");
}
}
}
@@ -981,48 +989,39 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
else {
fprintf(stderr,
"Couldn't find armature bone name for driver path - '%s'\n",
- fcu->rna_path);
+ rna_path);
}
}
- else if (GS(id->name) == ID_OB && strstr(fcu->rna_path, "modifiers[")) {
- /* modifier driver - connect directly to the modifier */
- char *modifier_name = BLI_str_quoted_substrN(fcu->rna_path, "modifiers[");
- if (modifier_name) {
- OperationKey modifier_key(id,
- DEPSNODE_TYPE_GEOMETRY,
- DEG_OPCODE_GEOMETRY_MODIFIER,
- modifier_name);
- if (has_node(modifier_key)) {
- add_relation(driver_key, modifier_key, DEPSREL_TYPE_DRIVER, "[Driver -> Modifier]");
- }
- else {
- printf("Unexisting driver RNA path: %s\n", fcu->rna_path);
- }
-
- MEM_freeN(modifier_name);
+ else if (GS(id->name) == ID_OB && strstr(rna_path, "modifiers[")) {
+ OperationKey modifier_key(id, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_UBEREVAL);
+ if (has_node(modifier_key)) {
+ add_relation(driver_key, modifier_key, "[Driver -> Modifier]");
+ }
+ else {
+ printf("Unexisting driver RNA path: %s\n", rna_path);
}
}
- else if (GS(id->name) == ID_KE && strstr(fcu->rna_path, "key_blocks[")) {
+ else if (GS(id->name) == ID_KE && strstr(rna_path, "key_blocks[")) {
/* shape key driver - hook into the base geometry operation */
// XXX: double check where this points
Key *shape_key = (Key *)id;
- ComponentKey geometry_key(shape_key->from, DEPSNODE_TYPE_GEOMETRY);
- add_relation(driver_key, geometry_key, DEPSREL_TYPE_DRIVER, "[Driver -> ShapeKey Geom]");
+ ComponentKey geometry_key(shape_key->from, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(driver_key, geometry_key, "[Driver -> ShapeKey Geom]");
}
- else if (strstr(fcu->rna_path, "key_blocks[")) {
- ComponentKey geometry_key(id, DEPSNODE_TYPE_GEOMETRY);
- add_relation(driver_key, geometry_key, DEPSREL_TYPE_DRIVER, "[Driver -> ShapeKey Geom]");
+ else if (strstr(rna_path, "key_blocks[")) {
+ ComponentKey geometry_key(id, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(driver_key, geometry_key, "[Driver -> ShapeKey Geom]");
}
else {
if (GS(id->name) == ID_OB) {
/* assume that driver affects a transform... */
- OperationKey local_transform_key(id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL);
- add_relation(driver_key, local_transform_key, DEPSREL_TYPE_OPERATION, "[Driver -> Transform]");
+ OperationKey local_transform_key(id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_LOCAL);
+ add_relation(driver_key, local_transform_key, "[Driver -> Transform]");
}
else if (GS(id->name) == ID_KE) {
- ComponentKey geometry_key(id, DEPSNODE_TYPE_GEOMETRY);
- add_relation(driver_key, geometry_key, DEPSREL_TYPE_GEOMETRY_EVAL, "[Driver -> Shapekey Geometry]");
+ ComponentKey geometry_key(id, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(driver_key, geometry_key, "[Driver -> Shapekey Geometry]");
}
}
@@ -1055,14 +1054,14 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
{
continue;
}
- OperationKey target_key(dtar->id, DEPSNODE_TYPE_BONE, target_pchan->name, DEG_OPCODE_BONE_DONE);
- add_relation(target_key, driver_key, DEPSREL_TYPE_DRIVER_TARGET, "[Bone Target -> Driver]");
+ OperationKey target_key(dtar->id, DEG_NODE_TYPE_BONE, target_pchan->name, DEG_OPCODE_BONE_DONE);
+ add_relation(target_key, driver_key, "[Bone Target -> Driver]");
}
}
else if (dtar->flag & DTAR_FLAG_STRUCT_REF) {
/* get node associated with the object's transforms */
- OperationKey target_key(dtar->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL);
- add_relation(target_key, driver_key, DEPSREL_TYPE_DRIVER_TARGET, "[Target -> Driver]");
+ OperationKey target_key(dtar->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_FINAL);
+ add_relation(target_key, driver_key, "[Target -> Driver]");
}
else if (dtar->rna_path && strstr(dtar->rna_path, "pose.bones[")) {
/* workaround for ensuring that local bone transforms don't end up
@@ -1082,8 +1081,8 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
{
continue;
}
- OperationKey bone_key(dtar->id, DEPSNODE_TYPE_BONE, target_pchan->name, DEG_OPCODE_BONE_LOCAL);
- add_relation(bone_key, driver_key, DEPSREL_TYPE_DRIVER, "[RNA Bone -> Driver]");
+ OperationKey bone_key(dtar->id, DEG_NODE_TYPE_BONE, target_pchan->name, DEG_OPCODE_BONE_LOCAL);
+ add_relation(bone_key, driver_key, "[RNA Bone -> Driver]");
}
}
else {
@@ -1095,7 +1094,7 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
}
/* resolve path to get node */
RNAPathKey target_key(dtar->id, dtar->rna_path ? dtar->rna_path : "");
- add_relation(target_key, driver_key, DEPSREL_TYPE_DRIVER_TARGET, "[RNA Target -> Driver]");
+ add_relation(target_key, driver_key, "[RNA Target -> Driver]");
}
}
DRIVER_TARGETS_LOOPER_END
@@ -1109,7 +1108,7 @@ void DepsgraphRelationBuilder::build_driver(ID *id, FCurve *fcu)
python_driver_depends_on_time(driver))
{
TimeSourceKey time_src_key;
- add_relation(time_src_key, driver_key, DEPSREL_TYPE_TIME, "[TimeSrc -> Driver]");
+ add_relation(time_src_key, driver_key, "[TimeSrc -> Driver]");
}
}
@@ -1129,27 +1128,29 @@ void DepsgraphRelationBuilder::build_world(World *world)
build_texture_stack(world->mtex);
/* world's nodetree */
- build_nodetree(world->nodetree);
+ if (world->nodetree != NULL) {
+ build_nodetree(world->nodetree);
+ ComponentKey ntree_key(&world->nodetree->id, DEG_NODE_TYPE_PARAMETERS);
+ ComponentKey world_key(world_id, DEG_NODE_TYPE_PARAMETERS);
+ add_relation(ntree_key, world_key, "NTree->World Parameters");
+ }
}
void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
{
RigidBodyWorld *rbw = scene->rigidbody_world;
- OperationKey init_key(&scene->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_RIGIDBODY_REBUILD);
- OperationKey sim_key(&scene->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_RIGIDBODY_SIM);
+ OperationKey init_key(&scene->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_RIGIDBODY_REBUILD);
+ OperationKey sim_key(&scene->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_RIGIDBODY_SIM);
/* rel between the two sim-nodes */
- add_relation(init_key, sim_key, DEPSREL_TYPE_OPERATION, "Rigidbody [Init -> SimStep]");
+ add_relation(init_key, sim_key, "Rigidbody [Init -> SimStep]");
/* set up dependencies between these operations and other builtin nodes --------------- */
/* time dependency */
TimeSourceKey time_src_key;
- add_relation(time_src_key,
- init_key,
- DEPSREL_TYPE_TIME,
- "TimeSrc -> Rigidbody Reset/Rebuild (Optional)");
+ add_relation(time_src_key, init_key, "TimeSrc -> Rigidbody Reset/Rebuild (Optional)");
/* objects - simulation participants */
if (rbw->group) {
@@ -1167,12 +1168,12 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
* XXX: there's probably a difference between passive and active
* - passive don't change, so may need to know full transform...
*/
- OperationKey rbo_key(&ob->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY);
+ OperationKey rbo_key(&ob->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY);
eDepsOperation_Code trans_opcode = ob->parent ? DEG_OPCODE_TRANSFORM_PARENT : DEG_OPCODE_TRANSFORM_LOCAL;
- OperationKey trans_op(&ob->id, DEPSNODE_TYPE_TRANSFORM, trans_opcode);
+ OperationKey trans_op(&ob->id, DEG_NODE_TYPE_TRANSFORM, trans_opcode);
- add_relation(sim_key, rbo_key, DEPSREL_TYPE_COMPONENT_ORDER, "Rigidbody Sim Eval -> RBO Sync");
+ add_relation(sim_key, rbo_key, "Rigidbody Sim Eval -> RBO Sync");
/* if constraints exist, those depend on the result of the rigidbody sim
* - This allows constraints to modify the result of the sim (i.e. clamping)
@@ -1184,12 +1185,9 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
*/
if (ob->constraints.first) {
OperationKey constraint_key(&ob->id,
- DEPSNODE_TYPE_TRANSFORM,
+ DEG_NODE_TYPE_TRANSFORM,
DEG_OPCODE_TRANSFORM_CONSTRAINTS);
- add_relation(rbo_key,
- constraint_key,
- DEPSREL_TYPE_COMPONENT_ORDER,
- "RBO Sync -> Ob Constraints");
+ add_relation(rbo_key, constraint_key, "RBO Sync -> Ob Constraints");
}
else {
/* Final object transform depends on rigidbody.
@@ -1198,19 +1196,13 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
* If it is gone we'll need to reconsider relation here.
*/
OperationKey uber_key(&ob->id,
- DEPSNODE_TYPE_TRANSFORM,
+ DEG_NODE_TYPE_TRANSFORM,
DEG_OPCODE_OBJECT_UBEREVAL);
- add_relation(rbo_key,
- uber_key,
- DEPSREL_TYPE_COMPONENT_ORDER,
- "RBO Sync -> Uber (Temp)");
+ add_relation(rbo_key, uber_key, "RBO Sync -> Uber (Temp)");
}
/* Needed to get correct base values. */
- add_relation(trans_op,
- sim_key,
- DEPSREL_TYPE_OPERATION,
- "Base Ob Transform -> Rigidbody Sim Eval");
+ add_relation(trans_op, sim_key, "Base Ob Transform -> Rigidbody Sim Eval");
}
}
@@ -1227,16 +1219,16 @@ void DepsgraphRelationBuilder::build_rigidbody(Scene *scene)
/* final result of the constraint object's transform controls how the
* constraint affects the physics sim for these objects
*/
- ComponentKey trans_key(&ob->id, DEPSNODE_TYPE_TRANSFORM);
- OperationKey ob1_key(&rbc->ob1->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY);
- OperationKey ob2_key(&rbc->ob2->id, DEPSNODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY);
+ ComponentKey trans_key(&ob->id, DEG_NODE_TYPE_TRANSFORM);
+ OperationKey ob1_key(&rbc->ob1->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY);
+ OperationKey ob2_key(&rbc->ob2->id, DEG_NODE_TYPE_TRANSFORM, DEG_OPCODE_TRANSFORM_RIGIDBODY);
/* - constrained-objects sync depends on the constraint-holder */
- add_relation(trans_key, ob1_key, DEPSREL_TYPE_TRANSFORM, "RigidBodyConstraint -> RBC.Object_1");
- add_relation(trans_key, ob2_key, DEPSREL_TYPE_TRANSFORM, "RigidBodyConstraint -> RBC.Object_2");
+ add_relation(trans_key, ob1_key, "RigidBodyConstraint -> RBC.Object_1");
+ add_relation(trans_key, ob2_key, "RigidBodyConstraint -> RBC.Object_2");
/* - ensure that sim depends on this constraint's transform */
- add_relation(trans_key, sim_key, DEPSREL_TYPE_TRANSFORM, "RigidBodyConstraint Transform -> RB Simulation");
+ add_relation(trans_key, sim_key, "RigidBodyConstraint Transform -> RB Simulation");
}
}
}
@@ -1245,8 +1237,15 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob)
{
TimeSourceKey time_src_key;
OperationKey obdata_ubereval_key(&ob->id,
- DEPSNODE_TYPE_GEOMETRY,
+ DEG_NODE_TYPE_GEOMETRY,
DEG_OPCODE_GEOMETRY_UBEREVAL);
+ OperationKey eval_init_key(&ob->id,
+ DEG_NODE_TYPE_EVAL_PARTICLES,
+ DEG_OPCODE_PSYS_EVAL_INIT);
+ /* TODO(sergey): Are all particle systems depends on time?
+ * Hair without dynamics i.e.
+ */
+ add_relation(time_src_key, eval_init_key, "TimeSrc -> PSys");
/* particle systems */
LINKLIST_FOREACH (ParticleSystem *, psys, &ob->particlesystem) {
@@ -1256,55 +1255,19 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob)
build_animdata(&part->id);
/* this particle system */
- OperationKey psys_key(&ob->id, DEPSNODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, psys->name);
+ OperationKey psys_key(&ob->id, DEG_NODE_TYPE_EVAL_PARTICLES, DEG_OPCODE_PSYS_EVAL, psys->name);
/* XXX: if particle system is later re-enabled, we must do full rebuild? */
if (!psys_check_enabled(ob, psys, G.is_rendering))
continue;
- /* TODO(sergey): Are all particle systems depends on time?
- * Hair without dynamics i.e.
- */
- add_relation(time_src_key, psys_key,
- DEPSREL_TYPE_TIME,
- "TimeSrc -> PSys");
+ add_relation(eval_init_key, psys_key, "Init -> PSys");
/* TODO(sergey): Currently particle update is just a placeholder,
* hook it to the ubereval node so particle system is getting updated
* on playback.
*/
- add_relation(psys_key,
- obdata_ubereval_key,
- DEPSREL_TYPE_OPERATION,
- "PSys -> UberEval");
-
-#if 0
- if (ELEM(part->phystype, PART_PHYS_KEYED, PART_PHYS_BOIDS)) {
- LINKLIST_FOREACH (ParticleTarget *, pt, &psys->targets) {
- if (pt->ob && BLI_findlink(&pt->ob->particlesystem, pt->psys - 1)) {
- node2 = dag_get_node(dag, pt->ob);
- dag_add_relation(dag, node2, node, DAG_RL_DATA_DATA | DAG_RL_OB_DATA, "Particle Targets");
- }
- }
- }
-
- if (part->ren_as == PART_DRAW_OB && part->dup_ob) {
- node2 = dag_get_node(dag, part->dup_ob);
- /* note that this relation actually runs in the wrong direction, the problem
- * is that dupli system all have this (due to parenting), and the render
- * engine instancing assumes particular ordering of objects in list */
- dag_add_relation(dag, node, node2, DAG_RL_OB_OB, "Particle Object Visualization");
- if (part->dup_ob->type == OB_MBALL)
- dag_add_relation(dag, node, node2, DAG_RL_DATA_DATA, "Particle Object Visualization");
- }
-
- if (part->ren_as == PART_DRAW_GR && part->dup_group) {
- LINKLIST_FOREACH (GroupObject *, go, &part->dup_group->gobject) {
- node2 = dag_get_node(dag, go->ob);
- dag_add_relation(dag, node2, node, DAG_RL_OB_OB, "Particle Group Visualization");
- }
- }
-#endif
+ add_relation(psys_key, obdata_ubereval_key, "PSys -> UberEval");
/* collisions */
if (part->type != PART_HAIR) {
@@ -1328,19 +1291,16 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob)
ruleob = ((BoidRuleFollowLeader *)rule)->ob;
if (ruleob) {
- ComponentKey ruleob_key(&ruleob->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(ruleob_key, psys_key, DEPSREL_TYPE_TRANSFORM, "Boid Rule");
+ ComponentKey ruleob_key(&ruleob->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(ruleob_key, psys_key, "Boid Rule");
}
}
}
}
if (part->ren_as == PART_DRAW_OB && part->dup_ob) {
- ComponentKey dup_ob_key(&part->dup_ob->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(dup_ob_key,
- psys_key,
- DEPSREL_TYPE_TRANSFORM,
- "Particle Object Visualization");
+ ComponentKey dup_ob_key(&part->dup_ob->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(dup_ob_key, psys_key, "Particle Object Visualization");
}
}
@@ -1350,11 +1310,8 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob)
* TODO(sergey): This relation should be altered once real granular update
* is implemented.
*/
- ComponentKey transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(transform_key,
- obdata_ubereval_key,
- DEPSREL_TYPE_GEOMETRY_EVAL,
- "Partcile Eval");
+ ComponentKey transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(transform_key, obdata_ubereval_key, "Partcile Eval");
/* pointcache */
// TODO...
@@ -1362,27 +1319,23 @@ void DepsgraphRelationBuilder::build_particles(Scene *scene, Object *ob)
void DepsgraphRelationBuilder::build_cloth(Scene * /*scene*/,
Object *object,
- ModifierData *md)
+ ModifierData * /*md*/)
{
OperationKey cache_key(&object->id,
- DEPSNODE_TYPE_CACHE,
+ DEG_NODE_TYPE_CACHE,
DEG_OPCODE_PLACEHOLDER,
"Cloth Modifier");
/* Cache component affects on modifier. */
OperationKey modifier_key(&object->id,
- DEPSNODE_TYPE_GEOMETRY,
- DEG_OPCODE_GEOMETRY_MODIFIER,
- md->name);
- add_relation(cache_key,
- modifier_key,
- DEPSREL_TYPE_TIME,
- "Cloth Cache -> Cloth");
+ DEG_NODE_TYPE_GEOMETRY,
+ DEG_OPCODE_GEOMETRY_UBEREVAL);
+ add_relation(cache_key, modifier_key, "Cloth Cache -> Cloth");
}
/* Shapekeys */
void DepsgraphRelationBuilder::build_shapekeys(ID *obdata, Key *key)
{
- ComponentKey obdata_key(obdata, DEPSNODE_TYPE_GEOMETRY);
+ ComponentKey obdata_key(obdata, DEG_NODE_TYPE_GEOMETRY);
/* attach animdata to geometry */
build_animdata(&key->id);
@@ -1390,8 +1343,8 @@ void DepsgraphRelationBuilder::build_shapekeys(ID *obdata, Key *key)
if (key->adt) {
// TODO: this should really be handled in build_animdata, since many of these cases will need it
if (key->adt->action || key->adt->nla_tracks.first) {
- ComponentKey adt_key(&key->id, DEPSNODE_TYPE_ANIMATION);
- add_relation(adt_key, obdata_key, DEPSREL_TYPE_OPERATION, "Animation");
+ ComponentKey adt_key(&key->id, DEG_NODE_TYPE_ANIMATION);
+ add_relation(adt_key, obdata_key, "Animation");
}
/* NOTE: individual shapekey drivers are handled above already */
@@ -1399,8 +1352,8 @@ void DepsgraphRelationBuilder::build_shapekeys(ID *obdata, Key *key)
/* attach to geometry */
// XXX: aren't shapekeys now done as a pseudo-modifier on object?
- //ComponentKey key_key(&key->id, DEPSNODE_TYPE_GEOMETRY); // FIXME: this doesn't exist
- //add_relation(key_key, obdata_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Shapekeys");
+ //ComponentKey key_key(&key->id, DEG_NODE_TYPE_GEOMETRY); // FIXME: this doesn't exist
+ //add_relation(key_key, obdata_key, "Shapekeys");
}
/**
@@ -1428,34 +1381,26 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje
ID *obdata = (ID *)ob->data;
/* Init operation of object-level geometry evaluation. */
- OperationKey geom_init_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Eval Init");
+ OperationKey geom_init_key(&ob->id, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Eval Init");
/* get nodes for result of obdata's evaluation, and geometry evaluation on object */
- ComponentKey obdata_geom_key(obdata, DEPSNODE_TYPE_GEOMETRY);
- ComponentKey geom_key(&ob->id, DEPSNODE_TYPE_GEOMETRY);
+ ComponentKey obdata_geom_key(obdata, DEG_NODE_TYPE_GEOMETRY);
+ ComponentKey geom_key(&ob->id, DEG_NODE_TYPE_GEOMETRY);
/* link components to each other */
- add_relation(obdata_geom_key, geom_key, DEPSREL_TYPE_DATABLOCK, "Object Geometry Base Data");
+ add_relation(obdata_geom_key, geom_key, "Object Geometry Base Data");
/* Modifiers */
- if (ob->modifiers.first) {
- OperationKey prev_mod_key;
+ if (ob->modifiers.first != NULL) {
+ OperationKey obdata_ubereval_key(&ob->id,
+ DEG_NODE_TYPE_GEOMETRY,
+ DEG_OPCODE_GEOMETRY_UBEREVAL);
LINKLIST_FOREACH (ModifierData *, md, &ob->modifiers) {
const ModifierTypeInfo *mti = modifierType_getInfo((ModifierType)md->type);
- OperationKey mod_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_MODIFIER, md->name);
-
- if (md->prev) {
- /* Stack relation: modifier depends on previous modifier in the stack */
- add_relation(prev_mod_key, mod_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Modifier Stack");
- }
- else {
- /* Stack relation: first modifier depends on the geometry. */
- add_relation(geom_init_key, mod_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Modifier Stack");
- }
if (mti->updateDepsgraph) {
- DepsNodeHandle handle = create_node_handle(mod_key);
+ DepsNodeHandle handle = create_node_handle(obdata_ubereval_key);
mti->updateDepsgraph(
md,
bmain,
@@ -1466,7 +1411,7 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje
if (BKE_object_modifier_use_time(ob, md)) {
TimeSourceKey time_src_key;
- add_relation(time_src_key, mod_key, DEPSREL_TYPE_TIME, "Time Source");
+ add_relation(time_src_key, obdata_ubereval_key, "Time Source");
/* Hacky fix for T45633 (Animated modifiers aren't updated)
*
@@ -1475,32 +1420,23 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje
*/
/* XXX: Remove this hack when these links are added as part of build_animdata() instead */
if (modifier_dependsOnTime(md) == false && needs_animdata_node(&ob->id)) {
- ComponentKey animation_key(&ob->id, DEPSNODE_TYPE_ANIMATION);
- add_relation(animation_key, mod_key, DEPSREL_TYPE_OPERATION, "Modifier Animation");
+ ComponentKey animation_key(&ob->id, DEG_NODE_TYPE_ANIMATION);
+ add_relation(animation_key, obdata_ubereval_key, "Modifier Animation");
}
}
if (md->type == eModifierType_Cloth) {
build_cloth(scene, ob, md);
}
-
- prev_mod_key = mod_key;
}
}
/* materials */
- if (ob->totcol != 0) {
- ComponentKey object_shading_key(&ob->id, DEPSNODE_TYPE_SHADING);
+ if (ob->totcol) {
for (int a = 1; a <= ob->totcol; a++) {
Material *ma = give_current_material(ob, a);
if (ma != NULL) {
build_material(ma);
- ComponentKey material_shading_key(&ma->id,
- DEPSNODE_TYPE_SHADING);
- add_relation(material_shading_key,
- object_shading_key,
- DEPSREL_TYPE_UPDATE,
- "Object Shading");
}
}
}
@@ -1516,15 +1452,8 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje
*/
if (ob->type != OB_ARMATURE) {
/* Armatures does no longer require uber node. */
- OperationKey obdata_ubereval_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_UBEREVAL);
- if (ob->modifiers.last) {
- ModifierData *md = (ModifierData *)ob->modifiers.last;
- OperationKey mod_key(&ob->id, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_MODIFIER, md->name);
- add_relation(mod_key, obdata_ubereval_key, DEPSREL_TYPE_OPERATION, "Object Geometry UberEval");
- }
- else {
- add_relation(geom_init_key, obdata_ubereval_key, DEPSREL_TYPE_OPERATION, "Object Geometry UberEval");
- }
+ OperationKey obdata_ubereval_key(&ob->id, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_UBEREVAL);
+ add_relation(geom_init_key, obdata_ubereval_key, "Object Geometry UberEval");
}
if (obdata->tag & LIB_TAG_DOIT) {
@@ -1533,13 +1462,26 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje
obdata->tag |= LIB_TAG_DOIT;
/* Link object data evaluation node to exit operation. */
- OperationKey obdata_geom_eval_key(obdata, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Geometry Eval");
- OperationKey obdata_geom_done_key(obdata, DEPSNODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Eval Done");
- add_relation(obdata_geom_eval_key, obdata_geom_done_key, DEPSREL_TYPE_DATABLOCK, "ObData Geom Eval Done");
+ OperationKey obdata_geom_eval_key(obdata, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Geometry Eval");
+ OperationKey obdata_geom_done_key(obdata, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_PLACEHOLDER, "Eval Done");
+ add_relation(obdata_geom_eval_key, obdata_geom_done_key, "ObData Geom Eval Done");
/* type-specific node/links */
switch (ob->type) {
case OB_MESH:
+ /* NOTE: This is compatibility code to support particle systems
+ *
+ * for viewport being properly rendered in final render mode.
+ * This relation is similar to what dag_object_time_update_flags()
+ * was doing for mesh objects with particle system/
+ *
+ * Ideally we need to get rid of this relation.
+ */
+ if (ob->particlesystem.first != NULL) {
+ TimeSourceKey time_key;
+ OperationKey obdata_ubereval_key(&ob->id, DEG_NODE_TYPE_GEOMETRY, DEG_OPCODE_GEOMETRY_UBEREVAL);
+ add_relation(time_key, obdata_ubereval_key, "Legacy particle time");
+ }
break;
case OB_MBALL:
@@ -1549,10 +1491,10 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje
/* motherball - mom depends on children! */
if (mom != ob) {
/* non-motherball -> cannot be directly evaluated! */
- ComponentKey mom_key(&mom->id, DEPSNODE_TYPE_GEOMETRY);
- ComponentKey transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(geom_key, mom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Metaball Motherball");
- add_relation(transform_key, mom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Metaball Motherball");
+ ComponentKey mom_key(&mom->id, DEG_NODE_TYPE_GEOMETRY);
+ ComponentKey transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(geom_key, mom_key, "Metaball Motherball");
+ add_relation(transform_key, mom_key, "Metaball Motherball");
}
break;
}
@@ -1565,20 +1507,20 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje
/* curve's dependencies */
// XXX: these needs geom data, but where is geom stored?
if (cu->bevobj) {
- ComponentKey bevob_key(&cu->bevobj->id, DEPSNODE_TYPE_GEOMETRY);
+ ComponentKey bevob_key(&cu->bevobj->id, DEG_NODE_TYPE_GEOMETRY);
build_object(bmain, scene, cu->bevobj);
- add_relation(bevob_key, geom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Curve Bevel");
+ add_relation(bevob_key, geom_key, "Curve Bevel");
}
if (cu->taperobj) {
- ComponentKey taperob_key(&cu->taperobj->id, DEPSNODE_TYPE_GEOMETRY);
+ ComponentKey taperob_key(&cu->taperobj->id, DEG_NODE_TYPE_GEOMETRY);
build_object(bmain, scene, cu->taperobj);
- add_relation(taperob_key, geom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Curve Taper");
+ add_relation(taperob_key, geom_key, "Curve Taper");
}
if (ob->type == OB_FONT) {
if (cu->textoncurve) {
- ComponentKey textoncurve_key(&cu->textoncurve->id, DEPSNODE_TYPE_GEOMETRY);
+ ComponentKey textoncurve_key(&cu->textoncurve->id, DEG_NODE_TYPE_GEOMETRY);
build_object(bmain, scene, cu->textoncurve);
- add_relation(textoncurve_key, geom_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Text on Curve");
+ add_relation(textoncurve_key, geom_key, "Text on Curve");
}
}
break;
@@ -1602,14 +1544,13 @@ void DepsgraphRelationBuilder::build_obdata_geom(Main *bmain, Scene *scene, Obje
}
if (needs_animdata_node(obdata)) {
- ComponentKey animation_key(obdata, DEPSNODE_TYPE_ANIMATION);
- ComponentKey parameters_key(obdata, DEPSNODE_TYPE_PARAMETERS);
- add_relation(animation_key, parameters_key,
- DEPSREL_TYPE_COMPONENT_ORDER, "Geom Parameters");
+ ComponentKey animation_key(obdata, DEG_NODE_TYPE_ANIMATION);
+ ComponentKey parameters_key(obdata, DEG_NODE_TYPE_PARAMETERS);
+ add_relation(animation_key, parameters_key, "Geom Parameters");
/* Evaluation usually depends on animation.
* TODO(sergey): Need to re-hook it after granular update is implemented..
*/
- add_relation(animation_key, obdata_geom_eval_key, DEPSREL_TYPE_GEOMETRY_EVAL, "Animation");
+ add_relation(animation_key, obdata_geom_eval_key, "Animation");
}
}
@@ -1624,19 +1565,18 @@ void DepsgraphRelationBuilder::build_camera(Object *ob)
}
camera_id->tag |= LIB_TAG_DOIT;
- ComponentKey parameters_key(camera_id, DEPSNODE_TYPE_PARAMETERS);
+ ComponentKey parameters_key(camera_id, DEG_NODE_TYPE_PARAMETERS);
if (needs_animdata_node(camera_id)) {
- ComponentKey animation_key(camera_id, DEPSNODE_TYPE_ANIMATION);
- add_relation(animation_key, parameters_key,
- DEPSREL_TYPE_COMPONENT_ORDER, "Camera Parameters");
+ ComponentKey animation_key(camera_id, DEG_NODE_TYPE_ANIMATION);
+ add_relation(animation_key, parameters_key, "Camera Parameters");
}
/* DOF */
if (cam->dof_ob) {
- ComponentKey ob_param_key(&ob->id, DEPSNODE_TYPE_PARAMETERS);
- ComponentKey dof_ob_key(&cam->dof_ob->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(dof_ob_key, ob_param_key, DEPSREL_TYPE_TRANSFORM, "Camera DOF");
+ ComponentKey ob_param_key(&ob->id, DEG_NODE_TYPE_PARAMETERS);
+ ComponentKey dof_ob_key(&cam->dof_ob->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(dof_ob_key, ob_param_key, "Camera DOF");
}
}
@@ -1650,20 +1590,18 @@ void DepsgraphRelationBuilder::build_lamp(Object *ob)
}
lamp_id->tag |= LIB_TAG_DOIT;
- ComponentKey parameters_key(lamp_id, DEPSNODE_TYPE_PARAMETERS);
+ ComponentKey parameters_key(lamp_id, DEG_NODE_TYPE_PARAMETERS);
if (needs_animdata_node(lamp_id)) {
- ComponentKey animation_key(lamp_id, DEPSNODE_TYPE_ANIMATION);
- add_relation(animation_key, parameters_key,
- DEPSREL_TYPE_COMPONENT_ORDER, "Lamp Parameters");
+ ComponentKey animation_key(lamp_id, DEG_NODE_TYPE_ANIMATION);
+ add_relation(animation_key, parameters_key, "Lamp Parameters");
}
/* lamp's nodetree */
if (la->nodetree) {
build_nodetree(la->nodetree);
- ComponentKey nodetree_key(&la->nodetree->id, DEPSNODE_TYPE_PARAMETERS);
- add_relation(nodetree_key, parameters_key,
- DEPSREL_TYPE_COMPONENT_ORDER, "NTree->Lamp Parameters");
+ ComponentKey nodetree_key(&la->nodetree->id, DEG_NODE_TYPE_PARAMETERS);
+ add_relation(nodetree_key, parameters_key, "NTree->Lamp Parameters");
}
/* textures */
@@ -1680,7 +1618,7 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
build_animdata(ntree_id);
OperationKey parameters_key(ntree_id,
- DEPSNODE_TYPE_PARAMETERS,
+ DEG_NODE_TYPE_PARAMETERS,
DEG_OPCODE_PLACEHOLDER,
"Parameters Eval");
@@ -1700,19 +1638,17 @@ void DepsgraphRelationBuilder::build_nodetree(bNodeTree *ntree)
group_ntree->id.tag |= LIB_TAG_DOIT;
}
OperationKey group_parameters_key(&group_ntree->id,
- DEPSNODE_TYPE_PARAMETERS,
+ DEG_NODE_TYPE_PARAMETERS,
DEG_OPCODE_PLACEHOLDER,
"Parameters Eval");
- add_relation(group_parameters_key, parameters_key,
- DEPSREL_TYPE_COMPONENT_ORDER, "Group Node");
+ add_relation(group_parameters_key, parameters_key, "Group Node");
}
}
}
if (needs_animdata_node(ntree_id)) {
- ComponentKey animation_key(ntree_id, DEPSNODE_TYPE_ANIMATION);
- add_relation(animation_key, parameters_key,
- DEPSREL_TYPE_COMPONENT_ORDER, "NTree Parameters");
+ ComponentKey animation_key(ntree_id, DEG_NODE_TYPE_ANIMATION);
+ add_relation(animation_key, parameters_key, "NTree Parameters");
}
}
@@ -1735,15 +1671,14 @@ void DepsgraphRelationBuilder::build_material(Material *ma)
if (ma->nodetree != NULL) {
build_nodetree(ma->nodetree);
OperationKey ntree_key(&ma->nodetree->id,
- DEPSNODE_TYPE_PARAMETERS,
+ DEG_NODE_TYPE_PARAMETERS,
DEG_OPCODE_PLACEHOLDER,
"Parameters Eval");
OperationKey material_key(&ma->id,
- DEPSNODE_TYPE_SHADING,
+ DEG_NODE_TYPE_SHADING,
DEG_OPCODE_PLACEHOLDER,
"Material Update");
- add_relation(ntree_key, material_key,
- DEPSREL_TYPE_UPDATE, "Material's NTree");
+ add_relation(ntree_key, material_key, "Material's NTree");
}
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations.h b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
index 4ca95bebe3f..02f8fc69070 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations.h
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations.h
@@ -78,17 +78,12 @@ struct Depsgraph;
struct DepsNode;
struct DepsNodeHandle;
struct RootDepsNode;
-struct SubgraphDepsNode;
struct IDDepsNode;
struct TimeSourceDepsNode;
struct ComponentDepsNode;
struct OperationDepsNode;
struct RootPChanMap;
-struct RootKey {
- RootKey();
-};
-
struct TimeSourceKey
{
TimeSourceKey();
@@ -177,19 +172,16 @@ struct DepsgraphRelationBuilder
template <typename KeyFrom, typename KeyTo>
void add_relation(const KeyFrom& key_from,
const KeyTo& key_to,
- eDepsRelation_Type type,
const char *description);
template <typename KeyTo>
void add_relation(const TimeSourceKey& key_from,
const KeyTo& key_to,
- eDepsRelation_Type type,
const char *description);
template <typename KeyType>
void add_node_handle_relation(const KeyType& key_from,
const DepsNodeHandle *handle,
- eDepsRelation_Type type,
const char *description);
void build_scene(Main *bmain, Scene *scene);
@@ -237,8 +229,9 @@ struct DepsgraphRelationBuilder
template <typename KeyType>
OperationDepsNode *find_operation_node(const KeyType &key);
+ Depsgraph *getGraph();
+
protected:
- RootDepsNode *find_node(const RootKey &key) const;
TimeSourceDepsNode *find_node(const TimeSourceKey &key) const;
ComponentDepsNode *find_node(const ComponentKey &key) const;
OperationDepsNode *find_node(const OperationKey &key) const;
@@ -250,7 +243,6 @@ protected:
const char *description);
void add_operation_relation(OperationDepsNode *node_from,
OperationDepsNode *node_to,
- eDepsRelation_Type type,
const char *description);
template <typename KeyType>
@@ -290,7 +282,6 @@ OperationDepsNode *DepsgraphRelationBuilder::find_operation_node(const KeyType&
template <typename KeyFrom, typename KeyTo>
void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from,
const KeyTo &key_to,
- eDepsRelation_Type type,
const char *description)
{
DepsNode *node_from = find_node(key_from);
@@ -298,27 +289,27 @@ void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from,
OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL;
OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL;
if (op_from && op_to) {
- add_operation_relation(op_from, op_to, type, description);
+ add_operation_relation(op_from, op_to, description);
}
else {
if (!op_from) {
/* XXX TODO handle as error or report if needed */
node_from = find_node(key_from);
- fprintf(stderr, "add_relation(%d, %s) - Could not find op_from (%s)\n",
- type, description, key_from.identifier().c_str());
+ fprintf(stderr, "add_relation(%s) - Could not find op_from (%s)\n",
+ description, key_from.identifier().c_str());
}
else {
- fprintf(stderr, "add_relation(%d, %s) - Failed, but op_from (%s) was ok\n",
- type, description, key_from.identifier().c_str());
+ fprintf(stderr, "add_relation(%s) - Failed, but op_from (%s) was ok\n",
+ description, key_from.identifier().c_str());
}
if (!op_to) {
/* XXX TODO handle as error or report if needed */
- fprintf(stderr, "add_relation(%d, %s) - Could not find op_to (%s)\n",
- type, description, key_to.identifier().c_str());
+ fprintf(stderr, "add_relation(%s) - Could not find op_to (%s)\n",
+ description, key_to.identifier().c_str());
}
else {
- fprintf(stderr, "add_relation(%d, %s) - Failed, but op_to (%s) was ok\n",
- type, description, key_to.identifier().c_str());
+ fprintf(stderr, "add_relation(%s) - Failed, but op_to (%s) was ok\n",
+ description, key_to.identifier().c_str());
}
}
}
@@ -326,11 +317,8 @@ void DepsgraphRelationBuilder::add_relation(const KeyFrom &key_from,
template <typename KeyTo>
void DepsgraphRelationBuilder::add_relation(const TimeSourceKey &key_from,
const KeyTo &key_to,
- eDepsRelation_Type type,
const char *description)
{
- (void)type; /* Ignored in release builds. */
- BLI_assert(type == DEPSREL_TYPE_TIME);
TimeSourceDepsNode *time_from = find_node(key_from);
DepsNode *node_to = find_node(key_to);
OperationDepsNode *op_to = node_to ? node_to->get_entry_operation() : NULL;
@@ -345,23 +333,22 @@ template <typename KeyType>
void DepsgraphRelationBuilder::add_node_handle_relation(
const KeyType &key_from,
const DepsNodeHandle *handle,
- eDepsRelation_Type type,
const char *description)
{
DepsNode *node_from = find_node(key_from);
OperationDepsNode *op_from = node_from ? node_from->get_exit_operation() : NULL;
OperationDepsNode *op_to = handle->node->get_entry_operation();
if (op_from && op_to) {
- add_operation_relation(op_from, op_to, type, description);
+ add_operation_relation(op_from, op_to, description);
}
else {
if (!op_from) {
- fprintf(stderr, "add_node_handle_relation(%d, %s) - Could not find op_from (%s)\n",
- type, description, key_from.identifier().c_str());
+ fprintf(stderr, "add_node_handle_relation(%s) - Could not find op_from (%s)\n",
+ description, key_from.identifier().c_str());
}
if (!op_to) {
- fprintf(stderr, "add_node_handle_relation(%d, %s) - Could not find op_to (%s)\n",
- type, description, key_from.identifier().c_str());
+ fprintf(stderr, "add_node_handle_relation(%s) - Could not find op_to (%s)\n",
+ description, key_from.identifier().c_str());
}
}
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc
index feae8bca303..9d6ab3358a7 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_keys.cc
@@ -35,13 +35,6 @@
namespace DEG {
/////////////////////////////////////////
-// Root.
-
-RootKey::RootKey()
-{
-}
-
-/////////////////////////////////////////
// Time source.
TimeSourceKey::TimeSourceKey()
@@ -64,7 +57,7 @@ string TimeSourceKey::identifier() const
ComponentKey::ComponentKey()
: id(NULL),
- type(DEPSNODE_TYPE_UNDEFINED),
+ type(DEG_NODE_TYPE_UNDEFINED),
name("")
{
}
@@ -90,7 +83,7 @@ string ComponentKey::identifier() const
OperationKey::OperationKey()
: id(NULL),
- component_type(DEPSNODE_TYPE_UNDEFINED),
+ component_type(DEG_NODE_TYPE_UNDEFINED),
component_name(""),
opcode(DEG_OPCODE_OPERATION),
name(""),
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
index 2b4c000f483..be666165a0b 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_rig.cc
@@ -38,10 +38,10 @@
#include "MEM_guardedalloc.h"
-extern "C" {
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_blenlib.h"
+extern "C" {
#include "DNA_action_types.h"
#include "DNA_anim_types.h"
#include "DNA_armature_types.h"
@@ -51,10 +51,10 @@ extern "C" {
#include "BKE_action.h"
#include "BKE_armature.h"
+} /* extern "C" */
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
-} /* extern "C" */
#include "intern/builder/deg_builder.h"
#include "intern/builder/deg_builder_pchanmap.h"
@@ -83,7 +83,7 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob,
* - see notes on direction of rel below...
*/
bPoseChannel *rootchan = BKE_armature_ik_solver_find_root(pchan, data);
- OperationKey solver_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name, DEG_OPCODE_POSE_IK_SOLVER);
+ OperationKey solver_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name, DEG_OPCODE_POSE_IK_SOLVER);
/* IK target */
// XXX: this should get handled as part of the constraint code
@@ -96,25 +96,25 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob,
* testing IK solver.
*/
// FIXME: geometry targets...
- ComponentKey pose_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE);
+ ComponentKey pose_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE);
if ((data->tar->type == OB_ARMATURE) && (data->subtarget[0])) {
/* TODO(sergey): This is only for until granular update stores intermediate result. */
if (data->tar != ob) {
/* different armature - can just read the results */
- ComponentKey target_key(&data->tar->id, DEPSNODE_TYPE_BONE, data->subtarget);
- add_relation(target_key, pose_key, DEPSREL_TYPE_TRANSFORM, con->name);
+ ComponentKey target_key(&data->tar->id, DEG_NODE_TYPE_BONE, data->subtarget);
+ add_relation(target_key, pose_key, con->name);
}
else {
/* same armature - we'll use the ready state only, just in case this bone is in the chain we're solving */
- OperationKey target_key(&data->tar->id, DEPSNODE_TYPE_BONE, data->subtarget, DEG_OPCODE_BONE_DONE);
- add_relation(target_key, solver_key, DEPSREL_TYPE_TRANSFORM, con->name);
+ OperationKey target_key(&data->tar->id, DEG_NODE_TYPE_BONE, data->subtarget, DEG_OPCODE_BONE_DONE);
+ add_relation(target_key, solver_key, con->name);
}
}
else if (ELEM(data->tar->type, OB_MESH, OB_LATTICE) && (data->subtarget[0])) {
/* vertex group target */
/* NOTE: for now, we don't need to represent vertex groups separately... */
- ComponentKey target_key(&data->tar->id, DEPSNODE_TYPE_GEOMETRY);
- add_relation(target_key, solver_key, DEPSREL_TYPE_GEOMETRY_EVAL, con->name);
+ ComponentKey target_key(&data->tar->id, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(target_key, solver_key, con->name);
if (data->tar->type == OB_MESH) {
OperationDepsNode *node2 = find_operation_node(target_key);
@@ -125,8 +125,8 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob,
}
else {
/* Standard Object Target */
- ComponentKey target_key(&data->tar->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(target_key, pose_key, DEPSREL_TYPE_TRANSFORM, con->name);
+ ComponentKey target_key(&data->tar->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(target_key, pose_key, con->name);
}
if ((data->tar == ob) && (data->subtarget[0])) {
@@ -142,14 +142,14 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob,
if (data->poletar != NULL) {
if ((data->poletar->type == OB_ARMATURE) && (data->polesubtarget[0])) {
// XXX: same armature issues - ready vs done?
- ComponentKey target_key(&data->poletar->id, DEPSNODE_TYPE_BONE, data->polesubtarget);
- add_relation(target_key, solver_key, DEPSREL_TYPE_TRANSFORM, con->name);
+ ComponentKey target_key(&data->poletar->id, DEG_NODE_TYPE_BONE, data->polesubtarget);
+ add_relation(target_key, solver_key, con->name);
}
else if (ELEM(data->poletar->type, OB_MESH, OB_LATTICE) && (data->polesubtarget[0])) {
/* vertex group target */
/* NOTE: for now, we don't need to represent vertex groups separately... */
- ComponentKey target_key(&data->poletar->id, DEPSNODE_TYPE_GEOMETRY);
- add_relation(target_key, solver_key, DEPSREL_TYPE_GEOMETRY_EVAL, con->name);
+ ComponentKey target_key(&data->poletar->id, DEG_NODE_TYPE_GEOMETRY);
+ add_relation(target_key, solver_key, con->name);
if (data->poletar->type == OB_MESH) {
OperationDepsNode *node2 = find_operation_node(target_key);
@@ -159,8 +159,8 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob,
}
}
else {
- ComponentKey target_key(&data->poletar->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(target_key, solver_key, DEPSREL_TYPE_TRANSFORM, con->name);
+ ComponentKey target_key(&data->poletar->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(target_key, solver_key, con->name);
}
}
@@ -170,19 +170,17 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob,
bPoseChannel *parchan = pchan;
/* exclude tip from chain? */
if (!(data->flag & CONSTRAINT_IK_TIP)) {
- OperationKey tip_transforms_key(&ob->id, DEPSNODE_TYPE_BONE,
+ OperationKey tip_transforms_key(&ob->id, DEG_NODE_TYPE_BONE,
parchan->name, DEG_OPCODE_BONE_LOCAL);
- add_relation(solver_key, tip_transforms_key,
- DEPSREL_TYPE_TRANSFORM, "IK Solver Result");
+ add_relation(solver_key, tip_transforms_key, "IK Solver Result");
parchan = pchan->parent;
}
root_map->add_bone(parchan->name, rootchan->name);
- OperationKey parchan_transforms_key(&ob->id, DEPSNODE_TYPE_BONE,
+ OperationKey parchan_transforms_key(&ob->id, DEG_NODE_TYPE_BONE,
parchan->name, DEG_OPCODE_BONE_READY);
- add_relation(parchan_transforms_key, solver_key,
- DEPSREL_TYPE_TRANSFORM, "IK Solver Owner");
+ add_relation(parchan_transforms_key, solver_key, "IK Solver Owner");
/* Walk to the chain's root */
//size_t segcount = 0;
@@ -196,15 +194,15 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob,
* grab the result with IK solver results...
*/
if (parchan != pchan) {
- OperationKey parent_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_READY);
- add_relation(parent_key, solver_key, DEPSREL_TYPE_TRANSFORM, "IK Chain Parent");
+ OperationKey parent_key(&ob->id, DEG_NODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_READY);
+ add_relation(parent_key, solver_key, "IK Chain Parent");
- OperationKey done_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE);
- add_relation(solver_key, done_key, DEPSREL_TYPE_TRANSFORM, "IK Chain Result");
+ OperationKey done_key(&ob->id, DEG_NODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE);
+ add_relation(solver_key, done_key, "IK Chain Result");
}
else {
- OperationKey final_transforms_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE);
- add_relation(solver_key, final_transforms_key, DEPSREL_TYPE_TRANSFORM, "IK Solver Result");
+ OperationKey final_transforms_key(&ob->id, DEG_NODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE);
+ add_relation(solver_key, final_transforms_key, "IK Solver Result");
}
parchan->flag |= POSE_DONE;
@@ -219,8 +217,8 @@ void DepsgraphRelationBuilder::build_ik_pose(Object *ob,
parchan = parchan->parent;
}
- OperationKey flush_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE);
- add_relation(solver_key, flush_key, DEPSREL_TYPE_OPERATION, "PoseEval Result-Bone Link");
+ OperationKey flush_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE);
+ add_relation(solver_key, flush_key, "PoseEval Result-Bone Link");
}
/* Spline IK Eval Steps */
@@ -231,14 +229,14 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *ob,
{
bSplineIKConstraint *data = (bSplineIKConstraint *)con->data;
bPoseChannel *rootchan = BKE_armature_splineik_solver_find_root(pchan, data);
- OperationKey transforms_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY);
- OperationKey solver_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, rootchan->name, DEG_OPCODE_POSE_SPLINE_IK_SOLVER);
+ OperationKey transforms_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY);
+ OperationKey solver_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, rootchan->name, DEG_OPCODE_POSE_SPLINE_IK_SOLVER);
/* attach owner to IK Solver too
* - assume that owner is always part of chain
* - see notes on direction of rel below...
*/
- add_relation(transforms_key, solver_key, DEPSREL_TYPE_TRANSFORM, "Spline IK Solver Owner");
+ add_relation(transforms_key, solver_key, "Spline IK Solver Owner");
/* attach path dependency to solver */
if (data->tar) {
@@ -247,14 +245,14 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *ob,
* See IK pose for a bit more information.
*/
// TODO: the bigggest point here is that we need the curve PATH and not just the general geometry...
- ComponentKey target_key(&data->tar->id, DEPSNODE_TYPE_GEOMETRY);
- ComponentKey pose_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE);
- add_relation(target_key, pose_key, DEPSREL_TYPE_TRANSFORM, "[Curve.Path -> Spline IK] DepsRel");
+ ComponentKey target_key(&data->tar->id, DEG_NODE_TYPE_GEOMETRY);
+ ComponentKey pose_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE);
+ add_relation(target_key, pose_key, "[Curve.Path -> Spline IK] DepsRel");
}
pchan->flag |= POSE_DONE;
- OperationKey final_transforms_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE);
- add_relation(solver_key, final_transforms_key, DEPSREL_TYPE_TRANSFORM, "Spline IK Result");
+ OperationKey final_transforms_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE);
+ add_relation(solver_key, final_transforms_key, "Spline IK Result");
root_map->add_bone(pchan->name, rootchan->name);
@@ -270,16 +268,16 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *ob,
* grab the result with IK solver results...
*/
if (parchan != pchan) {
- OperationKey parent_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_READY);
- add_relation(parent_key, solver_key, DEPSREL_TYPE_TRANSFORM, "Spline IK Solver Update");
+ OperationKey parent_key(&ob->id, DEG_NODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_READY);
+ add_relation(parent_key, solver_key, "Spline IK Solver Update");
- OperationKey done_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE);
- add_relation(solver_key, done_key, DEPSREL_TYPE_TRANSFORM, "IK Chain Result");
+ OperationKey done_key(&ob->id, DEG_NODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE);
+ add_relation(solver_key, done_key, "IK Chain Result");
}
parchan->flag |= POSE_DONE;
- OperationKey final_transforms_key(&ob->id, DEPSNODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE);
- add_relation(solver_key, final_transforms_key, DEPSREL_TYPE_TRANSFORM, "Spline IK Solver Result");
+ OperationKey final_transforms_key(&ob->id, DEG_NODE_TYPE_BONE, parchan->name, DEG_OPCODE_BONE_DONE);
+ add_relation(solver_key, final_transforms_key, "Spline IK Solver Result");
root_map->add_bone(parchan->name, rootchan->name);
@@ -288,8 +286,8 @@ void DepsgraphRelationBuilder::build_splineik_pose(Object *ob,
if ((segcount == data->chainlen) || (segcount > 255)) break; /* 255 is weak */
}
- OperationKey flush_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE);
- add_relation(solver_key, flush_key, DEPSREL_TYPE_OPERATION, "PoseEval Result-Bone Link");
+ OperationKey flush_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE);
+ add_relation(solver_key, flush_key, "PoseEval Result-Bone Link");
}
/* Pose/Armature Bones Graph */
@@ -301,21 +299,21 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob)
// TODO: selection status?
/* attach links between pose operations */
- OperationKey init_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_INIT);
- OperationKey flush_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE);
+ OperationKey init_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_INIT);
+ OperationKey flush_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE);
- add_relation(init_key, flush_key, DEPSREL_TYPE_COMPONENT_ORDER, "[Pose Init -> Pose Cleanup]");
+ add_relation(init_key, flush_key, "[Pose Init -> Pose Cleanup]");
/* Make sure pose is up-to-date with armature updates. */
OperationKey armature_key(&arm->id,
- DEPSNODE_TYPE_PARAMETERS,
+ DEG_NODE_TYPE_PARAMETERS,
DEG_OPCODE_PLACEHOLDER,
"Armature Eval");
- add_relation(armature_key, init_key, DEPSREL_TYPE_COMPONENT_ORDER, "Data dependency");
+ add_relation(armature_key, init_key, "Data dependency");
if (needs_animdata_node(&ob->id)) {
- ComponentKey animation_key(&ob->id, DEPSNODE_TYPE_ANIMATION);
- add_relation(animation_key, init_key, DEPSREL_TYPE_OPERATION, "Rig Animation");
+ ComponentKey animation_key(&ob->id, DEG_NODE_TYPE_ANIMATION);
+ add_relation(animation_key, init_key, "Rig Animation");
}
/* IK Solvers...
@@ -370,26 +368,25 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob)
/* TODO(sergey): Once partial updates are possible use relation between
* object transform and solver itself in it's build function.
*/
- ComponentKey pose_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE);
- ComponentKey local_transform_key(&ob->id, DEPSNODE_TYPE_TRANSFORM);
- add_relation(local_transform_key, pose_key, DEPSREL_TYPE_TRANSFORM, "Local Transforms");
+ ComponentKey pose_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE);
+ ComponentKey local_transform_key(&ob->id, DEG_NODE_TYPE_TRANSFORM);
+ add_relation(local_transform_key, pose_key, "Local Transforms");
}
-
/* links between operations for each bone */
LINKLIST_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
- OperationKey bone_local_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
- OperationKey bone_pose_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_POSE_PARENT);
- OperationKey bone_ready_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY);
- OperationKey bone_done_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE);
+ OperationKey bone_local_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
+ OperationKey bone_pose_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_POSE_PARENT);
+ OperationKey bone_ready_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY);
+ OperationKey bone_done_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE);
pchan->flag &= ~POSE_DONE;
/* pose init to bone local */
- add_relation(init_key, bone_local_key, DEPSREL_TYPE_OPERATION, "PoseEval Source-Bone Link");
+ add_relation(init_key, bone_local_key, "PoseEval Source-Bone Link");
/* local to pose parenting operation */
- add_relation(bone_local_key, bone_pose_key, DEPSREL_TYPE_OPERATION, "Bone Local - PoseSpace Link");
+ add_relation(bone_local_key, bone_pose_key, "Bone Local - PoseSpace Link");
/* parent relation */
if (pchan->parent != NULL) {
@@ -403,26 +400,26 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob)
parent_key_opcode = DEG_OPCODE_BONE_DONE;
}
- OperationKey parent_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->parent->name, parent_key_opcode);
- add_relation(parent_key, bone_pose_key, DEPSREL_TYPE_TRANSFORM, "[Parent Bone -> Child Bone]");
+ OperationKey parent_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->parent->name, parent_key_opcode);
+ add_relation(parent_key, bone_pose_key, "[Parent Bone -> Child Bone]");
}
/* constraints */
if (pchan->constraints.first != NULL) {
/* constraints stack and constraint dependencies */
- build_constraints(scene, &ob->id, DEPSNODE_TYPE_BONE, pchan->name, &pchan->constraints, &root_map);
+ build_constraints(scene, &ob->id, DEG_NODE_TYPE_BONE, pchan->name, &pchan->constraints, &root_map);
/* pose -> constraints */
- OperationKey constraints_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_CONSTRAINTS);
- add_relation(bone_pose_key, constraints_key, DEPSREL_TYPE_OPERATION, "Constraints Stack");
+ OperationKey constraints_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_CONSTRAINTS);
+ add_relation(bone_pose_key, constraints_key, "Constraints Stack");
/* constraints -> ready */
// TODO: when constraint stack is exploded, this step should occur before the first IK solver
- add_relation(constraints_key, bone_ready_key, DEPSREL_TYPE_OPERATION, "Constraints -> Ready");
+ add_relation(constraints_key, bone_ready_key, "Constraints -> Ready");
}
else {
/* pose -> ready */
- add_relation(bone_pose_key, bone_ready_key, DEPSREL_TYPE_OPERATION, "Pose -> Ready");
+ add_relation(bone_pose_key, bone_ready_key, "Pose -> Ready");
}
/* bone ready -> done
@@ -430,25 +427,25 @@ void DepsgraphRelationBuilder::build_rig(Scene *scene, Object *ob)
* For IK chains however, an additional rel is created from IK to done,
* with transitive reduction removing this one...
*/
- add_relation(bone_ready_key, bone_done_key, DEPSREL_TYPE_OPERATION, "Ready -> Done");
+ add_relation(bone_ready_key, bone_done_key, "Ready -> Done");
/* assume that all bones must be done for the pose to be ready (for deformers) */
- add_relation(bone_done_key, flush_key, DEPSREL_TYPE_OPERATION, "PoseEval Result-Bone Link");
+ add_relation(bone_done_key, flush_key, "PoseEval Result-Bone Link");
}
}
void DepsgraphRelationBuilder::build_proxy_rig(Object *ob)
{
- OperationKey pose_init_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_INIT);
- OperationKey pose_done_key(&ob->id, DEPSNODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE);
+ OperationKey pose_init_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_INIT);
+ OperationKey pose_done_key(&ob->id, DEG_NODE_TYPE_EVAL_POSE, DEG_OPCODE_POSE_DONE);
LINKLIST_FOREACH (bPoseChannel *, pchan, &ob->pose->chanbase) {
- OperationKey bone_local_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
- OperationKey bone_ready_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY);
- OperationKey bone_done_key(&ob->id, DEPSNODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE);
- add_relation(pose_init_key, bone_local_key, DEPSREL_TYPE_OPERATION, "Pose Init -> Bone Local");
- add_relation(bone_local_key, bone_ready_key, DEPSREL_TYPE_OPERATION, "Local -> Ready");
- add_relation(bone_ready_key, bone_done_key, DEPSREL_TYPE_OPERATION, "Ready -> Done");
- add_relation(bone_done_key, pose_done_key, DEPSREL_TYPE_OPERATION, "Bone Done -> Pose Done");
+ OperationKey bone_local_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_LOCAL);
+ OperationKey bone_ready_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_READY);
+ OperationKey bone_done_key(&ob->id, DEG_NODE_TYPE_BONE, pchan->name, DEG_OPCODE_BONE_DONE);
+ add_relation(pose_init_key, bone_local_key, "Pose Init -> Bone Local");
+ add_relation(bone_local_key, bone_ready_key, "Local -> Ready");
+ add_relation(bone_ready_key, bone_done_key, "Ready -> Done");
+ add_relation(bone_done_key, pose_done_key, "Bone Done -> Pose Done");
}
}
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
index 3bf435c37e0..6a9568e7e8d 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_relations_scene.cc
@@ -38,20 +38,20 @@
#include "MEM_guardedalloc.h"
-extern "C" {
-#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_blenlib.h"
+extern "C" {
#include "DNA_node_types.h"
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
#include "BKE_main.h"
#include "BKE_node.h"
+} /* extern "C" */
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_build.h"
-} /* extern "C" */
#include "intern/builder/deg_builder.h"
#include "intern/builder/deg_builder_pchanmap.h"
diff --git a/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc b/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc
index da71db09f3d..b12af21fc8d 100644
--- a/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc
+++ b/source/blender/depsgraph/intern/builder/deg_builder_transitive.cc
@@ -30,9 +30,7 @@
#include "intern/builder/deg_builder_transitive.h"
-extern "C" {
#include "MEM_guardedalloc.h"
-}
#include "intern/nodes/deg_node.h"
#include "intern/nodes/deg_node_component.h"
@@ -105,7 +103,7 @@ void deg_graph_transitive_reduction(Depsgraph *graph)
/* Increment in advance, so we can safely remove the relation. */
++it_rel;
- if (rel->from->type == DEPSNODE_TYPE_TIMESOURCE) {
+ if (rel->from->type == DEG_NODE_TYPE_TIMESOURCE) {
/* HACK: time source nodes don't get "done" flag set/cleared. */
/* TODO: there will be other types in future, so iterators above
* need modifying.
diff --git a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc
index 0d56ce71c7d..51d4ed91419 100644
--- a/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc
+++ b/source/blender/depsgraph/intern/debug/deg_debug_graphviz.cc
@@ -35,10 +35,10 @@
extern "C" {
#include "DNA_listBase.h"
+} /* extern "C" */
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_debug.h"
-} /* extern "C" */
#include "intern/depsgraph_intern.h"
#include "util/deg_util_foreach.h"
@@ -77,20 +77,18 @@ static const char *deg_debug_colors_light[] = {
#ifdef COLOR_SCHEME_NODE_TYPE
static const int deg_debug_node_type_color_map[][2] = {
- {DEPSNODE_TYPE_ROOT, 0},
- {DEPSNODE_TYPE_TIMESOURCE, 1},
- {DEPSNODE_TYPE_ID_REF, 2},
- {DEPSNODE_TYPE_SUBGRAPH, 3},
+ {DEG_NODE_TYPE_TIMESOURCE, 0},
+ {DEG_NODE_TYPE_ID_REF, 2},
/* Outer Types */
- {DEPSNODE_TYPE_PARAMETERS, 4},
- {DEPSNODE_TYPE_PROXY, 5},
- {DEPSNODE_TYPE_ANIMATION, 6},
- {DEPSNODE_TYPE_TRANSFORM, 7},
- {DEPSNODE_TYPE_GEOMETRY, 8},
- {DEPSNODE_TYPE_SEQUENCER, 9},
- {DEPSNODE_TYPE_SHADING, 10},
- {DEPSNODE_TYPE_CACHE, 11},
+ {DEG_NODE_TYPE_PARAMETERS, 2},
+ {DEG_NODE_TYPE_PROXY, 3},
+ {DEG_NODE_TYPE_ANIMATION, 4},
+ {DEG_NODE_TYPE_TRANSFORM, 5},
+ {DEG_NODE_TYPE_GEOMETRY, 6},
+ {DEG_NODE_TYPE_SEQUENCER, 7},
+ {DEG_NODE_TYPE_SHADING, 8},
+ {DEG_NODE_TYPE_CACHE, 9},
{-1, 0}
};
#endif
@@ -100,9 +98,9 @@ static int deg_debug_node_color_index(const DepsNode *node)
#ifdef COLOR_SCHEME_NODE_CLASS
/* Some special types. */
switch (node->type) {
- case DEPSNODE_TYPE_ID_REF:
+ case DEG_NODE_TYPE_ID_REF:
return 5;
- case DEPSNODE_TYPE_OPERATION:
+ case DEG_NODE_TYPE_OPERATION:
{
OperationDepsNode *op_node = (OperationDepsNode *)node;
if (op_node->is_noop())
@@ -115,9 +113,9 @@ static int deg_debug_node_color_index(const DepsNode *node)
}
/* Do others based on class. */
switch (node->tclass) {
- case DEPSNODE_CLASS_OPERATION:
+ case DEG_NODE_CLASS_OPERATION:
return 4;
- case DEPSNODE_CLASS_COMPONENT:
+ case DEG_NODE_CLASS_COMPONENT:
return 1;
default:
return 9;
@@ -201,7 +199,7 @@ static void deg_debug_graphviz_node_color(const DebugContext &ctx,
const char *color_update = "dodgerblue3";
const char *color = color_default;
if (ctx.show_tags) {
- if (node->tclass == DEPSNODE_CLASS_OPERATION) {
+ if (node->tclass == DEG_NODE_CLASS_OPERATION) {
OperationDepsNode *op_node = (OperationDepsNode *)node;
if (op_node->flag & DEPSOP_FLAG_DIRECTLY_MODIFIED) {
color = color_modified;
@@ -222,7 +220,7 @@ static void deg_debug_graphviz_node_penwidth(const DebugContext &ctx,
float penwidth_update = 4.0f;
float penwidth = penwidth_default;
if (ctx.show_tags) {
- if (node->tclass == DEPSNODE_CLASS_OPERATION) {
+ if (node->tclass == DEG_NODE_CLASS_OPERATION) {
OperationDepsNode *op_node = (OperationDepsNode *)node;
if (op_node->flag & DEPSOP_FLAG_DIRECTLY_MODIFIED) {
penwidth = penwidth_modified;
@@ -260,7 +258,7 @@ static void deg_debug_graphviz_node_style(const DebugContext &ctx, const DepsNod
{
const char *base_style = "filled"; /* default style */
if (ctx.show_tags) {
- if (node->tclass == DEPSNODE_CLASS_OPERATION) {
+ if (node->tclass == DEG_NODE_CLASS_OPERATION) {
OperationDepsNode *op_node = (OperationDepsNode *)node;
if (op_node->flag & (DEPSOP_FLAG_DIRECTLY_MODIFIED | DEPSOP_FLAG_NEEDS_UPDATE)) {
base_style = "striped";
@@ -268,13 +266,13 @@ static void deg_debug_graphviz_node_style(const DebugContext &ctx, const DepsNod
}
}
switch (node->tclass) {
- case DEPSNODE_CLASS_GENERIC:
+ case DEG_NODE_CLASS_GENERIC:
deg_debug_fprintf(ctx, "\"%s\"", base_style);
break;
- case DEPSNODE_CLASS_COMPONENT:
+ case DEG_NODE_CLASS_COMPONENT:
deg_debug_fprintf(ctx, "\"%s\"", base_style);
break;
- case DEPSNODE_CLASS_OPERATION:
+ case DEG_NODE_CLASS_OPERATION:
deg_debug_fprintf(ctx, "\"%s,rounded\"", base_style);
break;
}
@@ -286,13 +284,13 @@ static void deg_debug_graphviz_node_single(const DebugContext &ctx,
const char *shape = "box";
string name = node->identifier();
float priority = -1.0f;
- if (node->type == DEPSNODE_TYPE_ID_REF) {
+ if (node->type == DEG_NODE_TYPE_ID_REF) {
IDDepsNode *id_node = (IDDepsNode *)node;
char buf[256];
BLI_snprintf(buf, sizeof(buf), " (Layers: %u)", id_node->layers);
name += buf;
}
- if (ctx.show_eval_priority && node->tclass == DEPSNODE_CLASS_OPERATION) {
+ if (ctx.show_eval_priority && node->tclass == DEG_NODE_CLASS_OPERATION) {
priority = ((OperationDepsNode *)node)->eval_priority;
}
deg_debug_fprintf(ctx, "// %s\n", name.c_str());
@@ -322,7 +320,7 @@ static void deg_debug_graphviz_node_cluster_begin(const DebugContext &ctx,
const DepsNode *node)
{
string name = node->identifier();
- if (node->type == DEPSNODE_TYPE_ID_REF) {
+ if (node->type == DEG_NODE_TYPE_ID_REF) {
IDDepsNode *id_node = (IDDepsNode *)node;
char buf[256];
BLI_snprintf(buf, sizeof(buf), " (Layers: %u)", id_node->layers);
@@ -363,7 +361,7 @@ static void deg_debug_graphviz_node(const DebugContext &ctx,
const DepsNode *node)
{
switch (node->type) {
- case DEPSNODE_TYPE_ID_REF:
+ case DEG_NODE_TYPE_ID_REF:
{
const IDDepsNode *id_node = (const IDDepsNode *)node;
if (BLI_ghash_size(id_node->components) == 0) {
@@ -380,30 +378,17 @@ static void deg_debug_graphviz_node(const DebugContext &ctx,
}
break;
}
- case DEPSNODE_TYPE_SUBGRAPH:
- {
- SubgraphDepsNode *sub_node = (SubgraphDepsNode *)node;
- if (sub_node->graph) {
- deg_debug_graphviz_node_cluster_begin(ctx, node);
- deg_debug_graphviz_graph_nodes(ctx, sub_node->graph);
- deg_debug_graphviz_node_cluster_end(ctx);
- }
- else {
- deg_debug_graphviz_node_single(ctx, node);
- }
- break;
- }
- case DEPSNODE_TYPE_PARAMETERS:
- case DEPSNODE_TYPE_ANIMATION:
- case DEPSNODE_TYPE_TRANSFORM:
- case DEPSNODE_TYPE_PROXY:
- case DEPSNODE_TYPE_GEOMETRY:
- case DEPSNODE_TYPE_SEQUENCER:
- case DEPSNODE_TYPE_EVAL_POSE:
- case DEPSNODE_TYPE_BONE:
- case DEPSNODE_TYPE_SHADING:
- case DEPSNODE_TYPE_CACHE:
- case DEPSNODE_TYPE_EVAL_PARTICLES:
+ case DEG_NODE_TYPE_PARAMETERS:
+ case DEG_NODE_TYPE_ANIMATION:
+ case DEG_NODE_TYPE_TRANSFORM:
+ case DEG_NODE_TYPE_PROXY:
+ case DEG_NODE_TYPE_GEOMETRY:
+ case DEG_NODE_TYPE_SEQUENCER:
+ case DEG_NODE_TYPE_EVAL_POSE:
+ case DEG_NODE_TYPE_BONE:
+ case DEG_NODE_TYPE_SHADING:
+ case DEG_NODE_TYPE_CACHE:
+ case DEG_NODE_TYPE_EVAL_PARTICLES:
{
ComponentDepsNode *comp_node = (ComponentDepsNode *)node;
if (!comp_node->operations.empty()) {
@@ -427,24 +412,19 @@ static void deg_debug_graphviz_node(const DebugContext &ctx,
static bool deg_debug_graphviz_is_cluster(const DepsNode *node)
{
switch (node->type) {
- case DEPSNODE_TYPE_ID_REF:
+ case DEG_NODE_TYPE_ID_REF:
{
const IDDepsNode *id_node = (const IDDepsNode *)node;
return BLI_ghash_size(id_node->components) > 0;
}
- case DEPSNODE_TYPE_SUBGRAPH:
- {
- SubgraphDepsNode *sub_node = (SubgraphDepsNode *)node;
- return sub_node->graph != NULL;
- }
- case DEPSNODE_TYPE_PARAMETERS:
- case DEPSNODE_TYPE_ANIMATION:
- case DEPSNODE_TYPE_TRANSFORM:
- case DEPSNODE_TYPE_PROXY:
- case DEPSNODE_TYPE_GEOMETRY:
- case DEPSNODE_TYPE_SEQUENCER:
- case DEPSNODE_TYPE_EVAL_POSE:
- case DEPSNODE_TYPE_BONE:
+ case DEG_NODE_TYPE_PARAMETERS:
+ case DEG_NODE_TYPE_ANIMATION:
+ case DEG_NODE_TYPE_TRANSFORM:
+ case DEG_NODE_TYPE_PROXY:
+ case DEG_NODE_TYPE_GEOMETRY:
+ case DEG_NODE_TYPE_SEQUENCER:
+ case DEG_NODE_TYPE_EVAL_POSE:
+ case DEG_NODE_TYPE_BONE:
{
ComponentDepsNode *comp_node = (ComponentDepsNode *)node;
return !comp_node->operations.empty();
@@ -458,14 +438,14 @@ static bool deg_debug_graphviz_is_owner(const DepsNode *node,
const DepsNode *other)
{
switch (node->tclass) {
- case DEPSNODE_CLASS_COMPONENT:
+ case DEG_NODE_CLASS_COMPONENT:
{
ComponentDepsNode *comp_node = (ComponentDepsNode *)node;
if (comp_node->owner == other)
return true;
break;
}
- case DEPSNODE_CLASS_OPERATION:
+ case DEG_NODE_CLASS_OPERATION:
{
OperationDepsNode *op_node = (OperationDepsNode *)node;
if (op_node->owner == other)
@@ -517,15 +497,12 @@ static void deg_debug_graphviz_node_relations(const DebugContext &ctx,
static void deg_debug_graphviz_graph_nodes(const DebugContext &ctx,
const Depsgraph *graph)
{
- if (graph->root_node) {
- deg_debug_graphviz_node(ctx, graph->root_node);
- }
GHASH_FOREACH_BEGIN (DepsNode *, node, graph->id_hash)
{
deg_debug_graphviz_node(ctx, node);
}
GHASH_FOREACH_END();
- TimeSourceDepsNode *time_source = graph->find_time_source(NULL);
+ TimeSourceDepsNode *time_source = graph->find_time_source();
if (time_source != NULL) {
deg_debug_graphviz_node(ctx, time_source);
}
@@ -546,7 +523,7 @@ static void deg_debug_graphviz_graph_relations(const DebugContext &ctx,
}
GHASH_FOREACH_END();
- TimeSourceDepsNode *time_source = graph->find_time_source(NULL);
+ TimeSourceDepsNode *time_source = graph->find_time_source();
if (time_source != NULL) {
deg_debug_graphviz_node_relations(ctx, time_source);
}
diff --git a/source/blender/depsgraph/intern/depsgraph.cc b/source/blender/depsgraph/intern/depsgraph.cc
index 5604044e123..aa21f0995be 100644
--- a/source/blender/depsgraph/intern/depsgraph.cc
+++ b/source/blender/depsgraph/intern/depsgraph.cc
@@ -69,26 +69,22 @@ static DEG_EditorUpdateSceneCb deg_editor_update_scene_cb = NULL;
static DEG_EditorUpdateScenePreCb deg_editor_update_scene_pre_cb = NULL;
Depsgraph::Depsgraph()
- : root_node(NULL),
+ : time_source(NULL),
need_update(false),
layers(0)
{
BLI_spin_init(&lock);
id_hash = BLI_ghash_ptr_new("Depsgraph id hash");
- subgraphs = BLI_gset_ptr_new("Depsgraph subgraphs");
entry_tags = BLI_gset_ptr_new("Depsgraph entry_tags");
}
Depsgraph::~Depsgraph()
{
- /* Free root node - it won't have been freed yet... */
clear_id_nodes();
- clear_subgraph_nodes();
BLI_ghash_free(id_hash, NULL, NULL);
- BLI_gset_free(subgraphs, NULL);
BLI_gset_free(entry_tags, NULL);
- if (this->root_node != NULL) {
- OBJECT_GUARDED_DELETE(this->root_node, RootDepsNode);
+ if (time_source != NULL) {
+ OBJECT_GUARDED_DELETE(time_source, TimeSourceDepsNode);
}
BLI_spin_end(&lock);
}
@@ -131,7 +127,7 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr,
bPoseChannel *pchan = (bPoseChannel *)ptr->data;
/* Bone - generally, we just want the bone component... */
- *type = DEPSNODE_TYPE_BONE;
+ *type = DEG_NODE_TYPE_BONE;
*subdata = pchan->name;
return true;
@@ -141,7 +137,7 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr,
/* armature-level bone, but it ends up going to bone component anyway */
// TODO: the ID in thise case will end up being bArmature, not Object as needed!
- *type = DEPSNODE_TYPE_BONE;
+ *type = DEG_NODE_TYPE_BONE;
*subdata = bone->name;
//*id = ...
@@ -155,7 +151,7 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr,
if (BLI_findindex(&ob->constraints, con) != -1) {
/* object transform */
// XXX: for now, we can't address the specific constraint or the constraint stack...
- *type = DEPSNODE_TYPE_TRANSFORM;
+ *type = DEG_NODE_TYPE_TRANSFORM;
return true;
}
else if (ob->pose) {
@@ -163,7 +159,7 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr,
for (pchan = (bPoseChannel *)ob->pose->chanbase.first; pchan; pchan = pchan->next) {
if (BLI_findindex(&pchan->constraints, con) != -1) {
/* bone transforms */
- *type = DEPSNODE_TYPE_BONE;
+ *type = DEG_NODE_TYPE_BONE;
*subdata = pchan->name;
return true;
}
@@ -178,7 +174,7 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr,
* so although we have unique ops for modifiers,
* we can't lump them together
*/
- *type = DEPSNODE_TYPE_BONE;
+ *type = DEG_NODE_TYPE_BONE;
//*subdata = md->name;
return true;
@@ -195,14 +191,14 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr,
strstr(prop_identifier, "scale") ||
strstr(prop_identifier, "matrix_"))
{
- *type = DEPSNODE_TYPE_TRANSFORM;
+ *type = DEG_NODE_TYPE_TRANSFORM;
return true;
}
else if (strstr(prop_identifier, "data")) {
/* We access object.data, most likely a geometry.
* Might be a bone tho..
*/
- *type = DEPSNODE_TYPE_GEOMETRY;
+ *type = DEG_NODE_TYPE_GEOMETRY;
return true;
}
}
@@ -212,21 +208,21 @@ static bool pointer_to_component_node_criteria(const PointerRNA *ptr,
/* ShapeKeys are currently handled as geometry on the geometry that owns it */
*id = key->from; // XXX
- *type = DEPSNODE_TYPE_PARAMETERS;
+ *type = DEG_NODE_TYPE_PARAMETERS;
return true;
}
else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) {
Sequence *seq = (Sequence *)ptr->data;
/* Sequencer strip */
- *type = DEPSNODE_TYPE_SEQUENCER;
+ *type = DEG_NODE_TYPE_SEQUENCER;
*subdata = seq->name; // xxx?
return true;
}
if (prop) {
/* All unknown data effectively falls under "parameter evaluation" */
- *type = DEPSNODE_TYPE_PARAMETERS;
+ *type = DEG_NODE_TYPE_PARAMETERS;
return true;
}
@@ -263,72 +259,18 @@ static void id_node_deleter(void *value)
OBJECT_GUARDED_DELETE(id_node, IDDepsNode);
}
-RootDepsNode *Depsgraph::add_root_node()
+TimeSourceDepsNode *Depsgraph::add_time_source()
{
- if (!root_node) {
- DepsNodeFactory *factory = deg_get_node_factory(DEPSNODE_TYPE_ROOT);
- root_node = (RootDepsNode *)factory->create_node(NULL, "", "Root (Scene)");
+ if (time_source == NULL) {
+ DepsNodeFactory *factory = deg_get_node_factory(DEG_NODE_TYPE_TIMESOURCE);
+ time_source = (TimeSourceDepsNode *)factory->create_node(NULL, "", "Time Source");
}
- return root_node;
+ return time_source;
}
-TimeSourceDepsNode *Depsgraph::find_time_source(const ID *id) const
+TimeSourceDepsNode *Depsgraph::find_time_source() const
{
- /* Search for one attached to a particular ID? */
- if (id) {
- /* Check if it was added as a component
- * (as may be done for subgraphs needing timeoffset).
- */
- IDDepsNode *id_node = find_id_node(id);
- if (id_node) {
- // XXX: review this
-// return id_node->find_component(DEPSNODE_TYPE_TIMESOURCE);
- }
- BLI_assert(!"Not implemented yet");
- }
- else {
- /* Use "official" timesource. */
- return root_node->time_source;
- }
- return NULL;
-}
-
-SubgraphDepsNode *Depsgraph::add_subgraph_node(const ID *id)
-{
- DepsNodeFactory *factory = deg_get_node_factory(DEPSNODE_TYPE_SUBGRAPH);
- SubgraphDepsNode *subgraph_node =
- (SubgraphDepsNode *)factory->create_node(id, "", id->name + 2);
-
- /* Add to subnodes list. */
- BLI_gset_insert(subgraphs, subgraph_node);
-
- /* if there's an ID associated, add to ID-nodes lookup too */
- if (id) {
-#if 0
- /* XXX subgraph node is NOT a true IDDepsNode - what is this supposed to do? */
- // TODO: what to do if subgraph's ID has already been added?
- BLI_assert(!graph->find_id_node(id));
- graph->id_hash[id] = this;
-#endif
- }
-
- return subgraph_node;
-}
-
-void Depsgraph::remove_subgraph_node(SubgraphDepsNode *subgraph_node)
-{
- BLI_gset_remove(subgraphs, subgraph_node, NULL);
- OBJECT_GUARDED_DELETE(subgraph_node, SubgraphDepsNode);
-}
-
-void Depsgraph::clear_subgraph_nodes()
-{
- GSET_FOREACH_BEGIN(SubgraphDepsNode *, subgraph_node, subgraphs)
- {
- OBJECT_GUARDED_DELETE(subgraph_node, SubgraphDepsNode);
- }
- GSET_FOREACH_END();
- BLI_gset_clear(subgraphs, NULL);
+ return time_source;
}
IDDepsNode *Depsgraph::find_id_node(const ID *id) const
@@ -340,7 +282,7 @@ IDDepsNode *Depsgraph::add_id_node(ID *id, const char *name)
{
IDDepsNode *id_node = find_id_node(id);
if (!id_node) {
- DepsNodeFactory *factory = deg_get_node_factory(DEPSNODE_TYPE_ID_REF);
+ DepsNodeFactory *factory = deg_get_node_factory(DEG_NODE_TYPE_ID_REF);
id_node = (IDDepsNode *)factory->create_node(id, "", name);
id->tag |= LIB_TAG_DOIT;
/* register */
@@ -349,16 +291,6 @@ IDDepsNode *Depsgraph::add_id_node(ID *id, const char *name)
return id_node;
}
-void Depsgraph::remove_id_node(const ID *id)
-{
- IDDepsNode *id_node = find_id_node(id);
- if (id_node) {
- /* unregister */
- BLI_ghash_remove(id_hash, id, NULL, NULL);
- OBJECT_GUARDED_DELETE(id_node, IDDepsNode);
- }
-}
-
void Depsgraph::clear_id_nodes()
{
BLI_ghash_clear(id_hash, NULL, id_node_deleter);
@@ -367,15 +299,14 @@ void Depsgraph::clear_id_nodes()
/* Add new relationship between two nodes. */
DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from,
OperationDepsNode *to,
- eDepsRelation_Type type,
const char *description)
{
/* Create new relation, and add it to the graph. */
- DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, type, description);
+ DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description);
/* TODO(sergey): Find a better place for this. */
#ifdef WITH_OPENSUBDIV
ComponentDepsNode *comp_node = from->owner;
- if (comp_node->type == DEPSNODE_TYPE_GEOMETRY) {
+ if (comp_node->type == DEG_NODE_TYPE_GEOMETRY) {
IDDepsNode *id_to = to->owner->owner;
IDDepsNode *id_from = from->owner->owner;
if (id_to != id_from && (id_to->id->tag & LIB_TAG_ID_RECALC_ALL)) {
@@ -391,11 +322,10 @@ DepsRelation *Depsgraph::add_new_relation(OperationDepsNode *from,
/* Add new relation between two nodes */
DepsRelation *Depsgraph::add_new_relation(DepsNode *from, DepsNode *to,
- eDepsRelation_Type type,
const char *description)
{
/* Create new relation, and add it to the graph. */
- DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, type, description);
+ DepsRelation *rel = OBJECT_GUARDED_NEW(DepsRelation, from, to, description);
return rel;
}
@@ -404,12 +334,10 @@ DepsRelation *Depsgraph::add_new_relation(DepsNode *from, DepsNode *to,
DepsRelation::DepsRelation(DepsNode *from,
DepsNode *to,
- eDepsRelation_Type type,
const char *description)
: from(from),
to(to),
name(description),
- type(type),
flag(0)
{
#ifndef NDEBUG
@@ -472,11 +400,10 @@ void Depsgraph::add_entry_tag(OperationDepsNode *node)
void Depsgraph::clear_all_nodes()
{
clear_id_nodes();
- clear_subgraph_nodes();
BLI_ghash_clear(id_hash, NULL, NULL);
- if (this->root_node) {
- OBJECT_GUARDED_DELETE(this->root_node, RootDepsNode);
- root_node = NULL;
+ if (time_source != NULL) {
+ OBJECT_GUARDED_DELETE(time_source, TimeSourceDepsNode);
+ time_source = NULL;
}
}
diff --git a/source/blender/depsgraph/intern/depsgraph.h b/source/blender/depsgraph/intern/depsgraph.h
index e668facd645..f72f8dd9311 100644
--- a/source/blender/depsgraph/intern/depsgraph.h
+++ b/source/blender/depsgraph/intern/depsgraph.h
@@ -49,10 +49,8 @@ struct PropertyRNA;
namespace DEG {
struct DepsNode;
-struct RootDepsNode;
struct TimeSourceDepsNode;
struct IDDepsNode;
-struct SubgraphDepsNode;
struct ComponentDepsNode;
struct OperationDepsNode;
@@ -79,12 +77,10 @@ struct DepsRelation {
/* relationship attributes */
const char *name; /* label for debugging */
- eDepsRelation_Type type; /* type */
int flag; /* (eDepsRelation_Flag) */
DepsRelation(DepsNode *from,
DepsNode *to,
- eDepsRelation_Type type,
const char *description);
~DepsRelation();
@@ -111,28 +107,20 @@ struct Depsgraph {
*/
DepsNode *find_node_from_pointer(const PointerRNA *ptr, const PropertyRNA *prop) const;
- RootDepsNode *add_root_node();
-
- TimeSourceDepsNode *find_time_source(const ID *id = NULL) const;
-
- SubgraphDepsNode *add_subgraph_node(const ID *id);
- void remove_subgraph_node(SubgraphDepsNode *subgraph_node);
- void clear_subgraph_nodes();
+ TimeSourceDepsNode *add_time_source();
+ TimeSourceDepsNode *find_time_source() const;
IDDepsNode *find_id_node(const ID *id) const;
IDDepsNode *add_id_node(ID *id, const char *name = "");
- void remove_id_node(const ID *id);
void clear_id_nodes();
/* Add new relationship between two nodes. */
DepsRelation *add_new_relation(OperationDepsNode *from,
OperationDepsNode *to,
- eDepsRelation_Type type,
const char *description);
DepsRelation *add_new_relation(DepsNode *from,
DepsNode *to,
- eDepsRelation_Type type,
const char *description);
/* Tag a specific node as needing updates. */
@@ -147,11 +135,8 @@ struct Depsgraph {
* (for quick lookups). */
GHash *id_hash;
- /* "root" node - the one where all evaluation enters from. */
- RootDepsNode *root_node;
-
- /* Subgraphs referenced in tree. */
- GSet *subgraphs;
+ /* Top-level time source node. */
+ TimeSourceDepsNode *time_source;
/* Indicates whether relations needs to be updated. */
bool need_update;
diff --git a/source/blender/depsgraph/intern/depsgraph_build.cc b/source/blender/depsgraph/intern/depsgraph_build.cc
index 3a69469053c..47bf5e7ecbb 100644
--- a/source/blender/depsgraph/intern/depsgraph_build.cc
+++ b/source/blender/depsgraph/intern/depsgraph_build.cc
@@ -34,12 +34,6 @@
// #define DEBUG_TIME
-extern "C" {
-#include "DNA_cachefile_types.h"
-#include "DNA_object_types.h"
-#include "DNA_scene_types.h"
-#include "DNA_object_force.h"
-
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
@@ -48,17 +42,22 @@ extern "C" {
# include "PIL_time_utildefines.h"
#endif
+extern "C" {
+#include "DNA_cachefile_types.h"
+#include "DNA_object_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_object_force.h"
+
#include "BKE_main.h"
#include "BKE_collision.h"
#include "BKE_effect.h"
#include "BKE_modifier.h"
+} /* extern "C" */
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_debug.h"
#include "DEG_depsgraph_build.h"
-} /* extern "C" */
-
#include "builder/deg_builder.h"
#include "builder/deg_builder_cycle.h"
#include "builder/deg_builder_nodes.h"
@@ -81,29 +80,29 @@ static DEG::eDepsNode_Type deg_build_scene_component_type(
eDepsSceneComponentType component)
{
switch (component) {
- case DEG_SCENE_COMP_PARAMETERS: return DEG::DEPSNODE_TYPE_PARAMETERS;
- case DEG_SCENE_COMP_ANIMATION: return DEG::DEPSNODE_TYPE_ANIMATION;
- case DEG_SCENE_COMP_SEQUENCER: return DEG::DEPSNODE_TYPE_SEQUENCER;
+ case DEG_SCENE_COMP_PARAMETERS: return DEG::DEG_NODE_TYPE_PARAMETERS;
+ case DEG_SCENE_COMP_ANIMATION: return DEG::DEG_NODE_TYPE_ANIMATION;
+ case DEG_SCENE_COMP_SEQUENCER: return DEG::DEG_NODE_TYPE_SEQUENCER;
}
- return DEG::DEPSNODE_TYPE_UNDEFINED;
+ return DEG::DEG_NODE_TYPE_UNDEFINED;
}
static DEG::eDepsNode_Type deg_build_object_component_type(
eDepsObjectComponentType component)
{
switch (component) {
- case DEG_OB_COMP_PARAMETERS: return DEG::DEPSNODE_TYPE_PARAMETERS;
- case DEG_OB_COMP_PROXY: return DEG::DEPSNODE_TYPE_PROXY;
- case DEG_OB_COMP_ANIMATION: return DEG::DEPSNODE_TYPE_ANIMATION;
- case DEG_OB_COMP_TRANSFORM: return DEG::DEPSNODE_TYPE_TRANSFORM;
- case DEG_OB_COMP_GEOMETRY: return DEG::DEPSNODE_TYPE_GEOMETRY;
- case DEG_OB_COMP_EVAL_POSE: return DEG::DEPSNODE_TYPE_EVAL_POSE;
- case DEG_OB_COMP_BONE: return DEG::DEPSNODE_TYPE_BONE;
- case DEG_OB_COMP_EVAL_PARTICLES: return DEG::DEPSNODE_TYPE_EVAL_PARTICLES;
- case DEG_OB_COMP_SHADING: return DEG::DEPSNODE_TYPE_SHADING;
- case DEG_OB_COMP_CACHE: return DEG::DEPSNODE_TYPE_CACHE;
+ case DEG_OB_COMP_PARAMETERS: return DEG::DEG_NODE_TYPE_PARAMETERS;
+ case DEG_OB_COMP_PROXY: return DEG::DEG_NODE_TYPE_PROXY;
+ case DEG_OB_COMP_ANIMATION: return DEG::DEG_NODE_TYPE_ANIMATION;
+ case DEG_OB_COMP_TRANSFORM: return DEG::DEG_NODE_TYPE_TRANSFORM;
+ case DEG_OB_COMP_GEOMETRY: return DEG::DEG_NODE_TYPE_GEOMETRY;
+ case DEG_OB_COMP_EVAL_POSE: return DEG::DEG_NODE_TYPE_EVAL_POSE;
+ case DEG_OB_COMP_BONE: return DEG::DEG_NODE_TYPE_BONE;
+ case DEG_OB_COMP_EVAL_PARTICLES: return DEG::DEG_NODE_TYPE_EVAL_PARTICLES;
+ case DEG_OB_COMP_SHADING: return DEG::DEG_NODE_TYPE_SHADING;
+ case DEG_OB_COMP_CACHE: return DEG::DEG_NODE_TYPE_CACHE;
}
- return DEG::DEPSNODE_TYPE_UNDEFINED;
+ return DEG::DEG_NODE_TYPE_UNDEFINED;
}
static DEG::DepsNodeHandle *get_handle(DepsNodeHandle *handle)
@@ -121,7 +120,6 @@ void DEG_add_scene_relation(DepsNodeHandle *handle,
DEG::DepsNodeHandle *deg_handle = get_handle(handle);
deg_handle->builder->add_node_handle_relation(comp_key,
deg_handle,
- DEG::DEPSREL_TYPE_GEOMETRY_EVAL,
description);
}
@@ -135,7 +133,6 @@ void DEG_add_object_relation(DepsNodeHandle *handle,
DEG::DepsNodeHandle *deg_handle = get_handle(handle);
deg_handle->builder->add_node_handle_relation(comp_key,
deg_handle,
- DEG::DEPSREL_TYPE_GEOMETRY_EVAL,
description);
}
@@ -149,7 +146,6 @@ void DEG_add_object_cache_relation(DepsNodeHandle *handle,
DEG::DepsNodeHandle *deg_handle = get_handle(handle);
deg_handle->builder->add_node_handle_relation(comp_key,
deg_handle,
- DEG::DEPSREL_TYPE_CACHE,
description);
}
@@ -167,10 +163,16 @@ void DEG_add_bone_relation(DepsNodeHandle *handle,
*/
deg_handle->builder->add_node_handle_relation(comp_key,
deg_handle,
- DEG::DEPSREL_TYPE_GEOMETRY_EVAL,
description);
}
+struct Depsgraph *DEG_get_graph_from_handle(struct DepsNodeHandle *handle)
+{
+ DEG::DepsNodeHandle *deg_handle = get_handle(handle);
+ DEG::DepsgraphRelationBuilder *relation_builder = deg_handle->builder;
+ return reinterpret_cast<Depsgraph *>(relation_builder->getGraph());
+}
+
void DEG_add_special_eval_flag(Depsgraph *graph, ID *id, short flag)
{
DEG::Depsgraph *deg_graph = reinterpret_cast<DEG::Depsgraph *>(graph);
@@ -205,30 +207,14 @@ void DEG_graph_build_from_scene(Depsgraph *graph, Main *bmain, Scene *scene)
/* 1) Generate all the nodes in the graph first */
DEG::DepsgraphNodeBuilder node_builder(bmain, deg_graph);
- /* create root node for scene first
- * - this way it should be the first in the graph,
- * reflecting its role as the entrypoint
- */
node_builder.begin_build(bmain);
- node_builder.add_root_node();
node_builder.build_scene(bmain, scene);
/* 2) Hook up relationships between operations - to determine evaluation
* order.
*/
DEG::DepsgraphRelationBuilder relation_builder(deg_graph);
- /* Hook scene up to the root node as entrypoint to graph. */
- /* XXX what does this relation actually mean?
- * it doesnt add any operations anyway and is not clear what part of the
- * scene is to be connected.
- */
relation_builder.begin_build(bmain);
-#if 0
- relation_builder.add_relation(RootKey(),
- IDKey(scene),
- DEPSREL_TYPE_ROOT_TO_ACTIVE,
- "Root to Active Scene");
-#endif
relation_builder.build_scene(bmain, scene);
/* Detect and solve cycles. */
diff --git a/source/blender/depsgraph/intern/depsgraph_debug.cc b/source/blender/depsgraph/intern/depsgraph_debug.cc
index d3b48930779..388b692d742 100644
--- a/source/blender/depsgraph/intern/depsgraph_debug.cc
+++ b/source/blender/depsgraph/intern/depsgraph_debug.cc
@@ -35,11 +35,11 @@
extern "C" {
#include "DNA_scene_types.h"
+} /* extern "C" */
#include "DEG_depsgraph.h"
#include "DEG_depsgraph_debug.h"
#include "DEG_depsgraph_build.h"
-} /* extern "C" */
#include "intern/eval/deg_eval_debug.h"
#include "intern/depsgraph_intern.h"
@@ -165,7 +165,7 @@ bool DEG_debug_consistency_check(Depsgraph *graph)
return false;
}
foreach (DEG::DepsRelation *rel, node->outlinks) {
- if (rel->to->type == DEG::DEPSNODE_TYPE_OPERATION) {
+ if (rel->to->type == DEG::DEG_NODE_TYPE_OPERATION) {
DEG::OperationDepsNode *to = (DEG::OperationDepsNode *)rel->to;
BLI_assert(to->num_links_pending < to->inlinks.size());
++to->num_links_pending;
@@ -177,7 +177,7 @@ bool DEG_debug_consistency_check(Depsgraph *graph)
foreach (DEG::OperationDepsNode *node, deg_graph->operations) {
int num_links_pending = 0;
foreach (DEG::DepsRelation *rel, node->inlinks) {
- if (rel->from->type == DEG::DEPSNODE_TYPE_OPERATION) {
+ if (rel->from->type == DEG::DEG_NODE_TYPE_OPERATION) {
++num_links_pending;
}
}
@@ -232,7 +232,7 @@ void DEG_stats_simple(const Depsgraph *graph, size_t *r_outer,
}
GHASH_FOREACH_END();
- DEG::TimeSourceDepsNode *time_source = deg_graph->find_time_source(NULL);
+ DEG::TimeSourceDepsNode *time_source = deg_graph->find_time_source();
if (time_source != NULL) {
tot_rels += time_source->inlinks.size();
}
diff --git a/source/blender/depsgraph/intern/depsgraph_eval.cc b/source/blender/depsgraph/intern/depsgraph_eval.cc
index c41f28b07e8..85a0d336d28 100644
--- a/source/blender/depsgraph/intern/depsgraph_eval.cc
+++ b/source/blender/depsgraph/intern/depsgraph_eval.cc
@@ -32,17 +32,17 @@
#include "MEM_guardedalloc.h"
-extern "C" {
-#include "DNA_scene_types.h"
-
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
+extern "C" {
+#include "DNA_scene_types.h"
+
#include "BKE_depsgraph.h"
#include "BKE_scene.h"
+} /* extern "C" */
#include "DEG_depsgraph.h"
-} /* extern "C" */
#include "intern/eval/deg_eval.h"
#include "intern/eval/deg_eval_flush.h"
diff --git a/source/blender/depsgraph/intern/depsgraph_query.cc b/source/blender/depsgraph/intern/depsgraph_query.cc
index 7f2f6a65f5e..e58a7a32407 100644
--- a/source/blender/depsgraph/intern/depsgraph_query.cc
+++ b/source/blender/depsgraph/intern/depsgraph_query.cc
@@ -35,9 +35,9 @@
extern "C" {
#include "BKE_idcode.h"
#include "BKE_main.h"
+} /* extern "C" */
#include "DEG_depsgraph_query.h"
-} /* extern "C" */
#include "intern/depsgraph_intern.h"
diff --git a/source/blender/depsgraph/intern/depsgraph_tag.cc b/source/blender/depsgraph/intern/depsgraph_tag.cc
index cfc9005a1e3..31b4bbc7950 100644
--- a/source/blender/depsgraph/intern/depsgraph_tag.cc
+++ b/source/blender/depsgraph/intern/depsgraph_tag.cc
@@ -34,15 +34,16 @@
#include <cstring> /* required for memset */
#include <queue>
-extern "C" {
#include "BLI_utildefines.h"
+#include "BLI_task.h"
+#include "BLI_listbase.h"
+extern "C" {
#include "DNA_object_types.h"
#include "DNA_particle_types.h"
#include "DNA_screen_types.h"
#include "DNA_windowmanager_types.h"
-#include "BLI_task.h"
#include "BKE_idcode.h"
#include "BKE_library.h"
@@ -52,9 +53,9 @@ extern "C" {
#define new new_
#include "BKE_screen.h"
#undef new
+} /* extern "C" */
#include "DEG_depsgraph.h"
-} /* extern "C" */
#include "intern/builder/deg_builder.h"
#include "intern/eval/deg_eval_flush.h"
@@ -336,7 +337,7 @@ void DEG_graph_on_visible_update(Main *bmain, Scene *scene)
{
id_node->tag_update(graph);
DEG::ComponentDepsNode *anim_comp =
- id_node->find_component(DEG::DEPSNODE_TYPE_ANIMATION);
+ id_node->find_component(DEG::DEG_NODE_TYPE_ANIMATION);
if (anim_comp != NULL && object->recalc & OB_RECALC_TIME) {
anim_comp->tag_update(graph);
}
@@ -356,6 +357,10 @@ void DEG_graph_on_visible_update(Main *bmain, Scene *scene)
Object *object = base->object;
DEG::IDDepsNode *id_node = graph->find_id_node(&object->id);
id_node->layers |= base->lay;
+ if (object == scene->camera) {
+ /* Camera should always be updated, it used directly by viewport. */
+ id_node->layers |= (unsigned int)(-1);
+ }
}
DEG::deg_graph_build_flush_layers(graph);
LINKLIST_FOREACH (Base *, base, &scene->base) {
diff --git a/source/blender/depsgraph/intern/depsgraph_type_defines.cc b/source/blender/depsgraph/intern/depsgraph_type_defines.cc
index 39c189629f2..e5033affe2f 100644
--- a/source/blender/depsgraph/intern/depsgraph_type_defines.cc
+++ b/source/blender/depsgraph/intern/depsgraph_type_defines.cc
@@ -32,12 +32,11 @@
#include <cstdlib> // for BLI_assert()
-extern "C" {
+
#include "BLI_utildefines.h"
#include "BLI_ghash.h"
#include "DEG_depsgraph.h"
-} /* extern "C" */
#include "intern/nodes/deg_node.h"
#include "intern/nodes/deg_node_component.h"
@@ -98,23 +97,17 @@ static const char *stringify_opcode(eDepsOperation_Code opcode)
#define STRINGIFY_OPCODE(name) case DEG_OPCODE_##name: return #name
STRINGIFY_OPCODE(OPERATION);
STRINGIFY_OPCODE(PLACEHOLDER);
- STRINGIFY_OPCODE(NOOP);
STRINGIFY_OPCODE(ANIMATION);
STRINGIFY_OPCODE(DRIVER);
- //STRINGIFY_OPCODE(PROXY);
STRINGIFY_OPCODE(TRANSFORM_LOCAL);
STRINGIFY_OPCODE(TRANSFORM_PARENT);
STRINGIFY_OPCODE(TRANSFORM_CONSTRAINTS);
- //STRINGIFY_OPCODE(TRANSFORM_CONSTRAINTS_INIT);
- //STRINGIFY_OPCODE(TRANSFORM_CONSTRAINT);
- //STRINGIFY_OPCODE(TRANSFORM_CONSTRAINTS_DONE);
STRINGIFY_OPCODE(RIGIDBODY_REBUILD);
STRINGIFY_OPCODE(RIGIDBODY_SIM);
STRINGIFY_OPCODE(TRANSFORM_RIGIDBODY);
STRINGIFY_OPCODE(TRANSFORM_FINAL);
STRINGIFY_OPCODE(OBJECT_UBEREVAL);
STRINGIFY_OPCODE(GEOMETRY_UBEREVAL);
- STRINGIFY_OPCODE(GEOMETRY_MODIFIER);
STRINGIFY_OPCODE(GEOMETRY_PATH);
STRINGIFY_OPCODE(POSE_INIT);
STRINGIFY_OPCODE(POSE_DONE);
@@ -123,12 +116,10 @@ static const char *stringify_opcode(eDepsOperation_Code opcode)
STRINGIFY_OPCODE(BONE_LOCAL);
STRINGIFY_OPCODE(BONE_POSE_PARENT);
STRINGIFY_OPCODE(BONE_CONSTRAINTS);
- //STRINGIFY_OPCODE(BONE_CONSTRAINTS_INIT);
- //STRINGIFY_OPCODE(BONE_CONSTRAINT);
- //STRINGIFY_OPCODE(BONE_CONSTRAINTS_DONE);
STRINGIFY_OPCODE(BONE_READY);
STRINGIFY_OPCODE(BONE_DONE);
STRINGIFY_OPCODE(PSYS_EVAL);
+ STRINGIFY_OPCODE(PSYS_EVAL_INIT);
case DEG_NUM_OPCODES: return "SpecialCase";
#undef STRINGIFY_OPCODE
diff --git a/source/blender/depsgraph/intern/depsgraph_types.h b/source/blender/depsgraph/intern/depsgraph_types.h
index c9c4329769d..f05f82caa3d 100644
--- a/source/blender/depsgraph/intern/depsgraph_types.h
+++ b/source/blender/depsgraph/intern/depsgraph_types.h
@@ -67,74 +67,66 @@ typedef enum eDepsNode_Class {
/* Types generally unassociated with user-visible entities,
* but needed for graph functioning.
*/
- DEPSNODE_CLASS_GENERIC = 0,
+ DEG_NODE_CLASS_GENERIC = 0,
/* [Outer Node] An "aspect" of evaluating/updating an ID-Block, requiring
* certain types of evaluation behavior.
*/
- DEPSNODE_CLASS_COMPONENT = 1,
+ DEG_NODE_CLASS_COMPONENT = 1,
/* [Inner Node] A glorified function-pointer/callback for scheduling up
* evaluation operations for components, subject to relationship
* requirements.
*/
- DEPSNODE_CLASS_OPERATION = 2,
+ DEG_NODE_CLASS_OPERATION = 2,
} eDepsNode_Class;
/* Types of Nodes */
typedef enum eDepsNode_Type {
/* Fallback type for invalid return value */
- DEPSNODE_TYPE_UNDEFINED = -1,
+ DEG_NODE_TYPE_UNDEFINED = -1,
/* Inner Node (Operation) */
- DEPSNODE_TYPE_OPERATION = 0,
+ DEG_NODE_TYPE_OPERATION = 0,
/* **** Generic Types **** */
- /* "Current Scene" - basically whatever kicks off the evaluation process. */
- DEPSNODE_TYPE_ROOT,
/* Time-Source */
- DEPSNODE_TYPE_TIMESOURCE,
+ DEG_NODE_TYPE_TIMESOURCE,
/* ID-Block reference - used as landmarks/collection point for components,
* but not usually part of main graph.
*/
- DEPSNODE_TYPE_ID_REF,
- /* Isolated sub-graph - used for keeping instanced data separate from
- * instances using them.
- */
- DEPSNODE_TYPE_SUBGRAPH,
+ DEG_NODE_TYPE_ID_REF,
/* **** Outer Types **** */
/* Parameters Component - Default when nothing else fits
* (i.e. just SDNA property setting).
*/
- DEPSNODE_TYPE_PARAMETERS,
- /* Generic "Proxy-Inherit" Component
- * XXX: Also for instancing of subgraphs?
- */
- DEPSNODE_TYPE_PROXY,
+ DEG_NODE_TYPE_PARAMETERS,
+ /* Generic "Proxy-Inherit" Component. */
+ DEG_NODE_TYPE_PROXY,
/* Animation Component
*
* XXX: merge in with parameters?
*/
- DEPSNODE_TYPE_ANIMATION,
+ DEG_NODE_TYPE_ANIMATION,
/* Transform Component (Parenting/Constraints) */
- DEPSNODE_TYPE_TRANSFORM,
+ DEG_NODE_TYPE_TRANSFORM,
/* Geometry Component (DerivedMesh/Displist) */
- DEPSNODE_TYPE_GEOMETRY,
+ DEG_NODE_TYPE_GEOMETRY,
/* Sequencer Component (Scene Only) */
- DEPSNODE_TYPE_SEQUENCER,
+ DEG_NODE_TYPE_SEQUENCER,
/* **** Evaluation-Related Outer Types (with Subdata) **** */
/* Pose Component - Owner/Container of Bones Eval */
- DEPSNODE_TYPE_EVAL_POSE,
+ DEG_NODE_TYPE_EVAL_POSE,
/* Bone Component - Child/Subcomponent of Pose */
- DEPSNODE_TYPE_BONE,
+ DEG_NODE_TYPE_BONE,
/* Particle Systems Component */
- DEPSNODE_TYPE_EVAL_PARTICLES,
+ DEG_NODE_TYPE_EVAL_PARTICLES,
/* Material Shading Component */
- DEPSNODE_TYPE_SHADING,
+ DEG_NODE_TYPE_SHADING,
/* Cache Component */
- DEPSNODE_TYPE_CACHE,
+ DEG_NODE_TYPE_CACHE,
} eDepsNode_Type;
/* Identifiers for common operations (as an enum). */
@@ -147,8 +139,6 @@ typedef enum eDepsOperation_Code {
// XXX: Placeholder while porting depsgraph code
DEG_OPCODE_PLACEHOLDER,
- DEG_OPCODE_NOOP,
-
/* Animation, Drivers, etc. ------------------------ */
/* NLA + Action */
@@ -157,9 +147,6 @@ typedef enum eDepsOperation_Code {
/* Driver */
DEG_OPCODE_DRIVER,
- /* Proxy Inherit? */
- //DEG_OPCODE_PROXY,
-
/* Transform --------------------------------------- */
/* Transform entry point - local transforms only */
@@ -170,9 +157,6 @@ typedef enum eDepsOperation_Code {
/* Constraints */
DEG_OPCODE_TRANSFORM_CONSTRAINTS,
- //DEG_OPCODE_TRANSFORM_CONSTRAINTS_INIT,
- //DEG_OPCODE_TRANSFORM_CONSTRAINT,
- //DEG_OPCODE_TRANSFORM_CONSTRAINTS_DONE,
/* Rigidbody Sim - Perform Sim */
DEG_OPCODE_RIGIDBODY_REBUILD,
@@ -192,9 +176,6 @@ typedef enum eDepsOperation_Code {
/* XXX: Placeholder - UberEval */
DEG_OPCODE_GEOMETRY_UBEREVAL,
- /* Modifier */
- DEG_OPCODE_GEOMETRY_MODIFIER,
-
/* Curve Objects - Path Calculation (used for path-following tools, */
DEG_OPCODE_GEOMETRY_PATH,
@@ -220,9 +201,6 @@ typedef enum eDepsOperation_Code {
/* Constraints */
DEG_OPCODE_BONE_CONSTRAINTS,
- //DEG_OPCODE_BONE_CONSTRAINTS_INIT,
- //DEG_OPCODE_BONE_CONSTRAINT,
- //DEG_OPCODE_BONE_CONSTRAINTS_DONE,
/* Bone transforms are ready
*
@@ -241,6 +219,7 @@ typedef enum eDepsOperation_Code {
/* Particles --------------------------------------- */
/* XXX: placeholder - Particle System eval */
+ DEG_OPCODE_PSYS_EVAL_INIT,
DEG_OPCODE_PSYS_EVAL,
DEG_NUM_OPCODES,
@@ -258,83 +237,4 @@ protected:
/* String defines for these opcodes, defined in depsgraph_type_defines.cpp */
extern DepsOperationStringifier DEG_OPNAMES;
-/* Type of operation */
-typedef enum eDepsOperation_Type {
- /* **** Primary operation types **** */
-
- /* Initialise evaluation data */
- DEPSOP_TYPE_INIT = 0,
- /* Standard evaluation step */
- DEPSOP_TYPE_EXEC = 1,
- /* Cleanup evaluation data + flush results */
- DEPSOP_TYPE_POST = 2,
-
- /* **** Additional operation types **** */
- /* Indicator for outputting a temporary result that other components
- * can use. // XXX?
- */
- DEPSOP_TYPE_OUT = 3,
- /* Indicator for things like IK Solvers and Rigidbody Sim steps which
- * modify final results of separate entities at once.
- */
- DEPSOP_TYPE_SIM = 4,
- /* Rebuild internal evaluation data - used for Rigidbody Reset and
- * Armature Rebuild-On-Load.
- */
- DEPSOP_TYPE_REBUILD = 5,
-} eDepsOperation_Type;
-
-/* Types of relationships between nodes
- *
- * This is used to provide additional hints to use when filtering
- * the graph, so that we can go without doing more extensive
- * data-level checks...
- */
-typedef enum eDepsRelation_Type {
- /* relationship type unknown/irrelevant */
- DEPSREL_TYPE_STANDARD = 0,
-
- /* root -> active scene or entity (screen, image, etc.) */
- DEPSREL_TYPE_ROOT_TO_ACTIVE,
-
- /* general datablock dependency */
- DEPSREL_TYPE_DATABLOCK,
-
- /* time dependency */
- DEPSREL_TYPE_TIME,
-
- /* component depends on results of another */
- DEPSREL_TYPE_COMPONENT_ORDER,
-
- /* relationship is just used to enforce ordering of operations
- * (e.g. "init()" callback done before "exec() and "cleanup()")
- */
- DEPSREL_TYPE_OPERATION,
-
- /* relationship results from a property driver affecting property */
- DEPSREL_TYPE_DRIVER,
-
- /* relationship is something driver depends on */
- DEPSREL_TYPE_DRIVER_TARGET,
-
- /* relationship is used for transform stack
- * (e.g. parenting, user transforms, constraints)
- */
- DEPSREL_TYPE_TRANSFORM,
-
- /* relationship is used for geometry evaluation
- * (e.g. metaball "motherball" or modifiers)
- */
- DEPSREL_TYPE_GEOMETRY_EVAL,
-
- /* relationship is used to trigger a post-change validity updates */
- DEPSREL_TYPE_UPDATE,
-
- /* relationship is used to trigger editor/screen updates */
- DEPSREL_TYPE_UPDATE_UI,
-
- /* cache dependency */
- DEPSREL_TYPE_CACHE,
-} eDepsRelation_Type;
-
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/eval/deg_eval.cc b/source/blender/depsgraph/intern/eval/deg_eval.cc
index e739bc9dbb5..98b10718404 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval.cc
@@ -34,16 +34,16 @@
#include "PIL_time.h"
-extern "C" {
#include "BLI_utildefines.h"
#include "BLI_task.h"
#include "BLI_ghash.h"
+extern "C" {
#include "BKE_depsgraph.h"
#include "BKE_global.h"
+} /* extern "C" */
#include "DEG_depsgraph.h"
-} /* extern "C" */
#include "atomic_ops.h"
@@ -126,7 +126,9 @@ static void deg_task_run_func(TaskPool *pool,
#endif
}
+ BLI_task_pool_delayed_push_begin(pool, thread_id);
schedule_children(pool, state->graph, node, state->layers, thread_id);
+ BLI_task_pool_delayed_push_end(pool, thread_id);
}
typedef struct CalculatePengindData {
@@ -150,7 +152,7 @@ static void calculate_pending_func(void *data_v, int i)
(node->flag & DEPSOP_FLAG_NEEDS_UPDATE) != 0)
{
foreach (DepsRelation *rel, node->inlinks) {
- if (rel->from->type == DEPSNODE_TYPE_OPERATION &&
+ if (rel->from->type == DEG_NODE_TYPE_OPERATION &&
(rel->flag & DEPSREL_FLAG_CYCLIC) == 0)
{
OperationDepsNode *from = (OperationDepsNode *)rel->from;
@@ -195,7 +197,7 @@ static void calculate_eval_priority(OperationDepsNode *node)
foreach (DepsRelation *rel, node->outlinks) {
OperationDepsNode *to = (OperationDepsNode *)rel->to;
- BLI_assert(to->type == DEPSNODE_TYPE_OPERATION);
+ BLI_assert(to->type == DEG_NODE_TYPE_OPERATION);
calculate_eval_priority(to);
node->eval_priority += to->eval_priority;
}
@@ -263,7 +265,7 @@ static void schedule_children(TaskPool *pool,
{
foreach (DepsRelation *rel, node->outlinks) {
OperationDepsNode *child = (OperationDepsNode *)rel->to;
- BLI_assert(child->type == DEPSNODE_TYPE_OPERATION);
+ BLI_assert(child->type == DEG_NODE_TYPE_OPERATION);
if (child->scheduled) {
/* Happens when having cyclic dependencies. */
continue;
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_debug.cc b/source/blender/depsgraph/intern/eval/deg_eval_debug.cc
index 060544a4407..23f4adbaacd 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_debug.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_debug.cc
@@ -34,16 +34,16 @@
#include <cstring> /* required for STREQ later on. */
-extern "C" {
#include "BLI_listbase.h"
#include "BLI_ghash.h"
-#include "DEG_depsgraph_debug.h"
-
+extern "C" {
#include "WM_api.h"
#include "WM_types.h"
} /* extern "C" */
+#include "DEG_depsgraph_debug.h"
+
#include "intern/nodes/deg_node.h"
#include "intern/nodes/deg_node_component.h"
#include "intern/nodes/deg_node_operation.h"
diff --git a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
index e10f86f6e95..c230ab4c8fd 100644
--- a/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
+++ b/source/blender/depsgraph/intern/eval/deg_eval_flush.cc
@@ -35,16 +35,16 @@
// TODO(sergey): Use some sort of wrapper.
#include <deque>
-extern "C" {
-#include "DNA_object_types.h"
-
#include "BLI_utildefines.h"
#include "BLI_task.h"
#include "BLI_ghash.h"
-#include "DEG_depsgraph.h"
+extern "C" {
+#include "DNA_object_types.h"
} /* extern "C" */
+#include "DEG_depsgraph.h"
+
#include "intern/nodes/deg_node.h"
#include "intern/nodes/deg_node_component.h"
#include "intern/nodes/deg_node_operation.h"
@@ -139,18 +139,18 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
IDDepsNode *id_node = comp_node->owner;
ID *id = id_node->id;
- if(id_node->done == 0) {
+ if (id_node->done == 0) {
deg_editors_id_update(bmain, id);
lib_id_recalc_tag(bmain, id);
/* TODO(sergey): For until we've got proper data nodes in the graph. */
lib_id_recalc_data_tag(bmain, id);
}
- if(comp_node->done == 0) {
+ if (comp_node->done == 0) {
Object *object = NULL;
if (GS(id->name) == ID_OB) {
object = (Object *)id;
- if(id_node->done == 0) {
+ if (id_node->done == 0) {
++num_flushed_objects;
}
}
@@ -164,14 +164,30 @@ void deg_graph_flush_updates(Main *bmain, Depsgraph *graph)
* Plus it ensures visibility changes and relations and
* layers visibility update has proper flags to work with.
*/
- if (comp_node->type == DEPSNODE_TYPE_ANIMATION) {
- object->recalc |= OB_RECALC_TIME;
- }
- else if (comp_node->type == DEPSNODE_TYPE_TRANSFORM) {
- object->recalc |= OB_RECALC_OB;
- }
- else {
- object->recalc |= OB_RECALC_DATA;
+ switch (comp_node->type) {
+ case DEG_NODE_TYPE_UNDEFINED:
+ case DEG_NODE_TYPE_OPERATION:
+ case DEG_NODE_TYPE_TIMESOURCE:
+ case DEG_NODE_TYPE_ID_REF:
+ case DEG_NODE_TYPE_PARAMETERS:
+ case DEG_NODE_TYPE_SEQUENCER:
+ /* Ignore, does not translate to object component. */
+ break;
+ case DEG_NODE_TYPE_ANIMATION:
+ object->recalc |= OB_RECALC_TIME;
+ break;
+ case DEG_NODE_TYPE_TRANSFORM:
+ object->recalc |= OB_RECALC_OB;
+ break;
+ case DEG_NODE_TYPE_GEOMETRY:
+ case DEG_NODE_TYPE_EVAL_POSE:
+ case DEG_NODE_TYPE_BONE:
+ case DEG_NODE_TYPE_EVAL_PARTICLES:
+ case DEG_NODE_TYPE_SHADING:
+ case DEG_NODE_TYPE_CACHE:
+ case DEG_NODE_TYPE_PROXY:
+ object->recalc |= OB_RECALC_DATA;
+ break;
}
}
}
diff --git a/source/blender/depsgraph/intern/nodes/deg_node.cc b/source/blender/depsgraph/intern/nodes/deg_node.cc
index 57b25c10670..a15317586c1 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node.cc
@@ -41,15 +41,14 @@ extern "C" {
#include "DNA_anim_types.h"
#include "BKE_animsys.h"
+}
#include "DEG_depsgraph.h"
-}
#include "intern/nodes/deg_node_component.h"
#include "intern/nodes/deg_node_operation.h"
#include "intern/depsgraph_intern.h"
#include "util/deg_util_foreach.h"
-#include "util/deg_util_hash.h"
namespace DEG {
@@ -61,12 +60,12 @@ namespace DEG {
DepsNode::TypeInfo::TypeInfo(eDepsNode_Type type, const char *tname)
{
this->type = type;
- if (type == DEPSNODE_TYPE_OPERATION)
- this->tclass = DEPSNODE_CLASS_OPERATION;
- else if (type < DEPSNODE_TYPE_PARAMETERS)
- this->tclass = DEPSNODE_CLASS_GENERIC;
+ if (type == DEG_NODE_TYPE_OPERATION)
+ this->tclass = DEG_NODE_CLASS_OPERATION;
+ else if (type < DEG_NODE_TYPE_PARAMETERS)
+ this->tclass = DEG_NODE_CLASS_GENERIC;
else
- this->tclass = DEPSNODE_CLASS_COMPONENT;
+ this->tclass = DEG_NODE_CLASS_COMPONENT;
this->tname = tname;
}
@@ -110,34 +109,9 @@ void TimeSourceDepsNode::tag_update(Depsgraph *graph)
}
}
-
-/* Root Node ============================================== */
-
-RootDepsNode::RootDepsNode() : scene(NULL), time_source(NULL)
-{
-}
-
-RootDepsNode::~RootDepsNode()
-{
- OBJECT_GUARDED_DELETE(time_source, TimeSourceDepsNode);
-}
-
-TimeSourceDepsNode *RootDepsNode::add_time_source(const char *name)
-{
- if (!time_source) {
- DepsNodeFactory *factory = deg_get_node_factory(DEPSNODE_TYPE_TIMESOURCE);
- time_source = (TimeSourceDepsNode *)factory->create_node(NULL, "", name);
- /*time_source->owner = this;*/ // XXX
- }
- return time_source;
-}
-
-DEG_DEPSNODE_DEFINE(RootDepsNode, DEPSNODE_TYPE_ROOT, "Root DepsNode");
-static DepsNodeFactoryImpl<RootDepsNode> DNTI_ROOT;
-
/* Time Source Node ======================================= */
-DEG_DEPSNODE_DEFINE(TimeSourceDepsNode, DEPSNODE_TYPE_TIMESOURCE, "Time Source");
+DEG_DEPSNODE_DEFINE(TimeSourceDepsNode, DEG_NODE_TYPE_TIMESOURCE, "Time Source");
static DepsNodeFactoryImpl<TimeSourceDepsNode> DNTI_TIMESOURCE;
/* ID Node ================================================ */
@@ -158,8 +132,8 @@ static unsigned int id_deps_node_hash_key(const void *key_v)
{
const IDDepsNode::ComponentIDKey *key =
reinterpret_cast<const IDDepsNode::ComponentIDKey *>(key_v);
- return hash_combine(BLI_ghashutil_uinthash(key->type),
- BLI_ghashutil_strhash_p(key->name));
+ return BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(key->type),
+ BLI_ghashutil_strhash_p(key->name));
}
static bool id_deps_node_hash_key_cmp(const void *a, const void *b)
@@ -211,8 +185,9 @@ void IDDepsNode::init(const ID *id, const char *UNUSED(subdata))
/* Free 'id' node. */
IDDepsNode::~IDDepsNode()
{
- clear_components();
- BLI_ghash_free(components, id_deps_node_hash_key_free, NULL);
+ BLI_ghash_free(components,
+ id_deps_node_hash_key_free,
+ id_deps_node_hash_value_free);
}
ComponentDepsNode *IDDepsNode::find_component(eDepsNode_Type type,
@@ -238,33 +213,13 @@ ComponentDepsNode *IDDepsNode::add_component(eDepsNode_Type type,
return comp_node;
}
-void IDDepsNode::remove_component(eDepsNode_Type type, const char *name)
-{
- ComponentDepsNode *comp_node = find_component(type, name);
- if (comp_node) {
- /* Unregister. */
- ComponentIDKey key(type, name);
- BLI_ghash_remove(components,
- &key,
- id_deps_node_hash_key_free,
- id_deps_node_hash_value_free);
- }
-}
-
-void IDDepsNode::clear_components()
-{
- BLI_ghash_clear(components,
- id_deps_node_hash_key_free,
- id_deps_node_hash_value_free);
-}
-
void IDDepsNode::tag_update(Depsgraph *graph)
{
GHASH_FOREACH_BEGIN(ComponentDepsNode *, comp_node, components)
{
/* TODO(sergey): What about drievrs? */
- bool do_component_tag = comp_node->type != DEPSNODE_TYPE_ANIMATION;
- if (comp_node->type == DEPSNODE_TYPE_ANIMATION) {
+ bool do_component_tag = comp_node->type != DEG_NODE_TYPE_ANIMATION;
+ if (comp_node->type == DEG_NODE_TYPE_ANIMATION) {
AnimData *adt = BKE_animdata_from_id(id);
/* Animation data might be null if relations are tagged for update. */
if (adt != NULL && (adt->recalc & ADT_RECALC_ANIM)) {
@@ -287,46 +242,13 @@ void IDDepsNode::finalize_build()
GHASH_FOREACH_END();
}
-DEG_DEPSNODE_DEFINE(IDDepsNode, DEPSNODE_TYPE_ID_REF, "ID Node");
+DEG_DEPSNODE_DEFINE(IDDepsNode, DEG_NODE_TYPE_ID_REF, "ID Node");
static DepsNodeFactoryImpl<IDDepsNode> DNTI_ID_REF;
-/* Subgraph Node ========================================== */
-
-/* Initialize 'subgraph' node - from pointer data given. */
-void SubgraphDepsNode::init(const ID *id, const char *UNUSED(subdata))
-{
- /* Store ID-ref if provided. */
- this->root_id = (ID *)id;
-
- /* NOTE: graph will need to be added manually,
- * as we don't have any way of passing this down.
- */
-}
-
-/* Free 'subgraph' node */
-SubgraphDepsNode::~SubgraphDepsNode()
-{
- /* Only free if graph not shared, of if this node is the first
- * reference to it...
- */
- // XXX: prune these flags a bit...
- if ((this->flag & SUBGRAPH_FLAG_FIRSTREF) || !(this->flag & SUBGRAPH_FLAG_SHARED)) {
- /* Free the referenced graph. */
- DEG_graph_free(reinterpret_cast< ::Depsgraph* >(graph));
- graph = NULL;
- }
-}
-
-DEG_DEPSNODE_DEFINE(SubgraphDepsNode, DEPSNODE_TYPE_SUBGRAPH, "Subgraph Node");
-static DepsNodeFactoryImpl<SubgraphDepsNode> DNTI_SUBGRAPH;
-
void deg_register_base_depsnodes()
{
- deg_register_node_typeinfo(&DNTI_ROOT);
deg_register_node_typeinfo(&DNTI_TIMESOURCE);
-
deg_register_node_typeinfo(&DNTI_ID_REF);
- deg_register_node_typeinfo(&DNTI_SUBGRAPH);
}
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/nodes/deg_node.h b/source/blender/depsgraph/intern/nodes/deg_node.h
index 7c2f53840b6..9f1b61faf24 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node.h
+++ b/source/blender/depsgraph/intern/nodes/deg_node.h
@@ -127,22 +127,6 @@ struct TimeSourceDepsNode : public DepsNode {
DEG_DEPSNODE_DECLARE;
};
-/* Root Node. */
-struct RootDepsNode : public DepsNode {
- RootDepsNode();
- ~RootDepsNode();
-
- TimeSourceDepsNode *add_time_source(const char *name = "");
-
- /* scene that this corresponds to */
- Scene *scene;
-
- /* Entrypoint node for time-changed. */
- TimeSourceDepsNode *time_source;
-
- DEG_DEPSNODE_DECLARE;
-};
-
/* ID-Block Reference */
struct IDDepsNode : public DepsNode {
struct ComponentIDKey {
@@ -160,8 +144,6 @@ struct IDDepsNode : public DepsNode {
const char *name = "") const;
ComponentDepsNode *add_component(eDepsNode_Type type,
const char *name = "");
- void remove_component(eDepsNode_Type type, const char *name = "");
- void clear_components();
void tag_update(Depsgraph *graph);
@@ -185,41 +167,6 @@ struct IDDepsNode : public DepsNode {
DEG_DEPSNODE_DECLARE;
};
-/* Subgraph Reference. */
-struct SubgraphDepsNode : public DepsNode {
- void init(const ID *id, const char *subdata);
- ~SubgraphDepsNode();
-
- /* Instanced graph. */
- Depsgraph *graph;
-
- /* ID-block at root of subgraph (if applicable). */
- ID *root_id;
-
- /* Number of nodes which use/reference this subgraph - if just 1, it may be
- * possible to merge into main,
- */
- size_t num_users;
-
- /* (eSubgraphRef_Flag) assorted settings for subgraph node. */
- int flag;
-
- DEG_DEPSNODE_DECLARE;
-};
-
-/* Flags for subgraph node */
-typedef enum eSubgraphRef_Flag {
- /* Subgraph referenced is shared with another reference, so shouldn't
- * free on exit.
- */
- SUBGRAPH_FLAG_SHARED = (1 << 0),
-
- /* Node is first reference to subgraph, so it can be freed when we are
- * removed.
- */
- SUBGRAPH_FLAG_FIRSTREF = (1 << 1),
-} eSubgraphRef_Flag;
-
void deg_register_base_depsnodes();
} // namespace DEG
diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.cc b/source/blender/depsgraph/intern/nodes/deg_node_component.cc
index 06f91ac7fdc..e87c87813e3 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node_component.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node_component.cc
@@ -33,9 +33,10 @@
#include <stdio.h>
#include <cstring> /* required for STREQ later on. */
-extern "C" {
#include "BLI_utildefines.h"
+#include "BLI_ghash.h"
+extern "C" {
#include "DNA_object_types.h"
#include "BKE_action.h"
@@ -44,7 +45,6 @@ extern "C" {
#include "intern/nodes/deg_node_operation.h"
#include "intern/depsgraph_intern.h"
#include "util/deg_util_foreach.h"
-#include "util/deg_util_hash.h"
namespace DEG {
@@ -95,8 +95,8 @@ static unsigned int comp_node_hash_key(const void *key_v)
{
const ComponentDepsNode::OperationIDKey *key =
reinterpret_cast<const ComponentDepsNode::OperationIDKey *>(key_v);
- return hash_combine(BLI_ghashutil_uinthash(key->opcode),
- BLI_ghashutil_strhash_p(key->name));
+ return BLI_ghashutil_combine_hash(BLI_ghashutil_uinthash(key->opcode),
+ BLI_ghashutil_strhash_p(key->name));
}
static bool comp_node_hash_key_cmp(const void *a, const void *b)
@@ -198,32 +198,20 @@ OperationDepsNode *ComponentDepsNode::has_operation(eDepsOperation_Code opcode,
return has_operation(key);
}
-OperationDepsNode *ComponentDepsNode::add_operation(eDepsOperation_Type optype,
- DepsEvalOperationCb op,
+OperationDepsNode *ComponentDepsNode::add_operation(const DepsEvalOperationCb& op,
eDepsOperation_Code opcode,
const char *name,
int name_tag)
{
OperationDepsNode *op_node = has_operation(opcode, name, name_tag);
if (!op_node) {
- DepsNodeFactory *factory = deg_get_node_factory(DEPSNODE_TYPE_OPERATION);
+ DepsNodeFactory *factory = deg_get_node_factory(DEG_NODE_TYPE_OPERATION);
op_node = (OperationDepsNode *)factory->create_node(this->owner->id, "", name);
/* register opnode in this component's operation set */
OperationIDKey *key = OBJECT_GUARDED_NEW(OperationIDKey, opcode, name, name_tag);
BLI_ghash_insert(operations_map, key, op_node);
- /* set as entry/exit node of component (if appropriate) */
- if (optype == DEPSOP_TYPE_INIT) {
- BLI_assert(this->entry_operation == NULL);
- this->entry_operation = op_node;
- }
- else if (optype == DEPSOP_TYPE_POST) {
- // XXX: review whether DEPSOP_TYPE_OUT is better than DEPSOP_TYPE_POST, or maybe have both?
- BLI_assert(this->exit_operation == NULL);
- this->exit_operation = op_node;
- }
-
/* set backlink */
op_node->owner = this;
}
@@ -235,13 +223,24 @@ OperationDepsNode *ComponentDepsNode::add_operation(eDepsOperation_Type optype,
/* attach extra data */
op_node->evaluate = op;
- op_node->optype = optype;
op_node->opcode = opcode;
op_node->name = name;
return op_node;
}
+void ComponentDepsNode::set_entry_operation(OperationDepsNode *op_node)
+{
+ BLI_assert(entry_operation == NULL);
+ entry_operation = op_node;
+}
+
+void ComponentDepsNode::set_exit_operation(OperationDepsNode *op_node)
+{
+ BLI_assert(exit_operation == NULL);
+ exit_operation = op_node;
+}
+
void ComponentDepsNode::clear_operations()
{
if (operations_map != NULL) {
@@ -336,37 +335,37 @@ void ComponentDepsNode::finalize_build()
/* Parameter Component Defines ============================ */
-DEG_DEPSNODE_DEFINE(ParametersComponentDepsNode, DEPSNODE_TYPE_PARAMETERS, "Parameters Component");
+DEG_DEPSNODE_DEFINE(ParametersComponentDepsNode, DEG_NODE_TYPE_PARAMETERS, "Parameters Component");
static DepsNodeFactoryImpl<ParametersComponentDepsNode> DNTI_PARAMETERS;
/* Animation Component Defines ============================ */
-DEG_DEPSNODE_DEFINE(AnimationComponentDepsNode, DEPSNODE_TYPE_ANIMATION, "Animation Component");
+DEG_DEPSNODE_DEFINE(AnimationComponentDepsNode, DEG_NODE_TYPE_ANIMATION, "Animation Component");
static DepsNodeFactoryImpl<AnimationComponentDepsNode> DNTI_ANIMATION;
/* Transform Component Defines ============================ */
-DEG_DEPSNODE_DEFINE(TransformComponentDepsNode, DEPSNODE_TYPE_TRANSFORM, "Transform Component");
+DEG_DEPSNODE_DEFINE(TransformComponentDepsNode, DEG_NODE_TYPE_TRANSFORM, "Transform Component");
static DepsNodeFactoryImpl<TransformComponentDepsNode> DNTI_TRANSFORM;
/* Proxy Component Defines ================================ */
-DEG_DEPSNODE_DEFINE(ProxyComponentDepsNode, DEPSNODE_TYPE_PROXY, "Proxy Component");
+DEG_DEPSNODE_DEFINE(ProxyComponentDepsNode, DEG_NODE_TYPE_PROXY, "Proxy Component");
static DepsNodeFactoryImpl<ProxyComponentDepsNode> DNTI_PROXY;
/* Geometry Component Defines ============================= */
-DEG_DEPSNODE_DEFINE(GeometryComponentDepsNode, DEPSNODE_TYPE_GEOMETRY, "Geometry Component");
+DEG_DEPSNODE_DEFINE(GeometryComponentDepsNode, DEG_NODE_TYPE_GEOMETRY, "Geometry Component");
static DepsNodeFactoryImpl<GeometryComponentDepsNode> DNTI_GEOMETRY;
/* Sequencer Component Defines ============================ */
-DEG_DEPSNODE_DEFINE(SequencerComponentDepsNode, DEPSNODE_TYPE_SEQUENCER, "Sequencer Component");
+DEG_DEPSNODE_DEFINE(SequencerComponentDepsNode, DEG_NODE_TYPE_SEQUENCER, "Sequencer Component");
static DepsNodeFactoryImpl<SequencerComponentDepsNode> DNTI_SEQUENCER;
/* Pose Component ========================================= */
-DEG_DEPSNODE_DEFINE(PoseComponentDepsNode, DEPSNODE_TYPE_EVAL_POSE, "Pose Eval Component");
+DEG_DEPSNODE_DEFINE(PoseComponentDepsNode, DEG_NODE_TYPE_EVAL_POSE, "Pose Eval Component");
static DepsNodeFactoryImpl<PoseComponentDepsNode> DNTI_EVAL_POSE;
/* Bone Component ========================================= */
@@ -388,22 +387,22 @@ void BoneComponentDepsNode::init(const ID *id, const char *subdata)
this->pchan = BKE_pose_channel_find_name(ob->pose, subdata);
}
-DEG_DEPSNODE_DEFINE(BoneComponentDepsNode, DEPSNODE_TYPE_BONE, "Bone Component");
+DEG_DEPSNODE_DEFINE(BoneComponentDepsNode, DEG_NODE_TYPE_BONE, "Bone Component");
static DepsNodeFactoryImpl<BoneComponentDepsNode> DNTI_BONE;
/* Particles Component Defines ============================ */
-DEG_DEPSNODE_DEFINE(ParticlesComponentDepsNode, DEPSNODE_TYPE_EVAL_PARTICLES, "Particles Component");
+DEG_DEPSNODE_DEFINE(ParticlesComponentDepsNode, DEG_NODE_TYPE_EVAL_PARTICLES, "Particles Component");
static DepsNodeFactoryImpl<ParticlesComponentDepsNode> DNTI_EVAL_PARTICLES;
/* Shading Component Defines ============================ */
-DEG_DEPSNODE_DEFINE(ShadingComponentDepsNode, DEPSNODE_TYPE_SHADING, "Shading Component");
+DEG_DEPSNODE_DEFINE(ShadingComponentDepsNode, DEG_NODE_TYPE_SHADING, "Shading Component");
static DepsNodeFactoryImpl<ShadingComponentDepsNode> DNTI_SHADING;
/* Cache Component Defines ============================ */
-DEG_DEPSNODE_DEFINE(CacheComponentDepsNode, DEPSNODE_TYPE_CACHE, "Cache Component");
+DEG_DEPSNODE_DEFINE(CacheComponentDepsNode, DEG_NODE_TYPE_CACHE, "Cache Component");
static DepsNodeFactoryImpl<CacheComponentDepsNode> DNTI_CACHE;
diff --git a/source/blender/depsgraph/intern/nodes/deg_node_component.h b/source/blender/depsgraph/intern/nodes/deg_node_component.h
index 969771a29c9..4ef7dad3ac6 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node_component.h
+++ b/source/blender/depsgraph/intern/nodes/deg_node_component.h
@@ -99,12 +99,18 @@ struct ComponentDepsNode : public DepsNode {
* \param op: The operation to perform
* \param name: Identifier for operation - used to find/locate it again
*/
- OperationDepsNode *add_operation(eDepsOperation_Type optype,
- DepsEvalOperationCb op,
+ OperationDepsNode *add_operation(const DepsEvalOperationCb& op,
eDepsOperation_Code opcode,
const char *name,
int name_tag);
+ /* Entry/exit operations management.
+ *
+ * Use those instead of direct set since this will perform sanity checks.
+ */
+ void set_entry_operation(OperationDepsNode *op_node);
+ void set_exit_operation(OperationDepsNode *op_node);
+
void clear_operations();
void tag_update(Depsgraph *graph);
diff --git a/source/blender/depsgraph/intern/nodes/deg_node_operation.cc b/source/blender/depsgraph/intern/nodes/deg_node_operation.cc
index 9eed4dfe8d8..7467264f612 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node_operation.cc
+++ b/source/blender/depsgraph/intern/nodes/deg_node_operation.cc
@@ -32,13 +32,11 @@
#include "MEM_guardedalloc.h"
-extern "C" {
#include "BLI_utildefines.h"
-} /* extern "C" */
+#include "BLI_ghash.h"
#include "intern/depsgraph.h"
#include "intern/depsgraph_intern.h"
-#include "util/deg_util_hash.h"
namespace DEG {
@@ -67,7 +65,7 @@ string OperationDepsNode::identifier() const
string OperationDepsNode::full_identifier() const
{
string owner_str = "";
- if (owner->type == DEPSNODE_TYPE_BONE) {
+ if (owner->type == DEG_NODE_TYPE_BONE) {
owner_str = string(owner->owner->name) + "." + owner->name;
}
else {
@@ -86,7 +84,19 @@ void OperationDepsNode::tag_update(Depsgraph *graph)
graph->add_entry_tag(this);
}
-DEG_DEPSNODE_DEFINE(OperationDepsNode, DEPSNODE_TYPE_OPERATION, "Operation");
+void OperationDepsNode::set_as_entry()
+{
+ BLI_assert(owner != NULL);
+ owner->set_entry_operation(this);
+}
+
+void OperationDepsNode::set_as_exit()
+{
+ BLI_assert(owner != NULL);
+ owner->set_exit_operation(this);
+}
+
+DEG_DEPSNODE_DEFINE(OperationDepsNode, DEG_NODE_TYPE_OPERATION, "Operation");
static DepsNodeFactoryImpl<OperationDepsNode> DNTI_OPERATION;
void deg_register_operation_depsnodes()
diff --git a/source/blender/depsgraph/intern/nodes/deg_node_operation.h b/source/blender/depsgraph/intern/nodes/deg_node_operation.h
index 598393054db..1e5c3832d03 100644
--- a/source/blender/depsgraph/intern/nodes/deg_node_operation.h
+++ b/source/blender/depsgraph/intern/nodes/deg_node_operation.h
@@ -44,9 +44,6 @@ typedef enum eDepsOperation_Flag {
DEPSOP_FLAG_NEEDS_UPDATE = (1 << 0),
/* node was directly modified, causing need for update */
- /* XXX: intention is to make it easier to tell when we just need to
- * take subgraphs.
- */
DEPSOP_FLAG_DIRECTLY_MODIFIED = (1 << 1),
/* Operation is evaluated using CPython; has GIL and security
@@ -57,8 +54,6 @@ typedef enum eDepsOperation_Flag {
/* Atomic Operation - Base type for all operations */
struct OperationDepsNode : public DepsNode {
-
-
OperationDepsNode();
~OperationDepsNode();
@@ -72,21 +67,21 @@ struct OperationDepsNode : public DepsNode {
OperationDepsNode *get_entry_operation() { return this; }
OperationDepsNode *get_exit_operation() { return this; }
+ /* Set this operation as compoonent's entry/exit operation. */
+ void set_as_entry();
+ void set_as_exit();
+
/* Component that contains the operation. */
ComponentDepsNode *owner;
/* Callback for operation. */
DepsEvalOperationCb evaluate;
-
/* How many inlinks are we still waiting on before we can be evaluated. */
uint32_t num_links_pending;
float eval_priority;
bool scheduled;
- /* Stage of evaluation */
- eDepsOperation_Type optype;
-
/* Identifier for the operation being performed. */
eDepsOperation_Code opcode;
diff --git a/source/blender/depsgraph/util/deg_util_foreach.h b/source/blender/depsgraph/util/deg_util_foreach.h
index 87d37168d51..cb7361fc708 100644
--- a/source/blender/depsgraph/util/deg_util_foreach.h
+++ b/source/blender/depsgraph/util/deg_util_foreach.h
@@ -46,28 +46,3 @@
# define foreach(x, y) for (x; false; (void)y)
#endif
-
-#define GHASH_FOREACH_BEGIN(type, var, what) \
- do { \
- GHashIterator gh_iter##var; \
- GHASH_ITER(gh_iter##var, what) { \
- type var = reinterpret_cast<type>(BLI_ghashIterator_getValue(&gh_iter##var)); \
-
-#define GHASH_FOREACH_END() \
- } \
- } while(0)
-
-#define GSET_FOREACH_BEGIN(type, var, what) \
- do { \
- GSetIterator gh_iter##var; \
- GSET_ITER(gh_iter##var, what) { \
- type var = reinterpret_cast<type>(BLI_gsetIterator_getKey(&gh_iter##var)); \
-
-#define GSET_FOREACH_END() \
- } \
- } while(0)
-
-#define LINKLIST_FOREACH(type, var, list) \
- for (type var = (type)((list)->first); \
- var != NULL; \
- var = (type)(((Link*)(var))->next))
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index 98900812bb2..a6febdb575e 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -579,6 +579,7 @@ void ANIM_center_frame(struct bContext *C, int smooth_viewtx)
break;
}
/* else drop through, keep range instead */
+ ATTR_FALLTHROUGH;
case ZOOM_FRAME_MODE_KEEP_RANGE:
default:
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 823cde75334..be01f8cbe69 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -888,13 +888,14 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *even
ed_marker_move_cancel(C, op);
return OPERATOR_CANCELLED;
}
- /* else continue; <--- see if release event should be caught for tweak-end */
+ /* else continue; <--- see if release event should be caught for tweak-end */
+ ATTR_FALLTHROUGH;
case RETKEY:
case PADENTER:
case LEFTMOUSE:
case MIDDLEMOUSE:
- if (WM_modal_tweak_exit(event, mm->event_type)) {
+ if (WM_event_is_modal_tweak_exit(event, mm->event_type)) {
ed_marker_move_exit(C, op);
WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index 4571df0f077..9d25fc9e1a3 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -452,7 +452,7 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac)
ok |= KEYFRAME_OK_H2; \
} \
} (void)0
-
+
/* ------------------------ */
static short ok_bezier_frame(KeyframeEditData *ked, BezTriple *bezt)
diff --git a/source/blender/editors/armature/armature_naming.c b/source/blender/editors/armature/armature_naming.c
index c928508237d..db4b642fe91 100644
--- a/source/blender/editors/armature/armature_naming.c
+++ b/source/blender/editors/armature/armature_naming.c
@@ -311,8 +311,8 @@ typedef struct BoneFlipNameData {
* This way if we are flipping related bones (e.g., Bone.L, Bone.R) at the same time
* all the bones are safely renamed, without conflicting with each other.
*
- * \param arm Armature the bones belong to
- * \param bones ListBase of BoneConflict elems, populated via ED_armature_bones_flip_names_add
+ * \param arm: Armature the bones belong to
+ * \param bones_names: List of BoneConflict elems.
*/
void ED_armature_bones_flip_names(bArmature *arm, ListBase *bones_names)
{
diff --git a/source/blender/editors/armature/pose_lib.c b/source/blender/editors/armature/pose_lib.c
index e3c64b523b1..25f1b282f14 100644
--- a/source/blender/editors/armature/pose_lib.c
+++ b/source/blender/editors/armature/pose_lib.c
@@ -328,7 +328,7 @@ static int poselib_sanitize_exec(bContext *C, wmOperator *op)
/* add pose to poselib */
marker = MEM_callocN(sizeof(TimeMarker), "ActionMarker");
- BLI_strncpy(marker->name, "Pose", sizeof(marker->name));
+ BLI_snprintf(marker->name, sizeof(marker->name), "F%d Pose", (int)ak->cfra);
marker->frame = (int)ak->cfra;
marker->flag = -1;
diff --git a/source/blender/editors/armature/pose_slide.c b/source/blender/editors/armature/pose_slide.c
index 21cb405c32b..8dfcd5acab8 100644
--- a/source/blender/editors/armature/pose_slide.c
+++ b/source/blender/editors/armature/pose_slide.c
@@ -885,6 +885,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
break;
}
default:
+ {
if ((event->val == KM_PRESS) && handleNumInput(C, &pso->num, event)) {
float value;
@@ -972,6 +973,7 @@ static int pose_slide_modal(bContext *C, wmOperator *op, const wmEvent *event)
/* allow to pass through */
return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH;
}
+ }
}
diff --git a/source/blender/editors/armature/reeb.c b/source/blender/editors/armature/reeb.c
index 661a8e1de9f..2bcf3099104 100644
--- a/source/blender/editors/armature/reeb.c
+++ b/source/blender/editors/armature/reeb.c
@@ -2240,9 +2240,9 @@ static void glueByMergeSort(ReebGraph *rg, ReebArc *a0, ReebArc *a1, ReebEdge *e
else {
a1 = nextArcMappedToEdge(a1, e1);
}
+ }
}
}
-}
static void mergePaths(ReebGraph *rg, ReebEdge *e0, ReebEdge *e1, ReebEdge *e2)
{
diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 037c85e19dc..4580b0f667b 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -4161,7 +4161,7 @@ static int make_segment_exec(bContext *C, wmOperator *op)
*/
bp = nu->bp;
- if (bp[nu->pntsu - 1].f1 & SELECT) {
+ if (bp[nu->pntsu - 1].f1 & SELECT) {
if (nu2 == NULL) {
nu2 = nu;
}
@@ -5851,6 +5851,7 @@ static int curve_dissolve_exec(bContext *C, wmOperator *UNUSED(op))
BLI_assert(points_stride + dims == points + (points_len * dims));
float tan_l[3], tan_r[3], error_sq_dummy;
+ unsigned int error_index_dummy;
sub_v3_v3v3(tan_l, bezt_prev->vec[1], bezt_prev->vec[2]);
normalize_v3(tan_l);
@@ -5861,7 +5862,7 @@ static int curve_dissolve_exec(bContext *C, wmOperator *UNUSED(op))
points, points_len, NULL, dims, FLT_EPSILON,
tan_l, tan_r,
bezt_prev->vec[2], bezt_next->vec[0],
- &error_sq_dummy);
+ &error_sq_dummy, &error_index_dummy);
if (!ELEM(bezt_prev->h2, HD_FREE, HD_ALIGN)) {
bezt_prev->h2 = (bezt_prev->h2 == HD_VECT) ? HD_FREE : HD_ALIGN;
@@ -6048,6 +6049,9 @@ int join_curve_exec(bContext *C, wmOperator *op)
cu = ob->data;
BLI_movelisttolist(&cu->nurb, &tempbase);
+ /* Account for mixed 2D/3D curves when joining */
+ BKE_curve_curve_dimension_update(cu);
+
DAG_relations_tag_update(bmain); // because we removed object(s), call before editmode!
DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA);
diff --git a/source/blender/editors/gpencil/drawgpencil.c b/source/blender/editors/gpencil/drawgpencil.c
index f091609da49..ecab37c729f 100644
--- a/source/blender/editors/gpencil/drawgpencil.c
+++ b/source/blender/editors/gpencil/drawgpencil.c
@@ -528,15 +528,15 @@ static void gp_draw_stroke_fill(
}
else {
/* As an initial implementation, we use the OpenGL filled polygon drawing
- * here since it's the easiest option to implement for this case. It does
- * come with limitations (notably for concave shapes), though it shouldn't
- * be much of an issue in most cases.
- *
- * We keep this legacy implementation around despite now having the high quality
- * fills, as this is necessary for keeping everything working nicely for files
- * created using old versions of Blender which may have depended on the artifacts
- * the old fills created.
- */
+ * here since it's the easiest option to implement for this case. It does
+ * come with limitations (notably for concave shapes), though it shouldn't
+ * be much of an issue in most cases.
+ *
+ * We keep this legacy implementation around despite now having the high quality
+ * fills, as this is necessary for keeping everything working nicely for files
+ * created using old versions of Blender which may have depended on the artifacts
+ * the old fills created.
+ */
bGPDspoint *pt;
glBegin(GL_POLYGON);
diff --git a/source/blender/editors/gpencil/gpencil_brush.c b/source/blender/editors/gpencil/gpencil_brush.c
index ec5a42c23a5..e5fb162a96c 100644
--- a/source/blender/editors/gpencil/gpencil_brush.c
+++ b/source/blender/editors/gpencil/gpencil_brush.c
@@ -297,9 +297,9 @@ static bool gp_brush_strength_apply(
float inf;
/* Compute strength of effect
- * - We divide the strength by 10, so that users can set "sane" values.
- * Otherwise, good default values are in the range of 0.093
- */
+ * - We divide the strength by 10, so that users can set "sane" values.
+ * Otherwise, good default values are in the range of 0.093
+ */
inf = gp_brush_influence_calc(gso, radius, co) / 10.0f;
/* apply */
@@ -710,7 +710,7 @@ static bool gp_brush_randomize_apply(tGP_BrushEditData *gso, bGPDstroke *gps, in
}
else {
/* ERROR */
- BLI_assert("3D stroke being sculpted in non-3D view");
+ BLI_assert(!"3D stroke being sculpted in non-3D view");
}
}
else {
@@ -773,6 +773,9 @@ typedef struct tGPSB_CloneBrushData {
/* for "stamp" mode, the currently pasted brushes */
bGPDstroke **new_strokes;
+
+ /* mapping from colors referenced per stroke, to the new colours in the "pasted" strokes */
+ GHash *new_colors;
} tGPSB_CloneBrushData;
/* Initialise "clone" brush data */
@@ -816,6 +819,11 @@ static void gp_brush_clone_init(bContext *C, tGP_BrushEditData *gso)
if (1 /*gso->brush->mode == GP_EDITBRUSH_CLONE_MODE_STAMP*/) {
data->new_strokes = MEM_callocN(sizeof(bGPDstroke *) * data->totitems, "cloned strokes ptr array");
}
+
+ /* Init colormap for mapping between the pasted stroke's source colour(names)
+ * and the final colours that will be used here instead...
+ */
+ data->new_colors = gp_copybuf_validate_colormap(gso->gpd);
}
/* Free custom data used for "clone" brush */
@@ -829,6 +837,12 @@ static void gp_brush_clone_free(tGP_BrushEditData *gso)
data->new_strokes = NULL;
}
+ /* free copybuf colormap */
+ if (data->new_colors) {
+ BLI_ghash_free(data->new_colors, NULL, NULL);
+ data->new_colors = NULL;
+ }
+
/* free the customdata itself */
MEM_freeN(data);
gso->customdata = NULL;
@@ -869,6 +883,13 @@ static void gp_brush_clone_add(bContext *C, tGP_BrushEditData *gso)
new_stroke->next = new_stroke->prev = NULL;
BLI_addtail(&gpf->strokes, new_stroke);
+ /* Fix color references */
+ BLI_assert(new_stroke->colorname[0] != '\0');
+ new_stroke->palcolor = BLI_ghash_lookup(data->new_colors, new_stroke->colorname);
+
+ BLI_assert(new_stroke->palcolor != NULL);
+ BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname));
+
/* Adjust all the stroke's points, so that the strokes
* get pasted relative to where the cursor is now
*/
diff --git a/source/blender/editors/gpencil/gpencil_edit.c b/source/blender/editors/gpencil/gpencil_edit.c
index 601a86b97cb..fc6df49cf6c 100644
--- a/source/blender/editors/gpencil/gpencil_edit.c
+++ b/source/blender/editors/gpencil/gpencil_edit.c
@@ -38,8 +38,11 @@
#include "MEM_guardedalloc.h"
-#include "BLI_math.h"
#include "BLI_blenlib.h"
+#include "BLI_ghash.h"
+#include "BLI_math.h"
+#include "BLI_string.h"
+#include "BLI_string_utils.h"
#include "BLI_utildefines.h"
#include "BLT_translation.h"
@@ -335,11 +338,27 @@ void GPENCIL_OT_duplicate(wmOperatorType *ot)
/* NOTE: is exposed within the editors/gpencil module so that other tools can use it too */
ListBase gp_strokes_copypastebuf = {NULL, NULL};
+/* Hash for hanging on to all the palette colors used by strokes in the buffer
+ *
+ * This is needed to prevent dangling and unsafe pointers when pasting across datablocks,
+ * or after a color used by a stroke in the buffer gets deleted (via user action or undo).
+ */
+GHash *gp_strokes_copypastebuf_colors = NULL;
+
/* Free copy/paste buffer data */
void ED_gpencil_strokes_copybuf_free(void)
{
bGPDstroke *gps, *gpsn;
+ /* Free the palettes buffer
+ * NOTE: This is done before the strokes so that the name ptrs (keys) are still safe
+ */
+ if (gp_strokes_copypastebuf_colors) {
+ BLI_ghash_free(gp_strokes_copypastebuf_colors, NULL, MEM_freeN);
+ gp_strokes_copypastebuf_colors = NULL;
+ }
+
+ /* Free the stroke buffer */
for (gps = gp_strokes_copypastebuf.first; gps; gps = gpsn) {
gpsn = gps->next;
@@ -352,6 +371,46 @@ void ED_gpencil_strokes_copybuf_free(void)
gp_strokes_copypastebuf.first = gp_strokes_copypastebuf.last = NULL;
}
+/* Ensure that destination datablock has all the colours the pasted strokes need
+ * Helper function for copy-pasting strokes
+ */
+GHash *gp_copybuf_validate_colormap(bGPdata *gpd)
+{
+ GHash *new_colors = BLI_ghash_str_new("GPencil Paste Dst Colors");
+ GHashIterator gh_iter;
+
+ /* If there's no active palette yet (i.e. new datablock), add one */
+ bGPDpalette *palette = BKE_gpencil_palette_getactive(gpd);
+ if (palette == NULL) {
+ palette = BKE_gpencil_palette_addnew(gpd, "Pasted Palette", true);
+ }
+
+ /* For each color, figure out what to map to... */
+ GHASH_ITER(gh_iter, gp_strokes_copypastebuf_colors) {
+ bGPDpalettecolor *palcolor;
+ char *name = BLI_ghashIterator_getKey(&gh_iter);
+
+ /* Look for existing color to map to */
+ /* XXX: What to do if same name but different color? Behaviour here should depend on a property? */
+ palcolor = BKE_gpencil_palettecolor_getbyname(palette, name);
+ if (palcolor == NULL) {
+ /* Doesn't Exist - Create new matching color for this palette */
+ /* XXX: This still doesn't fix the pasting across file boundaries problem... */
+ bGPDpalettecolor *src_color = BLI_ghashIterator_getValue(&gh_iter);
+
+ palcolor = MEM_dupallocN(src_color);
+ BLI_addtail(&palette->colors, palcolor);
+
+ BLI_uniquename(&palette->colors, palcolor, DATA_("GP Color"), '.', offsetof(bGPDpalettecolor, info), sizeof(palcolor->info));
+ }
+
+ /* Store this mapping (for use later when pasting) */
+ BLI_ghash_insert(new_colors, name, palcolor);
+ }
+
+ return new_colors;
+}
+
/* --------------------- */
/* Copy selected strokes */
@@ -413,7 +472,26 @@ static int gp_strokes_copy_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
- /* done - no updates needed */
+ /* Build up hash of colors used in these strokes, making copies of these to protect against dangling pointers */
+ if (gp_strokes_copypastebuf.first) {
+ gp_strokes_copypastebuf_colors = BLI_ghash_str_new("GPencil CopyBuf Colors");
+
+ for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
+ if (ED_gpencil_stroke_can_use(C, gps)) {
+ if (BLI_ghash_haskey(gp_strokes_copypastebuf_colors, gps->colorname) == false) {
+ bGPDpalettecolor *color = MEM_dupallocN(gps->palcolor);
+
+ BLI_ghash_insert(gp_strokes_copypastebuf_colors, gps->colorname, color);
+ gps->palcolor = color;
+ }
+ }
+ }
+ }
+
+ /* updates (to ensure operator buttons are refreshed, when used via hotkeys) */
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL); // XXX?
+
+ /* done */
return OPERATOR_FINISHED;
}
@@ -458,6 +536,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
bGPDframe *gpf;
eGP_PasteMode type = RNA_enum_get(op->ptr, "type");
+ GHash *new_colors;
/* check for various error conditions */
if (gpd == NULL) {
@@ -515,6 +594,10 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
}
CTX_DATA_END;
+ /* Ensure that all the necessary colors exist */
+ new_colors = gp_copybuf_validate_colormap(gpd);
+
+ /* Copy over the strokes from the buffer (and adjust the colors) */
for (bGPDstroke *gps = gp_strokes_copypastebuf.first; gps; gps = gps->next) {
if (ED_gpencil_stroke_can_use(C, gps)) {
/* Need to verify if layer exists */
@@ -533,6 +616,7 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
*/
gpf = BKE_gpencil_layer_getframe(gpl, CFRA, true);
if (gpf) {
+ /* Create new stroke */
bGPDstroke *new_stroke = MEM_dupallocN(gps);
new_stroke->tmp_layerinfo[0] = '\0';
@@ -543,10 +627,22 @@ static int gp_strokes_paste_exec(bContext *C, wmOperator *op)
new_stroke->next = new_stroke->prev = NULL;
BLI_addtail(&gpf->strokes, new_stroke);
+
+ /* Fix color references */
+ BLI_assert(new_stroke->colorname[0] != '\0');
+ new_stroke->palcolor = BLI_ghash_lookup(new_colors, new_stroke->colorname);
+
+ BLI_assert(new_stroke->palcolor != NULL);
+ BLI_strncpy(new_stroke->colorname, new_stroke->palcolor->info, sizeof(new_stroke->colorname));
+
+ /*new_stroke->flag |= GP_STROKE_RECALC_COLOR; */
}
}
}
+ /* free temp data */
+ BLI_ghash_free(new_colors, NULL, NULL);
+
/* updates */
WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED, NULL);
@@ -748,10 +844,10 @@ static int gp_blank_frame_add_exec(bContext *C, wmOperator *op)
void GPENCIL_OT_blank_frame_add(wmOperatorType *ot)
{
/* identifiers */
- ot->name = "Add Blank Frame";
+ ot->name = "Insert Blank Frame";
ot->idname = "GPENCIL_OT_blank_frame_add";
- ot->description = "Add a new frame with nothing in it on the current frame. "
- "If there is already a frame, all existing frames are shifted one frame later";
+ ot->description = "Insert a blank frame on the current frame "
+ "(all subsequently existing frames, if any, are shifted right by one frame)";
/* callbacks */
ot->exec = gp_blank_frame_add_exec;
diff --git a/source/blender/editors/gpencil/gpencil_intern.h b/source/blender/editors/gpencil/gpencil_intern.h
index 5c7c9b84adb..a3734c56c59 100644
--- a/source/blender/editors/gpencil/gpencil_intern.h
+++ b/source/blender/editors/gpencil/gpencil_intern.h
@@ -40,6 +40,8 @@ struct bGPdata;
struct bGPDstroke;
struct bGPDspoint;
+struct GHash;
+
struct ARegion;
struct View2D;
struct wmOperatorType;
@@ -69,75 +71,23 @@ typedef struct GP_SpaceConversion {
float mat[4][4]; /* transform matrix on the strokes (introduced in [b770964]) */
} GP_SpaceConversion;
-
-/**
- * Check whether a given stroke segment is inside a circular brush
- *
- * \param mval The current screen-space coordinates (midpoint) of the brush
- * \param mvalo The previous screen-space coordinates (midpoint) of the brush (NOT CURRENTLY USED)
- * \param rad The radius of the brush
- *
- * \param x0, y0 The screen-space x and y coordinates of the start of the stroke segment
- * \param x1, y1 The screen-space x and y coordinates of the end of the stroke segment
- */
bool gp_stroke_inside_circle(const int mval[2], const int UNUSED(mvalo[2]),
int rad, int x0, int y0, int x1, int y1);
-
-/**
- * Init settings for stroke point space conversions
- *
- * \param[out] r_gsc The space conversion settings struct, populated with necessary params
- */
void gp_point_conversion_init(struct bContext *C, GP_SpaceConversion *r_gsc);
-/**
- * Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D)
- *
- * \param[out] r_x The screen-space x-coordinate of the point
- * \param[out] r_y The screen-space y-coordinate of the point
- */
void gp_point_to_xy(GP_SpaceConversion *settings, struct bGPDstroke *gps, struct bGPDspoint *pt,
int *r_x, int *r_y);
-/**
- * Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D)
- *
- * Just like gp_point_to_xy(), except the resulting coordinates are floats not ints.
- * Use this version to solve "stair-step" artifacts which may arise when roundtripping the calculations.
- *
- * \param[out] r_x The screen-space x-coordinate of the point
- * \param[out] r_y The screen-space y-coordinate of the point
- */
void gp_point_to_xy_fl(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
float *r_x, float *r_y);
-/**
- * Convert point to parent space
- *
- * \param pt Original point
- * \param diff_mat Matrix with the difference between original parent matrix
- * \param[out] r_pt Pointer to new point after apply matrix
- */
void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *r_pt);
-/**
- * Change points position relative to parent object
- */
+
void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps);
-/**
- * Change point position relative to parent object
- */
+
void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt);
-/**
- * Convert a screenspace point to a 3D Grease Pencil coordinate.
- *
- * For use with editing tools where it is easier to perform the operations in 2D,
- * and then later convert the transformed points back to 3D.
- *
- * \param screeN_co The screenspace 2D coordinates to convert to
- * \param[out] r_out The resulting 3D coordinates of the input point
- */
bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, struct Scene *scene, const float screen_co[2], float r_out[3]);
/* Poll Callbacks ------------------------------------ */
@@ -155,48 +105,18 @@ int gp_brush_crt_presets_poll(bContext *C);
extern ListBase gp_strokes_copypastebuf;
+/* Build a map for converting between old colornames and destination-color-refs */
+struct GHash *gp_copybuf_validate_colormap(bGPdata *gpd);
+
/* Stroke Editing ------------------------------------ */
void gp_stroke_delete_tagged_points(bGPDframe *gpf, bGPDstroke *gps, bGPDstroke *next_stroke, int tag_flags);
-/**
- * Apply smooth to stroke point
- * \param gps Stroke to smooth
- * \param i Point index
- * \param inf Amount of smoothing to apply
- * \param affect_pressure Apply smoothing to pressure values too?
- */
bool gp_smooth_stroke(bGPDstroke *gps, int i, float inf, bool affect_pressure);
-
-/**
-* Apply smooth for strength to stroke point
-* \param gps Stroke to smooth
-* \param i Point index
-* \param inf Amount of smoothing to apply
-*/
bool gp_smooth_stroke_strength(bGPDstroke *gps, int i, float inf);
-
-/**
-* Apply smooth for thickness to stroke point (use pressure)
-* \param gps Stroke to smooth
-* \param i Point index
-* \param inf Amount of smoothing to apply
-*/
bool gp_smooth_stroke_thickness(bGPDstroke *gps, int i, float inf);
-
-/**
- * Subdivide a stroke once, by adding points at the midpoint between each pair of points
- * \param gps Stroke data
- * \param new_totpoints Total number of points (after subdividing)
- */
void gp_subdivide_stroke(bGPDstroke *gps, const int new_totpoints);
-
-/**
-* Add randomness to stroke
-* \param gps Stroke data
-* \param brush Brush data
-*/
void gp_randomize_stroke(bGPDstroke *gps, bGPDbrush *brush);
/* Layers Enums -------------------------------------- */
diff --git a/source/blender/editors/gpencil/gpencil_interpolate.c b/source/blender/editors/gpencil/gpencil_interpolate.c
index d2360fea672..59b5b41f114 100644
--- a/source/blender/editors/gpencil/gpencil_interpolate.c
+++ b/source/blender/editors/gpencil/gpencil_interpolate.c
@@ -77,7 +77,6 @@
#include "ED_object.h"
#include "ED_screen.h"
#include "ED_view3d.h"
-#include "ED_screen.h"
#include "ED_space_api.h"
#include "gpencil_intern.h"
@@ -626,6 +625,7 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent
break;
}
default:
+ {
if ((event->val == KM_PRESS) && handleNumInput(C, &tgpi->num, event)) {
const float factor = tgpi->init_factor;
float value;
@@ -650,6 +650,7 @@ static int gpencil_interpolate_modal(bContext *C, wmOperator *op, const wmEvent
/* unhandled event - allow to pass through */
return OPERATOR_RUNNING_MODAL | OPERATOR_PASS_THROUGH;
}
+ }
}
/* still running... */
diff --git a/source/blender/editors/gpencil/gpencil_paint.c b/source/blender/editors/gpencil/gpencil_paint.c
index 5879306b06c..eb49060b629 100644
--- a/source/blender/editors/gpencil/gpencil_paint.c
+++ b/source/blender/editors/gpencil/gpencil_paint.c
@@ -162,6 +162,8 @@ typedef struct tGPsdata {
bGPDbrush *brush; /* current drawing brush */
short straight[2]; /* 1: line horizontal, 2: line vertical, other: not defined, second element position */
int lock_axis; /* lock drawing to one axis */
+
+ short keymodifier; /* key used for invoking the operator */
} tGPsdata;
/* ------ */
@@ -484,7 +486,8 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure,
bGPdata *gpd = p->gpd;
bGPDbrush *brush = p->brush;
tGPspoint *pt;
-
+ ToolSettings *ts = p->scene->toolsettings;
+
/* check painting mode */
if (p->paintmode == GP_PAINTMODE_DRAW_STRAIGHT) {
/* straight lines only - i.e. only store start and end point in buffer */
@@ -636,7 +639,7 @@ static short gp_stroke_addpoint(tGPsdata *p, const int mval[2], float pressure,
View3D *v3d = p->sa->spacedata.first;
view3d_region_operator_needs_opengl(p->win, p->ar);
- ED_view3d_autodist_init(p->scene, p->ar, v3d, (p->gpd->flag & GP_DATA_DEPTH_STROKE) ? 1 : 0);
+ ED_view3d_autodist_init(p->scene, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
}
/* convert screen-coordinates to appropriate coordinates (and store them) */
@@ -756,7 +759,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
int i, totelem;
/* since strokes are so fine, when using their depth we need a margin otherwise they might get missed */
- int depth_margin = (p->gpd->flag & GP_DATA_DEPTH_STROKE) ? 4 : 0;
+ int depth_margin = (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 4 : 0;
/* get total number of points to allocate space for
* - drawing straight-lines only requires the endpoints
@@ -893,7 +896,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
copy_v2_v2_int(mval, &ptc->x);
if ((ED_view3d_autodist_depth(p->ar, mval, depth_margin, depth_arr + i) == 0) &&
- (i && (ED_view3d_autodist_depth_seg(p->ar, mval, mval_prev, depth_margin + 1, depth_arr + i) == 0)))
+ (i && (ED_view3d_autodist_depth_seg(p->ar, mval, mval_prev, depth_margin + 1, depth_arr + i) == 0)))
{
interp_depth = true;
}
@@ -910,7 +913,7 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
depth_arr[i] = 0.9999f;
}
else {
- if (p->gpd->flag & GP_DATA_DEPTH_STROKE_ENDPOINTS) {
+ if (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE_ENDPOINTS) {
/* remove all info between the valid endpoints */
int first_valid = 0;
int last_valid = 0;
@@ -1004,9 +1007,9 @@ static void gp_stroke_newfrombuffer(tGPsdata *p)
BLI_strncpy(gps->colorname, palcolor->info, sizeof(gps->colorname));
/* add stroke to frame, usually on tail of the listbase, but if on back is enabled the stroke is added on listbase head
- * because the drawing order is inverse and the head stroke is the first to draw. This is very useful for artist
- * when drawing the background
- */
+ * because the drawing order is inverse and the head stroke is the first to draw. This is very useful for artist
+ * when drawing the background
+ */
if ((ts->gpencil_flags & GP_TOOL_FLAG_PAINT_ONBACK) && (p->paintmode != GP_PAINTMODE_DRAW_POLY)) {
BLI_addhead(&p->gpf->strokes, gps);
}
@@ -1794,6 +1797,7 @@ static void gp_paint_initstroke(tGPsdata *p, eGPencil_PaintModes paintmode)
/* finish off a stroke (clears buffer, but doesn't finish the paint operation) */
static void gp_paint_strokeend(tGPsdata *p)
{
+ ToolSettings *ts = p->scene->toolsettings;
/* for surface sketching, need to set the right OpenGL context stuff so that
* the conversions will project the values correctly...
*/
@@ -1802,7 +1806,7 @@ static void gp_paint_strokeend(tGPsdata *p)
/* need to restore the original projection settings before packing up */
view3d_region_operator_needs_opengl(p->win, p->ar);
- ED_view3d_autodist_init(p->scene, p->ar, v3d, (p->gpd->flag & GP_DATA_DEPTH_STROKE) ? 1 : 0);
+ ED_view3d_autodist_init(p->scene, p->ar, v3d, (ts->gpencil_v3d_align & GP_PROJECT_DEPTH_STROKE) ? 1 : 0);
}
/* check if doing eraser or not */
@@ -1938,7 +1942,7 @@ static void gpencil_draw_cancel(bContext *C, wmOperator *op)
/* ------------------------------- */
-static int gpencil_draw_init(bContext *C, wmOperator *op)
+static int gpencil_draw_init(bContext *C, wmOperator *op, const wmEvent *event)
{
tGPsdata *p;
eGPencil_PaintModes paintmode = RNA_enum_get(op->ptr, "mode");
@@ -1957,6 +1961,13 @@ static int gpencil_draw_init(bContext *C, wmOperator *op)
gpencil_draw_exit(C, op);
return 0;
}
+
+ if (event != NULL) {
+ p->keymodifier = event->keymodifier;
+ }
+ else {
+ p->keymodifier = -1;
+ }
/* everything is now setup ok */
return 1;
@@ -2198,7 +2209,7 @@ static int gpencil_draw_exec(bContext *C, wmOperator *op)
/* printf("GPencil - Starting Re-Drawing\n"); */
/* try to initialize context data needed while drawing */
- if (!gpencil_draw_init(C, op)) {
+ if (!gpencil_draw_init(C, op, NULL)) {
if (op->customdata) MEM_freeN(op->customdata);
/* printf("\tGP - no valid data\n"); */
return OPERATOR_CANCELLED;
@@ -2273,7 +2284,7 @@ static int gpencil_draw_invoke(bContext *C, wmOperator *op, const wmEvent *event
printf("GPencil - Starting Drawing\n");
/* try to initialize context data needed while drawing */
- if (!gpencil_draw_init(C, op)) {
+ if (!gpencil_draw_init(C, op, event)) {
if (op->customdata)
MEM_freeN(op->customdata);
if (G.debug & G_DEBUG)
@@ -2436,7 +2447,7 @@ static int gpencil_draw_modal(bContext *C, wmOperator *op, const wmEvent *event)
* is essential for ensuring that they can quickly return to that view
*/
}
- else if ((ELEM(event->type, DKEY)) && (event->val == KM_RELEASE)) {
+ else if ((ELEM(event->type, p->keymodifier)) && (event->val == KM_RELEASE)) {
/* enable continuous if release D key in mid drawing */
p->scene->toolsettings->gpencil_flags |= GP_TOOL_FLAG_PAINTSESSIONS_ON;
}
diff --git a/source/blender/editors/gpencil/gpencil_select.c b/source/blender/editors/gpencil/gpencil_select.c
index 45dbde80284..2912a1ac4eb 100644
--- a/source/blender/editors/gpencil/gpencil_select.c
+++ b/source/blender/editors/gpencil/gpencil_select.c
@@ -1012,7 +1012,7 @@ static int gpencil_lasso_select_exec(bContext *C, wmOperator *op)
}
/* test if in lasso boundbox + within the lasso noose */
if ((!ELEM(V2D_IS_CLIPPED, x0, y0)) && BLI_rcti_isect_pt(&rect, x0, y0) &&
- BLI_lasso_is_point_inside(mcords, mcords_tot, x0, y0, INT_MAX))
+ BLI_lasso_is_point_inside(mcords, mcords_tot, x0, y0, INT_MAX))
{
if (select) {
pt->flag |= GP_SPOINT_SELECT;
diff --git a/source/blender/editors/gpencil/gpencil_utils.c b/source/blender/editors/gpencil/gpencil_utils.c
index 76e85f20c36..ed05b8be9ca 100644
--- a/source/blender/editors/gpencil/gpencil_utils.c
+++ b/source/blender/editors/gpencil/gpencil_utils.c
@@ -391,7 +391,16 @@ EnumPropertyItem *ED_gpencil_layers_with_new_enum_itemf(bContext *C, PointerRNA
/* ******************************************************** */
/* Brush Tool Core */
-/* Check if part of stroke occurs within last segment drawn by eraser */
+/**
+ * Check whether a given stroke segment is inside a circular brush
+ *
+ * \param mval The current screen-space coordinates (midpoint) of the brush
+ * \param mvalo The previous screen-space coordinates (midpoint) of the brush (NOT CURRENTLY USED)
+ * \param rad The radius of the brush
+ *
+ * \param x0, y0 The screen-space x and y coordinates of the start of the stroke segment
+ * \param x1, y1 The screen-space x and y coordinates of the end of the stroke segment
+ */
bool gp_stroke_inside_circle(const int mval[2], const int UNUSED(mvalo[2]),
int rad, int x0, int y0, int x1, int y1)
{
@@ -502,7 +511,11 @@ bGPDpalettecolor *ED_gpencil_stroke_getcolor(bGPdata *gpd, bGPDstroke *gps)
/* ******************************************************** */
/* Space Conversion */
-/* Init handling for space-conversion function (from passed-in parameters) */
+/**
+ * Init settings for stroke point space conversions
+ *
+ * \param r_gsc: [out] The space conversion settings struct, populated with necessary params
+ */
void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
{
ScrArea *sa = CTX_wm_area(C);
@@ -538,7 +551,13 @@ void gp_point_conversion_init(bContext *C, GP_SpaceConversion *r_gsc)
}
}
-/* convert point to parent space */
+/**
+ * Convert point to parent space
+ *
+ * \param pt Original point
+ * \param diff_mat Matrix with the difference between original parent matrix
+ * \param[out] r_pt Pointer to new point after apply matrix
+ */
void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *r_pt)
{
float fpt[3];
@@ -547,7 +566,9 @@ void gp_point_to_parent_space(bGPDspoint *pt, float diff_mat[4][4], bGPDspoint *
copy_v3_v3(&r_pt->x, fpt);
}
-/* Change position relative to parent object */
+/**
+ * Change points position relative to parent object
+ */
void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps)
{
bGPDspoint *pt;
@@ -568,7 +589,9 @@ void gp_apply_parent(bGPDlayer *gpl, bGPDstroke *gps)
}
}
-/* Change point position relative to parent object */
+/**
+ * Change point position relative to parent object
+ */
void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt)
{
/* undo matrix */
@@ -583,8 +606,13 @@ void gp_apply_parent_point(bGPDlayer *gpl, bGPDspoint *pt)
copy_v3_v3(&pt->x, fpt);
}
-/* Convert Grease Pencil points to screen-space values
- * WARNING: This assumes that the caller has already checked whether the stroke in question can be drawn
+/**
+ * Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D)
+ *
+ * \param[out] r_x The screen-space x-coordinate of the point
+ * \param[out] r_y The screen-space y-coordinate of the point
+ *
+ * \warning This assumes that the caller has already checked whether the stroke in question can be drawn.
*/
void gp_point_to_xy(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
int *r_x, int *r_y)
@@ -628,8 +656,16 @@ void gp_point_to_xy(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
}
}
-/* Convert Grease Pencil points to screen-space values (as floats)
- * WARNING: This assumes that the caller has already checked whether the stroke in question can be drawn
+/**
+ * Convert a Grease Pencil coordinate (i.e. can be 2D or 3D) to screenspace (2D)
+ *
+ * Just like gp_point_to_xy(), except the resulting coordinates are floats not ints.
+ * Use this version to solve "stair-step" artifacts which may arise when roundtripping the calculations.
+ *
+ * \param r_x: [out] The screen-space x-coordinate of the point
+ * \param r_y: [out] The screen-space y-coordinate of the point
+ *
+ * \warning This assumes that the caller has already checked whether the stroke in question can be drawn
*/
void gp_point_to_xy_fl(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
float *r_x, float *r_y)
@@ -688,6 +724,12 @@ void gp_point_to_xy_fl(GP_SpaceConversion *gsc, bGPDstroke *gps, bGPDspoint *pt,
/**
* Project screenspace coordinates to 3D-space
*
+ * For use with editing tools where it is easier to perform the operations in 2D,
+ * and then later convert the transformed points back to 3D.
+ *
+ * \param screen_co: The screenspace 2D coordinates to convert to
+ * \param r_out: The resulting 3D coordinates of the input point
+ *
* \note We include this as a utility function, since the standard method
* involves quite a few steps, which are invariably always the same
* for all GPencil operations. So, it's nicer to just centralize these.
@@ -722,7 +764,7 @@ bool gp_point_xy_to_3d(GP_SpaceConversion *gsc, Scene *scene, const float screen
}
/**
- * Apply smooth to stroke point
+ * Apply smooth to stroke point
* \param gps Stroke to smooth
* \param i Point index
* \param inf Amount of smoothing to apply
@@ -830,8 +872,8 @@ bool gp_smooth_stroke_strength(bGPDstroke *gps, int i, float inf)
ptc = &gps->points[after];
/* the optimal value is the corresponding to the interpolation of the strength
- * at the distance of point b
- */
+ * at the distance of point b
+ */
const float fac = line_point_factor_v3(&ptb->x, &pta->x, &ptc->x);
const float optimal = (1.0f - fac) * pta->strength + fac * ptc->strength;
diff --git a/source/blender/editors/include/ED_clip.h b/source/blender/editors/include/ED_clip.h
index 5f8ebd87d19..91f8b39f7b9 100644
--- a/source/blender/editors/include/ED_clip.h
+++ b/source/blender/editors/include/ED_clip.h
@@ -63,7 +63,7 @@ int ED_space_clip_get_clip_frame_number(struct SpaceClip *sc);
struct ImBuf *ED_space_clip_get_buffer(struct SpaceClip *sc);
struct ImBuf *ED_space_clip_get_stable_buffer(struct SpaceClip *sc, float loc[2], float *scale, float *angle);
-bool ED_space_clip_color_sample(struct Scene *scene, struct SpaceClip *sc, struct ARegion *ar, int mval[2], float r_col[3]);
+bool ED_space_clip_color_sample(struct SpaceClip *sc, struct ARegion *ar, int mval[2], float r_col[3]);
void ED_clip_update_frame(const struct Main *mainp, int cfra);
bool ED_clip_view_selection(const struct bContext *C, struct ARegion *ar, bool fit);
diff --git a/source/blender/editors/include/ED_image.h b/source/blender/editors/include/ED_image.h
index 283113f93d6..9de550a20ce 100644
--- a/source/blender/editors/include/ED_image.h
+++ b/source/blender/editors/include/ED_image.h
@@ -46,7 +46,7 @@ void ED_space_image_set(struct SpaceImage *sima, struct Scene *scene, s
struct Mask *ED_space_image_get_mask(struct SpaceImage *sima);
void ED_space_image_set_mask(struct bContext *C, struct SpaceImage *sima, struct Mask *mask);
-bool ED_space_image_color_sample(struct Scene *scene, struct SpaceImage *sima, struct ARegion *ar, int mval[2], float r_col[3]);
+bool ED_space_image_color_sample(struct SpaceImage *sima, struct ARegion *ar, int mval[2], float r_col[3]);
struct ImBuf *ED_space_image_acquire_buffer(struct SpaceImage *sima, void **r_lock);
void ED_space_image_release_buffer(struct SpaceImage *sima, struct ImBuf *ibuf, void *lock);
bool ED_space_image_has_buffer(struct SpaceImage *sima);
diff --git a/source/blender/editors/include/ED_node.h b/source/blender/editors/include/ED_node.h
index f7b9d6b4f9e..e3c382382a9 100644
--- a/source/blender/editors/include/ED_node.h
+++ b/source/blender/editors/include/ED_node.h
@@ -107,7 +107,7 @@ void ED_node_composite_job(const struct bContext *C, struct bNodeTree *nodetree,
void ED_operatormacros_node(void);
/* node_view.c */
-bool ED_space_node_color_sample(struct Scene *scene, struct SpaceNode *snode, struct ARegion *ar, int mval[2], float r_col[3]);
+bool ED_space_node_color_sample(struct SpaceNode *snode, struct ARegion *ar, int mval[2], float r_col[3]);
#endif /* __ED_NODE_H__ */
diff --git a/source/blender/editors/include/ED_transform_snap_object_context.h b/source/blender/editors/include/ED_transform_snap_object_context.h
index 6eaae49912c..8066adf55ce 100644
--- a/source/blender/editors/include/ED_transform_snap_object_context.h
+++ b/source/blender/editors/include/ED_transform_snap_object_context.h
@@ -84,7 +84,6 @@ void ED_transform_snap_object_context_set_editmesh_callbacks(
bool ED_transform_snap_object_project_ray_ex(
struct SnapObjectContext *sctx,
- const unsigned short snap_to,
const struct SnapObjectParams *params,
const float ray_start[3], const float ray_normal[3], float *ray_depth,
/* return args */
@@ -98,7 +97,6 @@ bool ED_transform_snap_object_project_ray(
bool ED_transform_snap_object_project_ray_all(
SnapObjectContext *sctx,
- const unsigned short snap_to,
const struct SnapObjectParams *params,
const float ray_start[3], const float ray_normal[3],
float ray_depth, bool sort,
diff --git a/source/blender/editors/include/ED_view3d.h b/source/blender/editors/include/ED_view3d.h
index 9ce71258573..d5c301d98d6 100644
--- a/source/blender/editors/include/ED_view3d.h
+++ b/source/blender/editors/include/ED_view3d.h
@@ -356,6 +356,9 @@ void ED_view3d_draw_offscreen(
float winmat[4][4], bool do_bgpic, bool do_sky, bool is_persp, const char *viewname,
struct GPUFX *fx, struct GPUFXSettings *fx_settings,
struct GPUOffScreen *ofs);
+void ED_view3d_draw_setup_view(
+ struct wmWindow *win, struct Scene *scene, struct ARegion *ar, struct View3D *v3d,
+ float viewmat[4][4], float winmat[4][4], const struct rcti *rect);
struct ImBuf *ED_view3d_draw_offscreen_imbuf(
struct Scene *scene, struct View3D *v3d, struct ARegion *ar, int sizex, int sizey,
@@ -370,7 +373,9 @@ struct ImBuf *ED_view3d_draw_offscreen_imbuf_simple(
struct Base *ED_view3d_give_base_under_cursor(struct bContext *C, const int mval[2]);
void ED_view3d_quadview_update(struct ScrArea *sa, struct ARegion *ar, bool do_clip);
-void ED_view3d_update_viewmat(struct Scene *scene, struct View3D *v3d, struct ARegion *ar, float viewmat[4][4], float winmat[4][4]);
+void ED_view3d_update_viewmat(
+ struct Scene *scene, struct View3D *v3d, struct ARegion *ar,
+ float viewmat[4][4], float winmat[4][4], const struct rcti *rect);
bool ED_view3d_quat_from_axis_view(const char view, float quat[4]);
char ED_view3d_quat_to_axis_view(const float quat[4], const float epsilon);
char ED_view3d_lock_view_from_index(int index);
diff --git a/source/blender/editors/include/UI_icons.h b/source/blender/editors/include/UI_icons.h
index 8420591aa3e..0c83038b7a3 100644
--- a/source/blender/editors/include/UI_icons.h
+++ b/source/blender/editors/include/UI_icons.h
@@ -313,9 +313,9 @@ DEF_ICON(OUTLINER_OB_ARMATURE)
DEF_ICON(OUTLINER_OB_FONT)
DEF_ICON(OUTLINER_OB_SURFACE)
DEF_ICON(OUTLINER_OB_SPEAKER)
+DEF_ICON(OUTLINER_OB_FORCE_FIELD)
+DEF_ICON(OUTLINER_OB_GROUP_INSTANCE)
#ifndef DEF_ICON_BLANK_SKIP
- DEF_ICON(BLANK120)
- DEF_ICON(BLANK121)
DEF_ICON(BLANK122)
DEF_ICON(BLANK123)
DEF_ICON(BLANK124)
diff --git a/source/blender/editors/include/UI_interface.h b/source/blender/editors/include/UI_interface.h
index 2ce4f3e2790..7b4fac08a7b 100644
--- a/source/blender/editors/include/UI_interface.h
+++ b/source/blender/editors/include/UI_interface.h
@@ -217,7 +217,6 @@ enum {
/* scale fixed button widths by this to account for DPI */
#define UI_DPI_FAC ((U.pixelsize * (float)U.dpi) / 72.0f)
-#define UI_DPI_WINDOW_FAC (((float)U.dpi) / 72.0f)
/* 16 to copy ICON_DEFAULT_HEIGHT */
#define UI_DPI_ICON_SIZE ((float)16 * UI_DPI_FAC)
@@ -1083,7 +1082,7 @@ void UI_butstore_unregister(uiButStore *bs_handle, uiBut **but_p);
/* Float precision helpers */
-#define UI_PRECISION_FLOAT_MAX 7
+#define UI_PRECISION_FLOAT_MAX 6
/* For float buttons the 'step' (or a1), is scaled */
#define UI_PRECISION_FLOAT_SCALE 0.01f
diff --git a/source/blender/editors/interface/interface.c b/source/blender/editors/interface/interface.c
index 7180e18ab92..2bf10c1c932 100644
--- a/source/blender/editors/interface/interface.c
+++ b/source/blender/editors/interface/interface.c
@@ -1337,7 +1337,7 @@ static void ui_but_to_pixelrect(rcti *rect, const ARegion *ar, uiBlock *block, u
rctf rectf;
ui_block_to_window_rctf(ar, block, &rectf, (but) ? &but->rect : &block->rect);
- BLI_rcti_rctf_copy(rect, &rectf);
+ BLI_rcti_rctf_copy_round(rect, &rectf);
BLI_rcti_translate(rect, -ar->winrct.xmin, -ar->winrct.ymin);
}
@@ -2146,9 +2146,14 @@ static float ui_get_but_step_unit(uiBut *but, float step_default)
/**
* \param float_precision For number buttons the precision to use or -1 to fallback to the button default.
+ * \param use_exp_float Use exponent representation of floats when out of reasonable range (outside of 1e3/1e-3).
*/
-void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision)
+void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision, const bool use_exp_float, bool *r_use_exp_float)
{
+ if (r_use_exp_float) {
+ *r_use_exp_float = false;
+ }
+
if (but->rnaprop && ELEM(but->type, UI_BTYPE_TEXT, UI_BTYPE_SEARCH_MENU)) {
PropertyType type;
const char *buf = NULL;
@@ -2217,16 +2222,31 @@ void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int
}
else {
const int prec = (float_precision == -1) ? ui_but_calc_float_precision(but, value) : float_precision;
- BLI_snprintf(str, maxlen, "%.*f", prec, value);
+ if (use_exp_float) {
+ const int l10 = (int)log10(fabs(value));
+ if (l10 < -6 || l10 > 12) {
+ BLI_snprintf(str, maxlen, "%.*g", prec, value);
+ if (r_use_exp_float) {
+ *r_use_exp_float = true;
+ }
+ }
+ else {
+ BLI_snprintf(str, maxlen, "%.*f", prec - l10 + (int)(l10 < 0), value);
+ }
+ }
+ else {
+ BLI_snprintf(str, maxlen, "%.*f", prec, value);
+ }
}
}
- else
+ else {
BLI_snprintf(str, maxlen, "%d", (int)value);
+ }
}
}
void ui_but_string_get(uiBut *but, char *str, const size_t maxlen)
{
- ui_but_string_get_ex(but, str, maxlen, -1);
+ ui_but_string_get_ex(but, str, maxlen, -1, false, NULL);
}
/**
@@ -2335,11 +2355,10 @@ bool ui_but_string_set_eval_num(bContext *C, uiBut *but, const char *str, double
#else /* WITH_PYTHON */
- *value = atof(str);
+ *r_value = atof(str);
ok = true;
- (void)C;
- (void)but;
+ UNUSED_VARS(C, but);
#endif /* WITH_PYTHON */
@@ -3168,7 +3187,9 @@ static uiBut *ui_def_but(
}
if (block->flag & UI_BLOCK_RADIAL) {
- but->drawflag |= (UI_BUT_TEXT_LEFT | UI_BUT_ICON_LEFT);
+ but->drawflag |= UI_BUT_TEXT_LEFT;
+ if (but->str && but->str[0])
+ but->drawflag |= UI_BUT_ICON_LEFT;
}
else if ((block->flag & UI_BLOCK_LOOP) ||
ELEM(but->type,
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index f3859154dfb..eab609ebe84 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -225,7 +225,7 @@ static bool eyedropper_init(bContext *C, wmOperator *op)
return false;
}
- if (RNA_property_subtype(eye->prop) == PROP_COLOR) {
+ if (RNA_property_subtype(eye->prop) != PROP_COLOR) {
const char *display_device;
float col[4];
@@ -235,7 +235,7 @@ static bool eyedropper_init(bContext *C, wmOperator *op)
/* store inital color */
RNA_property_float_get_array(&eye->ptr, eye->prop, col);
if (eye->display) {
- IMB_colormanagement_scene_linear_to_display_v3(col, eye->display);
+ IMB_colormanagement_display_to_scene_linear_v3(col, eye->display);
}
copy_v3_v3(eye->init_col, col);
}
@@ -266,6 +266,8 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
/* we could use some clever */
wmWindow *win = CTX_wm_window(C);
ScrArea *sa = BKE_screen_find_area_xy(win->screen, SPACE_TYPE_ANY, mx, my);
+ const char *display_device = CTX_data_scene(C)->display_settings.display_device;
+ struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
if (sa) {
if (sa->spacetype == SPACE_IMAGE) {
@@ -275,7 +277,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
int mval[2] = {mx - ar->winrct.xmin,
my - ar->winrct.ymin};
- if (ED_space_image_color_sample(CTX_data_scene(C), sima, ar, mval, r_col)) {
+ if (ED_space_image_color_sample(sima, ar, mval, r_col)) {
return;
}
}
@@ -287,7 +289,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
int mval[2] = {mx - ar->winrct.xmin,
my - ar->winrct.ymin};
- if (ED_space_node_color_sample(CTX_data_scene(C), snode, ar, mval, r_col)) {
+ if (ED_space_node_color_sample(snode, ar, mval, r_col)) {
return;
}
}
@@ -299,7 +301,7 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
int mval[2] = {mx - ar->winrct.xmin,
my - ar->winrct.ymin};
- if (ED_space_clip_color_sample(CTX_data_scene(C), sc, ar, mval, r_col)) {
+ if (ED_space_clip_color_sample(sc, ar, mval, r_col)) {
return;
}
}
@@ -310,6 +312,8 @@ static void eyedropper_color_sample_fl(bContext *C, Eyedropper *UNUSED(eye), int
glReadBuffer(GL_FRONT);
glReadPixels(mx, my, 1, 1, GL_RGB, GL_FLOAT, r_col);
glReadBuffer(GL_BACK);
+
+ IMB_colormanagement_display_to_scene_linear_v3(r_col, display);
}
/* sets the sample color RGB, maintaining A */
@@ -320,10 +324,10 @@ static void eyedropper_color_set(bContext *C, Eyedropper *eye, const float col[3
/* to maintain alpha */
RNA_property_float_get_array(&eye->ptr, eye->prop, col_conv);
- /* convert from display space to linear rgb space */
+ /* convert from linear rgb space to display space */
if (eye->display) {
copy_v3_v3(col_conv, col);
- IMB_colormanagement_display_to_scene_linear_v3(col_conv, eye->display);
+ IMB_colormanagement_scene_linear_to_display_v3(col_conv, eye->display);
}
else {
copy_v3_v3(col_conv, col);
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 2974c2e9304..bcfe4fe6bb4 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -2319,7 +2319,7 @@ static void ui_but_copy_paste(bContext *C, uiBut *but, uiHandleButtonData *data,
/* Get many decimal places, then strip trailing zeros.
* note: too high values start to give strange results */
char buf_copy[UI_MAX_DRAW_STR];
- ui_but_string_get_ex(but, buf_copy, sizeof(buf_copy), UI_PRECISION_FLOAT_MAX);
+ ui_but_string_get_ex(but, buf_copy, sizeof(buf_copy), UI_PRECISION_FLOAT_MAX, false, NULL);
BLI_str_rstrip_float_zero(buf_copy, '\0');
WM_clipboard_text_set(buf_copy, 0);
@@ -3060,6 +3060,7 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
wmWindow *win = CTX_wm_window(C);
int len;
const bool is_num_but = ELEM(but->type, UI_BTYPE_NUM, UI_BTYPE_NUM_SLIDER);
+ bool no_zero_strip = false;
if (data->str) {
MEM_freeN(data->str);
@@ -3092,14 +3093,16 @@ static void ui_textedit_begin(bContext *C, uiBut *but, uiHandleButtonData *data)
data->maxlen = ui_but_string_get_max_length(but);
if (data->maxlen != 0) {
data->str = MEM_callocN(sizeof(char) * data->maxlen, "textedit str");
- ui_but_string_get(but, data->str, data->maxlen);
+ /* We do not want to truncate precision to default here, it's nice to show value,
+ * not to edit it - way too much precision is lost then. */
+ ui_but_string_get_ex(but, data->str, data->maxlen, UI_PRECISION_FLOAT_MAX, true, &no_zero_strip);
}
else {
data->is_str_dynamic = true;
data->str = ui_but_string_get_dynamic(but, &data->maxlen);
}
- if (ui_but_is_float(but) && !ui_but_is_unit(but) && !ui_but_anim_expression_get(but, NULL, 0)) {
+ if (ui_but_is_float(but) && !ui_but_is_unit(but) && !ui_but_anim_expression_get(but, NULL, 0) && !no_zero_strip) {
BLI_str_rstrip_float_zero(data->str, '\0');
}
@@ -3378,7 +3381,7 @@ static void ui_do_but_textedit(
if (event->type == WHEELDOWNMOUSE) {
break;
}
- /* fall-through */
+ ATTR_FALLTHROUGH;
case ENDKEY:
ui_textedit_move(but, data, STRCUR_DIR_NEXT,
event->shift != 0, STRCUR_JUMP_ALL);
@@ -3396,7 +3399,7 @@ static void ui_do_but_textedit(
if (event->type == WHEELUPMOUSE) {
break;
}
- /* fall-through */
+ ATTR_FALLTHROUGH;
case HOMEKEY:
ui_textedit_move(but, data, STRCUR_DIR_PREV,
event->shift != 0, STRCUR_JUMP_ALL);
@@ -6757,6 +6760,7 @@ static bool ui_but_menu(bContext *C, uiBut *but)
{
uiPopupMenu *pup;
uiLayout *layout;
+ MenuType *mt = WM_menutype_find("WM_MT_button_context", true);
bool is_array, is_array_component;
uiStringInfo label = {BUT_GET_LABEL, NULL};
@@ -6788,6 +6792,12 @@ static bool ui_but_menu(bContext *C, uiBut *but)
/*bool is_idprop = RNA_property_is_idprop(prop);*/ /* XXX does not work as expected, not strictly needed */
bool is_set = RNA_property_is_set(ptr, prop);
+ /* set the prop and pointer data for python access to the hovered ui element; TODO, index could be supported as well*/
+ PointerRNA temp_ptr;
+ RNA_pointer_create(NULL, &RNA_Property, but->rnaprop, &temp_ptr);
+ uiLayoutSetContextPointer(layout,"button_prop", &temp_ptr);
+ uiLayoutSetContextPointer(layout,"button_pointer", ptr);
+
/* second slower test, saved people finding keyframe items in menus when its not possible */
if (is_anim)
is_anim = RNA_property_path_from_ID_check(&but->rnapoin, but->rnaprop);
@@ -7003,7 +7013,11 @@ static bool ui_but_menu(bContext *C, uiBut *but)
0, 0, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, "");
UI_but_func_set(but2, popup_add_shortcut_func, but, NULL);
}
-
+
+ /* Set the operator pointer for python access */
+ if (but->opptr)
+ uiLayoutSetContextPointer(layout,"button_operator", but->opptr);
+
uiItemS(layout);
}
@@ -7050,6 +7064,14 @@ static bool ui_but_menu(bContext *C, uiBut *but)
}
uiItemFullO(layout, "UI_OT_edittranslation_init", NULL, ICON_NONE, NULL, WM_OP_INVOKE_DEFAULT, 0);
+ mt = WM_menutype_find("WM_MT_button_context", false);
+ if (mt) {
+ Menu menu = {NULL};
+ menu.layout = uiLayoutColumn(layout, false);
+ menu.type = mt;
+ mt->draw(C, &menu);
+ }
+
UI_popup_menu_end(C, pup);
return true;
@@ -8389,7 +8411,7 @@ static int ui_handle_button_event(bContext *C, const wmEvent *event, uiBut *but)
case MIDDLEMOUSE:
case MOUSEPAN:
UI_but_tooltip_timer_remove(C, but);
- /* fall-through */
+ ATTR_FALLTHROUGH;
default:
/* handle button type specific events */
retval = ui_do_button(C, block, but, event);
@@ -9183,23 +9205,23 @@ static int ui_handle_menu_event(
break;
case ONEKEY: case PAD1:
- act = 1;
+ act = 1; ATTR_FALLTHROUGH;
case TWOKEY: case PAD2:
- if (act == 0) act = 2;
+ if (act == 0) act = 2; ATTR_FALLTHROUGH;
case THREEKEY: case PAD3:
- if (act == 0) act = 3;
+ if (act == 0) act = 3; ATTR_FALLTHROUGH;
case FOURKEY: case PAD4:
- if (act == 0) act = 4;
+ if (act == 0) act = 4; ATTR_FALLTHROUGH;
case FIVEKEY: case PAD5:
- if (act == 0) act = 5;
+ if (act == 0) act = 5; ATTR_FALLTHROUGH;
case SIXKEY: case PAD6:
- if (act == 0) act = 6;
+ if (act == 0) act = 6; ATTR_FALLTHROUGH;
case SEVENKEY: case PAD7:
- if (act == 0) act = 7;
+ if (act == 0) act = 7; ATTR_FALLTHROUGH;
case EIGHTKEY: case PAD8:
- if (act == 0) act = 8;
+ if (act == 0) act = 8; ATTR_FALLTHROUGH;
case NINEKEY: case PAD9:
- if (act == 0) act = 9;
+ if (act == 0) act = 9; ATTR_FALLTHROUGH;
case ZEROKEY: case PAD0:
if (act == 0) act = 10;
@@ -9794,13 +9816,13 @@ static int ui_pie_handler(bContext *C, const wmEvent *event, uiPopupBlockHandle
case (ZEROKEY + n): case (PAD0 + n): \
{ if (num_dir == UI_RADIAL_NONE) num_dir = d; } (void)0
- CASE_NUM_TO_DIR(1, UI_RADIAL_SW);
- CASE_NUM_TO_DIR(2, UI_RADIAL_S);
- CASE_NUM_TO_DIR(3, UI_RADIAL_SE);
- CASE_NUM_TO_DIR(4, UI_RADIAL_W);
- CASE_NUM_TO_DIR(6, UI_RADIAL_E);
- CASE_NUM_TO_DIR(7, UI_RADIAL_NW);
- CASE_NUM_TO_DIR(8, UI_RADIAL_N);
+ CASE_NUM_TO_DIR(1, UI_RADIAL_SW); ATTR_FALLTHROUGH;
+ CASE_NUM_TO_DIR(2, UI_RADIAL_S); ATTR_FALLTHROUGH;
+ CASE_NUM_TO_DIR(3, UI_RADIAL_SE); ATTR_FALLTHROUGH;
+ CASE_NUM_TO_DIR(4, UI_RADIAL_W); ATTR_FALLTHROUGH;
+ CASE_NUM_TO_DIR(6, UI_RADIAL_E); ATTR_FALLTHROUGH;
+ CASE_NUM_TO_DIR(7, UI_RADIAL_NW); ATTR_FALLTHROUGH;
+ CASE_NUM_TO_DIR(8, UI_RADIAL_N); ATTR_FALLTHROUGH;
CASE_NUM_TO_DIR(9, UI_RADIAL_NE);
{
but = ui_block_pie_dir_activate(block, event, num_dir);
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 067279777ba..ab760c40451 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -473,7 +473,9 @@ extern void ui_hsvcircle_pos_from_vals(struct uiBut *but, const rcti *rect, floa
extern void ui_hsvcube_pos_from_vals(struct uiBut *but, const rcti *rect, float *hsv, float *xp, float *yp);
bool ui_but_is_colorpicker_display_space(struct uiBut *but);
-extern void ui_but_string_get_ex(uiBut *but, char *str, const size_t maxlen, const int float_precision) ATTR_NONNULL();
+extern void ui_but_string_get_ex(
+ uiBut *but, char *str, const size_t maxlen,
+ const int float_precision, const bool use_exp_float, bool *r_use_exp_float) ATTR_NONNULL(1, 2);
extern void ui_but_string_get(uiBut *but, char *str, const size_t maxlen) ATTR_NONNULL();
extern char *ui_but_string_get_dynamic(uiBut *but, int *r_str_size);
extern void ui_but_convert_to_unit_alt_name(uiBut *but, char *str, size_t maxlen) ATTR_NONNULL();
diff --git a/source/blender/editors/interface/interface_layout.c b/source/blender/editors/interface/interface_layout.c
index 9b6547cf8a1..da43a58bc74 100644
--- a/source/blender/editors/interface/interface_layout.c
+++ b/source/blender/editors/interface/interface_layout.c
@@ -1274,7 +1274,8 @@ static void ui_item_rna_size(
if (!w) {
if (type == PROP_ENUM && icon_only) {
w = ui_text_icon_width(layout, "", ICON_BLANK1, 0);
- w += 0.6f * UI_UNIT_X;
+ if (index != RNA_ENUM_VALUE)
+ w += 0.6f * UI_UNIT_X;
}
else {
w = ui_text_icon_width(layout, name, icon, 0);
@@ -2395,8 +2396,10 @@ static void ui_litem_layout_radial(uiLayout *litem)
/* add a little bit more here to include number */
bitem->but->rect.xmax += 1.5f * UI_UNIT_X;
/* enable drawing as pie item if supported by widget */
- if (ui_item_is_radial_drawable(bitem))
+ if (ui_item_is_radial_drawable(bitem)) {
bitem->but->dt = UI_EMBOSS_RADIAL;
+ bitem->but->drawflag |= UI_BUT_ICON_LEFT;
+ }
}
ui_item_size(item, &itemw, &itemh);
diff --git a/source/blender/editors/interface/interface_regions.c b/source/blender/editors/interface/interface_regions.c
index 534bd4278ca..5ed94474726 100644
--- a/source/blender/editors/interface/interface_regions.c
+++ b/source/blender/editors/interface/interface_regions.c
@@ -2099,9 +2099,11 @@ static void ui_update_color_picker_buts_rgb(uiBlock *block, ColorPicker *cpicker
continue;
if (bt->rnaprop) {
-
ui_but_v3_set(bt, rgb);
+ /* original button that created the color picker already does undo
+ * push, so disable it on RNA buttons in the color picker block */
+ UI_but_flag_disable(bt, UI_BUT_UNDO);
}
else if (STREQ(bt->str, "Hex: ")) {
float rgb_gamma[3];
diff --git a/source/blender/editors/interface/interface_utils.c b/source/blender/editors/interface/interface_utils.c
index 636b7e4e9ce..1927d7280f3 100644
--- a/source/blender/editors/interface/interface_utils.c
+++ b/source/blender/editors/interface/interface_utils.c
@@ -265,7 +265,7 @@ int UI_icon_from_report_type(int type)
*/
int UI_calc_float_precision(int prec, double value)
{
- static const double pow10_neg[UI_PRECISION_FLOAT_MAX + 1] = {1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6, 1e-7};
+ static const double pow10_neg[UI_PRECISION_FLOAT_MAX + 1] = {1e0, 1e-1, 1e-2, 1e-3, 1e-4, 1e-5, 1e-6};
static const double max_pow = 10000000.0; /* pow(10, UI_PRECISION_FLOAT_MAX) */
BLI_assert(prec <= UI_PRECISION_FLOAT_MAX);
@@ -380,6 +380,17 @@ uiButStore *UI_butstore_create(uiBlock *block)
void UI_butstore_free(uiBlock *block, uiButStore *bs_handle)
{
+ /* Workaround for button store being moved into new block,
+ * which then can't use the previous buttons state ('ui_but_update_from_old_block' fails to find a match),
+ * keeping the active button in the old block holding a reference to the button-state in the new block: see T49034.
+ *
+ * Ideally we would manage moving the 'uiButStore', keeping a correct state.
+ * All things considered this is the most straightforward fix - Campbell.
+ */
+ if (block != bs_handle->block && bs_handle->block != NULL) {
+ block = bs_handle->block;
+ }
+
BLI_freelistN(&bs_handle->items);
BLI_remlink(&block->butstore, bs_handle);
diff --git a/source/blender/editors/io/io_alembic.c b/source/blender/editors/io/io_alembic.c
index 3f9eb33e239..ca4ab30a08d 100644
--- a/source/blender/editors/io/io_alembic.c
+++ b/source/blender/editors/io/io_alembic.c
@@ -31,6 +31,9 @@
# include "BLI_winstuff.h"
#endif
+#include <string.h>
+#include <errno.h>
+
#include "MEM_guardedalloc.h"
#include "DNA_mesh_types.h"
@@ -102,12 +105,12 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op)
char filename[FILE_MAX];
RNA_string_get(op->ptr, "filepath", filename);
- const struct AlembicExportParams params = {
+ struct AlembicExportParams params = {
.frame_start = RNA_int_get(op->ptr, "start"),
.frame_end = RNA_int_get(op->ptr, "end"),
- .frame_step_xform = 1.0 / (double)RNA_int_get(op->ptr, "xsamples"),
- .frame_step_shape = 1.0 / (double)RNA_int_get(op->ptr, "gsamples"),
+ .frame_samples_xform = RNA_int_get(op->ptr, "xsamples"),
+ .frame_samples_shape = RNA_int_get(op->ptr, "gsamples"),
.shutter_open = RNA_float_get(op->ptr, "sh_open"),
.shutter_close = RNA_float_get(op->ptr, "sh_close"),
@@ -122,6 +125,8 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op)
.renderable_only = RNA_boolean_get(op->ptr, "renderable_only"),
.face_sets = RNA_boolean_get(op->ptr, "face_sets"),
.use_subdiv_schema = RNA_boolean_get(op->ptr, "subdiv_schema"),
+ .export_hair = RNA_boolean_get(op->ptr, "export_hair"),
+ .export_particles = RNA_boolean_get(op->ptr, "export_particles"),
.compression_type = RNA_enum_get(op->ptr, "compression_type"),
.packuv = RNA_boolean_get(op->ptr, "packuv"),
.triangulate = RNA_boolean_get(op->ptr, "triangulate"),
@@ -131,15 +136,26 @@ static int wm_alembic_export_exec(bContext *C, wmOperator *op)
.global_scale = RNA_float_get(op->ptr, "global_scale"),
};
- ABC_export(CTX_data_scene(C), C, filename, &params);
+ /* Take some defaults from the scene, if not specified explicitly. */
+ Scene *scene = CTX_data_scene(C);
+ if (params.frame_start == INT_MIN) {
+ params.frame_start = SFRA;
+ }
+ if (params.frame_end == INT_MIN) {
+ params.frame_end = EFRA;
+ }
+
+ const bool as_background_job = RNA_boolean_get(op->ptr, "as_background_job");
+ bool ok = ABC_export(scene, C, filename, &params, as_background_job);
- return OPERATOR_FINISHED;
+ return as_background_job || ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
static void ui_alembic_export_settings(uiLayout *layout, PointerRNA *imfptr)
{
uiLayout *box;
uiLayout *row;
+ uiLayout *col;
#ifdef WITH_ALEMBIC_HDF5
box = uiLayoutBox(layout);
@@ -231,6 +247,15 @@ static void ui_alembic_export_settings(uiLayout *layout, PointerRNA *imfptr)
row = uiLayoutRow(box, false);
uiLayoutSetEnabled(row, triangulate);
uiItemR(row, imfptr, "ngon_method", 0, NULL, ICON_NONE);
+
+ /* Object Data */
+ box = uiLayoutBox(layout);
+ row = uiLayoutRow(box, false);
+ uiItemL(row, IFACE_("Particle Systems:"), ICON_PARTICLE_DATA);
+
+ col = uiLayoutColumn(box, true);
+ uiItemR(col, imfptr, "export_hair", 0, NULL, ICON_NONE);
+ uiItemR(col, imfptr, "export_particles", 0, NULL, ICON_NONE);
}
static void wm_alembic_export_draw(bContext *C, wmOperator *op)
@@ -282,11 +307,17 @@ void WM_OT_alembic_export(wmOperatorType *ot)
FILE_BLENDER, FILE_SAVE, WM_FILESEL_FILEPATH,
FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
- RNA_def_int(ot->srna, "start", 1, INT_MIN, INT_MAX,
- "Start Frame", "Start Frame", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "start", INT_MIN, INT_MIN, INT_MAX,
+ "Start Frame",
+ "Start frame of the export, use the default value to "
+ "take the start frame of the current scene",
+ INT_MIN, INT_MAX);
- RNA_def_int(ot->srna, "end", 1, INT_MIN, INT_MAX,
- "End Frame", "End Frame", INT_MIN, INT_MAX);
+ RNA_def_int(ot->srna, "end", INT_MIN, INT_MIN, INT_MAX,
+ "End Frame",
+ "End frame of the export, use the default value to "
+ "take the end frame of the current scene",
+ INT_MIN, INT_MAX);
RNA_def_int(ot->srna, "xsamples", 1, 1, 128,
"Transform Samples", "Number of times per frame transformations are sampled", 1, 128);
@@ -348,9 +379,15 @@ void WM_OT_alembic_export(wmOperatorType *ot)
RNA_def_enum(ot->srna, "ngon_method", rna_enum_modifier_triangulate_quad_method_items,
MOD_TRIANGULATE_NGON_BEAUTY, "Polygon Method", "Method for splitting the polygons into triangles");
+ RNA_def_boolean(ot->srna, "export_hair", 1, "Export Hair", "Exports hair particle systems as animated curves");
+ RNA_def_boolean(ot->srna, "export_particles", 1, "Export Particles", "Exports non-hair particle systems");
+
+ RNA_def_boolean(ot->srna, "as_background_job", true, "Run as Background Job",
+ "Enable this to run the import in the background, disable to block Blender while importing");
+
/* This dummy prop is used to check whether we need to init the start and
- * end frame values to that of the scene's, otherwise they are reset at
- * every change, draw update. */
+ * end frame values to that of the scene's, otherwise they are reset at
+ * every change, draw update. */
RNA_def_boolean(ot->srna, "init_scene_frame_range", false, "", "");
}
@@ -383,9 +420,20 @@ static int get_sequence_len(char *filename, int *ofs)
}
char path[FILE_MAX];
+ BLI_path_abs(filename, G.main->name);
BLI_split_dir_part(filename, path, FILE_MAX);
+ if (path[0] == '\0') {
+ /* The filename had no path, so just use the blend file path. */
+ BLI_split_dir_part(G.main->name, path, FILE_MAX);
+ }
+
DIR *dir = opendir(path);
+ if (dir == NULL) {
+ fprintf(stderr, "Error opening directory '%s': %s\n",
+ path, errno ? strerror(errno) : "unknown error");
+ return -1;
+ }
const char *ext = ".abc";
const char *basename = BLI_path_basename(filename);
@@ -482,17 +530,24 @@ static int wm_alembic_import_exec(bContext *C, wmOperator *op)
const bool is_sequence = RNA_boolean_get(op->ptr, "is_sequence");
const bool set_frame_range = RNA_boolean_get(op->ptr, "set_frame_range");
const bool validate_meshes = RNA_boolean_get(op->ptr, "validate_meshes");
+ const bool as_background_job = RNA_boolean_get(op->ptr, "as_background_job");
int offset = 0;
int sequence_len = 1;
if (is_sequence) {
sequence_len = get_sequence_len(filename, &offset);
+ if (sequence_len < 0) {
+ BKE_report(op->reports, RPT_ERROR, "Unable to determine ABC sequence length");
+ return OPERATOR_CANCELLED;
+ }
}
- ABC_import(C, filename, scale, is_sequence, set_frame_range, sequence_len, offset, validate_meshes);
+ bool ok = ABC_import(C, filename, scale, is_sequence, set_frame_range,
+ sequence_len, offset, validate_meshes,
+ as_background_job);
- return OPERATOR_FINISHED;
+ return as_background_job || ok ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
void WM_OT_alembic_import(wmOperatorType *ot)
@@ -523,6 +578,9 @@ void WM_OT_alembic_import(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "is_sequence", false, "Is Sequence",
"Set to true if the cache is split into separate files");
+
+ RNA_def_boolean(ot->srna, "as_background_job", true, "Run as Background Job",
+ "Enable this to run the export in the background, disable to block Blender while exporting");
}
#endif
diff --git a/source/blender/editors/io/io_cache.c b/source/blender/editors/io/io_cache.c
index ebe8898571d..a5e90ebbe7a 100644
--- a/source/blender/editors/io/io_cache.c
+++ b/source/blender/editors/io/io_cache.c
@@ -97,22 +97,24 @@ static int cachefile_open_exec(bContext *C, wmOperator *op)
BLI_strncpy(cache_file->filepath, filename, FILE_MAX);
BKE_cachefile_reload(bmain, cache_file);
- /* hook into UI */
- PropertyPointerRNA *pprop = op->customdata;
-
- if (pprop->prop) {
- /* when creating new ID blocks, use is already 1, but RNA
- * pointer se also increases user, so this compensates it */
- id_us_min(&cache_file->id);
-
- PointerRNA idptr;
- RNA_id_pointer_create(&cache_file->id, &idptr);
- RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
- RNA_property_update(C, &pprop->ptr, pprop->prop);
+ /* Will be set when running invoke, not exec directly. */
+ if (op->customdata != NULL) {
+ /* hook into UI */
+ PropertyPointerRNA *pprop = op->customdata;
+ if (pprop->prop) {
+ /* when creating new ID blocks, use is already 1, but RNA
+ * pointer se also increases user, so this compensates it */
+ id_us_min(&cache_file->id);
+
+ PointerRNA idptr;
+ RNA_id_pointer_create(&cache_file->id, &idptr);
+ RNA_property_pointer_set(&pprop->ptr, pprop->prop, idptr);
+ RNA_property_update(C, &pprop->ptr, pprop->prop);
+ }
+
+ MEM_freeN(op->customdata);
}
- MEM_freeN(op->customdata);
-
return OPERATOR_FINISHED;
}
@@ -143,7 +145,7 @@ static int cachefile_reload_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
- BLI_listbase_clear(&cache_file->object_paths);
+ BLI_freelistN(&cache_file->object_paths);
BKE_cachefile_reload(bmain, cache_file);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/io/io_collada.c b/source/blender/editors/io/io_collada.c
index 139c9817437..cead08afd61 100644
--- a/source/blender/editors/io/io_collada.c
+++ b/source/blender/editors/io/io_collada.c
@@ -87,8 +87,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
int include_shapekeys;
int deform_bones_only;
- int include_uv_textures;
- int include_material_textures;
+ int export_texture_type;
int use_texture_copies;
int active_uv_only;
@@ -139,8 +138,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
include_shapekeys = RNA_boolean_get(op->ptr, "include_shapekeys");
deform_bones_only = RNA_boolean_get(op->ptr, "deform_bones_only");
- include_uv_textures = RNA_boolean_get(op->ptr, "include_uv_textures");
- include_material_textures = RNA_boolean_get(op->ptr, "include_material_textures");
+ export_texture_type = RNA_enum_get(op->ptr, "export_texture_type_selection");
use_texture_copies = RNA_boolean_get(op->ptr, "use_texture_copies");
active_uv_only = RNA_boolean_get(op->ptr, "active_uv_only");
@@ -169,8 +167,7 @@ static int wm_collada_export_exec(bContext *C, wmOperator *op)
deform_bones_only,
active_uv_only,
- include_uv_textures,
- include_material_textures,
+ export_texture_type,
use_texture_copies,
triangulate,
@@ -241,10 +238,7 @@ static void uiCollada_exportSettings(uiLayout *layout, PointerRNA *imfptr)
uiItemR(row, imfptr, "active_uv_only", 0, NULL, ICON_NONE);
row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "include_uv_textures", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(box, false);
- uiItemR(row, imfptr, "include_material_textures", 0, NULL, ICON_NONE);
+ uiItemR(row, imfptr, "export_texture_type_selection", 0, "", ICON_NONE);
row = uiLayoutRow(box, false);
uiItemR(row, imfptr, "use_texture_copies", 1, NULL, ICON_NONE);
@@ -321,9 +315,15 @@ void WM_OT_collada_export(wmOperatorType *ot)
};
static EnumPropertyItem prop_bc_export_transformation_type[] = {
- {BC_TRANSFORMATION_TYPE_MATRIX, "matrix", 0, "Matrix", "Use <matrix> to specify transformations"},
- {BC_TRANSFORMATION_TYPE_TRANSROTLOC, "transrotloc", 0, "TransRotLoc", "Use <translate>, <rotate>, <scale> to specify transformations"},
- {0, NULL, 0, NULL, NULL}
+ { BC_TRANSFORMATION_TYPE_MATRIX, "matrix", 0, "Matrix", "Use <matrix> to specify transformations" },
+ { BC_TRANSFORMATION_TYPE_TRANSROTLOC, "transrotloc", 0, "TransRotLoc", "Use <translate>, <rotate>, <scale> to specify transformations" },
+ { 0, NULL, 0, NULL, NULL }
+ };
+
+ static EnumPropertyItem prop_bc_export_texture_type[] = {
+ { BC_TEXTURE_TYPE_MAT, "mat", 0, "Materials", "Export Materials" },
+ { BC_TEXTURE_TYPE_UV, "uv", 0, "UV Textures", "Export UV Textures (Face textures) as materials" },
+ { 0, NULL, 0, NULL, NULL }
};
ot->name = "Export COLLADA";
@@ -368,16 +368,9 @@ void WM_OT_collada_export(wmOperatorType *ot)
RNA_def_boolean(func, "deform_bones_only", 0, "Deform Bones only",
"Only export deforming bones with armatures");
-
RNA_def_boolean(func, "active_uv_only", 0, "Only Selected UV Map",
"Export only the selected UV Map");
- RNA_def_boolean(func, "include_uv_textures", 0, "Include UV Textures",
- "Export textures assigned to the object UV Maps");
-
- RNA_def_boolean(func, "include_material_textures", 0, "Include Material Textures",
- "Export textures assigned to the object Materials");
-
RNA_def_boolean(func, "use_texture_copies", 1, "Copy",
"Copy textures to same folder where the .dae file is exported");
@@ -394,11 +387,20 @@ void WM_OT_collada_export(wmOperatorType *ot)
RNA_def_boolean(func, "sort_by_name", 0, "Sort by Object name",
"Sort exported data by Object name");
+
RNA_def_int(func, "export_transformation_type", 0, INT_MIN, INT_MAX,
- "Transform", "Transformation type for translation, scale and rotation", INT_MIN, INT_MAX);
+ "Transform", "Transformation type for translation, scale and rotation", INT_MIN, INT_MAX);
RNA_def_enum(func, "export_transformation_type_selection", prop_bc_export_transformation_type, 0,
- "Transform", "Transformation type for translation, scale and rotation");
+ "Transform", "Transformation type for translation, scale and rotation");
+
+
+ RNA_def_int(func, "export_texture_type", 0, INT_MIN, INT_MAX,
+ "Texture Type", "Type for exported Textures (UV or MAT)", INT_MIN, INT_MAX);
+
+ RNA_def_enum(func, "export_texture_type_selection", prop_bc_export_texture_type, 0,
+ "Texture Type", "Type for exported Textures (UV or MAT)");
+
RNA_def_boolean(func, "open_sim", 0, "Export to SL/OpenSim",
"Compatibility mode for SL, OpenSim and other compatible online worlds");
diff --git a/source/blender/editors/mask/mask_add.c b/source/blender/editors/mask/mask_add.c
index f01af22cec9..69335195b96 100644
--- a/source/blender/editors/mask/mask_add.c
+++ b/source/blender/editors/mask/mask_add.c
@@ -770,14 +770,17 @@ static int create_primitive_from_points(bContext *C, wmOperator *op, const float
new_spline = BKE_mask_spline_add(mask_layer);
new_spline->flag = MASK_SPLINE_CYCLIC | SELECT;
- new_spline->tot_point = num_points;
new_spline->points = MEM_recallocN(new_spline->points,
- sizeof(MaskSplinePoint) * new_spline->tot_point);
+ sizeof(MaskSplinePoint) * num_points);
mask_layer->act_spline = new_spline;
mask_layer->act_point = NULL;
+ const int spline_index = BKE_mask_layer_shape_spline_to_index(mask_layer, new_spline);
+
for (i = 0; i < num_points; i++) {
+ new_spline->tot_point = i + 1;
+
MaskSplinePoint *new_point = &new_spline->points[i];
BKE_mask_parent_init(&new_point->parent);
@@ -788,6 +791,12 @@ static int create_primitive_from_points(bContext *C, wmOperator *op, const float
new_point->bezt.h1 = handle_type;
new_point->bezt.h2 = handle_type;
BKE_mask_point_select_set(new_point, true);
+
+ if (mask_layer->splines_shapes.first) {
+ BKE_mask_layer_shape_changed_add(mask_layer,
+ spline_index + i,
+ true, true);
+ }
}
WM_event_add_notifier(C, NC_MASK | NA_EDITED, mask);
diff --git a/source/blender/editors/mask/mask_draw.c b/source/blender/editors/mask/mask_draw.c
index 2b4f94a37ef..be7eb2bf9ed 100644
--- a/source/blender/editors/mask/mask_draw.c
+++ b/source/blender/editors/mask/mask_draw.c
@@ -834,13 +834,12 @@ void ED_mask_draw_region(Mask *mask, ARegion *ar,
/* apply transformation so mask editing tools will assume drawing from the origin in normalized space */
glPushMatrix();
-
+ glTranslatef(x + xofs, y + yofs, 0);
+ glScalef(zoomx, zoomy, 0);
if (stabmat) {
glMultMatrixf(stabmat);
}
-
- glTranslatef(x + xofs, y + yofs, 0);
- glScalef(maxdim * zoomx, maxdim * zoomy, 0);
+ glScalef(maxdim, maxdim, 0);
if (do_draw_cb) {
ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
diff --git a/source/blender/editors/mask/mask_ops.c b/source/blender/editors/mask/mask_ops.c
index eef03852007..35de390274c 100644
--- a/source/blender/editors/mask/mask_ops.c
+++ b/source/blender/editors/mask/mask_ops.c
@@ -889,7 +889,7 @@ static int slide_point_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY))
data->is_accurate = (event->val == KM_PRESS);
- /* fall-through */ /* update CV position */
+ ATTR_FALLTHROUGH; /* update CV position */
case MOUSEMOVE:
{
ScrArea *sa = CTX_wm_area(C);
@@ -1376,7 +1376,7 @@ static int slide_spline_curvature_modal(bContext *C, wmOperator *op, const wmEve
}
- /* fall-through */ /* update CV position */
+ ATTR_FALLTHROUGH; /* update CV position */
case MOUSEMOVE:
{
float B[2], mouse_coord[2], delta[2];
diff --git a/source/blender/editors/mesh/editface.c b/source/blender/editors/mesh/editface.c
index c4e87614732..6c6c106b19a 100644
--- a/source/blender/editors/mesh/editface.c
+++ b/source/blender/editors/mesh/editface.c
@@ -306,31 +306,30 @@ void paintface_deselect_all_visible(Object *ob, int action, bool flush_flags)
bool paintface_minmax(Object *ob, float r_min[3], float r_max[3])
{
- Mesh *me;
- MPoly *mp;
- MTexPoly *tf;
- MLoop *ml;
- MVert *mvert;
+ const Mesh *me;
+ const MPoly *mp;
+ const MLoop *ml;
+ const MVert *mvert;
int a, b;
bool ok = false;
float vec[3], bmat[3][3];
me = BKE_mesh_from_object(ob);
- if (!me || !me->mtpoly) return ok;
+ if (!me || !me->mloopuv) {
+ return ok;
+ }
copy_m3_m4(bmat, ob->obmat);
mvert = me->mvert;
mp = me->mpoly;
- tf = me->mtpoly;
- for (a = me->totpoly; a > 0; a--, mp++, tf++) {
+ for (a = me->totpoly; a > 0; a--, mp++) {
if (mp->flag & ME_HIDE || !(mp->flag & ME_FACE_SEL))
continue;
ml = me->mloop + mp->totloop;
for (b = 0; b < mp->totloop; b++, ml++) {
- copy_v3_v3(vec, (mvert[ml->v].co));
- mul_m3_v3(bmat, vec);
+ mul_v3_m3v3(vec, bmat, mvert[ml->v].co);
add_v3_v3v3(vec, vec, ob->obmat[3]);
minmax_v3v3_v3(r_min, r_max, vec);
}
@@ -798,25 +797,47 @@ void ED_mesh_mirrtopo_init(Mesh *me, DerivedMesh *dm, const int ob_mode, MirrTop
qsort(topo_pairs, totvert, sizeof(MirrTopoVert_t), mirrtopo_vert_sort);
- /* Since the loop starts at 2, we must define the last index where the hash's differ */
- last = ((totvert >= 2) && (topo_pairs[0].hash == topo_pairs[1].hash)) ? 0 : 1;
+ last = 0;
/* Get the pairs out of the sorted hashes, note, totvert+1 means we can use the previous 2,
* but you cant ever access the last 'a' index of MirrTopoPairs */
- for (a = 2; a <= totvert; a++) {
- /* printf("I %d %ld %d\n", (a-last), MirrTopoPairs[a ].hash, MirrTopoPairs[a ].v_index ); */
- if ((a == totvert) || (topo_pairs[a - 1].hash != topo_pairs[a].hash)) {
- if (a - last == 2) {
- if (em) {
- index_lookup[topo_pairs[a - 1].v_index] = (intptr_t)BM_vert_at_index(em->bm, topo_pairs[a - 2].v_index);
- index_lookup[topo_pairs[a - 2].v_index] = (intptr_t)BM_vert_at_index(em->bm, topo_pairs[a - 1].v_index);
+ if (em) {
+ BMVert **vtable = em->bm->vtable;
+ for (a = 1; a <= totvert; a++) {
+ /* printf("I %d %ld %d\n", (a - last), MirrTopoPairs[a].hash, MirrTopoPairs[a].v_indexs); */
+ if ((a == totvert) || (topo_pairs[a - 1].hash != topo_pairs[a].hash)) {
+ const int match_count = a - last;
+ if (match_count == 2) {
+ const int j = topo_pairs[a - 1].v_index, k = topo_pairs[a - 2].v_index;
+ index_lookup[j] = (intptr_t)vtable[k];
+ index_lookup[k] = (intptr_t)vtable[j];
+ }
+ else if (match_count == 1) {
+ /* Center vertex. */
+ const int j = topo_pairs[a - 1].v_index;
+ index_lookup[j] = (intptr_t)vtable[j];
+ }
+ last = a;
+ }
+ }
+ }
+ else {
+ /* same as above, for mesh */
+ for (a = 1; a <= totvert; a++) {
+ if ((a == totvert) || (topo_pairs[a - 1].hash != topo_pairs[a].hash)) {
+ const int match_count = a - last;
+ if (match_count == 2) {
+ const int j = topo_pairs[a - 1].v_index, k = topo_pairs[a - 2].v_index;
+ index_lookup[j] = k;
+ index_lookup[k] = j;
}
- else {
- index_lookup[topo_pairs[a - 1].v_index] = topo_pairs[a - 2].v_index;
- index_lookup[topo_pairs[a - 2].v_index] = topo_pairs[a - 1].v_index;
+ else if (match_count == 1) {
+ /* Center vertex. */
+ const int j = topo_pairs[a - 1].v_index;
+ index_lookup[j] = j;
}
+ last = a;
}
- last = a;
}
}
diff --git a/source/blender/editors/mesh/editmesh_add.c b/source/blender/editors/mesh/editmesh_add.c
index 3725590c188..07fedffaf80 100644
--- a/source/blender/editors/mesh/editmesh_add.c
+++ b/source/blender/editors/mesh/editmesh_add.c
@@ -384,7 +384,7 @@ void MESH_OT_primitive_cone_add(wmOperatorType *ot)
/* props */
RNA_def_int(ot->srna, "vertices", 32, 3, MESH_ADD_VERTS_MAXI, "Vertices", "", 3, 500);
RNA_def_float_distance(ot->srna, "radius1", 1.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Radius 1", "", 0.001, 100.00);
- RNA_def_float_distance(ot->srna, "radius2", 0.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Radius 2", "", 0.001, 100.00);
+ RNA_def_float_distance(ot->srna, "radius2", 0.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Radius 2", "", 0.0, 100.00);
RNA_def_float_distance(ot->srna, "depth", 2.0f, 0.0, OBJECT_ADD_SIZE_MAXF, "Depth", "", 0.001, 100.00);
RNA_def_enum(ot->srna, "end_fill_type", fill_type_items, 1, "Base Fill Type", "");
diff --git a/source/blender/editors/mesh/editmesh_knife.c b/source/blender/editors/mesh/editmesh_knife.c
index bf59693b856..5e44509e10a 100644
--- a/source/blender/editors/mesh/editmesh_knife.c
+++ b/source/blender/editors/mesh/editmesh_knife.c
@@ -1472,7 +1472,7 @@ static void clip_to_ortho_planes(float v1[3], float v2[3], const float center[3]
/* could be v1 or v2 */
sub_v3_v3(v1, center);
- project_plane_v3_v3v3(closest, v1, dir);
+ project_plane_normalized_v3_v3v3(closest, v1, dir);
add_v3_v3(closest, center);
madd_v3_v3v3fl(v1, closest, dir, d);
diff --git a/source/blender/editors/mesh/editmesh_select.c b/source/blender/editors/mesh/editmesh_select.c
index a6de1b284b7..68bd8ff27b1 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -446,6 +446,9 @@ BMVert *EDBM_vert_find_nearest_ex(
unsigned int index;
BMVert *eve;
+ /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
+ ED_view3d_backbuf_validate(vc);
+
index = ED_view3d_backbuf_sample_rect(
vc, vc->mval, dist_px, bm_wireoffs, 0xFFFFFF, &dist_test);
eve = index ? BM_vert_at_index_find_or_table(bm, index - 1) : NULL;
@@ -630,7 +633,8 @@ BMEdge *EDBM_edge_find_nearest_ex(
float dist_test = 0.0f;
unsigned int index;
BMEdge *eed;
-
+
+ /* No afterqueue (yet), so we check it now, otherwise the bm_xxxofs indices are bad. */
ED_view3d_backbuf_validate(vc);
index = ED_view3d_backbuf_sample_rect(vc, vc->mval, dist_px, bm_solidoffs, bm_wireoffs, &dist_test);
diff --git a/source/blender/editors/mesh/editmesh_tools.c b/source/blender/editors/mesh/editmesh_tools.c
index 65ee097e8e1..1f90b60a1f5 100644
--- a/source/blender/editors/mesh/editmesh_tools.c
+++ b/source/blender/editors/mesh/editmesh_tools.c
@@ -5235,8 +5235,10 @@ static int edbm_noise_exec(bContext *C, wmOperator *op)
else {
BM_ITER_MESH (eve, &iter, em->bm, BM_VERTS_OF_MESH) {
if (BM_elem_flag_test(eve, BM_ELEM_SELECT)) {
- float tin, dum;
- externtex(ma->mtex[0], eve->co, &tin, &dum, &dum, &dum, &dum, 0, NULL, false, false);
+ float tin = 0.0f, dum;
+ if (ma->mtex[ma->texact] != NULL) {
+ externtex(ma->mtex[ma->texact], eve->co, &tin, &dum, &dum, &dum, &dum, 0, NULL, false, false);
+ }
eve->co[2] += fac * tin;
}
}
diff --git a/source/blender/editors/mesh/meshtools.c b/source/blender/editors/mesh/meshtools.c
index 743efb246ab..3f06ba2ced4 100644
--- a/source/blender/editors/mesh/meshtools.c
+++ b/source/blender/editors/mesh/meshtools.c
@@ -57,6 +57,7 @@
#include "BKE_main.h"
#include "BKE_mesh.h"
#include "BKE_material.h"
+#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_editmesh.h"
#include "BKE_multires.h"
@@ -103,22 +104,26 @@ static void join_mesh_single(
/* vertex groups */
MDeformVert *dvert = CustomData_get(vdata, *vertofs, CD_MDEFORMVERT);
+ MDeformVert *dvert_src = CustomData_get(&me->vdata, 0, CD_MDEFORMVERT);
- /* NB: vertex groups here are new version */
- if (dvert) {
- for (a = 0; a < me->totvert; a++) {
- for (b = 0; b < dvert[a].totweight; b++) {
- /* Find the old vertex group */
- bDeformGroup *dg, *odg = BLI_findlink(&base_src->object->defbase, dvert[a].dw[b].def_nr);
- int index;
- if (odg) {
- /* Search for a match in the new object, and set new index */
- for (dg = ob_dst->defbase.first, index = 0; dg; dg = dg->next, index++) {
- if (STREQ(dg->name, odg->name)) {
- dvert[a].dw[b].def_nr = index;
- break;
- }
- }
+ /* Remap to correct new vgroup indices, if needed. */
+ if (dvert_src) {
+ BLI_assert(dvert != NULL);
+
+ /* Build src to merged mapping of vgroup indices. */
+ bDeformGroup *dg_src;
+ int *vgroup_index_map = alloca(sizeof(*vgroup_index_map) * BLI_listbase_count(&base_src->object->defbase));
+ bool is_vgroup_remap_needed = false;
+
+ for (dg_src = base_src->object->defbase.first, b = 0; dg_src; dg_src = dg_src->next, b++) {
+ vgroup_index_map[b] = defgroup_name_index(ob_dst, dg_src->name);
+ is_vgroup_remap_needed = is_vgroup_remap_needed || (vgroup_index_map[b] != b);
+ }
+
+ if (is_vgroup_remap_needed) {
+ for (a = 0; a < me->totvert; a++) {
+ for (b = 0; b < dvert[a].totweight; b++) {
+ dvert[a].dw[b].def_nr = vgroup_index_map[dvert_src[a].dw[b].def_nr];
}
}
}
@@ -596,6 +601,9 @@ int join_mesh_exec(bContext *C, wmOperator *op)
BKE_key_sort(key);
}
+ /* Due to dependnecy cycle some other object might access old derived data. */
+ BKE_object_free_derived_caches(ob);
+
DAG_relations_tag_update(bmain); /* removed objects, need to rebuild dag */
DAG_id_tag_update(&ob->id, OB_RECALC_OB | OB_RECALC_DATA);
diff --git a/source/blender/editors/object/object_add.c b/source/blender/editors/object/object_add.c
index 20523264cd9..4ed1e85fb48 100644
--- a/source/blender/editors/object/object_add.c
+++ b/source/blender/editors/object/object_add.c
@@ -1154,7 +1154,21 @@ static int object_delete_exec(bContext *C, wmOperator *op)
base->object->id.name + 2, scene->id.name + 2);
continue;
}
+
+ /* This is sort of a quick hack to address T51243 - Proper thing to do here would be to nuke most of all this
+ * custom scene/object/base handling, and use generic lib remap/query for that.
+ * But this is for later (aka 2.8, once layers & co are settled and working).
+ */
+ if (use_global && base->object->id.lib == NULL) {
+ /* We want to nuke the object, let's nuke it the easy way (not for linked data though)... */
+ BKE_libblock_delete(bmain, &base->object->id);
+ changed = true;
+ continue;
+ }
+
/* remove from Grease Pencil parent */
+ /* XXX This is likely not correct? Will also remove parent from grease pencil from other scenes,
+ * even when use_global is false... */
for (bGPdata *gpd = bmain->gpencil.first; gpd; gpd = gpd->id.next) {
for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
if (gpl->parent != NULL) {
@@ -1450,8 +1464,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
}
if (ob_dst->parent) {
- invert_m4_m4(ob_dst->parentinv, dob->mat);
-
/* note, this may be the parent of other objects, but it should
* still work out ok */
BKE_object_apply_mat4(ob_dst, dob->mat, false, true);
@@ -1472,7 +1484,6 @@ static void make_object_duplilist_real(bContext *C, Scene *scene, Base *base,
ob_dst->partype = PAROBJECT;
/* similer to the code above, see comments */
- invert_m4_m4(ob_dst->parentinv, dob->mat);
BKE_object_apply_mat4(ob_dst, dob->mat, false, true);
DAG_id_tag_update(&ob_dst->id, OB_RECALC_OB);
}
@@ -1626,7 +1637,7 @@ static int convert_exec(bContext *C, wmOperator *op)
MetaBall *mb;
Mesh *me;
const short target = RNA_enum_get(op->ptr, "target");
- const bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
+ bool keep_original = RNA_boolean_get(op->ptr, "keep_original");
int a, mballConverted = 0;
/* don't forget multiple users! */
@@ -1664,6 +1675,19 @@ static int convert_exec(bContext *C, wmOperator *op)
{
for (CollectionPointerLink *link = selected_editable_bases.first; link; link = link->next) {
Base *base = link->ptr.data;
+ ob = base->object;
+
+ /* The way object type conversion works currently (enforcing conversion of *all* objetcs using converted
+ * obdata, even some un-selected/hidden/inother scene ones, sounds totally bad to me.
+ * However, changing this is more design than bugfix, not to mention convoluted code below,
+ * so that will be for later.
+ * But at the very least, do not do that with linked IDs! */
+ if ((ID_IS_LINKED_DATABLOCK(ob) || (ob->data && ID_IS_LINKED_DATABLOCK(ob->data))) && !keep_original) {
+ keep_original = true;
+ BKE_reportf(op->reports, RPT_INFO,
+ "Converting some linked object/object data, enforcing 'Keep Original' option to True");
+ }
+
DAG_id_tag_update(&base->object->id, OB_RECALC_DATA);
}
diff --git a/source/blender/editors/object/object_bake_api.c b/source/blender/editors/object/object_bake_api.c
index 968081818a2..ad43c48f0b9 100644
--- a/source/blender/editors/object/object_bake_api.c
+++ b/source/blender/editors/object/object_bake_api.c
@@ -51,6 +51,7 @@
#include "BKE_image.h"
#include "BKE_library.h"
#include "BKE_main.h"
+#include "BKE_material.h"
#include "BKE_node.h"
#include "BKE_report.h"
#include "BKE_modifier.h"
@@ -411,22 +412,18 @@ static bool bake_object_check(Scene *scene, Object *ob, ReportList *reports)
}
}
else {
- if (ob->mat[i]) {
- BKE_reportf(reports, RPT_ERROR,
- "No active image found in material \"%s\" (%d) for object \"%s\"",
- ob->mat[i]->id.name + 2, i, ob->id.name + 2);
- }
- else if (((Mesh *) ob->data)->mat[i]) {
- BKE_reportf(reports, RPT_ERROR,
+ Material *mat = give_current_material(ob, i);
+ if (mat != NULL) {
+ BKE_reportf(reports, RPT_INFO,
"No active image found in material \"%s\" (%d) for object \"%s\"",
- ((Mesh *) ob->data)->mat[i]->id.name + 2, i, ob->id.name + 2);
+ mat->id.name + 2, i, ob->id.name + 2);
}
else {
- BKE_reportf(reports, RPT_ERROR,
- "No active image found in material (%d) for object \"%s\"",
+ BKE_reportf(reports, RPT_INFO,
+ "No active image found in material slot (%d) for object \"%s\"",
i, ob->id.name + 2);
}
- return false;
+ continue;
}
image->id.tag |= LIB_TAG_DOIT;
@@ -566,7 +563,11 @@ static void build_image_lookup(Main *bmain, Object *ob, BakeImages *bake_images)
Image *image;
ED_object_get_active_image(ob, i + 1, &image, NULL, NULL, NULL);
- if ((image->id.tag & LIB_TAG_DOIT)) {
+ /* Some materials have no image, we just ignore those cases. */
+ if (image == NULL) {
+ bake_images->lookup[i] = -1;
+ }
+ else if (image->id.tag & LIB_TAG_DOIT) {
for (j = 0; j < i; j++) {
if (bake_images->data[j].image == image) {
bake_images->lookup[i] = j;
@@ -1172,6 +1173,9 @@ static int bake_exec(bContext *C, wmOperator *op)
BakeAPIRender bkr = {NULL};
Scene *scene = CTX_data_scene(C);
+ G.is_break = false;
+ G.is_rendering = true;
+
bake_set_props(op, scene);
bake_init_api_data(op, C, &bkr);
@@ -1223,6 +1227,7 @@ static int bake_exec(bContext *C, wmOperator *op)
finally:
+ G.is_rendering = false;
BLI_freelistN(&bkr.selected_objects);
return result;
}
diff --git a/source/blender/editors/object/object_group.c b/source/blender/editors/object/object_group.c
index 0fe43c44d7d..568778c0a86 100644
--- a/source/blender/editors/object/object_group.c
+++ b/source/blender/editors/object/object_group.c
@@ -528,8 +528,7 @@ static int group_unlink_exec(bContext *C, wmOperator *UNUSED(op))
if (!group)
return OPERATOR_CANCELLED;
- BKE_libblock_unlink(bmain, group, false, false);
- BKE_libblock_free(bmain, group);
+ BKE_libblock_delete(bmain, group);
WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, NULL);
diff --git a/source/blender/editors/object/object_modifier.c b/source/blender/editors/object/object_modifier.c
index 06d306ded42..1aa1407797b 100644
--- a/source/blender/editors/object/object_modifier.c
+++ b/source/blender/editors/object/object_modifier.c
@@ -793,7 +793,7 @@ void OBJECT_OT_modifier_add(wmOperatorType *ot)
/* identifiers */
ot->name = "Add Modifier";
- ot->description = "Add a modifier to the active object";
+ ot->description = "Add a procedural operation/effect to the active object";
ot->idname = "OBJECT_OT_modifier_add";
/* api callbacks */
diff --git a/source/blender/editors/object/object_relations.c b/source/blender/editors/object/object_relations.c
index b5fbe4ba586..3284af2df69 100644
--- a/source/blender/editors/object/object_relations.c
+++ b/source/blender/editors/object/object_relations.c
@@ -72,6 +72,7 @@
#include "BKE_global.h"
#include "BKE_group.h"
#include "BKE_fcurve.h"
+#include "BKE_idprop.h"
#include "BKE_lamp.h"
#include "BKE_lattice.h"
#include "BKE_library.h"
@@ -82,6 +83,7 @@
#include "BKE_mball.h"
#include "BKE_mesh.h"
#include "BKE_modifier.h"
+#include "BKE_node.h"
#include "BKE_object.h"
#include "BKE_report.h"
#include "BKE_sca.h"
@@ -2101,30 +2103,52 @@ void ED_object_single_users(Main *bmain, Scene *scene, const bool full, const bo
single_tex_users_expand(bmain);
}
- BKE_main_id_clear_newpoins(bmain);
- DAG_relations_tag_update(bmain);
-}
+ /* Relink nodetrees' pointers that have been duplicated. */
+ FOREACH_NODETREE(bmain, ntree, id)
+ {
+ /* This is a bit convoluted, we want to root ntree of copied IDs and only those,
+ * so we first check that old ID has been copied and that ntree is root tree of old ID,
+ * then get root tree of new ID and remap its pointers to new ID... */
+ if (id->newid && (&ntree->id != id)) {
+ ntree = ntreeFromID(id->newid);
+ BKE_libblock_relink_to_newid(&ntree->id);
+ }
+ } FOREACH_NODETREE_END
-/******************************* Make Local ***********************************/
+ /* Relink datablock pointer properties */
+ {
+ IDP_RelinkProperty(scene->id.properties);
-/* helper for below, ma was checked to be not NULL */
-static void make_local_makelocalmaterial(Material *ma)
-{
- AnimData *adt;
- int b;
+ for (Base *base = scene->base.first; base; base = base->next) {
+ Object *ob = base->object;
+ if (!ID_IS_LINKED_DATABLOCK(ob)) {
+ IDP_RelinkProperty(ob->id.properties);
+ }
+ }
- id_make_local(G.main, &ma->id, false, false);
+ if (scene->nodetree) {
+ IDP_RelinkProperty(scene->nodetree->id.properties);
+ for (bNode *node = scene->nodetree->nodes.first; node; node = node->next) {
+ IDP_RelinkProperty(node->prop);
+ }
+ }
- for (b = 0; b < MAX_MTEX; b++)
- if (ma->mtex[b] && ma->mtex[b]->tex)
- id_make_local(G.main, &ma->mtex[b]->tex->id, false, false);
+ if (scene->gpd) {
+ IDP_RelinkProperty(scene->gpd->id.properties);
+ }
- adt = BKE_animdata_from_id(&ma->id);
- if (adt) BKE_animdata_make_local(adt);
+ IDP_RelinkProperty(scene->world->id.properties);
- /* nodetree? XXX */
+ if (scene->clip) {
+ IDP_RelinkProperty(scene->clip->id.properties);
+ }
+ }
+ BKE_main_id_clear_newpoins(bmain);
+ DAG_relations_tag_update(bmain);
}
+/******************************* Make Local ***********************************/
+
enum {
MAKE_LOCAL_SELECT_OB = 1,
MAKE_LOCAL_SELECT_OBDATA = 2,
@@ -2210,123 +2234,142 @@ static bool make_local_all__instance_indirect_unused(Main *bmain, Scene *scene)
return changed;
}
-static int make_local_exec(bContext *C, wmOperator *op)
+static void make_local_animdata_tag_strips(ListBase *strips)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- AnimData *adt;
- ParticleSystem *psys;
- Material *ma, ***matarar;
- Lamp *la;
- ID *id;
- const int mode = RNA_enum_get(op->ptr, "type");
- int a, b;
-
- if (mode == MAKE_LOCAL_ALL) {
- /* de-select so the user can differentiate newly instanced from existing objects */
- BKE_scene_base_deselect_all(scene);
+ NlaStrip *strip;
- if (make_local_all__instance_indirect_unused(bmain, scene)) {
- BKE_report(op->reports, RPT_INFO,
- "Orphan library objects added to the current scene to avoid loss");
+ for (strip = strips->first; strip; strip = strip->next) {
+ if (strip->act) {
+ strip->act->id.tag &= ~LIB_TAG_PRE_EXISTING;
+ }
+ if (strip->remap && strip->remap->target) {
+ strip->remap->target->id.tag &= ~LIB_TAG_PRE_EXISTING;
}
- BKE_library_make_local(bmain, NULL, NULL, false, false); /* NULL is all libs */
- WM_event_add_notifier(C, NC_WINDOW, NULL);
- return OPERATOR_FINISHED;
+ make_local_animdata_tag_strips(&strip->strips);
}
+}
- tag_localizable_objects(C, mode);
-
- CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
- {
- if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
- continue;
+/* Tag all actions used by given animdata to be made local. */
+static void make_local_animdata_tag(AnimData *adt)
+{
+ if (adt) {
+ /* Actions - Active and Temp */
+ if (adt->action) {
+ adt->action->id.tag &= ~LIB_TAG_PRE_EXISTING;
+ }
+ if (adt->tmpact) {
+ adt->tmpact->id.tag &= ~LIB_TAG_PRE_EXISTING;
+ }
+ /* Remaps */
+ if (adt->remap && adt->remap->target) {
+ adt->remap->target->id.tag &= ~LIB_TAG_PRE_EXISTING;
}
- if (ob->id.lib)
- id_make_local(bmain, &ob->id, false, false);
- }
- CTX_DATA_END;
+ /* Drivers */
+ /* TODO: need to handle the ID-targets too? */
- /* maybe object pointers */
- CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
- {
- if (ob->id.lib == NULL) {
- ID_NEW_REMAP(ob->parent);
+ /* NLA Data */
+ for (NlaTrack *nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+ make_local_animdata_tag_strips(&nlt->strips);
}
}
- CTX_DATA_END;
-
- CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
- {
- if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
- continue;
- }
+}
- id = ob->data;
+static void make_local_material_tag(Material *ma)
+{
+ if (ma) {
+ ma->id.tag &= ~LIB_TAG_PRE_EXISTING;
+ make_local_animdata_tag(BKE_animdata_from_id(&ma->id));
- if (id && (ELEM(mode, MAKE_LOCAL_SELECT_OBDATA, MAKE_LOCAL_SELECT_OBDATA_MATERIAL))) {
- id_make_local(bmain, id, false, false);
- adt = BKE_animdata_from_id(id);
- if (adt) BKE_animdata_make_local(adt);
+ /* About nodetrees: root one is made local together with material, others we keep linked for now... */
- /* tag indirect data direct */
- matarar = give_matarar(ob);
- if (matarar) {
- for (a = 0; a < ob->totcol; a++) {
- ma = (*matarar)[a];
- if (ma)
- id_lib_extern(&ma->id);
- }
+ for (int a = 0; a < MAX_MTEX; a++) {
+ if (ma->mtex[a] && ma->mtex[a]->tex) {
+ ma->mtex[a]->tex->id.tag &= ~LIB_TAG_PRE_EXISTING;
}
}
+ }
+}
- for (psys = ob->particlesystem.first; psys; psys = psys->next)
- id_make_local(bmain, &psys->part->id, false, false);
+static int make_local_exec(bContext *C, wmOperator *op)
+{
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ParticleSystem *psys;
+ Material *ma, ***matarar;
+ Lamp *la;
+ const int mode = RNA_enum_get(op->ptr, "type");
+ int a;
+
+ /* Note: we (ab)use LIB_TAG_PRE_EXISTING to cherry pick which ID to make local... */
+ if (mode == MAKE_LOCAL_ALL) {
+ BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, false);
- adt = BKE_animdata_from_id(&ob->id);
- if (adt) BKE_animdata_make_local(adt);
+ /* de-select so the user can differentiate newly instanced from existing objects */
+ BKE_scene_base_deselect_all(scene);
+
+ if (make_local_all__instance_indirect_unused(bmain, scene)) {
+ BKE_report(op->reports, RPT_INFO, "Orphan library objects added to the current scene to avoid loss");
+ }
}
- CTX_DATA_END;
+ else {
+ BKE_main_id_tag_all(bmain, LIB_TAG_PRE_EXISTING, true);
+ tag_localizable_objects(C, mode);
- if (mode == MAKE_LOCAL_SELECT_OBDATA_MATERIAL) {
CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
{
if ((ob->id.tag & LIB_TAG_DOIT) == 0) {
continue;
}
- if (ob->type == OB_LAMP) {
- la = ob->data;
-
- for (b = 0; b < MAX_MTEX; b++)
- if (la->mtex[b] && la->mtex[b]->tex)
- id_make_local(bmain, &la->mtex[b]->tex->id, false, false);
+ ob->id.tag &= ~LIB_TAG_PRE_EXISTING;
+ make_local_animdata_tag(BKE_animdata_from_id(&ob->id));
+ for (psys = ob->particlesystem.first; psys; psys = psys->next) {
+ psys->part->id.tag &= ~LIB_TAG_PRE_EXISTING;
}
- else {
+
+ if (mode == MAKE_LOCAL_SELECT_OBDATA_MATERIAL) {
for (a = 0; a < ob->totcol; a++) {
ma = ob->mat[a];
- if (ma)
- make_local_makelocalmaterial(ma);
+ if (ma) {
+ make_local_material_tag(ma);
+ }
}
matarar = (Material ***)give_matarar(ob);
if (matarar) {
for (a = 0; a < ob->totcol; a++) {
ma = (*matarar)[a];
- if (ma)
- make_local_makelocalmaterial(ma);
+ if (ma) {
+ make_local_material_tag(ma);
+ }
+ }
+ }
+
+ if (ob->type == OB_LAMP) {
+ BLI_assert(ob->data != NULL);
+ la = ob->data;
+ for (a = 0; a < MAX_MTEX; a++) {
+ if (la->mtex[a] && la->mtex[a]->tex) {
+ la->id.tag &= ~LIB_TAG_PRE_EXISTING;
+ }
}
}
}
+
+ if (ELEM(mode, MAKE_LOCAL_SELECT_OBDATA, MAKE_LOCAL_SELECT_OBDATA_MATERIAL) && ob->data != NULL) {
+ ID *ob_data = ob->data;
+ ob_data->tag &= ~LIB_TAG_PRE_EXISTING;
+ make_local_animdata_tag(BKE_animdata_from_id(ob_data));
+ }
}
CTX_DATA_END;
}
- BKE_main_id_clear_newpoins(bmain);
- WM_event_add_notifier(C, NC_WINDOW, NULL);
+ BKE_library_make_local(bmain, NULL, NULL, true, false); /* NULL is all libs */
+ WM_event_add_notifier(C, NC_WINDOW, NULL);
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/object/object_transform.c b/source/blender/editors/object/object_transform.c
index 4d7d7df0d2f..47a3f79b0b4 100644
--- a/source/blender/editors/object/object_transform.c
+++ b/source/blender/editors/object/object_transform.c
@@ -923,8 +923,8 @@ static int object_origin_set_exec(bContext *C, wmOperator *op)
cent[2] = 0.0f;
- cu->xof = cu->xof - (cent[0] / cu->fsize);
- cu->yof = cu->yof - (cent[1] / cu->fsize);
+ cu->xof = cu->xof - cent[0];
+ cu->yof = cu->yof - cent[1];
tot_change++;
cu->id.tag |= LIB_TAG_DOIT;
diff --git a/source/blender/editors/physics/dynamicpaint_ops.c b/source/blender/editors/physics/dynamicpaint_ops.c
index 3d7a45843cc..edc3f6c784c 100644
--- a/source/blender/editors/physics/dynamicpaint_ops.c
+++ b/source/blender/editors/physics/dynamicpaint_ops.c
@@ -279,10 +279,10 @@ void DPAINT_OT_output_toggle(wmOperatorType *ot)
/***************************** Image Sequence Baking ******************************/
typedef struct DynamicPaintBakeJob {
- /* from wmJob */
- void *owner;
- short *stop, *do_update;
- float *progress;
+ /* from wmJob */
+ void *owner;
+ short *stop, *do_update;
+ float *progress;
struct Main *bmain;
Scene *scene;
@@ -297,13 +297,13 @@ typedef struct DynamicPaintBakeJob {
static void dpaint_bake_free(void *customdata)
{
- DynamicPaintBakeJob *job = customdata;
- MEM_freeN(job);
+ DynamicPaintBakeJob *job = customdata;
+ MEM_freeN(job);
}
static void dpaint_bake_endjob(void *customdata)
{
- DynamicPaintBakeJob *job = customdata;
+ DynamicPaintBakeJob *job = customdata;
DynamicPaintCanvasSettings *canvas = job->canvas;
canvas->flags &= ~MOD_DPAINT_BAKING;
@@ -311,7 +311,7 @@ static void dpaint_bake_endjob(void *customdata)
dynamicPaint_freeSurfaceData(job->surface);
G.is_rendering = false;
- BKE_spacedata_draw_locks(false);
+ BKE_spacedata_draw_locks(false);
WM_set_locked_interface(G.main->wm.first, false);
@@ -421,26 +421,26 @@ static void dynamicPaint_bakeImageSequence(DynamicPaintBakeJob *job)
static void dpaint_bake_startjob(void *customdata, short *stop, short *do_update, float *progress)
{
- DynamicPaintBakeJob *job = customdata;
+ DynamicPaintBakeJob *job = customdata;
- job->stop = stop;
- job->do_update = do_update;
- job->progress = progress;
+ job->stop = stop;
+ job->do_update = do_update;
+ job->progress = progress;
job->start = PIL_check_seconds_timer();
job->success = 1;
- G.is_break = false; /* reset BKE_blender_test_break*/
+ G.is_break = false; /* reset BKE_blender_test_break*/
/* XXX annoying hack: needed to prevent data corruption when changing
* scene frame in separate threads
- */
- G.is_rendering = true;
- BKE_spacedata_draw_locks(true);
+ */
+ G.is_rendering = true;
+ BKE_spacedata_draw_locks(true);
dynamicPaint_bakeImageSequence(job);
- *do_update = true;
- *stop = 0;
+ *do_update = true;
+ *stop = 0;
}
/*
diff --git a/source/blender/editors/physics/particle_edit.c b/source/blender/editors/physics/particle_edit.c
index e22a145b3a6..2541aaa4b11 100644
--- a/source/blender/editors/physics/particle_edit.c
+++ b/source/blender/editors/physics/particle_edit.c
@@ -4419,7 +4419,7 @@ void PE_undo_push(Scene *scene, const char *str)
undo= undo->prev;
}
if (undo) {
- while (edit->undo.first!=undo) {
+ while (edit->undo.first != undo) {
PTCacheUndo *first= edit->undo.first;
BLI_remlink(&edit->undo, first);
free_PTCacheUndo(first);
diff --git a/source/blender/editors/physics/physics_fluid.c b/source/blender/editors/physics/physics_fluid.c
index b5adf38527b..6460e83e2a0 100644
--- a/source/blender/editors/physics/physics_fluid.c
+++ b/source/blender/editors/physics/physics_fluid.c
@@ -631,71 +631,63 @@ static int fluid_validate_scene(ReportList *reports, Scene *scene, Object *fsDom
#define FLUID_SUFFIX_CONFIG_TMP (FLUID_SUFFIX_CONFIG ".tmp")
#define FLUID_SUFFIX_SURFACE "fluidsurface"
-static int fluid_init_filepaths(Object *fsDomain, char *targetDir, char *targetFile, char *debugStrBuffer)
+static bool fluid_init_filepaths(
+ ReportList *reports, FluidsimSettings *domainSettings, Object *fsDomain,
+ char *targetDir, char *targetFile)
{
- FluidsimModifierData *fluidmd = (FluidsimModifierData *)modifiers_findByType(fsDomain, eModifierType_Fluidsim);
- FluidsimSettings *domainSettings= fluidmd->fss;
- FILE *fileCfg;
- int dirExist = 0;
- char newSurfdataPath[FILE_MAX]; /* modified output settings */
const char *suffixConfigTmp = FLUID_SUFFIX_CONFIG_TMP;
- int outStringsChanged = 0;
/* prepare names... */
- const char *relbase= modifier_path_relbase(fsDomain);
+ const char *relbase = modifier_path_relbase(fsDomain);
+
+ /* We do not accept empty paths, they can end in random places silently, see T51176. */
+ if (domainSettings->surfdataPath[0] == '\0') {
+ modifier_path_init(domainSettings->surfdataPath, sizeof(domainSettings->surfdataPath),
+ OB_FLUIDSIM_SURF_DIR_DEFAULT);
+ BKE_reportf(reports, RPT_WARNING, "Fluidsim: empty cache path, reset to default '%s'",
+ domainSettings->surfdataPath);
+ }
BLI_strncpy(targetDir, domainSettings->surfdataPath, FILE_MAXDIR);
- BLI_strncpy(newSurfdataPath, domainSettings->surfdataPath, FILE_MAXDIR); /* if 0'd out below, this value is never used! */
- BLI_path_abs(targetDir, relbase); /* fixed #frame-no */
+ BLI_path_abs(targetDir, relbase);
/* .tmp: don't overwrite/delete original file */
BLI_join_dirfile(targetFile, FILE_MAX, targetDir, suffixConfigTmp);
- // make sure all directories exist
- // as the bobjs use the same dir, this only needs to be checked
- // for the cfg output
- BLI_make_existing_file(targetFile);
-
- // check selected directory
- // simply try to open cfg file for writing to test validity of settings
- fileCfg = BLI_fopen(targetFile, "w");
- if (fileCfg) {
- dirExist = 1; fclose(fileCfg);
- // remove cfg dummy from directory test
- BLI_delete(targetFile, false, false);
- }
-
- if (targetDir[0] == '\0' || (!dirExist)) {
- char blendFile[FILE_MAX];
-
- // invalid dir, reset to current/previous
- BLI_split_file_part(G.main->name, blendFile, sizeof(blendFile));
- BLI_replace_extension(blendFile, FILE_MAX, ""); /* strip .blend */
- BLI_snprintf(newSurfdataPath, FILE_MAX, "//fluidsimdata/%s_%s_", blendFile, fsDomain->id.name);
-
- BLI_snprintf(debugStrBuffer, 256, "fluidsimBake::error - warning resetting output dir to '%s'\n", newSurfdataPath);
- elbeemDebugOut(debugStrBuffer);
- outStringsChanged=1;
- }
-
- /* check if modified output dir is ok */
-#if 0
- if (outStringsChanged) {
- char dispmsg[FILE_MAX+256];
- int selection=0;
- BLI_strncpy(dispmsg, "Output settings set to: '", sizeof(dispmsg));
- strcat(dispmsg, newSurfdataPath);
- strcat(dispmsg, "'%t|Continue with changed settings %x1|Discard and abort %x0");
-
- /* ask user if thats what he/she wants... */
- selection = pupmenu(dispmsg);
- if (selection < 1) return 0; /* 0 from menu, or -1 aborted */
- BLI_strncpy(targetDir, newSurfdataPath, sizeof(targetDir));
- strncpy(domainSettings->surfdataPath, newSurfdataPath, FILE_MAXDIR);
- BLI_path_abs(targetDir, G.main->name); /* fixed #frame-no */
+ /* Ensure whole path exists and is wirtable. */
+ const bool dir_exists = BLI_dir_create_recursive(targetDir);
+ const bool is_writable = BLI_file_is_writable(targetFile);
+
+ /* We change path to some presumably valid default value, but do not allow bake process to continue,
+ * this gives user chance to set manually another path. */
+ if (!dir_exists || !is_writable) {
+ modifier_path_init(domainSettings->surfdataPath, sizeof(domainSettings->surfdataPath),
+ OB_FLUIDSIM_SURF_DIR_DEFAULT);
+
+ if (!dir_exists) {
+ BKE_reportf(reports, RPT_ERROR, "Fluidsim: could not create cache directory '%s', reset to default '%s'",
+ targetDir, domainSettings->surfdataPath);
+ }
+ else {
+ BKE_reportf(reports, RPT_ERROR, "Fluidsim: cache directory '%s' is not writable, reset to default '%s'",
+ targetDir, domainSettings->surfdataPath);
+ }
+
+ BLI_strncpy(targetDir, domainSettings->surfdataPath, FILE_MAXDIR);
+ BLI_path_abs(targetDir, relbase);
+
+ /* .tmp: don't overwrite/delete original file */
+ BLI_join_dirfile(targetFile, FILE_MAX, targetDir, suffixConfigTmp);
+
+ /* Ensure whole path exists and is wirtable. */
+ if (!BLI_dir_create_recursive(targetDir) || !BLI_file_is_writable(targetFile)) {
+ BKE_reportf(reports, RPT_ERROR, "Fluidsim: could not use default cache directory '%s', "
+ "please define a valid cache path manually", targetDir);
+ }
+ return false;
}
-#endif
- return outStringsChanged;
+
+ return true;
}
/* ******************************************************************************** */
@@ -857,7 +849,6 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
char targetDir[FILE_MAX]; // store & modify output settings
char targetFile[FILE_MAX]; // temp. store filename from targetDir for access
- int outStringsChanged = 0; // modified? copy back before baking
float domainMat[4][4];
float invDomMat[4][4];
@@ -943,7 +934,11 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
/* ******** prepare output file paths ******** */
- outStringsChanged = fluid_init_filepaths(fsDomain, targetDir, targetFile, debugStrBuffer);
+ if (!fluid_init_filepaths(reports, domainSettings, fsDomain, targetDir, targetFile)) {
+ fluidbake_free_data(channels, fobjects, fsset, fb);
+ return false;
+ }
+
channels->length = scene->r.efra; // DG TODO: why using endframe and not "noFrames" here? .. because "noFrames" is buggy too? (not using sfra)
channels->aniFrameTime = (double)((double)domainSettings->animEnd - (double)domainSettings->animStart) / (double)noFrames;
@@ -968,11 +963,6 @@ static int fluidsimBake(bContext *C, ReportList *reports, Object *fsDomain, shor
/* ******** start writing / exporting ******** */
// use .tmp, don't overwrite/delete original file
BLI_join_dirfile(targetFile, sizeof(targetFile), targetDir, suffixConfigTmp);
-
- // make sure these directories exist as well
- if (outStringsChanged) {
- BLI_make_existing_file(targetFile);
- }
/* ******** export domain to elbeem ******** */
elbeemResetSettings(fsset);
diff --git a/source/blender/editors/physics/physics_pointcache.c b/source/blender/editors/physics/physics_pointcache.c
index e81aa584586..f36ebb3715e 100644
--- a/source/blender/editors/physics/physics_pointcache.c
+++ b/source/blender/editors/physics/physics_pointcache.c
@@ -99,45 +99,45 @@ static int ptcache_job_break(void *customdata)
static void ptcache_job_update(void *customdata, float progress, int *cancel)
{
- PointCacheJob *job = customdata;
+ PointCacheJob *job = customdata;
- if (ptcache_job_break(job)) {
- *cancel = 1;
- }
+ if (ptcache_job_break(job)) {
+ *cancel = 1;
+ }
- *(job->do_update) = true;
- *(job->progress) = progress;
+ *(job->do_update) = true;
+ *(job->progress) = progress;
}
static void ptcache_job_startjob(void *customdata, short *stop, short *do_update, float *progress)
{
- PointCacheJob *job = customdata;
+ PointCacheJob *job = customdata;
- job->stop = stop;
- job->do_update = do_update;
- job->progress = progress;
+ job->stop = stop;
+ job->do_update = do_update;
+ job->progress = progress;
- G.is_break = false;
+ G.is_break = false;
- /* XXX annoying hack: needed to prevent data corruption when changing
- * scene frame in separate threads
- */
- G.is_rendering = true;
- BKE_spacedata_draw_locks(true);
+ /* XXX annoying hack: needed to prevent data corruption when changing
+ * scene frame in separate threads
+ */
+ G.is_rendering = true;
+ BKE_spacedata_draw_locks(true);
BKE_ptcache_bake(job->baker);
- *do_update = true;
- *stop = 0;
+ *do_update = true;
+ *stop = 0;
}
static void ptcache_job_endjob(void *customdata)
{
- PointCacheJob *job = customdata;
+ PointCacheJob *job = customdata;
Scene *scene = job->baker->scene;
- G.is_rendering = false;
- BKE_spacedata_draw_locks(false);
+ G.is_rendering = false;
+ BKE_spacedata_draw_locks(false);
WM_set_locked_interface(G.main->wm.first, false);
diff --git a/source/blender/editors/render/render_internal.c b/source/blender/editors/render/render_internal.c
index 8c5d25ad44d..9d98a3676ac 100644
--- a/source/blender/editors/render/render_internal.c
+++ b/source/blender/editors/render/render_internal.c
@@ -116,6 +116,7 @@ typedef struct RenderJob {
ScrArea *sa;
ColorManagedViewSettings view_settings;
ColorManagedDisplaySettings display_settings;
+ bool supports_glsl_draw;
bool interface_locked;
} RenderJob;
@@ -210,7 +211,7 @@ static void image_buffer_rect_update(RenderJob *rj, RenderResult *rr, ImBuf *ibu
}
else {
if (rr->renlay == NULL) return;
- rectf = RE_RenderLayerGetPass(rr->renlay, SCE_PASS_COMBINED, viewname);
+ rectf = RE_RenderLayerGetPass(rr->renlay, RE_PASSNAME_COMBINED, viewname);
}
}
if (rectf == NULL) return;
@@ -569,6 +570,7 @@ static void image_rect_update(void *rjv, RenderResult *rr, volatile rcti *renrec
* operate with.
*/
if (rr->do_exr_tile ||
+ !rj->supports_glsl_draw ||
ibuf->channels == 1 ||
U.image_draw_method != IMAGE_DRAW_METHOD_GLSL)
{
@@ -904,6 +906,7 @@ static int screen_render_invoke(bContext *C, wmOperator *op, const wmEvent *even
rj->orig_layer = 0;
rj->last_layer = 0;
rj->sa = sa;
+ rj->supports_glsl_draw = IMB_colormanagement_support_glsl_draw(&scene->view_settings);
BKE_color_managed_display_settings_copy(&rj->display_settings, &scene->display_settings);
BKE_color_managed_view_settings_copy(&rj->view_settings, &scene->view_settings);
@@ -1234,7 +1237,7 @@ static void render_view3d_startjob(void *customdata, short *stop, short *do_upda
use_border = render_view3d_disprect(rp->scene, rp->ar, rp->v3d,
rp->rv3d, &cliprct);
- if ((update_flag & (PR_UPDATE_RENDERSIZE | PR_UPDATE_DATABASE)) || rstats->convertdone == 0) {
+ if ((update_flag & (PR_UPDATE_RENDERSIZE | PR_UPDATE_DATABASE | PR_UPDATE_VIEW)) || rstats->convertdone == 0) {
RenderData rdata;
/* no osa, blur, seq, layers, savebuffer etc for preview render */
diff --git a/source/blender/editors/render/render_opengl.c b/source/blender/editors/render/render_opengl.c
index 1d0f433ba38..01050eda70b 100644
--- a/source/blender/editors/render/render_opengl.c
+++ b/source/blender/editors/render/render_opengl.c
@@ -38,7 +38,6 @@
#include "BLI_math_color_blend.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
-#include "BLI_jitter.h"
#include "BLI_threads.h"
#include "BLI_task.h"
@@ -257,10 +256,8 @@ static void screen_opengl_views_setup(OGLRender *oglrender)
}
}
- BLI_lock_thread(LOCK_DRAW_IMAGE);
if (!(is_multiview && BKE_scene_multiview_is_stereo3d(rd)))
oglrender->iuser.flag &= ~IMA_SHOW_STEREO;
- BLI_unlock_thread(LOCK_DRAW_IMAGE);
/* will only work for non multiview correctly */
if (v3d) {
@@ -874,7 +871,7 @@ static bool screen_opengl_render_anim_initialize(bContext *C, wmOperator *op)
typedef struct WriteTaskData {
RenderResult *rr;
- int cfra;
+ Scene tmp_scene;
} WriteTaskData;
static void write_result_func(TaskPool * __restrict pool,
@@ -883,10 +880,10 @@ static void write_result_func(TaskPool * __restrict pool,
{
OGLRender *oglrender = (OGLRender *) BLI_task_pool_userdata(pool);
WriteTaskData *task_data = (WriteTaskData *) task_data_v;
- Scene *scene = oglrender->scene;
+ Scene *scene = &task_data->tmp_scene;
RenderResult *rr = task_data->rr;
const bool is_movie = BKE_imtype_is_movie(scene->r.im_format.imtype);
- const int cfra = task_data->cfra;
+ const int cfra = scene->r.cfra;
bool ok;
/* Don't attempt to write if we've got an error. */
if (!oglrender->pool_ok) {
@@ -908,13 +905,11 @@ static void write_result_func(TaskPool * __restrict pool,
* This is because underlying calls do not use r.cfra but use scene
* for that.
*/
- Scene tmp_scene = *scene;
- tmp_scene.r.cfra = cfra;
if (is_movie) {
ok = RE_WriteRenderViewsMovie(&reports,
rr,
- &tmp_scene,
- &tmp_scene.r,
+ scene,
+ &scene->r,
oglrender->mh,
oglrender->movie_ctx_arr,
oglrender->totvideos,
@@ -934,8 +929,8 @@ static void write_result_func(TaskPool * __restrict pool,
true,
NULL);
- BKE_render_result_stamp_info(&tmp_scene, tmp_scene.camera, rr, false);
- ok = RE_WriteRenderViewsImage(NULL, rr, &tmp_scene, true, name);
+ BKE_render_result_stamp_info(scene, scene->camera, rr, false);
+ ok = RE_WriteRenderViewsImage(NULL, rr, scene, true, name);
if (!ok) {
BKE_reportf(&reports,
RPT_ERROR,
@@ -974,7 +969,7 @@ static bool schedule_write_result(OGLRender *oglrender, RenderResult *rr)
Scene *scene = oglrender->scene;
WriteTaskData *task_data = MEM_mallocN(sizeof(WriteTaskData), "write task data");
task_data->rr = rr;
- task_data->cfra = scene->r.cfra;
+ task_data->tmp_scene = *scene;
BLI_mutex_lock(&oglrender->task_mutex);
oglrender->num_scheduled_frames++;
if (oglrender->num_scheduled_frames > MAX_SCHEDULED_FRAMES) {
@@ -1088,7 +1083,7 @@ static int screen_opengl_render_modal(bContext *C, wmOperator *op, const wmEvent
/* render frame? */
if (oglrender->timer == event->customdata)
break;
- /* fall-through */
+ ATTR_FALLTHROUGH;
default:
/* nothing to do */
return OPERATOR_RUNNING_MODAL;
diff --git a/source/blender/editors/render/render_preview.c b/source/blender/editors/render/render_preview.c
index fa18b82507e..35d772afae7 100644
--- a/source/blender/editors/render/render_preview.c
+++ b/source/blender/editors/render/render_preview.c
@@ -1180,7 +1180,7 @@ void ED_preview_icon_render(Main *bmain, Scene *scene, ID *id, unsigned int *rec
ip.bmain = bmain;
ip.scene = scene;
- ip.owner = id;
+ ip.owner = BKE_previewimg_id_ensure(id);
ip.id = id;
icon_preview_add_size(&ip, rect, sizex, sizey);
diff --git a/source/blender/editors/render/render_shading.c b/source/blender/editors/render/render_shading.c
index 837573ad175..9bdb34f5384 100644
--- a/source/blender/editors/render/render_shading.c
+++ b/source/blender/editors/render/render_shading.c
@@ -611,7 +611,7 @@ void WORLD_OT_new(wmOperatorType *ot)
/* identifiers */
ot->name = "New World";
ot->idname = "WORLD_OT_new";
- ot->description = "Add a new world";
+ ot->description = "Create a new world Data-Block";
/* api callbacks */
ot->exec = new_world_exec;
@@ -1818,7 +1818,7 @@ static void paste_mtex_copybuf(ID *id)
mtex = &(((FreestyleLineStyle *)id)->mtex[(int)((FreestyleLineStyle *)id)->texact]);
break;
default:
- BLI_assert("invalid id type");
+ BLI_assert(!"invalid id type");
return;
}
diff --git a/source/blender/editors/render/render_update.c b/source/blender/editors/render/render_update.c
index f11a8177bf8..4e02ff77a31 100644
--- a/source/blender/editors/render/render_update.c
+++ b/source/blender/editors/render/render_update.c
@@ -189,8 +189,12 @@ void ED_render_engine_changed(Main *bmain)
RE_FreePersistentData();
- for (scene = bmain->scene.first; scene; scene = scene->id.next)
+ for (scene = bmain->scene.first; scene; scene = scene->id.next) {
ED_render_id_flush_update(bmain, &scene->id);
+ if (scene->nodetree) {
+ ntreeCompositUpdateRLayers(scene->nodetree);
+ }
+ }
}
/***************************** Updates ***********************************
diff --git a/source/blender/editors/render/render_view.c b/source/blender/editors/render/render_view.c
index 65f0fec50bc..c4a9af79ec2 100644
--- a/source/blender/editors/render/render_view.c
+++ b/source/blender/editors/render/render_view.c
@@ -44,6 +44,7 @@
#include "WM_types.h"
#include "ED_screen.h"
+#include "UI_interface.h"
#include "wm_window.h"
@@ -128,8 +129,8 @@ static ScrArea *find_area_image_empty(bContext *C)
/* new window uses x,y to set position */
ScrArea *render_view_open(bContext *C, int mx, int my, ReportList *reports)
{
- wmWindow *win = CTX_wm_window(C);
Scene *scene = CTX_data_scene(C);
+ wmWindow *win = NULL;
ScrArea *sa = NULL;
SpaceImage *sima;
bool area_was_image = false;
@@ -138,25 +139,15 @@ ScrArea *render_view_open(bContext *C, int mx, int my, ReportList *reports)
return NULL;
if (scene->r.displaymode == R_OUTPUT_WINDOW) {
- rcti rect;
- int sizex, sizey;
-
- sizex = 10 + (scene->r.xsch * scene->r.size) / 100;
- sizey = 40 + (scene->r.ysch * scene->r.size) / 100;
+ int sizex = 30 * UI_DPI_FAC + (scene->r.xsch * scene->r.size) / 100;
+ int sizey = 60 * UI_DPI_FAC + (scene->r.ysch * scene->r.size) / 100;
/* arbitrary... miniature image window views don't make much sense */
if (sizex < 320) sizex = 320;
if (sizey < 256) sizey = 256;
- /* some magic to calculate postition */
- /* pixelsize: mouse coords are in U.pixelsize units :/ */
- rect.xmin = (mx / U.pixelsize) + win->posx - sizex / 2;
- rect.ymin = (my / U.pixelsize) + win->posy - sizey / 2;
- rect.xmax = rect.xmin + sizex;
- rect.ymax = rect.ymin + sizey;
-
/* changes context! */
- if (WM_window_open_temp(C, &rect, WM_WINDOW_RENDER) == NULL) {
+ if (WM_window_open_temp(C, mx, my, sizex, sizey, WM_WINDOW_RENDER) == NULL) {
BKE_report(reports, RPT_ERROR, "Failed to open window!");
return NULL;
}
diff --git a/source/blender/editors/screen/glutil.c b/source/blender/editors/screen/glutil.c
index 93bac3f6660..216cbe9d7f4 100644
--- a/source/blender/editors/screen/glutil.c
+++ b/source/blender/editors/screen/glutil.c
@@ -566,7 +566,7 @@ void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int fo
float rast_x = x + off_x * xzoom;
float rast_y = y + off_y * yzoom;
- GLfloat scissor[4];
+ GLfloat viewport[4];
int draw_w, draw_h;
/* Determine the smallest number of pixels we need to draw
@@ -581,9 +581,9 @@ void glaDrawPixelsSafe(float x, float y, int img_w, int img_h, int row_w, int fo
* fails if we zoom in on one really huge pixel so that it
* covers the entire screen).
*/
- glGetFloatv(GL_SCISSOR_BOX, scissor);
- draw_w = min_ii(img_w - off_x, ceil((scissor[2] - rast_x) / xzoom));
- draw_h = min_ii(img_h - off_y, ceil((scissor[3] - rast_y) / yzoom));
+ glGetFloatv(GL_VIEWPORT, viewport);
+ draw_w = min_ii(img_w - off_x, ceil((viewport[2] - rast_x) / xzoom));
+ draw_h = min_ii(img_h - off_y, ceil((viewport[3] - rast_y) / yzoom));
if (draw_w > 0 && draw_h > 0) {
diff --git a/source/blender/editors/screen/screen_edit.c b/source/blender/editors/screen/screen_edit.c
index 5cd0d33c365..f469686b0b2 100644
--- a/source/blender/editors/screen/screen_edit.c
+++ b/source/blender/editors/screen/screen_edit.c
@@ -766,7 +766,9 @@ static void screen_test_scale(bScreen *sc, int winsize_x, int winsize_y)
/* lower edge */
const int yval = sa->v2->vec.y - headery_init;
se = screen_findedge(sc, sa->v4, sa->v1);
- select_connected_scredge(sc, se);
+ if (se != NULL) {
+ select_connected_scredge(sc, se);
+ }
for (sv = sc->vertbase.first; sv; sv = sv->next) {
if (sv != sa->v2 && sv != sa->v3) {
if (sv->flag) {
@@ -779,7 +781,9 @@ static void screen_test_scale(bScreen *sc, int winsize_x, int winsize_y)
/* upper edge */
const int yval = sa->v1->vec.y + headery_init;
se = screen_findedge(sc, sa->v2, sa->v3);
- select_connected_scredge(sc, se);
+ if (se != NULL) {
+ select_connected_scredge(sc, se);
+ }
for (sv = sc->vertbase.first; sv; sv = sv->next) {
if (sv != sa->v1 && sv != sa->v4) {
if (sv->flag) {
@@ -1224,6 +1228,7 @@ void ED_screen_refresh(wmWindowManager *wm, wmWindow *win)
winrct.ymax = winsize_y - 1;
/* header size depends on DPI, let's verify */
+ WM_window_set_dpi(win);
screen_refresh_headersizes();
screen_test_scale(win->screen, winsize_x, winsize_y);
@@ -1758,7 +1763,7 @@ bool ED_screen_delete_scene(bContext *C, Scene *scene)
BKE_libblock_remap(bmain, scene, newscene, ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_NEVER_NULL_USAGE);
- BKE_libblock_free(bmain, scene);
+ BKE_libblock_free_us(bmain, scene);
return true;
}
@@ -1922,7 +1927,6 @@ ScrArea *ED_screen_state_toggle(bContext *C, wmWindow *win, ScrArea *sa, const s
ED_screen_set(C, sc);
- BKE_screen_free(oldscreen);
BKE_libblock_free(CTX_data_main(C), oldscreen);
/* After we've restored back to SCREENNORMAL, we have to wait with
@@ -2166,10 +2170,11 @@ void ED_update_for_newframe(Main *bmain, Scene *scene, int UNUSED(mute))
/* update animated texture nodes */
{
Tex *tex;
- for (tex = bmain->tex.first; tex; tex = tex->id.next)
+ for (tex = bmain->tex.first; tex; tex = tex->id.next) {
if (tex->use_nodes && tex->nodetree) {
ntreeTexTagAnimated(tex->nodetree);
}
+ }
}
}
diff --git a/source/blender/editors/screen/screen_ops.c b/source/blender/editors/screen/screen_ops.c
index c2e094fc161..27e19ca1fc3 100644
--- a/source/blender/editors/screen/screen_ops.c
+++ b/source/blender/editors/screen/screen_ops.c
@@ -2260,25 +2260,28 @@ static int keyframe_jump_exec(bContext *C, wmOperator *op)
BLI_dlrbTree_linkedlist_sync(&keys);
/* find matching keyframe in the right direction */
- do {
- if (next)
- ak = (ActKeyColumn *)BLI_dlrbTree_search_next(&keys, compare_ak_cfraPtr, &cfra);
- else
- ak = (ActKeyColumn *)BLI_dlrbTree_search_prev(&keys, compare_ak_cfraPtr, &cfra);
-
- if (ak) {
- if (CFRA != (int)ak->cfra) {
- /* this changes the frame, so set the frame and we're done */
- CFRA = (int)ak->cfra;
- done = true;
+ if (next)
+ ak = (ActKeyColumn *)BLI_dlrbTree_search_next(&keys, compare_ak_cfraPtr, &cfra);
+ else
+ ak = (ActKeyColumn *)BLI_dlrbTree_search_prev(&keys, compare_ak_cfraPtr, &cfra);
+
+ while ((ak != NULL) && (done == false)) {
+ if (CFRA != (int)ak->cfra) {
+ /* this changes the frame, so set the frame and we're done */
+ CFRA = (int)ak->cfra;
+ done = true;
+ }
+ else {
+ /* take another step... */
+ if (next) {
+ ak = ak->next;
}
else {
- /* make this the new starting point for the search */
- cfra = ak->cfra;
+ ak = ak->prev;
}
}
- } while ((ak != NULL) && (done == false));
-
+ }
+
/* free temp stuff */
BLI_dlrbTree_free(&keys);
@@ -3756,7 +3759,7 @@ static int screen_animation_cancel_exec(bContext *C, wmOperator *op)
bScreen *screen = ED_screen_animation_playing(CTX_wm_manager(C));
if (screen) {
- if (RNA_boolean_get(op->ptr, "restore_frame")) {
+ if (RNA_boolean_get(op->ptr, "restore_frame") && screen->animtimer) {
ScreenAnimData *sad = screen->animtimer->customdata;
Scene *scene = CTX_data_scene(C);
@@ -3883,22 +3886,11 @@ static void SCREEN_OT_back_to_previous(struct wmOperatorType *ot)
static int userpref_show_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- wmWindow *win = CTX_wm_window(C);
- rcti rect;
- int sizex, sizey;
-
- sizex = 800 * UI_DPI_WINDOW_FAC;
- sizey = 480 * UI_DPI_WINDOW_FAC;
-
- /* some magic to calculate postition */
- /* pixelsize: mouse coords are in U.pixelsize units :/ */
- rect.xmin = (event->x / U.pixelsize) + win->posx - sizex / 2;
- rect.ymin = (event->y / U.pixelsize) + win->posy - sizey / 2;
- rect.xmax = rect.xmin + sizex;
- rect.ymax = rect.ymin + sizey;
+ int sizex = 800 * UI_DPI_FAC;
+ int sizey = 480 * UI_DPI_FAC;
/* changes context! */
- if (WM_window_open_temp(C, &rect, WM_WINDOW_USERPREFS) != NULL) {
+ if (WM_window_open_temp(C, event->x, event->y, sizex, sizey, WM_WINDOW_USERPREFS) != NULL) {
return OPERATOR_FINISHED;
}
else {
diff --git a/source/blender/editors/sculpt_paint/paint_image_2d.c b/source/blender/editors/sculpt_paint/paint_image_2d.c
index 4f93c12385d..09b0847b306 100644
--- a/source/blender/editors/sculpt_paint/paint_image_2d.c
+++ b/source/blender/editors/sculpt_paint/paint_image_2d.c
@@ -797,6 +797,7 @@ static void paint_2d_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const bool is_torus
float map_alpha = (rgb[3] == 0.0f) ? rrgbf[3] : rrgbf[3] / rgb[3];
mul_v3_v3fl(rrgbf, rgb, map_alpha);
+ rrgbf[3] = rgb[3];
}
else {
unsigned char straight[4];
@@ -806,6 +807,7 @@ static void paint_2d_ibuf_rgb_set(ImBuf *ibuf, int x, int y, const bool is_torus
rrgb[0] = straight[0];
rrgb[1] = straight[1];
rrgb[2] = straight[2];
+ rrgb[3] = straight[3];
}
}
@@ -995,7 +997,7 @@ static void paint_2d_lift_smear(ImBuf *ibuf, ImBuf *ibufb, int *pos, short tile)
IMB_rectblend(ibufb, ibufb, ibuf, NULL, NULL, NULL, 0, region[a].destx, region[a].desty,
region[a].destx, region[a].desty,
region[a].srcx, region[a].srcy,
- region[a].width, region[a].height, IMB_BLEND_COPY_RGB, false);
+ region[a].width, region[a].height, IMB_BLEND_COPY, false);
}
static ImBuf *paint_2d_lift_clone(ImBuf *ibuf, ImBuf *ibufb, int *pos)
@@ -1096,6 +1098,7 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *curveb, unsign
/* lift from canvas */
if (s->tool == PAINT_TOOL_SOFTEN) {
paint_2d_lift_soften(s, s->canvas, ibufb, bpos, tile);
+ blend = IMB_BLEND_INTERPOLATE;
}
else if (s->tool == PAINT_TOOL_SMEAR) {
if (lastpos[0] == pos[0] && lastpos[1] == pos[1])
@@ -1103,6 +1106,7 @@ static int paint_2d_op(void *state, ImBuf *ibufb, unsigned short *curveb, unsign
paint_2d_convert_brushco(ibufb, lastpos, blastpos);
paint_2d_lift_smear(s->canvas, ibufb, blastpos, tile);
+ blend = IMB_BLEND_INTERPOLATE;
}
else if (s->tool == PAINT_TOOL_CLONE && s->clonecanvas) {
liftpos[0] = pos[0] - offset[0] * s->canvas->x;
diff --git a/source/blender/editors/sculpt_paint/paint_image_proj.c b/source/blender/editors/sculpt_paint/paint_image_proj.c
index d0f1cc99b8d..8586eb42bec 100644
--- a/source/blender/editors/sculpt_paint/paint_image_proj.c
+++ b/source/blender/editors/sculpt_paint/paint_image_proj.c
@@ -3712,8 +3712,12 @@ static void project_paint_prepare_all_faces(
}
/* don't allow using the same inage for painting and stencilling */
- if (slot->ima == ps->stencil_ima)
+ if (slot->ima == ps->stencil_ima) {
+ /* While this shouldn't be used, face-winding reads all polys.
+ * It's less trouble to set all faces to valid UV's, avoiding NULL checks all over. */
+ ps->dm_mloopuv[lt->poly] = mloopuv_base;
continue;
+ }
tpage = slot->ima;
}
@@ -4291,7 +4295,7 @@ static void do_projectpaint_soften_f(ProjPaintState *ps, ProjPixel *projPixel, f
return;
}
else {
- blend_color_interpolate_float(rgba, rgba, projPixel->pixel.f_pt, mask);
+ blend_color_interpolate_float(rgba, projPixel->pixel.f_pt, rgba, mask);
}
BLI_linklist_prepend_arena(softenPixels, (void *)projPixel, softenArena);
@@ -4750,6 +4754,9 @@ static void *do_projectpaint_thread(void *ph_v)
copy_v3_v3(texrgb, texrgba);
mask *= texrgba[3];
}
+ else {
+ zero_v3(texrgb);
+ }
/* extra mask for normal, layer stencil, .. */
mask *= ((float)projPixel->mask) * (1.0f / 65535.0f);
diff --git a/source/blender/editors/sculpt_paint/paint_utils.c b/source/blender/editors/sculpt_paint/paint_utils.c
index 31c471c3517..10628d8cccb 100644
--- a/source/blender/editors/sculpt_paint/paint_utils.c
+++ b/source/blender/editors/sculpt_paint/paint_utils.c
@@ -426,7 +426,7 @@ void paint_sample_color(bContext *C, ARegion *ar, int x, int y, bool texpaint_pr
Scene *scene = CTX_data_scene(C);
Paint *paint = BKE_paint_get_active_from_context(C);
Palette *palette = BKE_paint_palette(paint);
- PaletteColor *color;
+ PaletteColor *color = NULL;
Brush *br = BKE_paint_brush(BKE_paint_get_active_from_context(C));
unsigned int col;
const unsigned char *cp;
diff --git a/source/blender/editors/sound/sound_ops.c b/source/blender/editors/sound/sound_ops.c
index c2c52f58181..e273d3a40f0 100644
--- a/source/blender/editors/sound/sound_ops.c
+++ b/source/blender/editors/sound/sound_ops.c
@@ -670,7 +670,7 @@ static void SOUND_OT_mixdown(wmOperatorType *ot)
/* identifiers */
ot->name = "Mixdown";
- ot->description = "Mixes the scene's audio to a sound file";
+ ot->description = "Mix the scene's audio to a sound file";
ot->idname = "SOUND_OT_mixdown";
/* api callbacks */
diff --git a/source/blender/editors/space_buttons/buttons_texture.c b/source/blender/editors/space_buttons/buttons_texture.c
index 72de7e5c81c..1d67ac620b0 100644
--- a/source/blender/editors/space_buttons/buttons_texture.c
+++ b/source/blender/editors/space_buttons/buttons_texture.c
@@ -470,7 +470,7 @@ void buttons_texture_context_compute(const bContext *C, SpaceButs *sbuts)
}
else {
/* set one user as active based on active index */
- if (ct->index == BLI_listbase_count_ex(&ct->users, ct->index + 1))
+ if (ct->index >= BLI_listbase_count_ex(&ct->users, ct->index + 1))
ct->index = 0;
ct->user = BLI_findlink(&ct->users, ct->index);
diff --git a/source/blender/editors/space_clip/clip_editor.c b/source/blender/editors/space_clip/clip_editor.c
index 14d0f909d23..59dd755173f 100644
--- a/source/blender/editors/space_clip/clip_editor.c
+++ b/source/blender/editors/space_clip/clip_editor.c
@@ -259,11 +259,9 @@ ImBuf *ED_space_clip_get_stable_buffer(SpaceClip *sc, float loc[2], float *scale
return NULL;
}
-/* Returns color in the display space, matching ED_space_image_color_sample(). */
-bool ED_space_clip_color_sample(Scene *scene, SpaceClip *sc, ARegion *ar, int mval[2], float r_col[3])
+/* Returns color in linear space, matching ED_space_image_color_sample(). */
+bool ED_space_clip_color_sample(SpaceClip *sc, ARegion *ar, int mval[2], float r_col[3])
{
- const char *display_device = scene->display_settings.display_device;
- struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
ImBuf *ibuf;
float fx, fy, co[2];
bool ret = false;
@@ -299,11 +297,7 @@ bool ED_space_clip_color_sample(Scene *scene, SpaceClip *sc, ARegion *ar, int mv
ret = true;
}
}
-
- if (ret) {
- IMB_colormanagement_scene_linear_to_display_v3(r_col, display);
- }
-
+
IMB_freeImBuf(ibuf);
return ret;
diff --git a/source/blender/editors/space_clip/space_clip.c b/source/blender/editors/space_clip/space_clip.c
index 05e69968e35..237082f948b 100644
--- a/source/blender/editors/space_clip/space_clip.c
+++ b/source/blender/editors/space_clip/space_clip.c
@@ -337,7 +337,7 @@ static void clip_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
switch (wmn->data) {
case ND_FRAME:
clip_scopes_tag_refresh(sa);
- /* fall-through */
+ ATTR_FALLTHROUGH;
case ND_FRAME_RANGE:
ED_area_tag_redraw(sa);
diff --git a/source/blender/editors/space_clip/tracking_ops.c b/source/blender/editors/space_clip/tracking_ops.c
index 169eb76399b..56c240c3d20 100644
--- a/source/blender/editors/space_clip/tracking_ops.c
+++ b/source/blender/editors/space_clip/tracking_ops.c
@@ -875,8 +875,7 @@ static int slide_marker_modal(bContext *C, wmOperator *op, const wmEvent *event)
if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) {
data->accurate = event->val == KM_PRESS;
}
-
- /* fall-through */
+ ATTR_FALLTHROUGH;
case MOUSEMOVE:
mdelta[0] = event->mval[0] - data->mval[0];
mdelta[1] = event->mval[1] - data->mval[1];
diff --git a/source/blender/editors/space_clip/tracking_ops_plane.c b/source/blender/editors/space_clip/tracking_ops_plane.c
index 4332f3ea765..aa8518befaa 100644
--- a/source/blender/editors/space_clip/tracking_ops_plane.c
+++ b/source/blender/editors/space_clip/tracking_ops_plane.c
@@ -301,8 +301,7 @@ static int slide_plane_marker_modal(bContext *C,
if (ELEM(event->type, LEFTSHIFTKEY, RIGHTSHIFTKEY)) {
data->accurate = event->val == KM_PRESS;
}
-
- /* fall-through */
+ ATTR_FALLTHROUGH;
case MOUSEMOVE:
mdelta[0] = event->mval[0] - data->previous_mval[0];
mdelta[1] = event->mval[1] - data->previous_mval[1];
diff --git a/source/blender/editors/space_file/filelist.c b/source/blender/editors/space_file/filelist.c
index 83469a48165..d94aad640b7 100644
--- a/source/blender/editors/space_file/filelist.c
+++ b/source/blender/editors/space_file/filelist.c
@@ -277,9 +277,10 @@ typedef struct FileListFilter {
/* FileListFilter.flags */
enum {
- FLF_HIDE_DOT = 1 << 0,
- FLF_HIDE_PARENT = 1 << 1,
- FLF_HIDE_LIB_DIR = 1 << 2,
+ FLF_DO_FILTER = 1 << 0,
+ FLF_HIDE_DOT = 1 << 1,
+ FLF_HIDE_PARENT = 1 << 2,
+ FLF_HIDE_LIB_DIR = 1 << 3,
};
typedef struct FileList {
@@ -594,24 +595,27 @@ static bool is_filtered_file(FileListInternEntry *file, const char *UNUSED(root)
{
bool is_filtered = !is_hidden_file(file->relpath, filter);
- if (is_filtered && filter->filter && !FILENAME_IS_CURRPAR(file->relpath)) {
- if (file->typeflag & FILE_TYPE_DIR) {
- if (file->typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) {
- if (!(filter->filter & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))) {
- is_filtered = false;
+ if (is_filtered && (filter->flags & FLF_DO_FILTER) && !FILENAME_IS_CURRPAR(file->relpath)) {
+ /* We only check for types if some type are enabled in filtering. */
+ if (filter->filter) {
+ if (file->typeflag & FILE_TYPE_DIR) {
+ if (file->typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) {
+ if (!(filter->filter & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))) {
+ is_filtered = false;
+ }
+ }
+ else {
+ if (!(filter->filter & FILE_TYPE_FOLDER)) {
+ is_filtered = false;
+ }
}
}
else {
- if (!(filter->filter & FILE_TYPE_FOLDER)) {
+ if (!(file->typeflag & filter->filter)) {
is_filtered = false;
}
}
}
- else {
- if (!(file->typeflag & filter->filter)) {
- is_filtered = false;
- }
- }
if (is_filtered && (filter->filter_search[0] != '\0')) {
if (fnmatch(filter->filter_search, file->relpath, FNM_CASEFOLD) != 0) {
is_filtered = false;
@@ -631,28 +635,31 @@ static bool is_filtered_lib(FileListInternEntry *file, const char *root, FileLis
if (BLO_library_path_explode(path, dir, &group, &name)) {
is_filtered = !is_hidden_file(file->relpath, filter);
- if (is_filtered && filter->filter && !FILENAME_IS_CURRPAR(file->relpath)) {
- if (file->typeflag & FILE_TYPE_DIR) {
- if (file->typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) {
- if (!(filter->filter & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))) {
- is_filtered = false;
+ if (is_filtered && (filter->flags & FLF_DO_FILTER) && !FILENAME_IS_CURRPAR(file->relpath)) {
+ /* We only check for types if some type are enabled in filtering. */
+ if (filter->filter || filter->filter_id) {
+ if (file->typeflag & FILE_TYPE_DIR) {
+ if (file->typeflag & (FILE_TYPE_BLENDERLIB | FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP)) {
+ if (!(filter->filter & (FILE_TYPE_BLENDER | FILE_TYPE_BLENDER_BACKUP))) {
+ is_filtered = false;
+ }
}
- }
- else {
- if (!(filter->filter & FILE_TYPE_FOLDER)) {
- is_filtered = false;
+ else {
+ if (!(filter->filter & FILE_TYPE_FOLDER)) {
+ is_filtered = false;
+ }
}
}
- }
- if (is_filtered && group) {
- if (!name && (filter->flags & FLF_HIDE_LIB_DIR)) {
- is_filtered = false;
- }
- else {
- unsigned int filter_id = groupname_to_filter_id(group);
- if (!(filter_id & filter->filter_id)) {
+ if (is_filtered && group) {
+ if (!name && (filter->flags & FLF_HIDE_LIB_DIR)) {
is_filtered = false;
}
+ else {
+ unsigned int filter_id = groupname_to_filter_id(group);
+ if (!(filter_id & filter->filter_id)) {
+ is_filtered = false;
+ }
+ }
}
}
if (is_filtered && (filter->filter_search[0] != '\0')) {
@@ -729,12 +736,17 @@ void filelist_filter(FileList *filelist)
MEM_freeN(filtered_tmp);
}
-void filelist_setfilter_options(FileList *filelist, const bool hide_dot, const bool hide_parent,
+void filelist_setfilter_options(FileList *filelist, const bool do_filter,
+ const bool hide_dot, const bool hide_parent,
const unsigned int filter, const unsigned int filter_id,
const char *filter_glob, const char *filter_search)
{
bool update = false;
+ if (((filelist->filter_data.flags & FLF_DO_FILTER) != 0) != (do_filter != 0)) {
+ filelist->filter_data.flags ^= FLF_DO_FILTER;
+ update = true;
+ }
if (((filelist->filter_data.flags & FLF_HIDE_DOT) != 0) != (hide_dot != 0)) {
filelist->filter_data.flags ^= FLF_HIDE_DOT;
update = true;
@@ -1104,7 +1116,10 @@ static void filelist_cache_preview_runf(TaskPool *__restrict pool, void *taskdat
preview->img = IMB_thumb_manage(preview->path, THB_LARGE, source);
IMB_thumb_path_unlock(preview->path);
- preview->flags = 0; /* Used to tell free func to not free anything! */
+ /* Used to tell free func to not free anything.
+ * Note that we do not care about cas result here,
+ * we only want value attribution itself to be atomic (and memory barier).*/
+ atomic_cas_uint32(&preview->flags, preview->flags, 0);
BLI_thread_queue_push(cache->previews_done, preview);
// printf("%s: End (%d)...\n", __func__, threadid);
@@ -1964,7 +1979,7 @@ int ED_path_extension_type(const char *path)
else if (BLI_testextensie(path, ".py")) {
return FILE_TYPE_PYSCRIPT;
}
- else if (BLI_testextensie_n(path, ".txt", ".glsl", ".osl", ".data", NULL)) {
+ else if (BLI_testextensie_n(path, ".txt", ".glsl", ".osl", ".data", ".pov", ".ini", ".mcr", ".inc", NULL)) {
return FILE_TYPE_TEXT;
}
else if (BLI_testextensie_n(path, ".ttf", ".ttc", ".pfb", ".otf", ".otc", NULL)) {
diff --git a/source/blender/editors/space_file/filelist.h b/source/blender/editors/space_file/filelist.h
index f4304681780..4e9c1e0dd1d 100644
--- a/source/blender/editors/space_file/filelist.h
+++ b/source/blender/editors/space_file/filelist.h
@@ -68,7 +68,8 @@ int folderlist_clear_next(struct SpaceFile *sfile);
void filelist_setsorting(struct FileList *filelist, const short sort);
void filelist_sort(struct FileList *filelist);
-void filelist_setfilter_options(struct FileList *filelist, const bool hide_dot, const bool hide_parent,
+void filelist_setfilter_options(struct FileList *filelist, const bool do_filter,
+ const bool hide_dot, const bool hide_parent,
const unsigned int filter, const unsigned int filter_id,
const char *filter_glob, const char *filter_search);
void filelist_filter(struct FileList *filelist);
diff --git a/source/blender/editors/space_file/fsmenu.c b/source/blender/editors/space_file/fsmenu.c
index 71d49e0dc2e..ee0ec3fda39 100644
--- a/source/blender/editors/space_file/fsmenu.c
+++ b/source/blender/editors/space_file/fsmenu.c
@@ -48,9 +48,6 @@
#ifdef WIN32
# include <windows.h> /* need to include windows.h so _WIN32_IE is defined */
-# ifndef _WIN32_IE
-# define _WIN32_IE 0x0400 /* minimal requirements for SHGetSpecialFolderPath on MINGW MSVC has this defined already */
-# endif
# include <shlobj.h> /* for SHGetSpecialFolderPath, has to be done before BLI_winstuff
* because 'near' is disabled through BLI_windstuff */
# include "BLI_winstuff.h"
diff --git a/source/blender/editors/space_file/space_file.c b/source/blender/editors/space_file/space_file.c
index 374db92297d..287b98fa589 100644
--- a/source/blender/editors/space_file/space_file.c
+++ b/source/blender/editors/space_file/space_file.c
@@ -223,9 +223,10 @@ static void file_refresh(const bContext *C, ScrArea *sa)
filelist_setdir(sfile->files, params->dir);
filelist_setrecursion(sfile->files, params->recursion_level);
filelist_setsorting(sfile->files, params->sort);
- filelist_setfilter_options(sfile->files, (params->flag & FILE_HIDE_DOT) != 0,
+ filelist_setfilter_options(sfile->files, (params->flag & FILE_FILTER) != 0,
+ (params->flag & FILE_HIDE_DOT) != 0,
false, /* TODO hide_parent, should be controllable? */
- (params->flag & FILE_FILTER) ? params->filter : 0,
+ params->filter,
params->filter_id,
params->filter_glob,
params->filter_search);
diff --git a/source/blender/editors/space_image/image_buttons.c b/source/blender/editors/space_image/image_buttons.c
index b9d98dfe794..8037c2deb5b 100644
--- a/source/blender/editors/space_image/image_buttons.c
+++ b/source/blender/editors/space_image/image_buttons.c
@@ -428,7 +428,6 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void *
RenderPass *rpass;
const char *fake_name;
int nr;
- int passflag = 0;
/* may have been freed since drawing */
rr = BKE_image_acquire_renderresult(scene, image);
@@ -450,30 +449,31 @@ static void ui_imageuser_pass_menu(bContext *UNUSED(C), uiLayout *layout, void *
fake_name = ui_imageuser_pass_fake_name(rl);
if (fake_name) {
- BLI_strncpy(rpass_fake.internal_name, fake_name, sizeof(rpass_fake.internal_name));
+ BLI_strncpy(rpass_fake.name, fake_name, sizeof(rpass_fake.name));
nr += 1;
}
+ ListBase added_passes;
+ BLI_listbase_clear(&added_passes);
+
/* rendered results don't have a Combined pass */
/* multiview: the ordering must be ascending, so the left-most pass is always the one picked */
for (rpass = rl ? rl->passes.first : NULL; rpass; rpass = rpass->next, nr++) {
-
/* just show one pass of each kind */
- if (passflag & rpass->passtype)
+ if (BLI_findstring_ptr(&added_passes, rpass->name, offsetof(LinkData, data))) {
continue;
+ }
+ BLI_addtail(&added_passes, BLI_genericNodeN(rpass->name));
- passflag |= rpass->passtype;
-
-final:
- uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rpass->internal_name), 0, 0,
+ uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rpass->name), 0, 0,
UI_UNIT_X * 5, UI_UNIT_X, &iuser->pass, (float) nr, 0.0, 0, -1, "");
}
+ BLI_freelistN(&added_passes);
+
if (fake_name) {
- fake_name = NULL;
- rpass = &rpass_fake;
- nr = 0;
- goto final;
+ uiDefButS(block, UI_BTYPE_BUT_MENU, B_NOP, IFACE_(rpass_fake.name), 0, 0,
+ UI_UNIT_X * 5, UI_UNIT_X, &iuser->pass, 0.0f, 0.0, 0, -1, "");
}
BKE_image_release_renderresult(scene, image);
@@ -633,7 +633,7 @@ static bool ui_imageuser_pass_menu_step(bContext *C, int direction, void *rnd_pt
int rp_index = iuser->pass + 1;
for (rp = rpass->next; rp; rp = rp->next, rp_index++) {
- if (rp->passtype != rpass->passtype) {
+ if (!STREQ(rp->name, rpass->name)) {
iuser->pass = rp_index;
changed = true;
break;
@@ -650,7 +650,7 @@ static bool ui_imageuser_pass_menu_step(bContext *C, int direction, void *rnd_pt
}
for (rp = rl->passes.first; rp; rp = rp->next, rp_index++) {
- if (rp->passtype == rpass->passtype) {
+ if (STREQ(rp->name, rpass->name)) {
iuser->pass = rp_index - 1;
changed = true;
break;
@@ -712,6 +712,10 @@ static void uiblock_layer_pass_buttons(
const char *display_name = "";
const bool show_stereo = (iuser->flag & IMA_SHOW_STEREO) != 0;
+ if (iuser->scene == NULL) {
+ return;
+ }
+
uiLayoutRow(layout, true);
/* layer menu is 1/3 larger than pass */
@@ -769,7 +773,7 @@ static void uiblock_layer_pass_buttons(
fake_name = ui_imageuser_pass_fake_name(rl);
rpass = (rl ? BLI_findlink(&rl->passes, iuser->pass - (fake_name ? 1 : 0)) : NULL);
- display_name = rpass ? rpass->internal_name : (fake_name ? fake_name : "");
+ display_name = rpass ? rpass->name : (fake_name ? fake_name : "");
rnd_pt = ui_imageuser_data_copy(&rnd_pt_local);
but = uiDefMenuBut(
block, ui_imageuser_pass_menu, rnd_pt, IFACE_(display_name),
@@ -1204,7 +1208,7 @@ void uiTemplateImageStereo3d(uiLayout *layout, PointerRNA *stereo3d_format_ptr)
case S3D_DISPLAY_SIDEBYSIDE:
{
uiItemR(col, stereo3d_format_ptr, "use_sidebyside_crosseyed", 0, NULL, ICON_NONE);
- /* fall-through */
+ ATTR_FALLTHROUGH;
}
case S3D_DISPLAY_TOPBOTTOM:
{
diff --git a/source/blender/editors/space_image/image_ops.c b/source/blender/editors/space_image/image_ops.c
index 324a3cb13b7..3c64d1ebb71 100644
--- a/source/blender/editors/space_image/image_ops.c
+++ b/source/blender/editors/space_image/image_ops.c
@@ -1067,6 +1067,7 @@ typedef struct ImageOpenData {
typedef struct ImageFrameRange {
struct ImageFrameRange *next, *prev;
ListBase frames;
+ /** The full path of the first file in the list of image files */
char filepath[FILE_MAX];
} ImageFrameRange;
@@ -1092,12 +1093,12 @@ static void image_open_cancel(bContext *UNUSED(C), wmOperator *op)
/**
* \brief Get a list of frames from the list of image files matching the first file name sequence pattern
* \param ptr [in] the RNA pointer containing the "directory" entry and "files" collection
- * \param frames [out] the list of frame numbers found in the files matching the first one by name
- * \param path [out] the full path of the first file in the list of image files
+ * \param frames_all [out] the list of frame numbers found in the files matching the first one by name
*/
static void image_sequence_get_frame_ranges(PointerRNA *ptr, ListBase *frames_all)
{
char dir[FILE_MAXDIR];
+ const bool do_frame_range = RNA_boolean_get(ptr, "use_sequence_detection");
ImageFrameRange *frame_range = NULL;
RNA_string_get(ptr, "directory", dir);
@@ -1113,7 +1114,8 @@ static void image_sequence_get_frame_ranges(PointerRNA *ptr, ListBase *frames_al
frame->framenr = BLI_stringdec(filename, head, tail, &digits);
/* still in the same sequence */
- if ((frame_range != NULL) &&
+ if (do_frame_range &&
+ (frame_range != NULL) &&
(STREQLEN(base_head, head, FILE_MAX)) &&
(STREQLEN(base_tail, tail, FILE_MAX)))
{
@@ -1167,6 +1169,7 @@ static int image_sequence_get_len(ListBase *frames, int *ofs)
}
return frame_curr - (*ofs);
}
+ *ofs = 0;
return 0;
}
@@ -1325,7 +1328,11 @@ static int image_open_exec(bContext *C, wmOperator *op)
iuser->frames = frame_seq_len;
iuser->sfra = 1;
iuser->framenr = 1;
- iuser->offset = frame_ofs - 1;
+ if (ima->source == IMA_SRC_MOVIE) {
+ iuser->offset = 0;
+ } else {
+ iuser->offset = frame_ofs - 1;
+ }
iuser->fie_ima = 2;
iuser->scene = scene;
BKE_image_init_imageuser(ima, iuser);
@@ -1448,6 +1455,9 @@ void IMAGE_OT_open(wmOperatorType *ot)
ot, FILE_TYPE_FOLDER | FILE_TYPE_IMAGE | FILE_TYPE_MOVIE, FILE_SPECIAL, FILE_OPENFILE,
WM_FILESEL_FILEPATH | WM_FILESEL_DIRECTORY | WM_FILESEL_FILES | WM_FILESEL_RELPATH,
FILE_DEFAULTDISPLAY, FILE_SORT_ALPHA);
+
+ RNA_def_boolean(ot->srna, "use_sequence_detection", true, "Detect Sequences",
+ "Automatically detect animated sequences in selected images (based on file names)");
}
/******************** Match movie length operator ********************/
@@ -1890,7 +1900,6 @@ static bool save_image_doit(bContext *C, SpaceImage *sima, wmOperator *op, SaveI
}
else {
colormanaged_ibuf = IMB_colormanagement_imbuf_for_write(ibuf, save_as_render, true, &imf->view_settings, &imf->display_settings, imf);
- IMB_metadata_copy(colormanaged_ibuf, ibuf);
ok = BKE_imbuf_write_as(colormanaged_ibuf, simopts->filepath, imf, save_copy);
save_imbuf_post(ibuf, colormanaged_ibuf);
}
@@ -2900,11 +2909,9 @@ static void image_sample_draw(const bContext *C, ARegion *ar, void *arg_info)
}
}
-/* Returns color in the display space, matching ED_space_node_color_sample(). */
-bool ED_space_image_color_sample(Scene *scene, SpaceImage *sima, ARegion *ar, int mval[2], float r_col[3])
+/* Returns color in linear space, matching ED_space_node_color_sample(). */
+bool ED_space_image_color_sample(SpaceImage *sima, ARegion *ar, int mval[2], float r_col[3])
{
- const char *display_device = scene->display_settings.display_device;
- struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
void *lock;
ImBuf *ibuf = ED_space_image_acquire_buffer(sima, &lock);
float fx, fy;
@@ -2938,10 +2945,6 @@ bool ED_space_image_color_sample(Scene *scene, SpaceImage *sima, ARegion *ar, in
}
}
- if (ret) {
- IMB_colormanagement_scene_linear_to_display_v3(r_col, display);
- }
-
ED_space_image_release_buffer(sima, ibuf, lock);
return ret;
}
diff --git a/source/blender/editors/space_info/info_ops.c b/source/blender/editors/space_info/info_ops.c
index 0e427623840..b87a0de23b9 100644
--- a/source/blender/editors/space_info/info_ops.c
+++ b/source/blender/editors/space_info/info_ops.c
@@ -162,7 +162,6 @@ static int pack_all_exec(bContext *C, wmOperator *op)
Main *bmain = CTX_data_main(C);
packAll(bmain, op->reports, true);
- G.fileflags |= G_AUTOPACK;
return OPERATOR_FINISHED;
}
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index 5355b8012db..c774b99629c 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -552,7 +552,7 @@ void nla_buttons_register(ARegionType *art)
pt = MEM_callocN(sizeof(PanelType), "spacetype nla panel modifiers");
strcpy(pt->idname, "NLA_PT_modifiers");
strcpy(pt->label, N_("Modifiers"));
- strcpy(pt->category, "Modifiers");
+ strcpy(pt->category, "Modifiers");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = nla_panel_modifiers;
pt->poll = nla_strip_eval_panel_poll;
diff --git a/source/blender/editors/space_nla/nla_draw.c b/source/blender/editors/space_nla/nla_draw.c
index 93dcdbb5c02..255fc0d6f8f 100644
--- a/source/blender/editors/space_nla/nla_draw.c
+++ b/source/blender/editors/space_nla/nla_draw.c
@@ -362,7 +362,7 @@ static void nla_draw_strip(SpaceNla *snla, AnimData *adt, NlaTrack *nlt, NlaStri
glVertex2f(strip->start, yminc);
glEnd();
}
- /* fall-through */
+ ATTR_FALLTHROUGH;
/* this only draws after the strip */
case NLASTRIP_EXTEND_HOLD_FORWARD:
diff --git a/source/blender/editors/space_node/drawnode.c b/source/blender/editors/space_node/drawnode.c
index e4f5802a395..f58b4050834 100644
--- a/source/blender/editors/space_node/drawnode.c
+++ b/source/blender/editors/space_node/drawnode.c
@@ -1234,6 +1234,7 @@ static void node_shader_set_butfunc(bNodeType *ntype)
case SH_NODE_BSDF_GLOSSY:
case SH_NODE_BSDF_GLASS:
case SH_NODE_BSDF_REFRACTION:
+ case SH_NODE_BSDF_PRINCIPLED:
ntype->draw_buttons = node_shader_buts_glossy;
break;
case SH_NODE_BSDF_ANISOTROPIC:
@@ -2477,6 +2478,11 @@ static void node_composit_buts_sunbeams(uiLayout *layout, bContext *UNUSED(C), P
uiItemR(layout, ptr, "ray_length", UI_ITEM_R_SLIDER, NULL, ICON_NONE);
}
+static void node_composit_buts_brightcontrast(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+{
+ uiItemR(layout, ptr, "use_premultiply", 0, NULL, ICON_NONE);
+}
+
/* only once called */
static void node_composit_set_butfunc(bNodeType *ntype)
{
@@ -2704,6 +2710,8 @@ static void node_composit_set_butfunc(bNodeType *ntype)
case CMP_NODE_SUNBEAMS:
ntype->draw_buttons = node_composit_buts_sunbeams;
break;
+ case CMP_NODE_BRIGHTCONTRAST:
+ ntype->draw_buttons = node_composit_buts_brightcontrast;
}
}
@@ -3075,7 +3083,7 @@ static void std_node_socket_draw(bContext *C, uiLayout *layout, PointerRNA *ptr,
node_file_output_socket_draw(C, layout, ptr, node_ptr);
return;
}
-
+
if ((sock->in_out == SOCK_OUT) || (sock->flag & SOCK_IN_USE) || (sock->flag & SOCK_HIDE_VALUE)) {
node_socket_button_label(C, layout, ptr, node_ptr, text);
return;
@@ -3424,7 +3432,6 @@ void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link,
/* store current linewidth */
float linew;
float arrow[2], arrow1[2], arrow2[2];
- const float px_fac = UI_DPI_WINDOW_FAC;
glGetFloatv(GL_LINE_WIDTH, &linew);
/* we can reuse the dist variable here to increment the GL curve eval amount*/
@@ -3451,7 +3458,7 @@ void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link,
}
if (do_triple) {
UI_ThemeColorShadeAlpha(th_col3, -80, -120);
- glLineWidth(4.0f * px_fac);
+ glLineWidth(4.0f);
glBegin(GL_LINE_STRIP);
for (i = 0; i <= LINK_RESOL; i++) {
@@ -3471,7 +3478,7 @@ void node_draw_link_bezier(View2D *v2d, SpaceNode *snode, bNodeLink *link,
* for Intel hardware, this breaks with GL_LINE_STRIP and
* changing color in begin/end blocks.
*/
- glLineWidth(1.5f * px_fac);
+ glLineWidth(1.5f);
if (do_shaded) {
glBegin(GL_LINES);
for (i = 0; i < LINK_RESOL; i++) {
@@ -3606,7 +3613,7 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
return;
if (link->fromsock->flag & SOCK_UNAVAIL)
return;
-
+
if (link->flag & NODE_LINK_VALID) {
/* special indicated link, on drop-node */
if (link->flag & NODE_LINKFLAG_HILITE) {
@@ -3626,7 +3633,7 @@ void node_draw_link(View2D *v2d, SpaceNode *snode, bNodeLink *link)
th_col1 = TH_REDALERT;
}
}
-
+
node_draw_link_bezier(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3);
// node_draw_link_straight(v2d, snode, link, th_col1, do_shaded, th_col2, do_triple, th_col3);
}
diff --git a/source/blender/editors/space_node/node_add.c b/source/blender/editors/space_node/node_add.c
index bcd0f6623e1..dc6b06790e0 100644
--- a/source/blender/editors/space_node/node_add.c
+++ b/source/blender/editors/space_node/node_add.c
@@ -107,13 +107,15 @@ static bool add_reroute_intersect_check(bNodeLink *link, float mcoords[][2], int
if (node_link_bezier_points(NULL, NULL, link, coord_array, NODE_LINK_RESOL)) {
- for (i = 0; i < tot - 1; i++)
- for (b = 0; b < NODE_LINK_RESOL; b++)
+ for (i = 0; i < tot - 1; i++) {
+ for (b = 0; b < NODE_LINK_RESOL; b++) {
if (isect_seg_seg_v2(mcoords[i], mcoords[i + 1], coord_array[b], coord_array[b + 1]) > 0) {
result[0] = (mcoords[i][0] + mcoords[i + 1][0]) / 2.0f;
result[1] = (mcoords[i][1] + mcoords[i + 1][1]) / 2.0f;
return 1;
}
+ }
+ }
}
return 0;
}
diff --git a/source/blender/editors/space_node/node_draw.c b/source/blender/editors/space_node/node_draw.c
index ab40c55b59d..6e25c87d274 100644
--- a/source/blender/editors/space_node/node_draw.c
+++ b/source/blender/editors/space_node/node_draw.c
@@ -820,14 +820,6 @@ static void node_draw_basis(const bContext *C, ARegion *ar, SpaceNode *snode, bN
UI_ThemeColorBlend(color_id, TH_REDALERT, 0.5f);
-#ifdef WITH_COMPOSITOR
- if (ntree->type == NTREE_COMPOSIT && (snode->flag & SNODE_SHOW_HIGHLIGHT)) {
- if (COM_isHighlightedbNode(node)) {
- UI_ThemeColorBlend(color_id, TH_ACTIVE, 0.5f);
- }
- }
-#endif
-
glLineWidth(1.0f);
UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_TOP_RIGHT);
@@ -989,16 +981,6 @@ static void node_draw_hidden(const bContext *C, ARegion *ar, SpaceNode *snode, b
if (node->flag & NODE_MUTED)
UI_ThemeColorBlend(color_id, TH_REDALERT, 0.5f);
-#ifdef WITH_COMPOSITOR
- if (ntree->type == NTREE_COMPOSIT && (snode->flag & SNODE_SHOW_HIGHLIGHT)) {
- if (COM_isHighlightedbNode(node)) {
- UI_ThemeColorBlend(color_id, TH_ACTIVE, 0.5f);
- }
- }
-#else
- (void)ntree;
-#endif
-
UI_draw_roundbox(rct->xmin, rct->ymin, rct->xmax, rct->ymax, hiddenrad);
/* outline active and selected emphasis */
@@ -1253,15 +1235,9 @@ static void snode_setup_v2d(SpaceNode *snode, ARegion *ar, const float center[2]
static void draw_nodetree(const bContext *C, ARegion *ar, bNodeTree *ntree, bNodeInstanceKey parent_key)
{
SpaceNode *snode = CTX_wm_space_node(C);
-
+
node_uiblocks_init(C, ntree);
-
-#ifdef WITH_COMPOSITOR
- if (ntree->type == NTREE_COMPOSIT) {
- COM_startReadHighlights();
- }
-#endif
-
+
node_update_nodetree(C, ntree);
node_draw_nodetree(C, ar, snode, ntree, parent_key);
}
diff --git a/source/blender/editors/space_node/node_edit.c b/source/blender/editors/space_node/node_edit.c
index fdfe316f5ed..5f8f839025f 100644
--- a/source/blender/editors/space_node/node_edit.c
+++ b/source/blender/editors/space_node/node_edit.c
@@ -505,8 +505,6 @@ void ED_node_composit_default(const bContext *C, struct Scene *sce)
nodeAddLink(sce->nodetree, in, fromsock, out, tosock);
ntreeUpdateTree(CTX_data_main(C), sce->nodetree);
-
- // XXX ntreeCompositForceHidden(sce->nodetree);
}
/* assumes nothing being done in ntree yet, sets the default in/out node */
@@ -582,17 +580,11 @@ void snode_set_context(const bContext *C)
}
}
- if (snode->nodetree != ntree || snode->id != id || snode->from != from || snode->treepath.last == NULL) {
+ if (snode->nodetree != ntree || snode->id != id || snode->from != from ||
+ (snode->treepath.last == NULL && ntree))
+ {
ED_node_tree_start(snode, ntree, id, from);
}
-
- /* XXX Legacy hack to update render layer node outputs.
- * This should be handled by the depsgraph eventually ...
- */
- if (ED_node_is_compositor(snode) && snode->nodetree) {
- /* update output sockets based on available layers */
- ntreeCompositForceHidden(snode->nodetree);
- }
}
void snode_update(SpaceNode *snode, bNode *node)
@@ -2094,7 +2086,7 @@ static int node_clipboard_paste_exec(bContext *C, wmOperator *op)
/* make sure all clipboard nodes would be valid in the target tree */
all_nodes_valid = true;
for (node = clipboard_nodes_lb->first; node; node = node->next) {
- if (!node->typeinfo->poll_instance(node, ntree)) {
+ if (!node->typeinfo->poll_instance || !node->typeinfo->poll_instance(node, ntree)) {
all_nodes_valid = false;
BKE_reportf(op->reports, RPT_ERROR, "Cannot add node %s into node tree %s", node->name, ntree->id.name + 2);
}
diff --git a/source/blender/editors/space_node/node_group.c b/source/blender/editors/space_node/node_group.c
index 26eeaa91dd0..9d750bfe348 100644
--- a/source/blender/editors/space_node/node_group.c
+++ b/source/blender/editors/space_node/node_group.c
@@ -37,6 +37,7 @@
#include "DNA_anim_types.h"
#include "BLI_listbase.h"
+#include "BLI_linklist.h"
#include "BLI_math.h"
#include "BLT_translation.h"
@@ -92,9 +93,9 @@ static int node_group_operator_editable(bContext *C)
* Disabled otherwise to allow pynodes define their own operators
* with same keymap.
*/
- if (STREQ(snode->tree_idname, "ShaderNodeTree") ||
- STREQ(snode->tree_idname, "CompositorNodeTree") ||
- STREQ(snode->tree_idname, "TextureNodeTree"))
+ if (ED_node_is_shader(snode) ||
+ ED_node_is_compositor(snode) ||
+ ED_node_is_texture(snode))
{
return true;
}
@@ -112,11 +113,11 @@ static const char *group_node_idname(bContext *C)
{
SpaceNode *snode = CTX_wm_space_node(C);
- if (STREQ(snode->tree_idname, "ShaderNodeTree"))
+ if (ED_node_is_shader(snode))
return "ShaderNodeGroup";
- else if (STREQ(snode->tree_idname, "CompositorNodeTree"))
+ else if (ED_node_is_compositor(snode))
return "CompositorNodeGroup";
- else if (STREQ(snode->tree_idname, "TextureNodeTree"))
+ else if (ED_node_is_texture(snode))
return "TextureNodeGroup";
return "";
@@ -186,6 +187,7 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
bNode *node, *nextnode;
bNodeTree *ngroup, *wgroup;
ListBase anim_basepaths = {NULL, NULL};
+ LinkNode *nodes_delayed_free = NULL;
ngroup = (bNodeTree *)gnode->id;
@@ -208,8 +210,8 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
* This also removes remaining links to and from interface nodes.
*/
if (ELEM(node->type, NODE_GROUP_INPUT, NODE_GROUP_OUTPUT)) {
- nodeFreeNode(wgroup, node);
- continue;
+ /* We must delay removal since sockets will reference this node. see: T52092 */
+ BLI_linklist_prepend(&nodes_delayed_free, node);
}
/* keep track of this node's RNA "base" path (the part of the path identifying the node)
@@ -336,6 +338,11 @@ static int node_group_ungroup(bNodeTree *ntree, bNode *gnode)
}
}
+ while (nodes_delayed_free) {
+ node = BLI_linklist_pop(&nodes_delayed_free);
+ nodeFreeNode(ntree, node);
+ }
+
/* delete the group instance */
nodeFreeNode(ntree, gnode);
diff --git a/source/blender/editors/space_node/node_view.c b/source/blender/editors/space_node/node_view.c
index 8c5d2d82468..f497a06cb12 100644
--- a/source/blender/editors/space_node/node_view.c
+++ b/source/blender/editors/space_node/node_view.c
@@ -345,7 +345,7 @@ static int backimage_fit_exec(bContext *C, wmOperator *UNUSED(op))
ima = BKE_image_verify_viewer(IMA_TYPE_COMPOSITE, "Viewer Node");
ibuf = BKE_image_acquire_ibuf(ima, NULL, &lock);
- if (ibuf == NULL) {
+ if ((ibuf == NULL) || (ibuf->x == 0) || (ibuf->y == 0)) {
BKE_image_release_ibuf(ima, ibuf, lock);
return OPERATOR_CANCELLED;
}
@@ -417,20 +417,18 @@ static void sample_draw(const bContext *C, ARegion *ar, void *arg_info)
}
}
-/* Returns color in the display space, matching ED_space_image_color_sample().
+/* Returns color in linear space, matching ED_space_image_color_sample().
* And here we've got recursion in the comments tips...
*/
-bool ED_space_node_color_sample(Scene *scene, SpaceNode *snode, ARegion *ar, int mval[2], float r_col[3])
+bool ED_space_node_color_sample(SpaceNode *snode, ARegion *ar, int mval[2], float r_col[3])
{
- const char *display_device = scene->display_settings.display_device;
- struct ColorManagedDisplay *display = IMB_colormanagement_display_get_named(display_device);
void *lock;
Image *ima;
ImBuf *ibuf;
float fx, fy, bufx, bufy;
bool ret = false;
- if (STREQ(snode->tree_idname, ntreeType_Composite->idname) || (snode->flag & SNODE_BACKDRAW) == 0) {
+ if (!ED_node_is_compositor(snode) || (snode->flag & SNODE_BACKDRAW) == 0) {
/* use viewer image for color sampling only if we're in compositor tree
* with backdrop enabled
*/
@@ -471,10 +469,6 @@ bool ED_space_node_color_sample(Scene *scene, SpaceNode *snode, ARegion *ar, int
}
}
- if (ret) {
- IMB_colormanagement_scene_linear_to_display_v3(r_col, display);
- }
-
BKE_image_release_ibuf(ima, ibuf, lock);
return ret;
diff --git a/source/blender/editors/space_node/space_node.c b/source/blender/editors/space_node/space_node.c
index bbdf6feef01..2267316d257 100644
--- a/source/blender/editors/space_node/space_node.c
+++ b/source/blender/editors/space_node/space_node.c
@@ -753,6 +753,10 @@ static void node_region_listener(bScreen *UNUSED(sc), ScrArea *UNUSED(sa), ARegi
break;
}
break;
+ case NC_WM:
+ if (wmn->data == ND_JOB)
+ ED_region_tag_redraw(ar);
+ break;
case NC_SCENE:
case NC_MATERIAL:
case NC_TEXTURE:
diff --git a/source/blender/editors/space_outliner/outliner_edit.c b/source/blender/editors/space_outliner/outliner_edit.c
index 335eb95da0e..265a19b9e7e 100644
--- a/source/blender/editors/space_outliner/outliner_edit.c
+++ b/source/blender/editors/space_outliner/outliner_edit.c
@@ -1944,7 +1944,7 @@ static int outliner_orphans_purge_invoke(bContext *C, wmOperator *op, const wmEv
{
/* present a prompt to informing users that this change is irreversible */
return WM_operator_confirm_message(C, op,
- "Purging unused data-blocks cannot be undone. "
+ "Purging unused data-blocks cannot be undone and saves to current .blend file. "
"Click here to proceed...");
}
@@ -1966,7 +1966,8 @@ void OUTLINER_OT_orphans_purge(wmOperatorType *ot)
/* identifiers */
ot->idname = "OUTLINER_OT_orphans_purge";
ot->name = "Purge All";
- ot->description = "Clear all orphaned data-blocks without any users from the file (cannot be undone)";
+ ot->description = "Clear all orphaned data-blocks without any users from the file "
+ "(cannot be undone, saves to current .blend file)";
/* callbacks */
ot->invoke = outliner_orphans_purge_invoke;
diff --git a/source/blender/editors/space_outliner/outliner_select.c b/source/blender/editors/space_outliner/outliner_select.c
index 89df471990a..18cc2a015e6 100644
--- a/source/blender/editors/space_outliner/outliner_select.c
+++ b/source/blender/editors/space_outliner/outliner_select.c
@@ -470,10 +470,11 @@ static eOLDrawState tree_element_active_defgroup(
WM_event_add_notifier(C, NC_OBJECT | ND_TRANSFORM, ob);
}
else {
- if (ob == OBACT)
+ if (ob == OBACT) {
if (ob->actdef == te->index + 1) {
return OL_DRAWSEL_NORMAL;
}
+ }
}
return OL_DRAWSEL_NONE;
}
@@ -706,7 +707,12 @@ static eOLDrawState tree_element_active_pose(
{
Object *ob = (Object *)tselem->id;
Base *base = BKE_scene_base_find(scene, ob);
-
+
+ if (base == NULL) {
+ /* Armature not instantiated in current scene (e.g. inside an appended group...). */
+ return OL_DRAWSEL_NONE;
+ }
+
if (set != OL_SETSEL_NONE) {
if (scene->obedit)
ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO);
diff --git a/source/blender/editors/space_outliner/outliner_tools.c b/source/blender/editors/space_outliner/outliner_tools.c
index 086cc55366b..29dcf73109c 100644
--- a/source/blender/editors/space_outliner/outliner_tools.c
+++ b/source/blender/editors/space_outliner/outliner_tools.c
@@ -235,8 +235,7 @@ static void unlink_group_cb(
}
else {
Main *bmain = CTX_data_main(C);
- BKE_libblock_unlink(bmain, group, false, false);
- BKE_libblock_free(bmain, group);
+ BKE_libblock_delete(bmain, group);
}
}
@@ -399,7 +398,7 @@ static void object_deselect_cb(
static void object_delete_cb(
bContext *C, ReportList *reports, Scene *scene, TreeElement *te,
- TreeStoreElem *UNUSED(tsep), TreeStoreElem *tselem, void *UNUSED(user_data))
+ TreeStoreElem *tsep, TreeStoreElem *tselem, void *user_data)
{
Base *base = (Base *)te->directdata;
@@ -431,6 +430,13 @@ static void object_delete_cb(
tselem->id = NULL;
#endif
}
+ else {
+ /* No base, means object is no more instantiated in any scene.
+ * Should not happen ideally, but does happens, see T51625.
+ * Rather than twisting in all kind of ways to address all possible cases leading to that situation, simpler
+ * to allow deleting such object as a mere generic data-block. */
+ id_delete_cb(C, reports, scene, te, tsep, tselem, user_data);
+ }
}
static void id_local_cb(
@@ -1051,7 +1057,7 @@ static EnumPropertyItem prop_group_op_types[] = {
{OL_GROUPOP_UNLINK, "UNLINK", 0, "Unlink Group", ""},
{OL_GROUPOP_LOCAL, "LOCAL", 0, "Make Local Group", ""},
{OL_GROUPOP_LINK, "LINK", 0, "Link Group Objects to Scene", ""},
- {OL_GROUPOP_DELETE, "DELETE", 0, "Delete Group", "WARNING: no undo"},
+ {OL_GROUPOP_DELETE, "DELETE", 0, "Delete Group", ""},
{OL_GROUPOP_REMAP, "REMAP", 0, "Remap Users",
"Make all users of selected data-blocks to use instead current (clicked) one"},
{OL_GROUPOP_INSTANCE, "INSTANCE", 0, "Instance Groups in Scene", ""},
@@ -1090,7 +1096,7 @@ static int outliner_group_operation_exec(bContext *C, wmOperator *op)
DAG_relations_tag_update(CTX_data_main(C));
break;
case OL_GROUPOP_DELETE:
- WM_operator_name_call(C, "OUTLINER_OT_id_delete", WM_OP_INVOKE_REGION_WIN, NULL);
+ outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_delete_cb, NULL);
break;
case OL_GROUPOP_REMAP:
outliner_do_libdata_operation(C, op->reports, scene, soops, &soops->tree, id_remap_cb, NULL);
diff --git a/source/blender/editors/space_outliner/outliner_tree.c b/source/blender/editors/space_outliner/outliner_tree.c
index ec46c5df9a0..09a49f201d4 100644
--- a/source/blender/editors/space_outliner/outliner_tree.c
+++ b/source/blender/editors/space_outliner/outliner_tree.c
@@ -1080,6 +1080,12 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
PointerRNA pptr, propptr, *ptr = (PointerRNA *)idv;
PropertyRNA *prop, *iterprop;
PropertyType proptype;
+
+ /* Don't display arrays larger, weak but index is stored as a short,
+ * also the outliner isn't intended for editing such large data-sets. */
+ BLI_STATIC_ASSERT(sizeof(te->index) == 2, "Index is no longer short!");
+ const int tot_limit = SHRT_MAX;
+
int a, tot;
/* we do lazy build, for speed and to avoid infinite recusion */
@@ -1101,6 +1107,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
iterprop = RNA_struct_iterator_property(ptr->type);
tot = RNA_property_collection_length(ptr, iterprop);
+ CLAMP_MAX(tot, tot_limit);
/* auto open these cases */
if (!parent || (RNA_property_type(parent->directdata)) == PROP_POINTER)
@@ -1147,6 +1154,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
}
else if (proptype == PROP_COLLECTION) {
tot = RNA_property_collection_length(ptr, prop);
+ CLAMP_MAX(tot, tot_limit);
if (TSELEM_OPEN(tselem, soops)) {
for (a = 0; a < tot; a++) {
@@ -1159,6 +1167,7 @@ static TreeElement *outliner_add_element(SpaceOops *soops, ListBase *lb, void *i
}
else if (ELEM(proptype, PROP_BOOLEAN, PROP_INT, PROP_FLOAT)) {
tot = RNA_property_array_length(ptr, prop);
+ CLAMP_MAX(tot, tot_limit);
if (TSELEM_OPEN(tselem, soops)) {
for (a = 0; a < tot; a++)
diff --git a/source/blender/editors/space_sequencer/sequencer_edit.c b/source/blender/editors/space_sequencer/sequencer_edit.c
index 8ae89941bdb..e63569ac386 100644
--- a/source/blender/editors/space_sequencer/sequencer_edit.c
+++ b/source/blender/editors/space_sequencer/sequencer_edit.c
@@ -562,7 +562,7 @@ int seq_effect_find_selected(Scene *scene, Sequence *activeseq, int type, Sequen
}
if (seq1 == NULL) seq1 = seq2;
if (seq3 == NULL) seq3 = seq2;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case 2:
if (seq1 == NULL || seq2 == NULL) {
*error_str = N_("2 selected sequence strips are needed");
@@ -3352,6 +3352,9 @@ static int sequencer_swap_data_exec(bContext *C, wmOperator *op)
if (seq_act->sound) BKE_sound_add_scene_sound_defaults(scene, seq_act);
if (seq_other->sound) BKE_sound_add_scene_sound_defaults(scene, seq_other);
+ BKE_sequence_invalidate_cache(scene, seq_act);
+ BKE_sequence_invalidate_cache(scene, seq_other);
+
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER, scene);
return OPERATOR_FINISHED;
@@ -3509,7 +3512,7 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op)
bool proxy_50 = RNA_boolean_get(op->ptr, "proxy_50");
bool proxy_75 = RNA_boolean_get(op->ptr, "proxy_75");
bool proxy_100 = RNA_boolean_get(op->ptr, "proxy_100");
- bool override = RNA_boolean_get(op->ptr, "override");
+ bool overwrite = RNA_boolean_get(op->ptr, "overwrite");
bool turnon = true;
if (ed == NULL || !(proxy_25 || proxy_50 || proxy_75 || proxy_100)) {
@@ -3545,7 +3548,7 @@ static int sequencer_enable_proxies_exec(bContext *C, wmOperator *op)
else
seq->strip->proxy->build_size_flags &= ~SEQ_PROXY_IMAGE_SIZE_100;
- if (!override)
+ if (!overwrite)
seq->strip->proxy->build_flags |= SEQ_PROXY_SKIP_EXISTING;
else
seq->strip->proxy->build_flags &= ~SEQ_PROXY_SKIP_EXISTING;
@@ -3577,7 +3580,7 @@ void SEQUENCER_OT_enable_proxies(wmOperatorType *ot)
RNA_def_boolean(ot->srna, "proxy_50", false, "50%", "");
RNA_def_boolean(ot->srna, "proxy_75", false, "75%", "");
RNA_def_boolean(ot->srna, "proxy_100", false, "100%", "");
- RNA_def_boolean(ot->srna, "override", false, "Override", "");
+ RNA_def_boolean(ot->srna, "overwrite", false, "Overwrite", "");
}
/* change ops */
diff --git a/source/blender/editors/space_sequencer/sequencer_select.c b/source/blender/editors/space_sequencer/sequencer_select.c
index 48c49f36471..d88ed36e392 100644
--- a/source/blender/editors/space_sequencer/sequencer_select.c
+++ b/source/blender/editors/space_sequencer/sequencer_select.c
@@ -683,7 +683,7 @@ static int sequencer_select_less_exec(bContext *C, wmOperator *UNUSED(op))
if (!select_more_less_seq__internal(scene, false, false))
return OPERATOR_CANCELLED;
-
+
WM_event_add_notifier(C, NC_SCENE | ND_SEQUENCER | NA_SELECTED, scene);
return OPERATOR_FINISHED;
diff --git a/source/blender/editors/space_text/CMakeLists.txt b/source/blender/editors/space_text/CMakeLists.txt
index de85ddc40ab..39b48f5b52c 100644
--- a/source/blender/editors/space_text/CMakeLists.txt
+++ b/source/blender/editors/space_text/CMakeLists.txt
@@ -43,6 +43,8 @@ set(SRC
text_format.c
text_format_lua.c
text_format_osl.c
+ text_format_pov.c
+ text_format_pov_ini.c
text_format_py.c
text_header.c
text_ops.c
diff --git a/source/blender/editors/space_text/space_text.c b/source/blender/editors/space_text/space_text.c
index 686a10fc785..fcb46ced750 100644
--- a/source/blender/editors/space_text/space_text.c
+++ b/source/blender/editors/space_text/space_text.c
@@ -158,7 +158,7 @@ static void text_listener(bScreen *UNUSED(sc), ScrArea *sa, wmNotifier *wmn)
}
ED_area_tag_redraw(sa);
- /* fall-through */ /* fall down to tag redraw */
+ ATTR_FALLTHROUGH; /* fall down to tag redraw */
case NA_ADDED:
case NA_REMOVED:
ED_area_tag_redraw(sa);
@@ -636,5 +636,7 @@ void ED_spacetype_text(void)
ED_text_format_register_py();
ED_text_format_register_osl();
ED_text_format_register_lua();
+ ED_text_format_register_pov();
+ ED_text_format_register_pov_ini();
}
diff --git a/source/blender/editors/space_text/text_autocomplete.c b/source/blender/editors/space_text/text_autocomplete.c
index c38c57b9528..da5fa9da046 100644
--- a/source/blender/editors/space_text/text_autocomplete.c
+++ b/source/blender/editors/space_text/text_autocomplete.c
@@ -328,7 +328,7 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e
if (tools & TOOL_SUGG_LIST) {
texttool_suggest_clear();
}
- if (tools & TOOL_DOCUMENT) {
+ if (tools & TOOL_DOCUMENT) {
texttool_docs_clear();
doc_scroll = 0;
}
@@ -455,7 +455,7 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e
break;
case PAGEDOWNKEY:
scroll = SUGG_LIST_SIZE - 1;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case WHEELDOWNMOUSE:
case DOWNARROWKEY:
if (event->val == KM_PRESS) {
@@ -489,7 +489,7 @@ static int text_autocomplete_modal(bContext *C, wmOperator *op, const wmEvent *e
break;
case PAGEUPKEY:
scroll = SUGG_LIST_SIZE - 1;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case WHEELUPMOUSE:
case UPARROWKEY:
if (event->val == KM_PRESS) {
diff --git a/source/blender/editors/space_text/text_format.h b/source/blender/editors/space_text/text_format.h
index b901ec83a9c..d7cf31d0b41 100644
--- a/source/blender/editors/space_text/text_format.h
+++ b/source/blender/editors/space_text/text_format.h
@@ -102,6 +102,8 @@ void ED_text_format_register(TextFormatType *tft);
void ED_text_format_register_py(void);
void ED_text_format_register_osl(void);
void ED_text_format_register_lua(void);
+void ED_text_format_register_pov(void);
+void ED_text_format_register_pov_ini(void);
#define STR_LITERAL_STARTSWITH(str, str_literal, len_var) \
(strncmp(str, str_literal, len_var = (sizeof(str_literal) - 1)) == 0)
diff --git a/source/blender/editors/space_text/text_format_pov.c b/source/blender/editors/space_text/text_format_pov.c
new file mode 100644
index 00000000000..0d19c503798
--- /dev/null
+++ b/source/blender/editors/space_text/text_format_pov.c
@@ -0,0 +1,809 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_text/text_format_pov.c
+ * \ingroup sptext
+ */
+
+#include <string.h>
+
+#include "BLI_blenlib.h"
+
+#include "DNA_text_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_text.h"
+
+#include "text_format.h"
+
+/* *** POV Keywords (for format_line) *** */
+
+/* Checks the specified source string for a POV keyword (minus boolean & 'nil').
+ * This name must start at the beginning of the source string and must be
+ * followed by a non-identifier (see text_check_identifier(char)) or null char.
+ *
+ * If a keyword is found, the length of the matching word is returned.
+ * Otherwise, -1 is returned.
+ *
+ * See:
+ * http://www.povray.org/documentation/view/3.7.0/212/
+ */
+
+static int txtfmt_pov_find_keyword(const char *string)
+{
+ int i, len;
+ /* Language Directives */
+ if (STR_LITERAL_STARTSWITH(string, "append", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "break", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "case", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "debug", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "declare", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "default", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "deprecated", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "elseif", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "else", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "end", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "error", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fclose", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fopen", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "for", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ifndef", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ifdef", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "if", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "include", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "local", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "macro", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "range", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "read", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "render", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "statistics", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "switch", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "undef", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "version", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "warning", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "while", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "write", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ return (i == 0 || text_check_identifier(string[i])) ? -1 : i;
+}
+
+static int txtfmt_pov_find_reserved_keywords(const char *string)
+{
+ int i, len;
+ /* POV-Ray Built-in Variables
+ * list is from...
+ * http://www.povray.org/documentation/view/3.7.0/212/
+ */
+ /* Language Keywords */
+ if (STR_LITERAL_STARTSWITH(string, "aa_level", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "aa_threshold", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "absorption", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "accuracy", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "adc_bailout", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "albedo", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "all_intersections", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "translucency", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "all", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "alpha", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "altitude", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "always_sample", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ambient_light", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ambient", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "angle", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "aperture", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "arc_angle", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "area_light", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "area_illumination", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "array", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "assumed_gamma", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "autostop", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "black_hole", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "blur_samples", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "brightness", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "brilliance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "caustics", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "charset", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "collect", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "component", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "composite", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "confidence", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "conserve_energy", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "contained_by", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "coords", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "count", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "crand", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cube", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cutaway_textures", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "diffuse", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "direction", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "dispersion_samples", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "dispersion", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "dist_exp", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "distance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "eccentricity", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "emission", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "error_bound", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "evaluate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "expand_thresholds", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "exponent", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "exterior", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "extinction", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "face_indices", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "falloff_angle", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "falloff", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "file_gamma", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "flatness", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "flip", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "focal_point", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fog_alt", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fog_offset", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fog_type", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "form", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fresnel", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "function", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gamma", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gather", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "global_settings", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gray_threshold", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hf_gray_16", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hierarchy", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hypercomplex", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "importance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "inside_vector", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "internal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "intervals", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ior", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "irid_wavelength", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "irid", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "load_file", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "location", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "look_at", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "looks_like", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "low_error_factor", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "major_radius", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_distance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_extent", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_gradient", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_intersections", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_iteration", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_sample", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_trace_level", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max_trace", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "maximum_reuse", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "metallic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "method", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "metric", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "minimum_reuse", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "nearest_count", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "normal_indices", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "normal_vectors", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "now", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "number_of_waves", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "offset", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "open", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "orientation", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pass_through", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pattern", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "phong_size", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "phong", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "point_at", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pot", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "precision", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "precompute", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pretrace_end", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pretrace_start", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "prod", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pwr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "quaternion", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "radiosity", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "radius", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ratio", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "reciprocal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "recursion_limit", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "reflection_exponent", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "reflection", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "refraction", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "repeat", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "right", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "roughness", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "samples", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "save_file", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "scattering", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "size", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sky", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "slice", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "smooth", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "solid", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "spacing", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "specular", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "split_union", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "spotlight", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "strength", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sturm", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sum", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "target", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "texture_list", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "thickness", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "threshold", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tightness", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tolerance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "toroidal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ttf", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "turb_depth", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "type", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "u_steps", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "up", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "use_alpha", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uv_indices", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uv_vectors", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "v_steps", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "variance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vertex_vectors", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "water_level", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "width", len)) i = len;
+
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ return (i == 0 || text_check_identifier(string[i])) ? -1 : i;
+}
+
+
+static int txtfmt_pov_find_reserved_builtins(const char *string)
+{
+ int i, len;
+
+ /* POV-Ray Built-in Variables
+ * list is from...
+ * http://www.povray.org/documentation/view/3.7.0/212/
+ */
+ if (STR_LITERAL_STARTSWITH(string, "clock_delta", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "clock", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "clock_on", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "final_clock", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "final_frame", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "frame_number", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "initial_clock", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "initial_frame", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "image_height", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "image_width", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "input_file_name", len)) i = len;
+ /* Color Identifiers */
+ else if (STR_LITERAL_STARTSWITH(string, "blue", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "filter", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gray", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "green", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "red", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rgbft", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rgbf", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rgbt", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rgb", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "srgb", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sRGB", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "SRGB", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "srgbft", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "srgbf", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "srgbt", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "transmit", len)) i = len;
+ /* Patterns */
+ else if (STR_LITERAL_STARTSWITH(string, "agate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "aoi", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "average", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "boxed", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bozo", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "brick", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bumps", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cells", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "checker", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "crackle", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cubic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cylindrical", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "density_file", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "dents", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "facets", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gradient", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "granite", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hexagon", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "image_pattern", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "julia", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "leopard", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "magnet", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "mandel", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "marble", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "onion", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pavement", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pigment_pattern", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "planar", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "quilted", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "radial", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ripples", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "slope", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "spherical", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "spiral1", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "spiral2", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "spotted", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "square", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tile2", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tiling", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tiles", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "triangular", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "waves", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "wood", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "wrinkles", len)) i = len;
+ /* Objects */
+ else if (STR_LITERAL_STARTSWITH(string, "background", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bicubic_patch", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "blob", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "box", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "camera", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cone", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cubic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cylinder", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "difference", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "disc", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fog", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "height_field", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "intersection", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "isosurface", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "julia_fractal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "lathe", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "light_group", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "light_source", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "merge", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "mesh2", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "mesh", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "object", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ovus", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "lemon", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "parametric", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "plane", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "poly", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "polygon", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "polynomial", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "prism", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "quadric", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "quartic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rainbow", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sky_sphere", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "smooth_triangle", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cubic_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sphere_sweep", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sphere", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "superellipsoid", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sor", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "text", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "torus", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "triangle", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "union", len)) i = len;
+ /* Filetypes */
+ else if (STR_LITERAL_STARTSWITH(string, "df3", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "exr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gif", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hdr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "iff", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "jpeg", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pgm", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "png", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ppm", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sys", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tga", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tiff", len)) i = len;
+ /* Spline Identifiers */
+ else if (STR_LITERAL_STARTSWITH(string, "b_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bezier_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "conic_sweep", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cubic_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "linear_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "linear_sweep", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "natural_spline", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "quadratic_spline", len)) i = len;
+ /* Encodings */
+ else if (STR_LITERAL_STARTSWITH(string, "ascii", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "utf8", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uint8", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uint16be", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uint16le", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sint8", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sint16be", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sint16le", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sint32be", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sint32le", len)) i = len;
+ /* Camera Types */
+ else if (STR_LITERAL_STARTSWITH(string, "fisheye", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "mesh_camera", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "omnimax", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "orthographic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "panoramic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "perspective", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ultra_wide_angle", len)) i = len;
+ /* Built-in Vectors */
+ else if (STR_LITERAL_STARTSWITH(string, "t", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "u", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "v", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "x", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "y", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "z", len)) i = len;
+
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ return (i == 0 || text_check_identifier(string[i])) ? -1 : i;
+}
+
+
+/* Checks the specified source string for a POV modifiers. This
+ * name must start at the beginning of the source string and must be followed
+ * by a non-identifier (see text_check_identifier(char)) or null character.
+ *
+ * If a special name is found, the length of the matching name is returned.
+ * Otherwise, -1 is returned.
+ *
+ * See:
+ * http://www.povray.org/documentation/view/3.7.0/212/
+ */
+
+static int txtfmt_pov_find_specialvar(const char *string)
+{
+ int i, len;
+ /* Modifiers */
+ if (STR_LITERAL_STARTSWITH(string, "interior_texture", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "double_illuminate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "media_interaction", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "media_attenuation", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "projected_through", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "noise_generator", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "agate_turb", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bounded_by", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "brick_size", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bump_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bump_size", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "circular", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "clipped_by", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cubic", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "color_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "color", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "colour_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "colour", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "control0", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "control1", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cubic_wave", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "density_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "density", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fade_color", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fade_colour", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fade_distance", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fade_power", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "frequency", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "global_lights", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hollow", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "image_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "adaptive", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "interior", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "interpolate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "inverse", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "jitter", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "lambda", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "map_type", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "material_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "material", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "matrix", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "media", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "mm_per_unit", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "mortar", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "no_bump_scale", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "no_image", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "no_radiosity", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "no_reflection", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "no_shadow", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "normal_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "normal", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "octaves", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "omega", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "once", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "orient", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "parallel", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "phase", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "photons", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pigment_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pigment", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "finish", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "poly_wave", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "quick_color", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "quick_colour", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ramp_wave", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rotate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "scale", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "scallop_wave", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "shadowless", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sine_wave", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "slope_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "subsurface", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "texture_map", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "texture", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "transform", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "translate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "triangle_wave", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "turbulence", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "use_color", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "use_colour", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "use_index", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uv_mapping", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "warp", len)) i = len;
+
+ /* Vector Functions */
+ else if (STR_LITERAL_STARTSWITH(string, "max_extent", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "min_extent", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "trace", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vaxis_rotate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vcross", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vnormalize", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vrotate", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vturbulence", len)) i = len;
+ /* String Functions */
+ else if (STR_LITERAL_STARTSWITH(string, "chr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "concat", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "datetime", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "str", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "strlwr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "strupr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "substr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vstr", len)) i = len;
+ /* Float Functions */
+ else if (STR_LITERAL_STARTSWITH(string, "abs", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "acosh", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "acos", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "asc", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "asinh", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "asin", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "atan2", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "atand", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "atanh", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "atan", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bitwise_and", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bitwise_or", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "bitwise_xor", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ceil", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cosh", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "cos", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "defined", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "degrees", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "dimension_size", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "dimensions", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "div", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "exp", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "file_exists", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "floor", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "inside", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "int", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ln", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "log", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "max", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "min", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "mod", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pow", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "radians", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "rand", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "seed", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "select", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sinh", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sin", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sqrt", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sqr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "strcmp", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "strlen", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tanh", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tan", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "val", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vdot", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "vlength", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ return (i == 0 || text_check_identifier(string[i])) ? -1 : i;
+}
+
+static int txtfmt_pov_find_bool(const char *string)
+{
+ int i, len;
+ /*Built-in Constants*/
+ if (STR_LITERAL_STARTSWITH(string, "false", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "no", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "off", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "true", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "yes", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "on", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pi", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tau", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "Nonetheless") no match */
+ return (i == 0 || text_check_identifier(string[i])) ? -1 : i;
+}
+
+static char txtfmt_pov_format_identifier(const char *str)
+{
+ char fmt;
+ if ((txtfmt_pov_find_specialvar(str)) != -1) fmt = FMT_TYPE_SPECIAL;
+ else if ((txtfmt_pov_find_keyword(str)) != -1) fmt = FMT_TYPE_KEYWORD;
+ else if ((txtfmt_pov_find_reserved_keywords(str)) != -1) fmt = FMT_TYPE_RESERVED;
+ else if ((txtfmt_pov_find_reserved_builtins(str)) != -1) fmt = FMT_TYPE_RESERVED;
+ else fmt = FMT_TYPE_DEFAULT;
+ return fmt;
+}
+
+static void txtfmt_pov_format_line(SpaceText *st, TextLine *line, const bool do_next)
+{
+ FlattenString fs;
+ const char *str;
+ char *fmt;
+ char cont_orig, cont, find, prev = ' ';
+ int len, i;
+
+ /* Get continuation from previous line */
+ if (line->prev && line->prev->format != NULL) {
+ fmt = line->prev->format;
+ cont = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
+ BLI_assert((FMT_CONT_ALL & cont) == cont);
+ }
+ else {
+ cont = FMT_CONT_NOP;
+ }
+
+ /* Get original continuation from this line */
+ if (line->format != NULL) {
+ fmt = line->format;
+ cont_orig = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
+ BLI_assert((FMT_CONT_ALL & cont_orig) == cont_orig);
+ }
+ else {
+ cont_orig = 0xFF;
+ }
+
+ len = flatten_string(st, &fs, line->line);
+ str = fs.buf;
+ if (!text_check_format_len(line, len)) {
+ flatten_string_free(&fs);
+ return;
+ }
+ fmt = line->format;
+
+ while (*str) {
+ /* Handle escape sequences by skipping both \ and next char */
+ if (*str == '\\') {
+ *fmt = prev; fmt++; str++;
+ if (*str == '\0') break;
+ *fmt = prev; fmt++; str += BLI_str_utf8_size_safe(str);
+ continue;
+ }
+ /* Handle continuations */
+ else if (cont) {
+ /* C-Style comments */
+ if (cont & FMT_CONT_COMMENT_C) {
+ if (*str == '*' && *(str + 1) == '/') {
+ *fmt = FMT_TYPE_COMMENT; fmt++; str++;
+ *fmt = FMT_TYPE_COMMENT;
+ cont = FMT_CONT_NOP;
+ }
+ else {
+ *fmt = FMT_TYPE_COMMENT;
+ }
+ /* Handle other comments */
+ }
+ else {
+ find = (cont & FMT_CONT_QUOTEDOUBLE) ? '"' : '\'';
+ if (*str == find) cont = 0;
+ *fmt = FMT_TYPE_STRING;
+ }
+
+ str += BLI_str_utf8_size_safe(str) - 1;
+ }
+ /* Not in a string... */
+ else {
+ /* C-Style (multi-line) comments */
+ if (*str == '/' && *(str + 1) == '*') {
+ cont = FMT_CONT_COMMENT_C;
+ *fmt = FMT_TYPE_COMMENT; fmt++; str++;
+ *fmt = FMT_TYPE_COMMENT;
+ }
+ /* Single line comment */
+ else if (*str == '/' && *(str + 1) == '/') {
+ text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(fmt - line->format));
+ }
+ else if (*str == '"' || *str == '\'') {
+ /* Strings */
+ find = *str;
+ cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE;
+ *fmt = FMT_TYPE_STRING;
+ }
+ /* Whitespace (all ws. has been converted to spaces) */
+ else if (*str == ' ') {
+ *fmt = FMT_TYPE_WHITESPACE;
+ }
+ /* Numbers (digits not part of an identifier and periods followed by digits) */
+ else if ((prev != FMT_TYPE_DEFAULT && text_check_digit(*str)) ||
+ (*str == '.' && text_check_digit(*(str + 1))))
+ {
+ *fmt = FMT_TYPE_NUMERAL;
+ }
+ /* Booleans */
+ else if (prev != FMT_TYPE_DEFAULT && (i = txtfmt_pov_find_bool(str)) != -1) {
+ if (i > 0) {
+ text_format_fill_ascii(&str, &fmt, FMT_TYPE_NUMERAL, i);
+ }
+ else {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ }
+ /* Punctuation */
+ else if (text_check_delim(*str)) {
+ *fmt = FMT_TYPE_SYMBOL;
+ }
+ /* Identifiers and other text (no previous ws. or delims. so text continues) */
+ else if (prev == FMT_TYPE_DEFAULT) {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ /* Not ws, a digit, punct, or continuing text. Must be new, check for special words */
+ else {
+ /* Special vars(v) or built-in keywords(b) */
+ /* keep in sync with 'txtfmt_pov_format_identifier()' */
+ if ((i = txtfmt_pov_find_specialvar(str)) != -1) prev = FMT_TYPE_SPECIAL;
+ else if ((i = txtfmt_pov_find_keyword(str)) != -1) prev = FMT_TYPE_KEYWORD;
+ else if ((i = txtfmt_pov_find_reserved_keywords(str)) != -1) prev = FMT_TYPE_RESERVED;
+ else if ((i = txtfmt_pov_find_reserved_builtins(str)) != -1) prev = FMT_TYPE_RESERVED;
+
+ if (i > 0) {
+ text_format_fill_ascii(&str, &fmt, prev, i);
+ }
+ else {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ }
+ }
+ prev = *fmt; fmt++; str++;
+ }
+
+ /* Terminate and add continuation char */
+ *fmt = '\0'; fmt++;
+ *fmt = cont;
+
+ /* If continuation has changed and we're allowed, process the next line */
+ if (cont != cont_orig && do_next && line->next) {
+ txtfmt_pov_format_line(st, line->next, do_next);
+ }
+
+ flatten_string_free(&fs);
+}
+
+void ED_text_format_register_pov(void)
+{
+ static TextFormatType tft = {NULL};
+ static const char *ext[] = {"pov", "inc", "mcr", "mac", NULL};
+
+ tft.format_identifier = txtfmt_pov_format_identifier;
+ tft.format_line = txtfmt_pov_format_line;
+ tft.ext = ext;
+
+ ED_text_format_register(&tft);
+}
diff --git a/source/blender/editors/space_text/text_format_pov_ini.c b/source/blender/editors/space_text/text_format_pov_ini.c
new file mode 100644
index 00000000000..719f4e3c036
--- /dev/null
+++ b/source/blender/editors/space_text/text_format_pov_ini.c
@@ -0,0 +1,488 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/editors/space_text/text_format_pov_ini.c
+ * \ingroup sptext
+ */
+
+#include <string.h>
+
+#include "BLI_blenlib.h"
+
+#include "DNA_text_types.h"
+#include "DNA_space_types.h"
+
+#include "BKE_text.h"
+
+#include "text_format.h"
+
+/* *** POV INI Keywords (for format_line) *** */
+
+/* Checks the specified source string for a POV INI keyword (minus boolean & 'nil').
+ * This name must start at the beginning of the source string and must be
+ * followed by a non-identifier (see text_check_identifier(char)) or null char.
+ *
+ * If a keyword is found, the length of the matching word is returned.
+ * Otherwise, -1 is returned.
+ *
+ * See:
+ * http://www.povray.org/documentation/view/3.7.0/212/
+ */
+
+static int txtfmt_ini_find_keyword(const char *string)
+{
+ int i, len;
+ /* Language Directives */
+ if (STR_LITERAL_STARTSWITH(string, "append", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "break", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "case", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "debug", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "declare", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "default", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "deprecated", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "elseif", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "else", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "end", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "error", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fclose", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "fopen", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "for", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ifdef", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ifndef", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "if", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "include", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "local", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "macro", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "range", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "read", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "render", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "statistics", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "switch", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "undef", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "version", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "warning", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "while", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "write", len)) i = len;
+
+ else if (STR_LITERAL_STARTSWITH(string, "I", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "S", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "A", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Q", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "U", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "F", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "C", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "N", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "P", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "T", len)) i = len;
+
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ return (i == 0 || text_check_identifier(string[i])) ? -1 : i;
+}
+
+static int txtfmt_ini_find_reserved(const char *string)
+{
+ int i, len;
+ /* POV-Ray Built-in INI Variables
+ * list is from...
+ * http://www.povray.org/documentation/view/3.7.0/212/
+ */
+ if (STR_LITERAL_STARTSWITH(string, "Antialias_Threshold", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Bounding_Method", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Antialias_Gamma", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Antialias_Depth", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "clock_delta", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "clock_on", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "clock", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "final_clock", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "final_frame", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "frame_number", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "initial_clock", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "initial_frame", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "image_height", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "image_width", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "input_file_name", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Subset_Start_Frame", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Subset_End_Frame", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Frame_Step", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Cyclic_Animation", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Field_Render", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Odd_Field", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Height", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Width", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Start_Column", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Start_Row", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "End_Column", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "End_Row", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Test_Abort_Count", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Test_Abort", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Continue_Trace", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Create_Continue_Trace_Log", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Create_Ini", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Display_Gamma", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Display", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Version", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Pause_When_Done", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Verbose", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Preview_Start_Size", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Preview_End_Size", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Output_to_File", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Input_File_Name", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Output_File_Name", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Output_File_Type", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Output_Alpha", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Bits_Per_Color", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Compression", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Dither_Method", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Dither", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Pre_Scene_Command", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Pre_Frame_Command", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Post_Scene_Command", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Post_Frame_Command", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "User_Abort_Command", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Fatal_Error_Command", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Pre_Scene_Return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Pre_Frame_Return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Post_Scene_Return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Post_Frame_Return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "User_Abort_Return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Fatal_Error_Return", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Include_Header", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Library_Path", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Debug_Console", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Fatal_Console", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Render_Console", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Statistic_Console", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Warning_Console", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Warning_Level", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "All_Console", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Debug_File", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Fatal_File", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Render_File", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Statistic_File", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Warning_File", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "All_File", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Quality", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Bounding_Threshold", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Bounding", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Light_Buffer", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Vista_Buffer", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Remove_Bounds", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Split_Unions", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Antialias", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Sampling_Method", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Jitter_Amount", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Jitter", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Antialias_Depth", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "CheckNewVersion", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "RunCount", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "CommandLine", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "TextColour", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "WarningColour", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ErrorColour", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "BackgroundColour", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "DropToEditor", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "LastRenderName", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "LastRenderPath", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "LastQueuePath", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "SecondaryINISection", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "BetaVersionNo64", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "LastBitmapName", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "LastBitmapPath", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "LastINIPath", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "SecondaryINIFile", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "BackgroundFile", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "SaveSettingsOnExit", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "TileBackground", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "HideNewUserHelp", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "SendSystemInfo", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ItsAboutTime", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "LastPath", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Band0Width", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Band1Width", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Band2Width", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Band3Width", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Band4Width", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ShowCmd", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "NormalPositionLeft", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "NormalPositionTop", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "NormalPositionRight", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "NormalPositionBottom", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "UseToolbar", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "UseTooltips", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "NormalPositionX", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "NormalPositionY", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Flags", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Transparency", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Use8BitMode", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "MakeActive", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "KeepAboveMain", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "HideWhenMainMinimized", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "AutoClose", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "PreserveBitmap", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "FontSize", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "FontWeight", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Font", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "KeepMessages", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "AlertSound", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Completion", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Priority", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "DutyCycle", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "AlertOnCompletion", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "AutoRender", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "PreventSleep", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "NoShelloutWait", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "SystemNoActive", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "RenderCompleteSoundEnabled", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ParseErrorSoundEnabled", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "RenderErrorSoundEnabled", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "RenderCompleteSound", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ParseErrorSound", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "RenderErrorSound", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "UseExtensions", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ReadWriteSourceDir", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "NoShellOuts", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "VideoSource", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "SceneFile", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "OutputFile", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "IniOutputFile", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "CurrentDirectory", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "SourceFile", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Rendering", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "RenderwinClose", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Append_File", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "Warning Level", len)) i = len;
+ /* Filetypes */
+ else if (STR_LITERAL_STARTSWITH(string, "df3", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "exr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "gif", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "hdr", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "iff", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "jpeg", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pgm", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "png", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "ppm", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sys", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tga", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tiff", len)) i = len;
+ /* Encodings */
+ else if (STR_LITERAL_STARTSWITH(string, "ascii", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "utf8", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uint8", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uint16be", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "uint16le", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sint8", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sint16be", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sint16le", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sint32be", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "sint32le", len)) i = len;
+
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "definate") no match */
+ return (i == 0 || text_check_identifier(string[i])) ? -1 : i;
+}
+
+
+
+
+static int txtfmt_ini_find_bool(const char *string)
+{
+ int i, len;
+ /* Built-in Constants */
+ if (STR_LITERAL_STARTSWITH(string, "false", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "no", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "off", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "true", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "yes", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "on", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "pi", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "tau", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "%o", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "%s", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "%n", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "%k", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "%h", len)) i = len;
+ else if (STR_LITERAL_STARTSWITH(string, "%w", len)) i = len;
+ else i = 0;
+
+ /* If next source char is an identifier (eg. 'i' in "Nonetheless") no match */
+ return (i == 0 || text_check_identifier(string[i])) ? -1 : i;
+}
+
+static char txtfmt_pov_ini_format_identifier(const char *str)
+{
+ char fmt;
+ if ((txtfmt_ini_find_keyword(str)) != -1) fmt = FMT_TYPE_KEYWORD;
+ else if ((txtfmt_ini_find_reserved(str)) != -1) fmt = FMT_TYPE_RESERVED;
+ else fmt = FMT_TYPE_DEFAULT;
+ return fmt;
+}
+
+static void txtfmt_pov_ini_format_line(SpaceText *st, TextLine *line, const bool do_next)
+{
+ FlattenString fs;
+ const char *str;
+ char *fmt;
+ char cont_orig, cont, find, prev = ' ';
+ int len, i;
+
+ /* Get continuation from previous line */
+ if (line->prev && line->prev->format != NULL) {
+ fmt = line->prev->format;
+ cont = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
+ BLI_assert((FMT_CONT_ALL & cont) == cont);
+ }
+ else {
+ cont = FMT_CONT_NOP;
+ }
+
+ /* Get original continuation from this line */
+ if (line->format != NULL) {
+ fmt = line->format;
+ cont_orig = fmt[strlen(fmt) + 1]; /* Just after the null-terminator */
+ BLI_assert((FMT_CONT_ALL & cont_orig) == cont_orig);
+ }
+ else {
+ cont_orig = 0xFF;
+ }
+
+ len = flatten_string(st, &fs, line->line);
+ str = fs.buf;
+ if (!text_check_format_len(line, len)) {
+ flatten_string_free(&fs);
+ return;
+ }
+ fmt = line->format;
+
+ while (*str) {
+ /* Handle escape sequences by skipping both \ and next char */
+ if (*str == '\\') {
+ *fmt = prev; fmt++; str++;
+ if (*str == '\0') break;
+ *fmt = prev; fmt++; str += BLI_str_utf8_size_safe(str);
+ continue;
+ }
+ /* Handle continuations */
+ else if (cont) {
+ /* Multi-line comments */
+ if (cont & FMT_CONT_COMMENT_C) {
+ if (*str == ']' && *(str + 1) == ']') {
+ *fmt = FMT_TYPE_COMMENT; fmt++; str++;
+ *fmt = FMT_TYPE_COMMENT;
+ cont = FMT_CONT_NOP;
+ }
+ else {
+ *fmt = FMT_TYPE_COMMENT;
+ }
+ /* Handle other comments */
+ }
+ else {
+ find = (cont & FMT_CONT_QUOTEDOUBLE) ? '"' : '\'';
+ if (*str == find) cont = 0;
+ *fmt = FMT_TYPE_STRING;
+ }
+
+ str += BLI_str_utf8_size_safe(str) - 1;
+ }
+ /* Not in a string... */
+ else {
+ /* Multi-line comments not supported */
+ /* Single line comment */
+ if (*str == ';') {
+ text_format_fill(&str, &fmt, FMT_TYPE_COMMENT, len - (int)(fmt - line->format));
+ }
+ else if (*str == '"' || *str == '\'') {
+ /* Strings */
+ find = *str;
+ cont = (*str == '"') ? FMT_CONT_QUOTEDOUBLE : FMT_CONT_QUOTESINGLE;
+ *fmt = FMT_TYPE_STRING;
+ }
+ /* Whitespace (all ws. has been converted to spaces) */
+ else if (*str == ' ') {
+ *fmt = FMT_TYPE_WHITESPACE;
+ }
+ /* Numbers (digits not part of an identifier and periods followed by digits) */
+ else if ((prev != FMT_TYPE_DEFAULT && text_check_digit(*str)) ||
+ (*str == '.' && text_check_digit(*(str + 1))))
+ {
+ *fmt = FMT_TYPE_NUMERAL;
+ }
+ /* Booleans */
+ else if (prev != FMT_TYPE_DEFAULT && (i = txtfmt_ini_find_bool(str)) != -1) {
+ if (i > 0) {
+ text_format_fill_ascii(&str, &fmt, FMT_TYPE_NUMERAL, i);
+ }
+ else {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ }
+ /* Punctuation */
+ else if ((*str != '#') && text_check_delim(*str)) {
+ *fmt = FMT_TYPE_SYMBOL;
+ }
+ /* Identifiers and other text (no previous ws. or delims. so text continues) */
+ else if (prev == FMT_TYPE_DEFAULT) {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ /* Not ws, a digit, punct, or continuing text. Must be new, check for special words */
+ else {
+ /* Special vars(v) or built-in keywords(b) */
+ /* keep in sync with 'txtfmt_ini_format_identifier()' */
+ if ((i = txtfmt_ini_find_keyword(str)) != -1) prev = FMT_TYPE_KEYWORD;
+ else if ((i = txtfmt_ini_find_reserved(str)) != -1) prev = FMT_TYPE_RESERVED;
+
+ if (i > 0) {
+ text_format_fill_ascii(&str, &fmt, prev, i);
+ }
+ else {
+ str += BLI_str_utf8_size_safe(str) - 1;
+ *fmt = FMT_TYPE_DEFAULT;
+ }
+ }
+ }
+ prev = *fmt; fmt++; str++;
+ }
+
+ /* Terminate and add continuation char */
+ *fmt = '\0'; fmt++;
+ *fmt = cont;
+
+ /* If continuation has changed and we're allowed, process the next line */
+ if (cont != cont_orig && do_next && line->next) {
+ txtfmt_pov_ini_format_line(st, line->next, do_next);
+ }
+
+ flatten_string_free(&fs);
+}
+
+void ED_text_format_register_pov_ini(void)
+{
+ static TextFormatType tft = {NULL};
+ static const char *ext[] = {"ini", NULL};
+
+ tft.format_identifier = txtfmt_pov_ini_format_identifier;
+ tft.format_line = txtfmt_pov_ini_format_line;
+ tft.ext = ext;
+
+ ED_text_format_register(&tft);
+}
diff --git a/source/blender/editors/space_view3d/drawarmature.c b/source/blender/editors/space_view3d/drawarmature.c
index 314b7bf3335..5208013b6fe 100644
--- a/source/blender/editors/space_view3d/drawarmature.c
+++ b/source/blender/editors/space_view3d/drawarmature.c
@@ -1903,6 +1903,11 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
}
}
+ /* custom bone may draw outline double-width */
+ if (arm->flag & ARM_POSEMODE) {
+ glLineWidth(1.0f);
+ }
+
/* draw custom bone shapes as wireframes */
if (!(arm->flag & ARM_NO_CUSTOM) &&
(draw_wire || (dt <= OB_WIRE)) )
@@ -1968,11 +1973,6 @@ static void draw_pose_bones(Scene *scene, View3D *v3d, ARegion *ar, Base *base,
index = -1;
}
}
-
- /* custom bone may draw outline double-width */
- if (arm->flag & ARM_POSEMODE) {
- glLineWidth(1.0f);
- }
/* wire draw over solid only in posemode */
if ((dt <= OB_WIRE) || (arm->flag & ARM_POSEMODE) || ELEM(arm->drawtype, ARM_LINE, ARM_WIRE)) {
diff --git a/source/blender/editors/space_view3d/drawobject.c b/source/blender/editors/space_view3d/drawobject.c
index 335d0649729..73fd77db477 100644
--- a/source/blender/editors/space_view3d/drawobject.c
+++ b/source/blender/editors/space_view3d/drawobject.c
@@ -867,7 +867,7 @@ void view3d_cached_text_draw_add(const float co[3],
memcpy(vos->str, str, alloc_len);
}
-void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, float mat[4][4])
+void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write)
{
RegionView3D *rv3d = ar->regiondata;
ViewCachedString *vos;
@@ -877,9 +877,6 @@ void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, flo
/* project first and test */
for (vos = g_v3d_strings[g_v3d_string_level]; vos; vos = vos->next) {
- if (mat && !(vos->flag & V3D_CACHE_TEXT_WORLDSPACE))
- mul_m4_v3(mat, vos->vec);
-
if (ED_view3d_project_short_ex(ar,
(vos->flag & V3D_CACHE_TEXT_GLOBALSPACE) ? rv3d->persmat : rv3d->persmatob,
(vos->flag & V3D_CACHE_TEXT_LOCALCLIP) != 0,
@@ -5123,7 +5120,7 @@ static void draw_new_particle_system(Scene *scene, View3D *v3d, RegionView3D *rv
copy_m4_m4(imat, rv3d->viewinv);
normalize_v3(imat[0]);
normalize_v3(imat[1]);
- /* fall-through */
+ ATTR_FALLTHROUGH;
case PART_DRAW_CROSS:
case PART_DRAW_AXIS:
/* lets calculate the scale: */
@@ -6419,19 +6416,16 @@ static void draw_editnurb(
vec_a[0] = fac;
vec_a[1] = 0.0f;
vec_a[2] = 0.0f;
-
- vec_b[0] = -fac;
- vec_b[1] = 0.0f;
- vec_b[2] = 0.0f;
mul_qt_v3(bevp->quat, vec_a);
- mul_qt_v3(bevp->quat, vec_b);
+ madd_v3_v3fl(vec_a, bevp->dir, -fac);
+
+ reflect_v3_v3v3(vec_b, vec_a, bevp->dir);
+ negate_v3(vec_b);
+
add_v3_v3(vec_a, bevp->vec);
add_v3_v3(vec_b, bevp->vec);
- madd_v3_v3fl(vec_a, bevp->dir, -fac);
- madd_v3_v3fl(vec_b, bevp->dir, -fac);
-
glBegin(GL_LINE_STRIP);
glVertex3fv(vec_a);
glVertex3fv(bevp->vec);
@@ -6475,7 +6469,6 @@ static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *b
Curve *cu = ob->data;
EditFont *ef = cu->editfont;
float vec1[3], vec2[3];
- int selstart, selend;
draw_editfont_textcurs(rv3d, ef->textcurs);
@@ -6528,17 +6521,16 @@ static void draw_editfont(Scene *scene, View3D *v3d, RegionView3D *rv3d, Base *b
setlinestyle(0);
- if (BKE_vfont_select_get(ob, &selstart, &selend) && ef->selboxes) {
- const int seltot = selend - selstart;
+ if (ef->selboxes && ef->selboxes_len) {
float selboxw;
cpack(0xffffff);
set_inverted_drawing(1);
- for (int i = 0; i <= seltot; i++) {
+ for (int i = 0; i < ef->selboxes_len; i++) {
EditFontSelBox *sb = &ef->selboxes[i];
float tvec[3];
- if (i != seltot) {
+ if (i + 1 != ef->selboxes_len) {
if (ef->selboxes[i + 1].y == sb->y)
selboxw = ef->selboxes[i + 1].x - sb->x;
else
@@ -7355,7 +7347,7 @@ static void draw_object_wire_color(Scene *scene, Base *base, unsigned char r_ob_
theme_id = TH_GROUP_ACTIVE;
if (scene->basact != base) {
- theme_shade = -16;
+ theme_shade = -32;
}
}
else {
@@ -7831,7 +7823,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
draw_new_particle_system(scene, v3d, rv3d, base, psys, dt, dflag);
}
invert_m4_m4(ob->imat, ob->obmat);
- view3d_cached_text_draw_end(v3d, ar, 0, NULL);
+ view3d_cached_text_draw_end(v3d, ar, 0);
glMultMatrixf(ob->obmat);
@@ -8006,7 +7998,7 @@ void draw_object(Scene *scene, ARegion *ar, View3D *v3d, Base *base, const short
/* return warning, this is cached text draw */
invert_m4_m4(ob->imat, ob->obmat);
- view3d_cached_text_draw_end(v3d, ar, 1, NULL);
+ view3d_cached_text_draw_end(v3d, ar, 1);
/* return warning, clear temp flag */
v3d->flag2 &= ~V3D_SHOW_SOLID_MATCAP;
@@ -8386,9 +8378,13 @@ static void bbs_mesh_solid_verts(Scene *scene, Object *ob)
DM_update_materials(dm, ob);
- dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, GPU_object_material_bind, NULL, me, DM_DRAW_SKIP_HIDDEN);
+ /* Only draw faces to mask out verts, we don't want their selection ID's. */
+ const int G_f_orig = G.f;
+ G.f &= ~G_BACKBUFSEL;
+
+ dm->drawMappedFaces(dm, bbs_mesh_solid_hide2__setDrawOpts, NULL, NULL, me, DM_DRAW_SKIP_HIDDEN);
- GPU_object_material_unbind();
+ G.f |= (G_f_orig & G_BACKBUFSEL);
bbs_obmode_mesh_verts(ob, dm, 1);
bm_vertoffs = me->totvert + 1;
@@ -8445,8 +8441,8 @@ void draw_object_backbufsel(Scene *scene, View3D *v3d, RegionView3D *rv3d, Objec
bbs_mesh_wire(em, dm, bm_solidoffs);
bm_wireoffs = bm_solidoffs + em->bm->totedge;
- /* we draw verts if vert select mode or if in transform (for snap). */
- if ((ts->selectmode & SCE_SELECT_VERTEX) || (G.moving & G_TRANSFORM_EDIT)) {
+ /* we draw verts if vert select mode. */
+ if (ts->selectmode & SCE_SELECT_VERTEX) {
bbs_mesh_verts(em, dm, bm_wireoffs);
bm_vertoffs = bm_wireoffs + em->bm->totvert;
}
diff --git a/source/blender/editors/space_view3d/drawsimdebug.c b/source/blender/editors/space_view3d/drawsimdebug.c
index 9414d39467d..3f23d4aa09a 100644
--- a/source/blender/editors/space_view3d/drawsimdebug.c
+++ b/source/blender/editors/space_view3d/drawsimdebug.c
@@ -171,7 +171,7 @@ void draw_sim_debug_data(Scene *UNUSED(scene), View3D *v3d, ARegion *ar)
view3d_cached_text_draw_begin();
draw_sim_debug_elements(_sim_debug_data, imat);
- view3d_cached_text_draw_end(v3d, ar, false, NULL);
+ view3d_cached_text_draw_end(v3d, ar, false);
glPopMatrix();
diff --git a/source/blender/editors/space_view3d/view3d_draw.c b/source/blender/editors/space_view3d/view3d_draw.c
index 3fb2761d40e..250e6559b8f 100644
--- a/source/blender/editors/space_view3d/view3d_draw.c
+++ b/source/blender/editors/space_view3d/view3d_draw.c
@@ -105,7 +105,8 @@
#include "view3d_intern.h" /* own include */
/* prototypes */
-static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar);
+static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d);
+static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect);
static void view3d_stereo3d_setup_offscreen(Scene *scene, View3D *v3d, ARegion *ar,
float winmat[4][4], const char *viewname);
@@ -2371,17 +2372,11 @@ void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
short zbuf = v3d->zbuf;
RegionView3D *rv3d = ar->regiondata;
- view3d_winmatrix_set(ar, v3d, NULL);
- view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
-
- mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
- invert_m4_m4(rv3d->persinv, rv3d->persmat);
- invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
+ /* Setup view matrix. */
+ ED_view3d_draw_setup_view(NULL, scene, ar, v3d, rv3d->viewmat, rv3d->winmat, NULL);
glClear(GL_DEPTH_BUFFER_BIT);
- glLoadMatrixf(rv3d->viewmat);
-
v3d->zbuf = true;
glEnable(GL_DEPTH_TEST);
@@ -2390,46 +2385,15 @@ void ED_view3d_draw_depth_gpencil(Scene *scene, ARegion *ar, View3D *v3d)
}
v3d->zbuf = zbuf;
-
}
-void ED_view3d_draw_depth(Scene *scene, ARegion *ar, View3D *v3d, bool alphaoverride)
+static void view3d_draw_depth_loop(Scene *scene, ARegion *ar, View3D *v3d)
{
- RegionView3D *rv3d = ar->regiondata;
Base *base;
- short zbuf = v3d->zbuf;
- short flag = v3d->flag;
- float glalphaclip = U.glalphaclip;
- int obcenter_dia = U.obcenter_dia;
+
/* no need for color when drawing depth buffer */
const short dflag_depth = DRAW_CONSTCOLOR;
- /* temp set drawtype to solid */
-
- /* Setting these temporarily is not nice */
- v3d->flag &= ~V3D_SELECT_OUTLINE;
- U.glalphaclip = alphaoverride ? 0.5f : glalphaclip; /* not that nice but means we wont zoom into billboards */
- U.obcenter_dia = 0;
-
- view3d_winmatrix_set(ar, v3d, NULL);
- view3d_viewmatrix_set(scene, v3d, rv3d); /* note: calls BKE_object_where_is_calc for camera... */
-
- mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
- invert_m4_m4(rv3d->persinv, rv3d->persmat);
- invert_m4_m4(rv3d->viewinv, rv3d->viewmat);
-
- glClear(GL_DEPTH_BUFFER_BIT);
-
- glLoadMatrixf(rv3d->viewmat);
-
- if (rv3d->rflag & RV3D_CLIPPING) {
- ED_view3d_clipping_set(rv3d);
- }
- /* get surface depth without bias */
- rv3d->rflag |= RV3D_ZOFFSET_DISABLED;
- v3d->zbuf = true;
- glEnable(GL_DEPTH_TEST);
-
/* draw set first */
if (scene->set) {
Scene *sce_iter;
@@ -2503,8 +2467,39 @@ void ED_view3d_draw_depth(Scene *scene, ARegion *ar, View3D *v3d, bool alphaover
glDepthMask(mask_orig);
}
+}
+
+void ED_view3d_draw_depth(Scene *scene, ARegion *ar, View3D *v3d, bool alphaoverride)
+{
+ RegionView3D *rv3d = ar->regiondata;
+ short zbuf = v3d->zbuf;
+ short flag = v3d->flag;
+ float glalphaclip = U.glalphaclip;
+ int obcenter_dia = U.obcenter_dia;
+ /* temp set drawtype to solid */
+
+ /* Setting these temporarily is not nice */
+ v3d->flag &= ~V3D_SELECT_OUTLINE;
+ U.glalphaclip = alphaoverride ? 0.5f : glalphaclip; /* not that nice but means we wont zoom into billboards */
+ U.obcenter_dia = 0;
+
+ /* Setup view matrix. */
+ ED_view3d_draw_setup_view(NULL, scene, ar, v3d, rv3d->viewmat, rv3d->winmat, NULL);
+
+ glClear(GL_DEPTH_BUFFER_BIT);
if (rv3d->rflag & RV3D_CLIPPING) {
+ ED_view3d_clipping_set(rv3d);
+ }
+ /* get surface depth without bias */
+ rv3d->rflag |= RV3D_ZOFFSET_DISABLED;
+
+ v3d->zbuf = true;
+ glEnable(GL_DEPTH_TEST);
+
+ view3d_draw_depth_loop(scene, ar, v3d);
+
+ if (rv3d->rflag & RV3D_CLIPPING) {
ED_view3d_clipping_disable();
}
rv3d->rflag &= ~RV3D_ZOFFSET_DISABLED;
@@ -2737,7 +2732,8 @@ CustomDataMask ED_view3d_screen_datamask(const bScreen *screen)
/**
* \note keep this synced with #ED_view3d_mats_rv3d_backup/#ED_view3d_mats_rv3d_restore
*/
-void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
+void ED_view3d_update_viewmat(
+ Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
{
RegionView3D *rv3d = ar->regiondata;
@@ -2745,7 +2741,7 @@ void ED_view3d_update_viewmat(Scene *scene, View3D *v3d, ARegion *ar, float view
if (winmat)
copy_m4_m4(rv3d->winmat, winmat);
else
- view3d_winmatrix_set(ar, v3d, NULL);
+ view3d_winmatrix_set(ar, v3d, rect);
/* setup view matrix */
if (viewmat)
@@ -3008,11 +3004,12 @@ static void view3d_draw_objects(
}
}
-static void view3d_main_region_setup_view(Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4])
+static void view3d_main_region_setup_view(
+ Scene *scene, View3D *v3d, ARegion *ar, float viewmat[4][4], float winmat[4][4], const rcti *rect)
{
RegionView3D *rv3d = ar->regiondata;
- ED_view3d_update_viewmat(scene, v3d, ar, viewmat, winmat);
+ ED_view3d_update_viewmat(scene, v3d, ar, viewmat, winmat, rect);
/* set for opengl */
glMatrixMode(GL_PROJECTION);
@@ -3195,7 +3192,7 @@ void ED_view3d_draw_offscreen(
if ((viewname != NULL && viewname[0] != '\0') && (viewmat == NULL) && rv3d->persp == RV3D_CAMOB && v3d->camera)
view3d_stereo3d_setup_offscreen(scene, v3d, ar, winmat, viewname);
else
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat);
+ view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
/* framebuffer fx needed, we need to draw offscreen first */
if (v3d->fx_settings.fx_flag && fx) {
@@ -3258,6 +3255,23 @@ void ED_view3d_draw_offscreen(
}
/**
+ * Set the correct matrices
+ */
+void ED_view3d_draw_setup_view(
+ wmWindow *win, Scene *scene, ARegion *ar, View3D *v3d, float viewmat[4][4], float winmat[4][4], const rcti *rect)
+{
+ RegionView3D *rv3d = ar->regiondata;
+
+ /* Setup the view matrix. */
+ if (view3d_stereo3d_active(win, scene, v3d, rv3d)) {
+ view3d_stereo3d_setup(scene, v3d, ar, rect);
+ }
+ else {
+ view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, rect);
+ }
+}
+
+/**
* Utility func for ED_view3d_draw_offscreen
*
* \param ofs: Optional off-screen buffer, can be NULL.
@@ -3624,7 +3638,7 @@ static bool view3d_main_region_draw_engine(const bContext *C, Scene *scene,
}
/* setup view matrices */
- view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL);
+ view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL, NULL);
/* background draw */
ED_region_pixelspace(ar);
@@ -3691,26 +3705,37 @@ static void view3d_main_region_draw_engine_info(View3D *v3d, RegionView3D *rv3d,
ED_region_info_draw(ar, rv3d->render_engine->text, fill_color, true);
}
-static bool view3d_stereo3d_active(const bContext *C, Scene *scene, View3D *v3d, RegionView3D *rv3d)
+static bool view3d_stereo3d_active(wmWindow *win, Scene *scene, View3D *v3d, RegionView3D *rv3d)
{
- wmWindow *win = CTX_wm_window(C);
-
- if ((scene->r.scemode & R_MULTIVIEW) == 0)
- return false;
-
- if (WM_stereo3d_enabled(win, true) == false)
+ if ((scene->r.scemode & R_MULTIVIEW) == 0) {
return false;
+ }
- if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB)
+ if ((v3d->camera == NULL) || (v3d->camera->type != OB_CAMERA) || rv3d->persp != RV3D_CAMOB) {
return false;
+ }
- if (scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) {
- if (v3d->stereo3d_camera == STEREO_MONO_ID)
+ switch (v3d->stereo3d_camera) {
+ case STEREO_MONO_ID:
return false;
-
- return BKE_scene_multiview_is_stereo3d(&scene->r);
+ break;
+ case STEREO_3D_ID:
+ /* win will be NULL when calling this from the selection or draw loop. */
+ if ((win == NULL) || (WM_stereo3d_enabled(win, true) == false)) {
+ return false;
+ }
+ if (((scene->r.views_format & SCE_VIEWS_FORMAT_MULTIVIEW) != 0) &&
+ !BKE_scene_multiview_is_stereo3d(&scene->r))
+ {
+ return false;
+ }
+ break;
+ /* We always need the stereo calculation for left and right cameras. */
+ case STEREO_LEFT_ID:
+ case STEREO_RIGHT_ID:
+ default:
+ break;
}
-
return true;
}
@@ -3722,7 +3747,7 @@ static bool view3d_stereo3d_active(const bContext *C, Scene *scene, View3D *v3d,
* we do a small hack to replace it temporarily so we don't need to change the
* view3d)main_region_setup_view() code to account for that.
*/
-static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar)
+static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar, const rcti *rect)
{
bool is_left;
const char *names[2] = {STEREO_LEFT_NAME, STEREO_RIGHT_NAME};
@@ -3748,7 +3773,7 @@ static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar)
data->shiftx = BKE_camera_multiview_shift_x(&scene->r, v3d->camera, viewname);
BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL);
+ view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL, rect);
data->shiftx = shiftx;
BLI_unlock_thread(LOCK_VIEW3D);
@@ -3762,7 +3787,7 @@ static void view3d_stereo3d_setup(Scene *scene, View3D *v3d, ARegion *ar)
v3d->camera = camera;
BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL);
+ view3d_main_region_setup_view(scene, v3d, ar, viewmat, NULL, rect);
v3d->camera = view_ob;
BLI_unlock_thread(LOCK_VIEW3D);
@@ -3778,14 +3803,14 @@ static void view3d_stereo3d_setup_offscreen(Scene *scene, View3D *v3d, ARegion *
const bool is_left = STREQ(viewname, STEREO_LEFT_NAME);
BKE_camera_multiview_view_matrix(&scene->r, v3d->camera, is_left, viewmat);
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat);
+ view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
}
else { /* SCE_VIEWS_FORMAT_MULTIVIEW */
float viewmat[4][4];
Object *camera = BKE_camera_multiview_render(scene, v3d->camera, viewname);
BKE_camera_multiview_view_matrix(&scene->r, camera, false, viewmat);
- view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat);
+ view3d_main_region_setup_view(scene, v3d, ar, viewmat, winmat, NULL);
}
}
@@ -3823,11 +3848,8 @@ static void view3d_main_region_draw_objects(const bContext *C, Scene *scene, Vie
GPU_default_lights();
}
- /* setup the view matrix */
- if (view3d_stereo3d_active(C, scene, v3d, rv3d))
- view3d_stereo3d_setup(scene, v3d, ar);
- else
- view3d_main_region_setup_view(scene, v3d, ar, NULL, NULL);
+ /* Setup the view matrix. */
+ ED_view3d_draw_setup_view(CTX_wm_window(C), scene, ar, v3d, NULL, NULL, NULL);
rv3d->rflag &= ~RV3D_IS_GAME_ENGINE;
#ifdef WITH_GAMEENGINE
diff --git a/source/blender/editors/space_view3d/view3d_edit.c b/source/blender/editors/space_view3d/view3d_edit.c
index f07727f8118..4e3f279e12e 100644
--- a/source/blender/editors/space_view3d/view3d_edit.c
+++ b/source/blender/editors/space_view3d/view3d_edit.c
@@ -85,6 +85,8 @@
#include "view3d_intern.h" /* own include */
+static bool view3d_ensure_persp(struct View3D *v3d, ARegion *ar);
+
bool ED_view3d_offset_lock_check(const View3D *v3d, const RegionView3D *rv3d)
{
return (rv3d->persp != RV3D_CAMOB) && (v3d->ob_centre_cursor || v3d->ob_centre);
@@ -697,16 +699,68 @@ static bool view3d_orbit_calc_center(bContext *C, float r_dyn_ofs[3])
return is_set;
}
+enum eViewOpsOrbit {
+ VIEWOPS_ORBIT_SELECT = (1 << 0),
+ VIEWOPS_ORBIT_DEPTH = (1 << 1),
+};
+
+static enum eViewOpsOrbit viewops_orbit_mode_ex(bool use_select, bool use_depth)
+{
+ enum eViewOpsOrbit flag = 0;
+ if (use_select) {
+ flag |= VIEWOPS_ORBIT_SELECT;
+ }
+ if (use_depth) {
+ flag |= VIEWOPS_ORBIT_DEPTH;
+ }
+
+ return flag;
+}
+
+static enum eViewOpsOrbit viewops_orbit_mode(void)
+{
+ return viewops_orbit_mode_ex(
+ (U.uiflag & USER_ORBIT_SELECTION) != 0,
+ (U.uiflag & USER_ZBUF_ORBIT) != 0);
+}
+
/**
* Calculate the values for #ViewOpsData
*/
-static void viewops_data_create_ex(bContext *C, wmOperator *op, const wmEvent *event,
- const bool use_orbit_select,
- const bool use_orbit_zbuf)
+static void viewops_data_create_ex(
+ bContext *C, wmOperator *op, const wmEvent *event,
+ bool switch_from_camera, enum eViewOpsOrbit orbit_mode)
{
ViewOpsData *vod = op->customdata;
RegionView3D *rv3d = vod->rv3d;
+ /* we need the depth info before changing any viewport options */
+ if (orbit_mode & VIEWOPS_ORBIT_DEPTH) {
+ float fallback_depth_pt[3];
+
+ view3d_operator_needs_opengl(C); /* needed for zbuf drawing */
+
+ negate_v3_v3(fallback_depth_pt, rv3d->ofs);
+
+ vod->use_dyn_ofs = ED_view3d_autodist(
+ vod->scene, vod->ar, vod->v3d,
+ event->mval, vod->dyn_ofs, true, fallback_depth_pt);
+ }
+ else {
+ vod->use_dyn_ofs = false;
+ }
+
+ if (switch_from_camera) {
+ /* switch from camera view when: */
+ if (view3d_ensure_persp(vod->v3d, vod->ar)) {
+ /* If we're switching from camera view to the perspective one,
+ * need to tag viewport update, so camera vuew and borders
+ * are properly updated.
+ */
+ ED_region_tag_redraw(vod->ar);
+ }
+ }
+
/* set the view from the camera, if view locking is enabled.
* we may want to make this optional but for now its needed always */
ED_view3d_camera_lock_init(vod->v3d, vod->rv3d);
@@ -718,28 +772,19 @@ static void viewops_data_create_ex(bContext *C, wmOperator *op, const wmEvent *e
vod->origx = vod->oldx = event->x;
vod->origy = vod->oldy = event->y;
vod->origkey = event->type; /* the key that triggered the operator. */
- vod->use_dyn_ofs = false;
copy_v3_v3(vod->ofs, rv3d->ofs);
- if (use_orbit_select) {
-
- vod->use_dyn_ofs = true;
-
- view3d_orbit_calc_center(C, vod->dyn_ofs);
-
- negate_v3(vod->dyn_ofs);
+ if (orbit_mode & VIEWOPS_ORBIT_SELECT) {
+ float ofs[3];
+ if (view3d_orbit_calc_center(C, ofs) || (vod->use_dyn_ofs == false)) {
+ vod->use_dyn_ofs = true;
+ negate_v3_v3(vod->dyn_ofs, ofs);
+ orbit_mode &= ~VIEWOPS_ORBIT_DEPTH;
+ }
}
- else if (use_orbit_zbuf) {
- Scene *scene = CTX_data_scene(C);
- float fallback_depth_pt[3];
-
- view3d_operator_needs_opengl(C); /* needed for zbuf drawing */
-
- negate_v3_v3(fallback_depth_pt, rv3d->ofs);
- if ((vod->use_dyn_ofs = ED_view3d_autodist(scene, vod->ar, vod->v3d,
- event->mval, vod->dyn_ofs, true, fallback_depth_pt)))
- {
+ if (orbit_mode & VIEWOPS_ORBIT_DEPTH) {
+ if (vod->use_dyn_ofs) {
if (rv3d->is_persp) {
float my_origin[3]; /* original G.vd->ofs */
float my_pivot[3]; /* view */
@@ -808,12 +853,10 @@ static void viewops_data_create_ex(bContext *C, wmOperator *op, const wmEvent *e
rv3d->rflag |= RV3D_NAVIGATING;
}
-static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event)
+static void viewops_data_create(bContext *C, wmOperator *op, const wmEvent *event, bool switch_from_camera)
{
- viewops_data_create_ex(
- C, op, event,
- (U.uiflag & USER_ORBIT_SELECTION) != 0,
- (U.uiflag & USER_ZBUF_ORBIT) != 0);
+ enum eViewOpsOrbit orbit_mode = viewops_orbit_mode();
+ viewops_data_create_ex(C, op, event, switch_from_camera, orbit_mode);
}
static void viewops_data_free(bContext *C, wmOperator *op)
@@ -1219,16 +1262,7 @@ static int viewrotate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
- /* switch from camera view when: */
- if (view3d_ensure_persp(vod->v3d, vod->ar)) {
- /* If we're switching from camera view to the perspective one,
- * need to tag viewport update, so camera vuew and borders
- * are properly updated.
- */
- ED_region_tag_redraw(vod->ar);
- }
-
- viewops_data_create(C, op, event);
+ viewops_data_create(C, op, event, true);
if (ELEM(event->type, MOUSEPAN, MOUSEROTATE)) {
/* Rotate direction we keep always same */
@@ -1637,8 +1671,9 @@ static int ndof_orbit_invoke(bContext *C, wmOperator *op, const wmEvent *event)
const wmNDOFMotionData *ndof = event->customdata;
viewops_data_alloc(C, op);
- viewops_data_create_ex(C, op, event,
- (U.uiflag & USER_ORBIT_SELECTION) != 0, false);
+ viewops_data_create_ex(
+ C, op, event,
+ viewops_orbit_mode_ex((U.uiflag & USER_ORBIT_SELECTION) != 0, false), false);
vod = op->customdata;
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
@@ -1705,8 +1740,9 @@ static int ndof_orbit_zoom_invoke(bContext *C, wmOperator *op, const wmEvent *ev
const wmNDOFMotionData *ndof = event->customdata;
viewops_data_alloc(C, op);
- viewops_data_create_ex(C, op, event,
- (U.uiflag & USER_ORBIT_SELECTION) != 0, false);
+ viewops_data_create_ex(
+ C, op, event,
+ viewops_orbit_mode_ex((U.uiflag & USER_ORBIT_SELECTION) != 0, false), false);
vod = op->customdata;
@@ -2020,7 +2056,7 @@ static int viewmove_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* makes op->customdata */
viewops_data_alloc(C, op);
- viewops_data_create(C, op, event);
+ viewops_data_create(C, op, event, false);
vod = op->customdata;
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
@@ -2501,7 +2537,7 @@ static int viewzoom_invoke(bContext *C, wmOperator *op, const wmEvent *event)
/* makes op->customdata */
viewops_data_alloc(C, op);
- viewops_data_create(C, op, event);
+ viewops_data_create(C, op, event, false);
vod = op->customdata;
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
@@ -2774,7 +2810,7 @@ static int viewdolly_invoke(bContext *C, wmOperator *op, const wmEvent *event)
ED_region_tag_redraw(vod->ar);
}
- viewops_data_create(C, op, event);
+ viewops_data_create(C, op, event, false);
/* if one or the other zoom position aren't set, set from event */
@@ -4298,7 +4334,7 @@ static int viewroll_invoke(bContext *C, wmOperator *op, const wmEvent *event)
else {
/* makes op->customdata */
viewops_data_alloc(C, op);
- viewops_data_create(C, op, event);
+ viewops_data_create(C, op, event, false);
vod = op->customdata;
ED_view3d_smooth_view_force_finish(C, vod->v3d, vod->ar);
@@ -4375,7 +4411,7 @@ static int viewpan_invoke(bContext *C, wmOperator *op, const wmEvent *event)
else if (pandir == V3D_VIEW_PANDOWN) { y = 25; }
viewops_data_alloc(C, op);
- viewops_data_create(C, op, event);
+ viewops_data_create(C, op, event, false);
ViewOpsData *vod = op->customdata;
viewmove_apply(vod, vod->oldx + x, vod->oldy + y);
diff --git a/source/blender/editors/space_view3d/view3d_intern.h b/source/blender/editors/space_view3d/view3d_intern.h
index c2b8d1f8bda..7a106a27833 100644
--- a/source/blender/editors/space_view3d/view3d_intern.h
+++ b/source/blender/editors/space_view3d/view3d_intern.h
@@ -154,7 +154,7 @@ void view3d_cached_text_draw_begin(void);
void view3d_cached_text_draw_add(const float co[3],
const char *str, const size_t str_len,
short xoffs, short flag, const unsigned char col[4]);
-void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write, float mat[4][4]);
+void view3d_cached_text_draw_end(View3D *v3d, ARegion *ar, bool depth_write);
bool check_object_draw_texture(struct Scene *scene, struct View3D *v3d, const char drawtype);
diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c
index ce4b7f7deeb..ef7b01f7a21 100644
--- a/source/blender/editors/space_view3d/view3d_iterators.c
+++ b/source/blender/editors/space_view3d/view3d_iterators.c
@@ -119,7 +119,7 @@ void meshobject_foreachScreenVert(
data.clip_flag = clip_flag;
if (clip_flag & V3D_PROJ_TEST_CLIP_BB) {
- ED_view3d_clipping_local(vc->rv3d, vc->obedit->obmat); /* for local clipping lookups */
+ ED_view3d_clipping_local(vc->rv3d, vc->obact->obmat);
}
dm->foreachMappedVert(dm, meshobject_foreachScreenVert__mapFunc, &data, DM_FOREACH_NOP);
diff --git a/source/blender/editors/space_view3d/view3d_view.c b/source/blender/editors/space_view3d/view3d_view.c
index fe8274064e5..5c13fd37dda 100644
--- a/source/blender/editors/space_view3d/view3d_view.c
+++ b/source/blender/editors/space_view3d/view3d_view.c
@@ -449,7 +449,7 @@ void ED_view3d_smooth_view_force_finish(
/* force update of view matrix so tools that run immediately after
* can use them without redrawing first */
Scene *scene = CTX_data_scene(C);
- ED_view3d_update_viewmat(scene, v3d, ar, NULL, NULL);
+ ED_view3d_update_viewmat(scene, v3d, ar, NULL, NULL, NULL);
}
}
@@ -1172,9 +1172,10 @@ int view3d_opengl_select(
G.f |= G_PICKSEL;
- view3d_winmatrix_set(ar, v3d, &rect);
- mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
-
+ /* Important we use the 'viewmat' and don't re-calculate since
+ * the object & bone view locking takes 'rect' into account, see: T51629. */
+ ED_view3d_draw_setup_view(vc->win, scene, ar, v3d, vc->rv3d->viewmat, NULL, &rect);
+
if (v3d->drawtype > OB_WIRE) {
v3d->zbuf = true;
glEnable(GL_DEPTH_TEST);
@@ -1190,7 +1191,7 @@ int view3d_opengl_select(
hits = GPU_select_end();
/* second pass, to get the closest object to camera */
- if (do_passes) {
+ if (do_passes && (hits > 0)) {
GPU_select_begin(buffer, bufsize, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
ED_view3d_draw_select_loop(vc, scene, v3d, ar, use_obedit_skip, use_nearest);
@@ -1199,8 +1200,7 @@ int view3d_opengl_select(
}
G.f &= ~G_PICKSEL;
- view3d_winmatrix_set(ar, v3d, NULL);
- mul_m4_m4m4(vc->rv3d->persmat, vc->rv3d->winmat, vc->rv3d->viewmat);
+ ED_view3d_draw_setup_view(vc->win, scene, ar, v3d, vc->rv3d->viewmat, NULL, NULL);
if (v3d->drawtype > OB_WIRE) {
v3d->zbuf = 0;
diff --git a/source/blender/editors/space_view3d/view3d_walk.c b/source/blender/editors/space_view3d/view3d_walk.c
index 542dc410bc3..c6b73056a9a 100644
--- a/source/blender/editors/space_view3d/view3d_walk.c
+++ b/source/blender/editors/space_view3d/view3d_walk.c
@@ -674,16 +674,6 @@ static int walkEnd(bContext *C, WalkInfo *walk)
return OPERATOR_CANCELLED;
}
-static bool wm_event_is_last_mousemove(const wmEvent *event)
-{
- while ((event = event->next)) {
- if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
- return false;
- }
- }
- return true;
-}
-
static void walkEvent(bContext *C, wmOperator *op, WalkInfo *walk, const wmEvent *event)
{
if (event->type == TIMER && event->customdata == walk->timer) {
@@ -736,7 +726,7 @@ static void walkEvent(bContext *C, wmOperator *op, WalkInfo *walk, const wmEvent
}
else
#endif
- if (wm_event_is_last_mousemove(event)) {
+ if (WM_event_is_last_mousemove(event)) {
wmWindow *win = CTX_wm_window(C);
#ifdef __APPLE__
diff --git a/source/blender/editors/transform/transform.c b/source/blender/editors/transform/transform.c
index 7d9063c3285..ca6e2267218 100644
--- a/source/blender/editors/transform/transform.c
+++ b/source/blender/editors/transform/transform.c
@@ -1605,7 +1605,7 @@ static void drawArrow(ArrowDirection d, short offset, short length, short size)
offset = -offset;
length = -length;
size = -size;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case RIGHT:
glBegin(GL_LINES);
glVertex2s(offset, 0);
@@ -1621,7 +1621,7 @@ static void drawArrow(ArrowDirection d, short offset, short length, short size)
offset = -offset;
length = -length;
size = -size;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case UP:
glBegin(GL_LINES);
glVertex2s(0, offset);
@@ -1640,7 +1640,7 @@ static void drawArrowHead(ArrowDirection d, short size)
switch (d) {
case LEFT:
size = -size;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case RIGHT:
glBegin(GL_LINES);
glVertex2s(0, 0);
@@ -1652,7 +1652,7 @@ static void drawArrowHead(ArrowDirection d, short size)
case DOWN:
size = -size;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case UP:
glBegin(GL_LINES);
glVertex2s(0, 0);
@@ -3051,19 +3051,13 @@ static void Bend(TransInfo *t, const int UNUSED(mval[2]))
/** \name Transform Shear
* \{ */
-static void postInputShear(TransInfo *UNUSED(t), float values[3])
-{
- mul_v3_fl(values, 0.05f);
-}
-
static void initShear(TransInfo *t)
{
t->mode = TFM_SHEAR;
t->transform = applyShear;
t->handleEvent = handleEventShear;
-
- setInputPostFct(&t->mouse, postInputShear);
- initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
+
+ initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
t->idx_max = 0;
t->num.idx_max = 0;
@@ -3085,24 +3079,24 @@ static eRedrawFlag handleEventShear(TransInfo *t, const wmEvent *event)
if (event->type == MIDDLEMOUSE && event->val == KM_PRESS) {
/* Use custom.mode.data pointer to signal Shear direction */
if (t->custom.mode.data == NULL) {
- initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
+ initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_RATIO);
t->custom.mode.data = (void *)1;
}
else {
- initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
+ initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
t->custom.mode.data = NULL;
}
status = TREDRAW_HARD;
}
else if (event->type == XKEY && event->val == KM_PRESS) {
- initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_ABSOLUTE);
+ initMouseInputMode(t, &t->mouse, INPUT_HORIZONTAL_RATIO);
t->custom.mode.data = NULL;
status = TREDRAW_HARD;
}
else if (event->type == YKEY && event->val == KM_PRESS) {
- initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_ABSOLUTE);
+ initMouseInputMode(t, &t->mouse, INPUT_VERTICAL_RATIO);
t->custom.mode.data = (void *)1;
status = TREDRAW_HARD;
@@ -4073,13 +4067,15 @@ static void initTrackball(TransInfo *t)
static void applyTrackballValue(TransInfo *t, const float axis1[3], const float axis2[3], float angles[2])
{
TransData *td = t->data;
- float mat[3][3], smat[3][3], totmat[3][3];
+ float mat[3][3];
+ float axis[3];
+ float angle;
int i;
- axis_angle_normalized_to_mat3(smat, axis1, angles[0]);
- axis_angle_normalized_to_mat3(totmat, axis2, angles[1]);
-
- mul_m3_m3m3(mat, smat, totmat);
+ mul_v3_v3fl(axis, axis1, angles[0]);
+ madd_v3_v3fl(axis, axis2, angles[1]);
+ angle = normalize_v3(axis);
+ axis_angle_normalized_to_mat3(mat, axis, angle);
for (i = 0; i < t->total; i++, td++) {
if (td->flag & TD_NOACTION)
@@ -4089,10 +4085,7 @@ static void applyTrackballValue(TransInfo *t, const float axis1[3], const float
continue;
if (t->flag & T_PROP_EDIT) {
- axis_angle_normalized_to_mat3(smat, axis1, td->factor * angles[0]);
- axis_angle_normalized_to_mat3(totmat, axis2, td->factor * angles[1]);
-
- mul_m3_m3m3(mat, smat, totmat);
+ axis_angle_normalized_to_mat3(mat, axis, td->factor * angle);
}
ElementRotation(t, td, mat, t->around);
@@ -4278,7 +4271,7 @@ static void headerTranslation(TransInfo *t, const float vec[3], char str[UI_MAX_
bUnit_AsString(distvec, sizeof(distvec), dist * t->scene->unit.scale_length, 4, t->scene->unit.system,
B_UNIT_LENGTH, do_split, false);
}
- else if (dist > 1e10f || dist < -1e10f) {
+ else if (dist > 1e10f || dist < -1e10f) {
/* prevent string buffer overflow */
BLI_snprintf(distvec, NUM_STR_REP_LEN, "%.4e", dist);
}
@@ -4948,7 +4941,7 @@ static void initPushPull(TransInfo *t)
static void applyPushPull(TransInfo *t, const int UNUSED(mval[2]))
{
- float vec[3], axis[3];
+ float vec[3], axis_global[3];
float distance;
int i;
char str[UI_MAX_DRAW_STR];
@@ -4976,7 +4969,7 @@ static void applyPushPull(TransInfo *t, const int UNUSED(mval[2]))
}
if (t->con.applyRot && t->con.mode & CON_APPLY) {
- t->con.applyRot(t, NULL, axis, NULL);
+ t->con.applyRot(t, NULL, axis_global, NULL);
}
for (i = 0; i < t->total; i++, td++) {
@@ -4988,7 +4981,11 @@ static void applyPushPull(TransInfo *t, const int UNUSED(mval[2]))
sub_v3_v3v3(vec, t->center, td->center);
if (t->con.applyRot && t->con.mode & CON_APPLY) {
+ float axis[3];
+ copy_v3_v3(axis, axis_global);
t->con.applyRot(t, td, axis, NULL);
+
+ mul_m3_v3(td->smtx, axis);
if (isLockConstraint(t)) {
float dvec[3];
project_v3_v3v3(dvec, vec, axis);
@@ -5561,7 +5558,7 @@ static void slide_origdata_interp_data_vert(
float v_proj[3][3];
if (do_loop_weight || do_loop_mdisps) {
- project_plane_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis);
+ project_plane_normalized_v3_v3v3(v_proj[1], sv->co_orig_3d, v_proj_axis);
}
// BM_ITER_ELEM (l, &liter, sv->v, BM_LOOPS_OF_VERT) {
@@ -5595,19 +5592,19 @@ static void slide_origdata_interp_data_vert(
/* In the unlikely case that we're next to a zero length edge - walk around the to the next.
* Since we only need to check if the vertex is in this corner,
* its not important _which_ loop - as long as its not overlapping 'sv->co_orig_3d', see: T45096. */
- project_plane_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
+ project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
while (UNLIKELY(((co_prev_ok = (len_squared_v3v3(v_proj[1], v_proj[0]) > eps)) == false) &&
((l_prev = l_prev->prev) != l->next)))
{
co_prev = slide_origdata_orig_vert_co(sod, l_prev->v);
- project_plane_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
+ project_plane_normalized_v3_v3v3(v_proj[0], co_prev, v_proj_axis);
}
- project_plane_v3_v3v3(v_proj[2], co_next, v_proj_axis);
+ project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis);
while (UNLIKELY(((co_next_ok = (len_squared_v3v3(v_proj[1], v_proj[2]) > eps)) == false) &&
((l_next = l_next->next) != l->prev)))
{
co_next = slide_origdata_orig_vert_co(sod, l_next->v);
- project_plane_v3_v3v3(v_proj[2], co_next, v_proj_axis);
+ project_plane_normalized_v3_v3v3(v_proj[2], co_next, v_proj_axis);
}
if (co_prev_ok && co_next_ok) {
diff --git a/source/blender/editors/transform/transform_conversions.c b/source/blender/editors/transform/transform_conversions.c
index 5e67f304755..4429d19613a 100644
--- a/source/blender/editors/transform/transform_conversions.c
+++ b/source/blender/editors/transform/transform_conversions.c
@@ -771,34 +771,43 @@ int count_set_pose_transflags(int *out_mode, short around, Object *ob)
/* -------- Auto-IK ---------- */
/* adjust pose-channel's auto-ik chainlen */
-static void pchan_autoik_adjust(bPoseChannel *pchan, short chainlen)
+static bool pchan_autoik_adjust(bPoseChannel *pchan, short chainlen)
{
bConstraint *con;
+ bool changed = false;
/* don't bother to search if no valid constraints */
- if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0)
- return;
+ if ((pchan->constflag & (PCHAN_HAS_IK | PCHAN_HAS_TARGET)) == 0) {
+ return changed;
+ }
/* check if pchan has ik-constraint */
for (con = pchan->constraints.first; con; con = con->next) {
if (con->type == CONSTRAINT_TYPE_KINEMATIC && (con->enforce != 0.0f)) {
bKinematicConstraint *data = con->data;
-
+
/* only accept if a temporary one (for auto-ik) */
if (data->flag & CONSTRAINT_IK_TEMP) {
/* chainlen is new chainlen, but is limited by maximum chainlen */
- if ((chainlen == 0) || (chainlen > data->max_rootbone))
+ const int old_rootbone = data->rootbone;
+ if ((chainlen == 0) || (chainlen > data->max_rootbone)) {
data->rootbone = data->max_rootbone;
- else
+ }
+ else {
data->rootbone = chainlen;
+ }
+ changed |= (data->rootbone != old_rootbone);
}
}
}
+
+ return changed;
}
/* change the chain-length of auto-ik */
void transform_autoik_update(TransInfo *t, short mode)
{
+ const short old_len = t->settings->autoik_chainlen;
short *chainlen = &t->settings->autoik_chainlen;
bPoseChannel *pchan;
@@ -812,13 +821,29 @@ void transform_autoik_update(TransInfo *t, short mode)
if (*chainlen > 0) (*chainlen)--;
}
+ /* IK length did not change, skip any updates. */
+ if (old_len == *chainlen) {
+ return;
+ }
+
/* sanity checks (don't assume t->poseobj is set, or that it is an armature) */
if (ELEM(NULL, t->poseobj, t->poseobj->pose))
return;
/* apply to all pose-channels */
+ bool changed = false;
for (pchan = t->poseobj->pose->chanbase.first; pchan; pchan = pchan->next) {
- pchan_autoik_adjust(pchan, *chainlen);
+ changed |= pchan_autoik_adjust(pchan, *chainlen);
+ }
+
+#ifdef WITH_LEGACY_DEPSGRAPH
+ if (!DEG_depsgraph_use_legacy())
+#endif
+ {
+ if (changed) {
+ /* TODO(sergey): Consider doing partial update only. */
+ DAG_relations_tag_update(G.main);
+ }
}
}
@@ -828,7 +853,9 @@ static void pose_grab_with_ik_clear(Object *ob)
bKinematicConstraint *data;
bPoseChannel *pchan;
bConstraint *con, *next;
+#ifdef WITH_LEGACY_DEPSGRAPH
bool need_dependency_update = false;
+#endif
for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
/* clear all temporary lock flags */
@@ -843,7 +870,9 @@ static void pose_grab_with_ik_clear(Object *ob)
data = con->data;
if (data->flag & CONSTRAINT_IK_TEMP) {
/* iTaSC needs clear for removed constraints */
+#ifdef WITH_LEGACY_DEPSGRAPH
need_dependency_update = true;
+#endif
BIK_clear_data(ob->pose);
BLI_remlink(&pchan->constraints, con);
@@ -1496,6 +1525,48 @@ static TransDataCurveHandleFlags *initTransDataCurveHandles(TransData *td, struc
return hdata;
}
+/**
+ * For the purpose of transform code we need to behave as if handles are selected,
+ * even when they aren't (see special case below).
+ */
+static int bezt_select_to_transform_triple_flag(
+ const BezTriple *bezt, const bool hide_handles)
+{
+ int flag = 0;
+
+ if (hide_handles) {
+ if (bezt->f2 & SELECT) {
+ flag = (1 << 0) | (1 << 1) | (1 << 2);
+ }
+ }
+ else {
+ flag = (
+ ((bezt->f1 & SELECT) ? (1 << 0) : 0) |
+ ((bezt->f2 & SELECT) ? (1 << 1) : 0) |
+ ((bezt->f3 & SELECT) ? (1 << 2) : 0)
+ );
+ }
+
+ /* Special case for auto & aligned handles:
+ * When a center point is being moved without the handles,
+ * leaving the handles stationary makes no sense and only causes strange behavior,
+ * where one handle is arbitrarily anchored, the other one is aligned and lengthened
+ * based on where the center point is moved. Also a bug when cancelling, see: T52007.
+ *
+ * A more 'correct' solution could be to store handle locations in 'TransDataCurveHandleFlags'.
+ * However that doesn't resolve odd behavior, so best transform the handles in this case.
+ */
+ if ((flag != ((1 << 0) | (1 << 1) | (1 << 2))) && (flag & (1 << 1))) {
+ if (ELEM(bezt->h1, HD_AUTO, HD_ALIGN) &&
+ ELEM(bezt->h2, HD_AUTO, HD_ALIGN))
+ {
+ flag = (1 << 0) | (1 << 1) | (1 << 2);
+ }
+ }
+
+ return flag;
+}
+
static void createTransCurveVerts(TransInfo *t)
{
Curve *cu = t->obedit->data;
@@ -1513,22 +1584,22 @@ static void createTransCurveVerts(TransInfo *t)
/* to be sure */
if (cu->editnurb == NULL) return;
+#define SEL_F1 (1 << 0)
+#define SEL_F2 (1 << 1)
+#define SEL_F3 (1 << 2)
+
/* count total of vertices, check identical as in 2nd loop for making transdata! */
nurbs = BKE_curve_editNurbs_get(cu);
for (nu = nurbs->first; nu; nu = nu->next) {
if (nu->type == CU_BEZIER) {
for (a = 0, bezt = nu->bezt; a < nu->pntsu; a++, bezt++) {
if (bezt->hide == 0) {
- if (hide_handles) {
- if (bezt->f2 & SELECT) countsel += 3;
- if (is_prop_edit) count += 3;
- }
- else {
- if (bezt->f1 & SELECT) countsel++;
- if (bezt->f2 & SELECT) countsel++;
- if (bezt->f3 & SELECT) countsel++;
- if (is_prop_edit) count += 3;
- }
+ const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
+ if (bezt_tx & SEL_F1) { countsel++; }
+ if (bezt_tx & SEL_F2) { countsel++; }
+ if (bezt_tx & SEL_F3) { countsel++; }
+ if (is_prop_edit) count += 3;
+
}
}
}
@@ -1579,10 +1650,10 @@ static void createTransCurveVerts(TransInfo *t)
}
}
- if (is_prop_edit ||
- ((bezt->f2 & SELECT) && hide_handles) ||
- ((bezt->f1 & SELECT) && hide_handles == 0))
- {
+ /* Elements that will be transform (not always a match to selection). */
+ const int bezt_tx = bezt_select_to_transform_triple_flag(bezt, hide_handles);
+
+ if (is_prop_edit || bezt_tx & SEL_F1) {
copy_v3_v3(td->iloc, bezt->vec[0]);
td->loc = bezt->vec[0];
copy_v3_v3(td->center, bezt->vec[(hide_handles ||
@@ -1613,7 +1684,7 @@ static void createTransCurveVerts(TransInfo *t)
}
/* This is the Curve Point, the other two are handles */
- if (is_prop_edit || (bezt->f2 & SELECT)) {
+ if (is_prop_edit || bezt_tx & SEL_F2) {
copy_v3_v3(td->iloc, bezt->vec[1]);
td->loc = bezt->vec[1];
copy_v3_v3(td->center, td->loc);
@@ -1639,7 +1710,7 @@ static void createTransCurveVerts(TransInfo *t)
copy_m3_m3(td->axismtx, axismtx);
}
- if ((bezt->f1 & SELECT) == 0 && (bezt->f3 & SELECT) == 0)
+ if ((bezt_tx & SEL_F1) == 0 && (bezt_tx & SEL_F3) == 0)
/* If the middle is selected but the sides arnt, this is needed */
if (hdata == NULL) { /* if the handle was not saved by the previous handle */
hdata = initTransDataCurveHandles(td, bezt);
@@ -1649,10 +1720,7 @@ static void createTransCurveVerts(TransInfo *t)
count++;
tail++;
}
- if (is_prop_edit ||
- ((bezt->f2 & SELECT) && hide_handles) ||
- ((bezt->f3 & SELECT) && hide_handles == 0))
- {
+ if (is_prop_edit || bezt_tx & SEL_F3) {
copy_v3_v3(td->iloc, bezt->vec[2]);
td->loc = bezt->vec[2];
copy_v3_v3(td->center, bezt->vec[(hide_handles ||
@@ -1707,6 +1775,26 @@ static void createTransCurveVerts(TransInfo *t)
for (a = nu->pntsu * nu->pntsv, bp = nu->bp; a > 0; a--, bp++) {
if (bp->hide == 0) {
if (is_prop_edit || (bp->f1 & SELECT)) {
+ float axismtx[3][3];
+
+ if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
+ if (nu->pntsv == 1) {
+ float normal[3], plane[3];
+
+ BKE_nurb_bpoint_calc_normal(nu, bp, normal);
+ BKE_nurb_bpoint_calc_plane(nu, bp, plane);
+
+ if (createSpaceNormalTangent(axismtx, normal, plane)) {
+ /* pass */
+ }
+ else {
+ normalize_v3(normal);
+ axis_dominant_v3_to_m3(axismtx, normal);
+ invert_m3(axismtx);
+ }
+ }
+ }
+
copy_v3_v3(td->iloc, bp->vec);
td->loc = bp->vec;
copy_v3_v3(td->center, td->loc);
@@ -1725,6 +1813,11 @@ static void createTransCurveVerts(TransInfo *t)
copy_m3_m3(td->smtx, smtx);
copy_m3_m3(td->mtx, mtx);
+ if (t->around == V3D_AROUND_LOCAL_ORIGINS) {
+ if (nu->pntsv == 1) {
+ copy_m3_m3(td->axismtx, axismtx);
+ }
+ }
td++;
count++;
@@ -1740,6 +1833,10 @@ static void createTransCurveVerts(TransInfo *t)
calc_distanceCurveVerts(head, tail - 1);
}
}
+
+#undef SEL_F1
+#undef SEL_F2
+#undef SEL_F3
}
/* ********************* lattice *************** */
@@ -2004,9 +2101,9 @@ static bool bmesh_test_dist_add(
}
/**
- * \parm mtx: Measure disatnce in this space.
- * \parm dists: Store the closest connected distance to selected vertices.
- * \parm index: Optionally store the original index we're measuring the distance to (can be NULL).
+ * \param mtx: Measure disatnce in this space.
+ * \param dists: Store the closest connected distance to selected vertices.
+ * \param index: Optionally store the original index we're measuring the distance to (can be NULL).
*/
static void editmesh_set_connectivity_distance(BMesh *bm, float mtx[3][3], float *dists, int *index)
{
@@ -2276,7 +2373,7 @@ static struct TransIslandData *editmesh_islands_info_calc(
}
if (group_tot_single != 0) {
- trans_islands = MEM_reallocN(trans_islands, group_tot + group_tot_single);
+ trans_islands = MEM_reallocN(trans_islands, sizeof(*trans_islands) * (group_tot + group_tot_single));
BM_ITER_MESH_INDEX (v, &viter, bm, BM_VERTS_OF_MESH, i) {
if (BM_elem_flag_test(v, BM_ELEM_SELECT) && (vert_map[i] == -1)) {
@@ -2398,7 +2495,8 @@ static void createTransEditVerts(TransInfo *t)
int island_info_tot;
int *island_vert_map = NULL;
- const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS) && (t->mode != TFM_TRANSLATION);
+ /* Even for translation this is needed because of island-orientation, see: T51651. */
+ const bool is_island_center = (t->around == V3D_AROUND_LOCAL_ORIGINS);
/* Original index of our connected vertex when connected distances are calculated.
* Optional, allocate if needed. */
int *dists_index = NULL;
@@ -2464,11 +2562,6 @@ static void createTransEditVerts(TransInfo *t)
editmesh_set_connectivity_distance(em->bm, mtx, dists, dists_index);
}
- /* Only in case of rotation and resize, we want the elements of the edited
- * object to behave as groups whose pivot are the individual origins
- *
- * TODO: use island_info to detect the closest point when the "Snap Target"
- * in Blender UI is "Closest" */
if (is_island_center) {
/* In this specific case, near-by vertices will need to know the island of the nearest connected vertex. */
const bool calc_single_islands = (
@@ -5349,7 +5442,8 @@ static void ObjectToTransData(TransInfo *t, TransData *td, Object *ob)
}
/* update object's loc/rot to get current rigid body transform */
mat4_to_loc_rot_size(ob->loc, rot, scale, ob->obmat);
- BKE_object_mat3_to_rot(ob, rot, false);
+ sub_v3_v3(ob->loc, ob->dloc);
+ BKE_object_mat3_to_rot(ob, rot, false); /* drot is already corrected here */
}
}
diff --git a/source/blender/editors/transform/transform_generics.c b/source/blender/editors/transform/transform_generics.c
index f78a23be7b8..c23da19f830 100644
--- a/source/blender/editors/transform/transform_generics.c
+++ b/source/blender/editors/transform/transform_generics.c
@@ -971,7 +971,7 @@ static void recalcData_sequencer(TransInfo *t)
/* force recalculation of triangles during transformation */
static void recalcData_gpencil_strokes(TransInfo *t)
- {
+{
TransData *td = t->data;
for (int i = 0; i < t->total; i++, td++) {
bGPDstroke *gps = td->extra;
diff --git a/source/blender/editors/transform/transform_input.c b/source/blender/editors/transform/transform_input.c
index 42cc918ec8c..5f2e5a99090 100644
--- a/source/blender/editors/transform/transform_input.c
+++ b/source/blender/editors/transform/transform_input.c
@@ -86,12 +86,11 @@ static void InputTrackBall(TransInfo *UNUSED(t), MouseInput *mi, const double mv
output[1] *= mi->factor;
}
-static void InputHorizontalRatio(TransInfo *t, MouseInput *UNUSED(mi), const double mval[2], float output[3])
+static void InputHorizontalRatio(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
{
const int winx = t->ar ? t->ar->winx : 1;
- const double pad = winx / 10;
- output[0] = (mval[0] - pad) / (winx - 2 * pad);
+ output[0] = ((mval[0] - mi->imval[0]) / winx) * 2.0f;
}
static void InputHorizontalAbsolute(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
@@ -104,12 +103,11 @@ static void InputHorizontalAbsolute(TransInfo *t, MouseInput *mi, const double m
output[0] = dot_v3v3(t->viewinv[0], vec) * 2.0f;
}
-static void InputVerticalRatio(TransInfo *t, MouseInput *UNUSED(mi), const double mval[2], float output[3])
+static void InputVerticalRatio(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
{
const int winy = t->ar ? t->ar->winy : 1;
- const double pad = winy / 10;
- output[0] = (mval[1] - pad) / (winy - 2 * pad);
+ output[0] = ((mval[1] - mi->imval[1]) / winy) * 2.0f;
}
static void InputVerticalAbsolute(TransInfo *t, MouseInput *mi, const double mval[2], float output[3])
@@ -187,7 +185,7 @@ static void InputAngle(TransInfo *UNUSED(t), MouseInput *mi, const double mval[2
/* use doubles here, to make sure a "1.0" (no rotation) doesn't become 9.999999e-01, which gives 0.02 for acos */
double deler = (((dx1 * dx1 + dy1 * dy1) +
(dx2 * dx2 + dy2 * dy2) -
- (dx3 * dx3 + dy3 * dy3)) / (2.0 * ((A * B) ? (A * B) : 1.0)));
+ (dx3 * dx3 + dy3 * dy3)) / (2.0 * (((A * B) != 0.0) ? (A * B) : 1.0)));
/* ((A * B) ? (A * B) : 1.0) this takes care of potential divide by zero errors */
float dphi;
@@ -314,7 +312,6 @@ void initMouseInputMode(TransInfo *t, MouseInput *mi, MouseInputMode mode)
t->helpline = HLP_TRACKBALL;
break;
case INPUT_HORIZONTAL_RATIO:
- mi->factor = (float)(mi->center[0] - mi->imval[0]);
mi->apply = InputHorizontalRatio;
t->helpline = HLP_HARROW;
break;
diff --git a/source/blender/editors/transform/transform_manipulator.c b/source/blender/editors/transform/transform_manipulator.c
index f23c913da1e..ec066ba91a4 100644
--- a/source/blender/editors/transform/transform_manipulator.c
+++ b/source/blender/editors/transform/transform_manipulator.c
@@ -619,7 +619,7 @@ static int calc_manipulator_stats(const bContext *C)
break;
}
/* if not gimbal, fall through to normal */
- /* fall-through */
+ ATTR_FALLTHROUGH;
}
case V3D_MANIP_NORMAL:
{
@@ -630,7 +630,7 @@ static int calc_manipulator_stats(const bContext *C)
break;
}
/* no break we define 'normal' as 'local' in Object mode */
- /* fall-through */
+ ATTR_FALLTHROUGH;
}
case V3D_MANIP_LOCAL:
{
@@ -1716,7 +1716,7 @@ void BIF_draw_manipulator(const bContext *C)
}
}
-static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], float hotspot)
+static int manipulator_selectbuf(Scene *scene, ScrArea *sa, ARegion *ar, const int mval[2], float hotspot)
{
View3D *v3d = sa->spacedata.first;
RegionView3D *rv3d = ar->regiondata;
@@ -1726,9 +1726,6 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
const bool is_picksel = true;
const bool do_passes = GPU_select_query_check_active();
- /* XXX check a bit later on this... (ton) */
- extern void view3d_winmatrix_set(ARegion *ar, View3D *v3d, const rcti *rect);
-
/* when looking through a selected camera, the manipulator can be at the
* exact same position as the view, skip so we don't break selection */
if (fabsf(mat4_to_scale(rv3d->twmat)) < 1e-7f)
@@ -1739,8 +1736,7 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
rect.ymin = mval[1] - hotspot;
rect.ymax = mval[1] + hotspot;
- view3d_winmatrix_set(ar, v3d, &rect);
- mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
+ ED_view3d_draw_setup_view(NULL, scene, ar, v3d, NULL, NULL, &rect);
if (do_passes)
GPU_select_begin(buffer, 64, &rect, GPU_SELECT_NEAREST_FIRST_PASS, 0);
@@ -1759,7 +1755,7 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
hits = GPU_select_end();
- if (do_passes) {
+ if (do_passes && (hits > 0)) {
GPU_select_begin(buffer, 64, &rect, GPU_SELECT_NEAREST_SECOND_PASS, hits);
/* do the drawing */
@@ -1775,8 +1771,7 @@ static int manipulator_selectbuf(ScrArea *sa, ARegion *ar, const int mval[2], fl
GPU_select_end();
}
- view3d_winmatrix_set(ar, v3d, NULL);
- mul_m4_m4m4(rv3d->persmat, rv3d->winmat, rv3d->viewmat);
+ ED_view3d_draw_setup_view(NULL, scene, ar, v3d, NULL, NULL, NULL);
if (hits == 1) return buffer[3];
else if (hits > 1) {
@@ -1841,6 +1836,7 @@ static const char *manipulator_get_operator_name(int man_val)
/* return 0; nothing happened */
int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
{
+ Scene *scene = CTX_data_scene(C);
ScrArea *sa = CTX_wm_area(C);
View3D *v3d = sa->spacedata.first;
ARegion *ar = CTX_wm_region(C);
@@ -1855,7 +1851,7 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
RNA_enum_set(op->ptr, "constraint_orientation", v3d->twmode);
// find the hotspots first test narrow hotspot
- val = manipulator_selectbuf(sa, ar, event->mval, 0.5f * (float)U.tw_hotspot);
+ val = manipulator_selectbuf(scene, sa, ar, event->mval, 0.5f * (float)U.tw_hotspot);
if (val) {
wmOperatorType *ot;
PointerRNA props_ptr;
@@ -1863,7 +1859,7 @@ int BIF_do_manipulator(bContext *C, const struct wmEvent *event, wmOperator *op)
const char *opname;
// drawflags still global, for drawing call above
- drawflags = manipulator_selectbuf(sa, ar, event->mval, 0.2f * (float)U.tw_hotspot);
+ drawflags = manipulator_selectbuf(scene, sa, ar, event->mval, 0.2f * (float)U.tw_hotspot);
if (drawflags == 0) drawflags = val;
/* Planar constraint doesn't make sense for rotation, give other keymaps a chance */
diff --git a/source/blender/editors/transform/transform_orientations.c b/source/blender/editors/transform/transform_orientations.c
index 674d2c376bb..54959304d72 100644
--- a/source/blender/editors/transform/transform_orientations.c
+++ b/source/blender/editors/transform/transform_orientations.c
@@ -455,14 +455,14 @@ void initTransformOrientation(bContext *C, TransInfo *t)
BLI_strncpy(t->spacename, IFACE_("gimbal"), sizeof(t->spacename));
break;
}
- /* fall-through */ /* no gimbal fallthrough to normal */
+ ATTR_FALLTHROUGH; /* no gimbal fallthrough to normal */
case V3D_MANIP_NORMAL:
if (obedit || (ob && ob->mode & OB_MODE_POSE)) {
BLI_strncpy(t->spacename, IFACE_("normal"), sizeof(t->spacename));
ED_getTransformOrientationMatrix(C, t->spacemtx, t->around);
break;
}
- /* fall-through */ /* we define 'normal' as 'local' in Object mode */
+ ATTR_FALLTHROUGH; /* we define 'normal' as 'local' in Object mode */
case V3D_MANIP_LOCAL:
BLI_strncpy(t->spacename, IFACE_("local"), sizeof(t->spacename));
@@ -817,15 +817,21 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
else if (ELEM(obedit->type, OB_CURVE, OB_SURF)) {
Curve *cu = obedit->data;
Nurb *nu = NULL;
- BezTriple *bezt = NULL;
int a;
ListBase *nurbs = BKE_curve_editNurbs_get(cu);
- if (activeOnly && BKE_curve_nurb_vert_active_get(cu, &nu, (void *)&bezt)) {
+ void *vert_act = NULL;
+ if (activeOnly && BKE_curve_nurb_vert_active_get(cu, &nu, &vert_act)) {
if (nu->type == CU_BEZIER) {
+ BezTriple *bezt = vert_act;
BKE_nurb_bezt_calc_normal(nu, bezt, normal);
BKE_nurb_bezt_calc_plane(nu, bezt, plane);
}
+ else {
+ BPoint *bp = vert_act;
+ BKE_nurb_bpoint_calc_normal(nu, bp, normal);
+ BKE_nurb_bpoint_calc_plane(nu, bp, plane);
+ }
}
else {
const bool use_handle = (cu->drawflag & CU_HIDE_HANDLES) == 0;
@@ -833,7 +839,7 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
for (nu = nurbs->first; nu; nu = nu->next) {
/* only bezier has a normal */
if (nu->type == CU_BEZIER) {
- bezt = nu->bezt;
+ BezTriple *bezt = nu->bezt;
a = nu->pntsu;
while (a--) {
short flag = 0;
@@ -885,6 +891,36 @@ int getTransformOrientation_ex(const bContext *C, float normal[3], float plane[3
bezt++;
}
}
+ else if (nu->bp && (nu->pntsv == 1)) {
+ BPoint *bp = nu->bp;
+ a = nu->pntsu;
+ while (a--) {
+ if (bp->f1 & SELECT) {
+ float tvec[3];
+
+ BPoint *bp_prev = BKE_nurb_bpoint_get_prev(nu, bp);
+ BPoint *bp_next = BKE_nurb_bpoint_get_next(nu, bp);
+
+ const bool is_prev_sel = bp_prev && (bp_prev->f1 & SELECT);
+ const bool is_next_sel = bp_next && (bp_next->f1 & SELECT);
+ if (is_prev_sel == false && is_next_sel == false) {
+ /* Isolated, add based on surrounding */
+ BKE_nurb_bpoint_calc_normal(nu, bp, tvec);
+ add_v3_v3(normal, tvec);
+ }
+ else if (is_next_sel) {
+ /* A segment, add the edge normal */
+ sub_v3_v3v3(tvec, bp->vec, bp_next->vec );
+ normalize_v3(tvec);
+ add_v3_v3(normal, tvec);
+ }
+
+ BKE_nurb_bpoint_calc_plane(nu, bp, tvec);
+ add_v3_v3(plane, tvec);
+ }
+ bp++;
+ }
+ }
}
}
diff --git a/source/blender/editors/transform/transform_snap_object.c b/source/blender/editors/transform/transform_snap_object.c
index b33528b4149..6c62c091a78 100644
--- a/source/blender/editors/transform/transform_snap_object.c
+++ b/source/blender/editors/transform/transform_snap_object.c
@@ -130,18 +130,150 @@ struct SnapObjectContext {
};
-static int dm_looptri_to_poly_index(DerivedMesh *dm, const MLoopTri *lt);
+/** \} */
/* -------------------------------------------------------------------- */
-/** \name Support for storing all depths, not just the first (raycast 'all')
+/** Common utilities
+* \{ */
+
+
+typedef void(*IterSnapObjsCallback)(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data);
+
+/**
+ * Walks through all objects in the scene to create the list of objets to snap.
*
- * This uses a list of #SnapObjectHitDepth structs.
+ * \param sctx: Snap context to store data.
+ * \param snap_select : from enum SnapSelect.
+ * \param obedit : Object Edited to use its coordinates of BMesh(if any) to do the snapping.
+ */
+static void iter_snap_objects(
+ SnapObjectContext *sctx,
+ const SnapSelect snap_select,
+ Object *obedit,
+ IterSnapObjsCallback sob_callback,
+ void *data)
+{
+ Base *base_act = sctx->scene->basact;
+ /* Need an exception for particle edit because the base is flagged with BA_HAS_RECALC_DATA
+ * which makes the loop skip it, even the derived mesh will never change
+ *
+ * To solve that problem, we do it first as an exception.
+ * */
+ if (base_act && base_act->object && base_act->object->mode & OB_MODE_PARTICLE_EDIT) {
+ sob_callback(sctx, false, base_act->object, base_act->object->obmat, data);
+ }
+
+ for (Base *base = sctx->scene->base.first; base != NULL; base = base->next) {
+ if ((BASE_VISIBLE_BGMODE(sctx->v3d_data.v3d, sctx->scene, base)) &&
+ (base->flag & (BA_HAS_RECALC_OB | BA_HAS_RECALC_DATA)) == 0 &&
+ !((snap_select == SNAP_NOT_SELECTED && (base->flag & (SELECT | BA_WAS_SEL))) ||
+ (snap_select == SNAP_NOT_ACTIVE && base == base_act)))
+ {
+ bool use_obedit;
+ Object *obj = base->object;
+ if (obj->transflag & OB_DUPLI) {
+ DupliObject *dupli_ob;
+ ListBase *lb = object_duplilist(sctx->bmain->eval_ctx, sctx->scene, obj);
+ for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) {
+ use_obedit = obedit && dupli_ob->ob->data == obedit->data;
+ sob_callback(sctx, use_obedit, use_obedit ? obedit : dupli_ob->ob, dupli_ob->mat, data);
+ }
+ free_object_duplilist(lb);
+ }
+
+ use_obedit = obedit && obj->data == obedit->data;
+ sob_callback(sctx, use_obedit, use_obedit ? obedit : obj, obj->obmat, data);
+ }
+ }
+}
+
+
+/**
+ * Generates a struct with the immutable parameters that will be used on all objects.
*
- * \{ */
+ * \param snap_to: Element to snap, Vertice, Edge or Face.
+ * \param view_proj: ORTHO or PERSP.
+ * Currently only works one at a time, but can eventually operate as flag.
+ *
+ * \param mval: Mouse coords.
+ * (When NULL, ray-casting is handled without any projection matrix correction.)
+ * \param ray_origin: ray_start before being moved toward the ray_normal at the distance from vew3d clip_min.
+ * \param ray_start: ray_origin moved for the start clipping plane (clip_min).
+ * \param ray_direction: Unit length direction of the ray.
+ * \param depth_range: distances of clipe plane min and clip plane max;
+ */
+static void snap_data_set(
+ SnapData *snapdata,
+ const ARegion *ar, const unsigned short snap_to, const enum eViewProj view_proj,
+ const float mval[2], const float ray_origin[3], const float ray_start[3],
+ const float ray_direction[3], const float depth_range[2])
+{
+ copy_m4_m4(snapdata->pmat, ((RegionView3D *)ar->regiondata)->persmat);
+ snapdata->win_half[0] = ar->winx / 2;
+ snapdata->win_half[1] = ar->winy / 2;
+ copy_v2_v2(snapdata->mval, mval);
+ snapdata->snap_to = snap_to;
+ copy_v3_v3(snapdata->ray_origin, ray_origin);
+ copy_v3_v3(snapdata->ray_start, ray_start);
+ copy_v3_v3(snapdata->ray_dir, ray_direction);
+ snapdata->view_proj = view_proj;
+ copy_v2_v2(snapdata->depth_range, depth_range);
+}
+
+
+MINLINE float depth_get(const float co[3], const float ray_start[3], const float ray_dir[3])
+{
+ float dvec[3];
+ sub_v3_v3v3(dvec, co, ray_start);
+ return dot_v3v3(dvec, ray_dir);
+}
+
+
+static bool walk_parent_bvhroot_cb(const BVHTreeAxisRange *bounds, void *userdata)
+{
+ BVHTreeRay *ray = userdata;
+ const float bbmin[3] = {bounds[0].min, bounds[1].min, bounds[2].min};
+ const float bbmax[3] = {bounds[0].max, bounds[1].max, bounds[2].max};
+ if (!isect_ray_aabb_v3_simple(ray->origin, ray->direction, bbmin, bbmax, &ray->radius, NULL)) {
+ ray->radius = -1;
+ }
+ return false;
+}
+
+
+static bool isect_ray_bvhroot_v3(struct BVHTree *tree, const float ray_start[3], const float ray_dir[3], float *depth)
+{
+ BVHTreeRay ray;
+ copy_v3_v3(ray.origin, ray_start);
+ copy_v3_v3(ray.direction, ray_dir);
+
+ BLI_bvhtree_walk_dfs(tree, walk_parent_bvhroot_cb, NULL, NULL, &ray);
+
+ if (ray.radius > 0) {
+ *depth = ray.radius;
+ return true;
+ }
+ else {
+ return false;
+ }
+}
+
+
+static int dm_looptri_to_poly_index(DerivedMesh *dm, const MLoopTri *lt);
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** \name Ray Cast Funcs
+* \{ */
+
+/* Store all ray-hits
+ * Support for storing all depths, not just the first (raycast 'all') */
-/* Store all ray-hits */
struct RayCastAll_Data {
void *bvhdata;
@@ -162,6 +294,7 @@ struct RayCastAll_Data {
bool retval;
};
+
static struct SnapObjectHitDepth *hit_depth_create(
const float depth, const float co[3], const float no[3], int index,
Object *ob, const float obmat[4][4], unsigned int ob_uuid)
@@ -229,57 +362,508 @@ static void raycast_all_cb(void *userdata, int index, const BVHTreeRay *ray, BVH
}
}
-/** \} */
+static bool raycastDerivedMesh(
+ SnapObjectContext *sctx,
+ const float ray_start[3], const float ray_dir[3],
+ Object *ob, DerivedMesh *dm, float obmat[4][4], const unsigned int ob_index,
+ /* read/write args */
+ float *ray_depth,
+ /* return args */
+ float r_loc[3], float r_no[3], int *r_index,
+ ListBase *r_hit_list)
+{
+ bool retval = false;
-/* -------------------------------------------------------------------- */
+ if (dm->getNumPolys(dm) == 0) {
+ return retval;
+ }
+
+ float imat[4][4];
+ float timat[3][3]; /* transpose inverse matrix for normals */
+ float ray_start_local[3], ray_normal_local[3];
+ float local_scale, local_depth, len_diff = 0.0f;
+
+ invert_m4_m4(imat, obmat);
+ transpose_m3_m4(timat, imat);
+
+ copy_v3_v3(ray_start_local, ray_start);
+ copy_v3_v3(ray_normal_local, ray_dir);
+
+ mul_m4_v3(imat, ray_start_local);
+ mul_mat3_m4_v3(imat, ray_normal_local);
+
+ /* local scale in normal direction */
+ local_scale = normalize_v3(ray_normal_local);
+ local_depth = *ray_depth;
+ if (local_depth != BVH_RAYCAST_DIST_MAX) {
+ local_depth *= local_scale;
+ }
+
+ /* Test BoundBox */
+ BoundBox *bb = BKE_object_boundbox_get(ob);
+ if (bb) {
+ /* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
+ if (!isect_ray_aabb_v3_simple(
+ ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], &len_diff, NULL))
+ {
+ return retval;
+ }
+ }
+
+ SnapObjectData_Mesh *sod = NULL;
+ BVHTreeFromMesh *treedata;
+
+ void **sod_p;
+ if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
+ sod = *sod_p;
+ }
+ else {
+ sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+ sod->sd.type = SNAP_MESH;
+ }
+
+ if (sod->bvh_trees[2] == NULL) {
+ sod->bvh_trees[2] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*treedata));
+ }
+
+ treedata = sod->bvh_trees[2];
+
+ if (treedata) {
+ /* the tree is owned by the DM and may have been freed since we last used! */
+ if (treedata->tree) {
+ if (treedata->cached && !bvhcache_has_tree(dm->bvhCache, treedata->tree)) {
+ free_bvhtree_from_mesh(treedata);
+ }
+ else {
+ if (!treedata->vert_allocated) {
+ treedata->vert = DM_get_vert_array(dm, &treedata->vert_allocated);
+ }
+ if (!treedata->loop_allocated) {
+ treedata->loop = DM_get_loop_array(dm, &treedata->loop_allocated);
+ }
+ if (!treedata->looptri_allocated) {
+ if (!sod->poly_allocated) {
+ sod->mpoly = DM_get_poly_array(dm, &sod->poly_allocated);
+ }
+ treedata->looptri = DM_get_looptri_array(
+ dm, treedata->vert,
+ sod->mpoly, dm->getNumPolys(dm),
+ treedata->loop, dm->getNumLoops(dm),
+ &treedata->looptri_allocated);
+ }
+ }
+ }
+
+ if (treedata->tree == NULL) {
+ bvhtree_from_mesh_looptri(treedata, dm, 0.0f, 4, 6);
+
+ if (treedata->tree == NULL) {
+ return retval;
+ }
+ }
+ }
+ else {
+ return retval;
+ }
+
+ /* Only use closer ray_start in case of ortho view! In perspective one, ray_start may already
+ * been *inside* boundbox, leading to snap failures (see T38409).
+ * Note also ar might be null (see T38435), in this case we assume ray_start is ok!
+ */
+ if (len_diff == 0.0f) { /* do_ray_start_correction */
+ /* We *need* a reasonably valid len_diff in this case.
+ * Get the distance to bvhtree root */
+ if (!isect_ray_bvhroot_v3(treedata->tree, ray_start_local, ray_normal_local, &len_diff))
+ {
+ return retval;
+ }
+ }
+ /* You need to make sure that ray_start is really far away,
+ * because even in the Orthografic view, in some cases,
+ * the ray can start inside the object (see T50486) */
+ if (len_diff > 400.0f) {
+ /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with
+ * very far away ray_start values (as returned in case of ortho view3d), see T38358.
+ */
+ len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */
+ madd_v3_v3fl(ray_start_local, ray_normal_local, len_diff);
+ local_depth -= len_diff;
+ }
+ else {
+ len_diff = 0.0f;
+ }
+ if (r_hit_list) {
+ struct RayCastAll_Data data;
+
+ data.bvhdata = treedata;
+ data.raycast_callback = treedata->raycast_callback;
+ data.obmat = obmat;
+ data.timat = timat;
+ data.len_diff = len_diff;
+ data.local_scale = local_scale;
+ data.ob = ob;
+ data.ob_uuid = ob_index;
+ data.hit_list = r_hit_list;
+ data.retval = retval;
+
+ BLI_bvhtree_ray_cast_all(
+ treedata->tree, ray_start_local, ray_normal_local, 0.0f,
+ *ray_depth, raycast_all_cb, &data);
+
+ retval = data.retval;
+ }
+ else {
+ BVHTreeRayHit hit = {.index = -1, .dist = local_depth};
+
+ if (BLI_bvhtree_ray_cast(
+ treedata->tree, ray_start_local, ray_normal_local, 0.0f,
+ &hit, treedata->raycast_callback, treedata) != -1)
+ {
+ hit.dist += len_diff;
+ hit.dist /= local_scale;
+ if (hit.dist <= *ray_depth) {
+ *ray_depth = hit.dist;
+ copy_v3_v3(r_loc, hit.co);
+
+ /* back to worldspace */
+ mul_m4_v3(obmat, r_loc);
+
+ if (r_no) {
+ copy_v3_v3(r_no, hit.no);
+ mul_m3_v3(timat, r_no);
+ normalize_v3(r_no);
+ }
+
+ retval = true;
+
+ if (r_index) {
+ *r_index = dm_looptri_to_poly_index(dm, &treedata->looptri[hit.index]);
+ }
+ }
+ }
+ }
+
+ return retval;
+}
+
+static bool raycastEditMesh(
+ SnapObjectContext *sctx,
+ const float ray_start[3], const float ray_dir[3],
+ Object *ob, BMEditMesh *em, float obmat[4][4], const unsigned int ob_index,
+ /* read/write args */
+ float *ray_depth,
+ /* return args */
+ float r_loc[3], float r_no[3], int *r_index,
+ ListBase *r_hit_list)
+{
+ bool retval = false;
+ if (em->bm->totface == 0) {
+ return retval;
+ }
+
+ SnapObjectData_EditMesh *sod = NULL;
+ BVHTreeFromEditMesh *treedata = NULL;
+
+ void **sod_p;
+ if (BLI_ghash_ensure_p(sctx->cache.object_map, ob, &sod_p)) {
+ sod = *sod_p;
+ }
+ else {
+ sod = *sod_p = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*sod));
+ sod->sd.type = SNAP_EDIT_MESH;
+ }
+
+ if (sod->bvh_trees[2] == NULL) {
+ sod->bvh_trees[2] = BLI_memarena_calloc(sctx->cache.mem_arena, sizeof(*treedata));
+ }
+ treedata = sod->bvh_trees[2];
+
+ if (treedata) {
+ if (treedata->tree == NULL) {
+ BLI_bitmap *elem_mask = NULL;
+ int looptri_num_active = -1;
+
+ if (sctx->callbacks.edit_mesh.test_face_fn) {
+ elem_mask = BLI_BITMAP_NEW(em->tottri, __func__);
+ looptri_num_active = BM_iter_mesh_bitmap_from_filter_tessface(
+ em->bm, elem_mask,
+ sctx->callbacks.edit_mesh.test_face_fn, sctx->callbacks.edit_mesh.user_data);
+ }
+ bvhtree_from_editmesh_looptri_ex(treedata, em, elem_mask, looptri_num_active, 0.0f, 4, 6, NULL);
+
+ if (elem_mask) {
+ MEM_freeN(elem_mask);
+ }
+ }
+ if (treedata->tree == NULL) {
+ return retval;
+ }
+ }
+ else {
+ return retval;
+ }
+
+ float imat[4][4];
+ float timat[3][3]; /* transpose inverse matrix for normals */
+ float ray_normal_local[3], ray_start_local[3], len_diff = 0.0f;
+
+ invert_m4_m4(imat, obmat);
+ transpose_m3_m4(timat, imat);
+
+ copy_v3_v3(ray_normal_local, ray_dir);
+ mul_mat3_m4_v3(imat, ray_normal_local);
+
+ copy_v3_v3(ray_start_local, ray_start);
+ mul_m4_v3(imat, ray_start_local);
+
+ /* local scale in normal direction */
+ float local_scale = normalize_v3(ray_normal_local);
+ float local_depth = *ray_depth;
+ if (local_depth != BVH_RAYCAST_DIST_MAX) {
+ local_depth *= local_scale;
+ }
+
+ /* Only use closer ray_start in case of ortho view! In perspective one, ray_start
+ * may already been *inside* boundbox, leading to snap failures (see T38409).
+ * Note also ar might be null (see T38435), in this case we assume ray_start is ok!
+ */
+ if (sctx->use_v3d && !((RegionView3D *)sctx->v3d_data.ar->regiondata)->is_persp) { /* do_ray_start_correction */
+ /* We *need* a reasonably valid len_diff in this case.
+ * Get the distance to bvhtree root */
+ if (!isect_ray_bvhroot_v3(treedata->tree, ray_start_local, ray_normal_local, &len_diff))
+ {
+ return retval;
+ }
+ /* You need to make sure that ray_start is really far away,
+ * because even in the Orthografic view, in some cases,
+ * the ray can start inside the object (see T50486) */
+ if (len_diff > 400.0f) {
+ /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with
+ * very far away ray_start values (as returned in case of ortho view3d), see T38358.
+ */
+ len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */
+ madd_v3_v3fl(ray_start_local, ray_normal_local, len_diff);
+ local_depth -= len_diff;
+ }
+ else len_diff = 0.0f;
+ }
+ if (r_hit_list) {
+ struct RayCastAll_Data data;
+
+ data.bvhdata = treedata;
+ data.raycast_callback = treedata->raycast_callback;
+ data.obmat = obmat;
+ data.timat = timat;
+ data.len_diff = len_diff;
+ data.local_scale = local_scale;
+ data.ob = ob;
+ data.ob_uuid = ob_index;
+ data.hit_list = r_hit_list;
+ data.retval = retval;
+
+ BLI_bvhtree_ray_cast_all(
+ treedata->tree, ray_start_local, ray_normal_local, 0.0f,
+ *ray_depth, raycast_all_cb, &data);
+
+ retval = data.retval;
+ }
+ else {
+ BVHTreeRayHit hit = {.index = -1, .dist = local_depth};
+
+ if (BLI_bvhtree_ray_cast(
+ treedata->tree, ray_start_local, ray_normal_local, 0.0f,
+ &hit, treedata->raycast_callback, treedata) != -1)
+ {
+ hit.dist += len_diff;
+ hit.dist /= local_scale;
+ if (hit.dist <= *ray_depth) {
+ *ray_depth = hit.dist;
+ copy_v3_v3(r_loc, hit.co);
+
+ /* back to worldspace */
+ mul_m4_v3(obmat, r_loc);
+
+ if (r_no) {
+ copy_v3_v3(r_no, hit.no);
+ mul_m3_v3(timat, r_no);
+ normalize_v3(r_no);
+ }
+
+ retval = true;
+
+ if (r_index) {
+ *r_index = hit.index;
+ }
+ }
+ }
+ }
+
+ return retval;
+}
-/** \Common utilities
- * \{ */
/**
- * Generates a struct with the immutable parameters that will be used on all objects.
- *
- * \param snap_to: Element to snap, Vertice, Edge or Face.
- * \param view_proj: ORTHO or PERSP.
- * Currently only works one at a time, but can eventually operate as flag.
+ * \param use_obedit: Uses the coordinates of BMesh (if any) to do the snapping;
*
- * \param mval: Mouse coords.
- * (When NULL, ray-casting is handled without any projection matrix correction.)
- * \param ray_origin: ray_start before being moved toward the ray_normal at the distance from vew3d clip_min.
- * \param ray_start: ray_origin moved for the start clipping plane (clip_min).
- * \param ray_direction: Unit length direction of the ray.
- * \param depth_range: distances of clipe plane min and clip plane max;
+ * \note Duplicate args here are documented at #snapObjectsRay
*/
-static void snap_data_set(
- SnapData *snapdata,
- const ARegion *ar, const unsigned short snap_to, const enum eViewProj view_proj,
- const float mval[2], const float ray_origin[3], const float ray_start[3],
- const float ray_direction[3], const float depth_range[2])
+static bool raycastObj(
+ SnapObjectContext *sctx,
+ const float ray_start[3], const float ray_dir[3],
+ Object *ob, float obmat[4][4], const unsigned int ob_index,
+ bool use_obedit,
+ /* read/write args */
+ float *ray_depth,
+ /* return args */
+ float r_loc[3], float r_no[3], int *r_index,
+ Object **r_ob, float r_obmat[4][4],
+ ListBase *r_hit_list)
{
- if (ar) {
- copy_m4_m4(snapdata->pmat, ((RegionView3D *)ar->regiondata)->persmat);
- snapdata->win_half[0] = ar->winx / 2;
- snapdata->win_half[1] = ar->winy / 2;
+ bool retval = false;
+
+ if (ob->type == OB_MESH) {
+ BMEditMesh *em;
+
+ if (use_obedit) {
+ em = BKE_editmesh_from_object(ob);
+ retval = raycastEditMesh(
+ sctx,
+ ray_start, ray_dir,
+ ob, em, obmat, ob_index,
+ ray_depth, r_loc, r_no, r_index, r_hit_list);
+ }
+ else {
+ /* in this case we want the mesh from the editmesh, avoids stale data. see: T45978.
+ * still set the 'em' to NULL, since we only want the 'dm'. */
+ DerivedMesh *dm;
+ em = BKE_editmesh_from_object(ob);
+ if (em) {
+ editbmesh_get_derived_cage_and_final(sctx->scene, ob, em, CD_MASK_BAREMESH, &dm);
+ }
+ else {
+ dm = mesh_get_derived_final(sctx->scene, ob, CD_MASK_BAREMESH);
+ }
+ retval = raycastDerivedMesh(
+ sctx,
+ ray_start, ray_dir,
+ ob, dm, obmat, ob_index,
+ ray_depth, r_loc, r_no, r_index, r_hit_list);
+
+ dm->release(dm);
+ }
}
- if (mval) {
- copy_v2_v2(snapdata->mval, mval);
+
+ if (retval) {
+ if (r_ob) {
+ *r_ob = ob;
+ copy_m4_m4(r_obmat, obmat);
+ }
}
- snapdata->snap_to = snap_to;
- copy_v3_v3(snapdata->ray_origin, ray_origin);
- copy_v3_v3(snapdata->ray_start, ray_start);
- copy_v3_v3(snapdata->ray_dir, ray_direction);
- snapdata->view_proj = view_proj;
- copy_v2_v2(snapdata->depth_range, depth_range);
+
+ return retval;
}
-MINLINE float depth_get(const float co[3], const float ray_start[3], const float ray_dir[3])
+
+struct RaycastObjUserData {
+ const float *ray_start;
+ const float *ray_dir;
+ unsigned int ob_index;
+ /* read/write args */
+ float *ray_depth;
+ /* return args */
+ float *r_loc;
+ float *r_no;
+ int *r_index;
+ Object **r_ob;
+ float (*r_obmat)[4];
+ ListBase *r_hit_list;
+ bool ret;
+};
+
+static void raycast_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data)
{
- float dvec[3];
- sub_v3_v3v3(dvec, co, ray_start);
- return dot_v3v3(dvec, ray_dir);
+ struct RaycastObjUserData *dt = data;
+ dt->ret |= raycastObj(
+ sctx,
+ dt->ray_start, dt->ray_dir,
+ ob, obmat, dt->ob_index++, is_obedit,
+ dt->ray_depth,
+ dt->r_loc, dt->r_no, dt->r_index,
+ dt->r_ob, dt->r_obmat,
+ dt->r_hit_list);
+}
+
+/**
+ * Main RayCast Function
+ * ======================
+ *
+ * Walks through all objects in the scene to find the `hit` on object surface.
+ *
+ * \param sctx: Snap context to store data.
+ * \param snapdata: struct generated in `set_snapdata`.
+ * \param snap_select : from enum SnapSelect.
+ * \param use_object_edit_cage : Uses the coordinates of BMesh(if any) to do the snapping.
+ * \param obj_list: List with objects to snap (created in `create_object_list`).
+ *
+ * Read/Write Args
+ * ---------------
+ *
+ * \param ray_depth: maximum depth allowed for r_co, elements deeper than this value will be ignored.
+ *
+ * Output Args
+ * -----------
+ *
+ * \param r_loc: Hit location.
+ * \param r_no: Hit normal (optional).
+ * \param r_index: Hit index or -1 when no valid index is found.
+ * (currently only set to the polygon index when when using ``snap_to == SCE_SNAP_MODE_FACE``).
+ * \param r_ob: Hit object.
+ * \param r_obmat: Object matrix (may not be #Object.obmat with dupli-instances).
+ * \param r_hit_list: List of #SnapObjectHitDepth (caller must free).
+ *
+ */
+static bool raycastObjects(
+ SnapObjectContext *sctx,
+ const float ray_start[3], const float ray_dir[3],
+ const SnapSelect snap_select, const bool use_object_edit_cage,
+ /* read/write args */
+ float *ray_depth,
+ /* return args */
+ float r_loc[3], float r_no[3], int *r_index,
+ Object **r_ob, float r_obmat[4][4],
+ ListBase *r_hit_list)
+{
+ Object *obedit = use_object_edit_cage ? sctx->scene->obedit : NULL;
+
+ struct RaycastObjUserData data = {
+ .ray_start = ray_start,
+ .ray_dir = ray_dir,
+ .ob_index = 0,
+ .ray_depth = ray_depth,
+ .r_loc = r_loc,
+ .r_no = r_no,
+ .r_index = r_index,
+ .r_ob = r_ob,
+ .r_obmat = r_obmat,
+ .r_hit_list = r_hit_list,
+ .ret = false,
+ };
+
+ iter_snap_objects(sctx, snap_select, obedit, raycast_obj_cb, &data);
+
+ return data.ret;
}
+
+/** \} */
+
+
+/* -------------------------------------------------------------------- */
+
+/** Snap Nearest utilities
+ * \{ */
+
static void copy_dm_vert_no(const int index, float r_no[3], const BVHTreeFromMesh *data)
{
const MVert *vert = data->vert + index;
@@ -558,15 +1142,12 @@ static float dist_squared_to_projected_aabb(
vb2d[0] *= data->win_half[0];
vb2d[1] *= data->win_half[1];
- //float dvec[2], edge[2], rdist;
- //sub_v2_v2v2(dvec, data->mval, va2d);
- //sub_v2_v2v2(edge, vb2d, va2d);
- float rdist;
- short dvec[2] = {data->mval[0] - va2d[0], data->mval[1] - va2d[1]};
- short edge[2] = {vb2d[0] - va2d[0], vb2d[1] - va2d[1]};
- float lambda = dvec[0] * edge[0] + dvec[1] * edge[1];
+ float dvec[2], edge[2], lambda, rdist;
+ sub_v2_v2v2(dvec, data->mval, va2d);
+ sub_v2_v2v2(edge, vb2d, va2d);
+ lambda = dot_v2v2(dvec, edge);
if (lambda != 0.0f) {
- lambda /= edge[0] * edge[0] + edge[1] * edge[1];
+ lambda /= len_squared_v2(edge);
if (lambda <= 0.0f) {
rdist = len_squared_v2v2(data->mval, va2d);
r_axis_closest[main_axis] = true;
@@ -603,24 +1184,12 @@ static float dist_squared_to_projected_aabb_simple(
return dist_squared_to_projected_aabb(&data, bbmin, bbmax, dummy);
}
-static float dist_aabb_to_plane(
- const float bbmin[3], const float bbmax[3],
- const float plane_co[3], const float plane_no[3])
-{
- const float local_bvmin[3] = {
- (plane_no[0] < 0) ? bbmax[0] : bbmin[0],
- (plane_no[1] < 0) ? bbmax[1] : bbmin[1],
- (plane_no[2] < 0) ? bbmax[2] : bbmin[2],
- };
- return depth_get(local_bvmin, plane_co, plane_no);
-}
-
/** \} */
/* -------------------------------------------------------------------- */
-/** \Walk DFS
+/** Walk DFS
* \{ */
typedef void (*Nearest2DGetEdgeVertsCallback)(const int index, const float *v_pair[2], void *data);
@@ -1053,21 +1622,15 @@ static int dm_looptri_to_poly_index(DerivedMesh *dm, const MLoopTri *lt)
static bool snapDerivedMesh(
SnapObjectContext *sctx, SnapData *snapdata,
- Object *ob, DerivedMesh *dm, float obmat[4][4], const unsigned int ob_index,
+ Object *ob, DerivedMesh *dm, float obmat[4][4],
/* read/write args */
float *ray_depth, float *dist_px,
/* return args */
- float r_loc[3], float r_no[3], int *r_index,
- ListBase *r_hit_list)
+ float r_loc[3], float r_no[3])
{
bool retval = false;
- if (snapdata->snap_to == SCE_SNAP_MODE_FACE) {
- if (dm->getNumPolys(dm) == 0) {
- return retval;
- }
- }
- else if (snapdata->snap_to == SCE_SNAP_MODE_EDGE) {
+ if (snapdata->snap_to == SCE_SNAP_MODE_EDGE) {
if (dm->getNumEdges(dm) == 0) {
return retval;
}
@@ -1078,38 +1641,27 @@ static bool snapDerivedMesh(
}
}
- bool need_ray_start_correction_init =
- (snapdata->snap_to == SCE_SNAP_MODE_FACE) &&
- (snapdata->view_proj == VIEW_PROJ_ORTHO);
-
float imat[4][4];
float timat[3][3]; /* transpose inverse matrix for normals */
- float ray_start_local[3], ray_normal_local[3];
- float local_scale, local_depth, len_diff;
+ float ray_normal_local[3];
+ float local_scale;
invert_m4_m4(imat, obmat);
transpose_m3_m4(timat, imat);
- copy_v3_v3(ray_start_local, snapdata->ray_start);
copy_v3_v3(ray_normal_local, snapdata->ray_dir);
- mul_m4_v3(imat, ray_start_local);
mul_mat3_m4_v3(imat, ray_normal_local);
/* local scale in normal direction */
local_scale = normalize_v3(ray_normal_local);
- local_depth = *ray_depth;
- if (local_depth != BVH_RAYCAST_DIST_MAX) {
- local_depth *= local_scale;
- }
float lpmat[4][4];
float ray_org_local[3];
float ray_min_dist;
- if (ELEM(snapdata->snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) {
- mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
- ray_min_dist = snapdata->depth_range[0] * local_scale;
- }
+
+ mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
+ ray_min_dist = snapdata->depth_range[0] * local_scale;
copy_v3_v3(ray_org_local, snapdata->ray_origin);
mul_m4_v3(imat, ray_org_local);
@@ -1118,26 +1670,12 @@ static bool snapDerivedMesh(
BoundBox *bb = BKE_object_boundbox_get(ob);
if (bb) {
/* In vertex and edges you need to get the pixel distance from ray to BoundBox, see: T46099, T46816 */
- if (ELEM(snapdata->snap_to, SCE_SNAP_MODE_VERTEX, SCE_SNAP_MODE_EDGE)) {
- float dist_px_sq = dist_squared_to_projected_aabb_simple(
- lpmat, snapdata->win_half, ray_min_dist, snapdata->mval,
- ray_org_local, ray_normal_local, bb->vec[0], bb->vec[6]);
- if (dist_px_sq > SQUARE(*dist_px)) {
- return retval;
- }
- }
- else {
- /* was BKE_boundbox_ray_hit_check, see: cf6ca226fa58 */
- if (!isect_ray_aabb_v3_simple(
- ray_start_local, ray_normal_local, bb->vec[0], bb->vec[6], NULL, NULL))
- {
- return retval;
- }
+ float dist_px_sq = dist_squared_to_projected_aabb_simple(
+ lpmat, snapdata->win_half, ray_min_dist, snapdata->mval,
+ ray_org_local, ray_normal_local, bb->vec[0], bb->vec[6]);
+ if (dist_px_sq > SQUARE(*dist_px)) {
+ return retval;
}
- /* was local_depth, see: T47838 */
- len_diff = dist_aabb_to_plane(bb->vec[0], bb->vec[6], ray_start_local, ray_normal_local);
- if (len_diff < 0) len_diff = 0.0f;
- need_ray_start_correction_init = false;
}
SnapObjectData_Mesh *sod = NULL;
@@ -1154,9 +1692,6 @@ static bool snapDerivedMesh(
int tree_index = -1;
switch (snapdata->snap_to) {
- case SCE_SNAP_MODE_FACE:
- tree_index = 2;
- break;
case SCE_SNAP_MODE_EDGE:
tree_index = 1;
break;
@@ -1180,179 +1715,71 @@ static bool snapDerivedMesh(
treedata->vert = DM_get_vert_array(dm, &treedata->vert_allocated);
}
if ((tree_index == 1) && !treedata->edge_allocated) {
- treedata->edge = DM_get_edge_array(dm, &treedata->vert_allocated);
- }
- if (tree_index == 2) {
- if (!treedata->loop_allocated) {
- treedata->loop = DM_get_loop_array(dm, &treedata->loop_allocated);
- }
- if (!treedata->looptri_allocated) {
- if (!sod->poly_allocated) {
- sod->mpoly = DM_get_poly_array(dm, &sod->poly_allocated);
- }
- treedata->looptri = DM_get_looptri_array(
- dm, treedata->vert,
- sod->mpoly, dm->getNumPolys(dm),
- treedata->loop, dm->getNumLoops(dm),
- &treedata->looptri_allocated);
- }
+ treedata->edge = DM_get_edge_array(dm, &treedata->edge_allocated);
}
}
}
}
- if (treedata && treedata->tree == NULL) {
- switch (snapdata->snap_to) {
- case SCE_SNAP_MODE_FACE:
- bvhtree_from_mesh_looptri(treedata, dm, 0.0f, 4, 6);
- break;
- case SCE_SNAP_MODE_EDGE:
- bvhtree_from_mesh_edges(treedata, dm, 0.0f, 2, 6);
- break;
- case SCE_SNAP_MODE_VERTEX:
- bvhtree_from_mesh_verts(treedata, dm, 0.0f, 2, 6);
- break;
+ if (treedata) {
+ if (treedata->tree == NULL) {
+ switch (snapdata->snap_to) {
+ case SCE_SNAP_MODE_EDGE:
+ bvhtree_from_mesh_edges(treedata, dm, 0.0f, 2, 6);
+ break;
+ case SCE_SNAP_MODE_VERTEX:
+ bvhtree_from_mesh_verts(treedata, dm, 0.0f, 2, 6);
+ break;
+ }
+ }
+ if (treedata->tree == NULL) {
+ return retval;
}
}
- if (!treedata || !treedata->tree) {
+ else {
return retval;
}
- if (snapdata->snap_to == SCE_SNAP_MODE_FACE) {
- /* Only use closer ray_start in case of ortho view! In perspective one, ray_start may already
- * been *inside* boundbox, leading to snap failures (see T38409).
- * Note also ar might be null (see T38435), in this case we assume ray_start is ok!
- */
- if (snapdata->view_proj == VIEW_PROJ_ORTHO) { /* do_ray_start_correction */
- if (need_ray_start_correction_init) {
- /* We *need* a reasonably valid len_diff in this case.
- * Use BHVTree to find the closest face from ray_start_local.
- */
- BVHTreeNearest nearest;
- nearest.index = -1;
- nearest.dist_sq = FLT_MAX;
- /* Compute and store result. */
- BLI_bvhtree_find_nearest(
- treedata->tree, ray_start_local, &nearest, treedata->nearest_callback, treedata);
- if (nearest.index != -1) {
- float dvec[3];
- sub_v3_v3v3(dvec, nearest.co, ray_start_local);
- len_diff = dot_v3v3(dvec, ray_normal_local);
- }
- }
- /* You need to make sure that ray_start is really far away,
- * because even in the Orthografic view, in some cases,
- * the ray can start inside the object (see T50486) */
- if (len_diff > 400.0f) {
- /* We pass a temp ray_start, set from object's boundbox, to avoid precision issues with
- * very far away ray_start values (as returned in case of ortho view3d), see T38358.
- */
- len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */
- madd_v3_v3v3fl(
- ray_start_local, ray_org_local, ray_normal_local,
- len_diff + snapdata->depth_range[0] * local_scale);
- local_depth -= len_diff;
- }
- else len_diff = 0.0f;
- }
- else {
- len_diff = 0.0f;
- }
- if (r_hit_list) {
- struct RayCastAll_Data data;
-
- data.bvhdata = treedata;
- data.raycast_callback = treedata->raycast_callback;
- data.obmat = obmat;
- data.timat = timat;
- data.len_diff = len_diff;
- data.local_scale = local_scale;
- data.ob = ob;
- data.ob_uuid = ob_index;
- data.hit_list = r_hit_list;
- data.retval = retval;
-
- BLI_bvhtree_ray_cast_all(
- treedata->tree, ray_start_local, ray_normal_local, 0.0f,
- *ray_depth, raycast_all_cb, &data);
-
- retval = data.retval;
- }
- else {
- BVHTreeRayHit hit = {.index = -1, .dist = local_depth};
+ /* Warning: the depth_max is currently being used only in perspective view.
+ * It is not correct to limit the maximum depth for elements obtained with nearest
+ * since this limitation depends on the normal and the size of the occlusion face.
+ * And more... ray_depth is being confused with Z-depth here... (varies only the precision) */
+ const float ray_depth_max_global = *ray_depth + snapdata->depth_range[0];
- if (BLI_bvhtree_ray_cast(
- treedata->tree, ray_start_local, ray_normal_local, 0.0f,
- &hit, treedata->raycast_callback, treedata) != -1)
- {
- hit.dist += len_diff;
- hit.dist /= local_scale;
- if (hit.dist <= *ray_depth) {
- *ray_depth = hit.dist;
- copy_v3_v3(r_loc, hit.co);
-
- /* back to worldspace */
- mul_m4_v3(obmat, r_loc);
-
- if (r_no) {
- copy_v3_v3(r_no, hit.no);
- mul_m3_v3(timat, r_no);
- normalize_v3(r_no);
- }
+ Nearest2dUserData neasrest2d = {
+ .dist_px_sq = SQUARE(*dist_px),
+ .r_axis_closest = {1.0f, 1.0f, 1.0f},
+ .depth_range = {snapdata->depth_range[0], ray_depth_max_global},
+ .userdata = treedata,
+ .get_edge_verts = (Nearest2DGetEdgeVertsCallback)get_dm_edge_verts,
+ .copy_vert_no = (Nearest2DCopyVertNoCallback)copy_dm_vert_no,
+ .index = -1};
- retval = true;
+ dist_squared_to_projected_aabb_precalc(
+ &neasrest2d.data_precalc, lpmat,
+ snapdata->view_proj == VIEW_PROJ_PERSP, snapdata->win_half,
+ ray_min_dist, snapdata->mval, ray_org_local, ray_normal_local);
- if (r_index) {
- *r_index = dm_looptri_to_poly_index(dm, &treedata->looptri[hit.index]);
- }
- }
- }
- }
- }
- /* SCE_SNAP_MODE_VERTEX or SCE_SNAP_MODE_EDGE */
- else {
+ BVHTree_WalkLeafCallback cb_walk_leaf =
+ (snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ?
+ cb_walk_leaf_snap_vert : cb_walk_leaf_snap_edge;
- /* Warning: the depth_max is currently being used only in perspective view.
- * It is not correct to limit the maximum depth for elements obtained with nearest
- * since this limitation depends on the normal and the size of the occlusion face.
- * And more... ray_depth is being confused with Z-depth here... (varies only the precision) */
- const float ray_depth_max_global = *ray_depth + snapdata->depth_range[0];
-
- Nearest2dUserData neasrest2d = {
- .dist_px_sq = SQUARE(*dist_px),
- .r_axis_closest = {1.0f, 1.0f, 1.0f},
- .depth_range = {snapdata->depth_range[0], ray_depth_max_global},
- .userdata = treedata,
- .get_edge_verts = (Nearest2DGetEdgeVertsCallback)get_dm_edge_verts,
- .copy_vert_no = (Nearest2DCopyVertNoCallback)copy_dm_vert_no,
- .index = -1};
-
- dist_squared_to_projected_aabb_precalc(
- &neasrest2d.data_precalc, lpmat,
- snapdata->view_proj == VIEW_PROJ_PERSP, snapdata->win_half,
- ray_min_dist, snapdata->mval, ray_org_local, ray_normal_local);
-
- BVHTree_WalkLeafCallback cb_walk_leaf =
- (snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ?
- cb_walk_leaf_snap_vert : cb_walk_leaf_snap_edge;
-
- BLI_bvhtree_walk_dfs(
- treedata->tree,
- cb_walk_parent_snap_project, cb_walk_leaf, cb_nearest_walk_order, &neasrest2d);
-
- if (neasrest2d.index != -1) {
- copy_v3_v3(r_loc, neasrest2d.co);
- mul_m4_v3(obmat, r_loc);
- if (r_no) {
- copy_v3_v3(r_no, neasrest2d.no);
- mul_m3_v3(timat, r_no);
- normalize_v3(r_no);
- }
- *dist_px = sqrtf(neasrest2d.dist_px_sq);
- *ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir);
+ BLI_bvhtree_walk_dfs(
+ treedata->tree,
+ cb_walk_parent_snap_project, cb_walk_leaf, cb_nearest_walk_order, &neasrest2d);
- retval = true;
+ if (neasrest2d.index != -1) {
+ copy_v3_v3(r_loc, neasrest2d.co);
+ mul_m4_v3(obmat, r_loc);
+ if (r_no) {
+ copy_v3_v3(r_no, neasrest2d.no);
+ mul_m3_v3(timat, r_no);
+ normalize_v3(r_no);
}
+ *dist_px = sqrtf(neasrest2d.dist_px_sq);
+ *ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir);
+
+ retval = true;
}
return retval;
@@ -1360,20 +1787,14 @@ static bool snapDerivedMesh(
static bool snapEditMesh(
SnapObjectContext *sctx, SnapData *snapdata,
- Object *ob, BMEditMesh *em, float obmat[4][4], const unsigned int ob_index,
+ Object *ob, BMEditMesh *em, float obmat[4][4],
/* read/write args */
float *ray_depth, float *dist_px,
/* return args */
- float r_loc[3], float r_no[3], int *r_index,
- ListBase *r_hit_list)
+ float r_loc[3], float r_no[3])
{
bool retval = false;
- if (snapdata->snap_to == SCE_SNAP_MODE_FACE) {
- if (em->bm->totface == 0) {
- return retval;
- }
- }
if (snapdata->snap_to == SCE_SNAP_MODE_EDGE) {
if (em->bm->totedge == 0) {
return retval;
@@ -1398,13 +1819,8 @@ static bool snapEditMesh(
/* local scale in normal direction */
float local_scale = normalize_v3(ray_normal_local);
- float local_depth = *ray_depth;
- if (local_depth != BVH_RAYCAST_DIST_MAX) {
- local_depth *= local_scale;
- }
SnapObjectData_EditMesh *sod = NULL;
-
BVHTreeFromEditMesh *treedata = NULL;
void **sod_p;
@@ -1418,9 +1834,6 @@ static bool snapEditMesh(
int tree_index = -1;
switch (snapdata->snap_to) {
- case SCE_SNAP_MODE_FACE:
- tree_index = 2;
- break;
case SCE_SNAP_MODE_EDGE:
tree_index = 1;
break;
@@ -1435,197 +1848,90 @@ static bool snapEditMesh(
treedata = sod->bvh_trees[tree_index];
}
- if (treedata && treedata->tree == NULL) {
- BLI_bitmap *elem_mask = NULL;
- switch (snapdata->snap_to) {
- case SCE_SNAP_MODE_FACE:
- {
- int looptri_num_active = -1;
- if (sctx->callbacks.edit_mesh.test_face_fn) {
- elem_mask = BLI_BITMAP_NEW(em->tottri, __func__);
- looptri_num_active = BM_iter_mesh_bitmap_from_filter_tessface(
- em->bm, elem_mask,
- sctx->callbacks.edit_mesh.test_face_fn, sctx->callbacks.edit_mesh.user_data);
+ if (treedata) {
+ if (treedata->tree == NULL) {
+ BLI_bitmap *elem_mask = NULL;
+ switch (snapdata->snap_to) {
+ case SCE_SNAP_MODE_EDGE:
+ {
+ int edges_num_active = -1;
+ if (sctx->callbacks.edit_mesh.test_edge_fn) {
+ elem_mask = BLI_BITMAP_NEW(em->bm->totedge, __func__);
+ edges_num_active = BM_iter_mesh_bitmap_from_filter(
+ BM_EDGES_OF_MESH, em->bm, elem_mask,
+ (bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_edge_fn,
+ sctx->callbacks.edit_mesh.user_data);
+ }
+ bvhtree_from_editmesh_edges_ex(treedata, em, elem_mask, edges_num_active, 0.0f, 2, 6);
+ break;
}
- bvhtree_from_editmesh_looptri_ex(treedata, em, elem_mask, looptri_num_active, 0.0f, 4, 6, NULL);
- break;
- }
- case SCE_SNAP_MODE_EDGE:
- {
- int edges_num_active = -1;
- if (sctx->callbacks.edit_mesh.test_edge_fn) {
- elem_mask = BLI_BITMAP_NEW(em->bm->totedge, __func__);
- edges_num_active = BM_iter_mesh_bitmap_from_filter(
- BM_EDGES_OF_MESH, em->bm, elem_mask,
- (bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_edge_fn,
- sctx->callbacks.edit_mesh.user_data);
+ case SCE_SNAP_MODE_VERTEX:
+ {
+ int verts_num_active = -1;
+ if (sctx->callbacks.edit_mesh.test_vert_fn) {
+ elem_mask = BLI_BITMAP_NEW(em->bm->totvert, __func__);
+ verts_num_active = BM_iter_mesh_bitmap_from_filter(
+ BM_VERTS_OF_MESH, em->bm, elem_mask,
+ (bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_vert_fn,
+ sctx->callbacks.edit_mesh.user_data);
+ }
+ bvhtree_from_editmesh_verts_ex(treedata, em, elem_mask, verts_num_active, 0.0f, 2, 6);
+ break;
}
- bvhtree_from_editmesh_edges_ex(treedata, em, elem_mask, edges_num_active, 0.0f, 2, 6);
- break;
}
- case SCE_SNAP_MODE_VERTEX:
- {
- int verts_num_active = -1;
- if (sctx->callbacks.edit_mesh.test_vert_fn) {
- elem_mask = BLI_BITMAP_NEW(em->bm->totvert, __func__);
- verts_num_active = BM_iter_mesh_bitmap_from_filter(
- BM_VERTS_OF_MESH, em->bm, elem_mask,
- (bool (*)(BMElem *, void *))sctx->callbacks.edit_mesh.test_vert_fn,
- sctx->callbacks.edit_mesh.user_data);
- }
- bvhtree_from_editmesh_verts_ex(treedata, em, elem_mask, verts_num_active, 0.0f, 2, 6);
- break;
+ if (elem_mask) {
+ MEM_freeN(elem_mask);
}
}
- if (elem_mask) {
- MEM_freeN(elem_mask);
+ if (treedata->tree == NULL) {
+ return retval;
}
}
-
- if (!treedata || !treedata->tree) {
+ else {
return retval;
}
- if (snapdata->snap_to == SCE_SNAP_MODE_FACE) {
- float ray_start_local[3];
- copy_v3_v3(ray_start_local, snapdata->ray_start);
- mul_m4_v3(imat, ray_start_local);
+ float ray_org_local[3];
+ copy_v3_v3(ray_org_local, snapdata->ray_origin);
+ mul_m4_v3(imat, ray_org_local);
- /* Only use closer ray_start in case of ortho view! In perspective one, ray_start
- * may already been *inside* boundbox, leading to snap failures (see T38409).
- * Note also ar might be null (see T38435), in this case we assume ray_start is ok!
- */
- float len_diff = 0.0f;
- if (snapdata->view_proj == VIEW_PROJ_ORTHO) { /* do_ray_start_correction */
- /* We *need* a reasonably valid len_diff in this case.
- * Use BHVTree to find the closest face from ray_start_local.
- */
- BVHTreeNearest nearest;
- nearest.index = -1;
- nearest.dist_sq = FLT_MAX;
- /* Compute and store result. */
- if (BLI_bvhtree_find_nearest(
- treedata->tree, ray_start_local, &nearest, NULL, NULL) != -1)
- {
- float dvec[3];
- sub_v3_v3v3(dvec, nearest.co, ray_start_local);
- len_diff = dot_v3v3(dvec, ray_normal_local);
- /* You need to make sure that ray_start is really far away,
- * because even in the Orthografic view, in some cases,
- * the ray can start inside the object (see T50486) */
- if (len_diff > 400.0f) {
- float ray_org_local[3];
-
- copy_v3_v3(ray_org_local, snapdata->ray_origin);
- mul_m4_v3(imat, ray_org_local);
-
- /* We pass a temp ray_start, set from object's boundbox,
- * to avoid precision issues with very far away ray_start values
- * (as returned in case of ortho view3d), see T38358.
- */
- len_diff -= local_scale; /* make temp start point a bit away from bbox hit point. */
- madd_v3_v3v3fl(
- ray_start_local, ray_org_local, ray_normal_local,
- len_diff + snapdata->depth_range[0] * local_scale);
- local_depth -= len_diff;
- }
- else len_diff = 0.0f;
- }
- }
- if (r_hit_list) {
- struct RayCastAll_Data data;
-
- data.bvhdata = treedata;
- data.raycast_callback = treedata->raycast_callback;
- data.obmat = obmat;
- data.timat = timat;
- data.len_diff = len_diff;
- data.local_scale = local_scale;
- data.ob = ob;
- data.ob_uuid = ob_index;
- data.hit_list = r_hit_list;
- data.retval = retval;
-
- BLI_bvhtree_ray_cast_all(
- treedata->tree, ray_start_local, ray_normal_local, 0.0f,
- *ray_depth, raycast_all_cb, &data);
-
- retval = data.retval;
- }
- else {
- BVHTreeRayHit hit = {.index = -1, .dist = local_depth};
+ Nearest2dUserData neasrest2d = {
+ .dist_px_sq = SQUARE(*dist_px),
+ .r_axis_closest = {1.0f, 1.0f, 1.0f},
+ .depth_range = {snapdata->depth_range[0], *ray_depth + snapdata->depth_range[0]},
+ .userdata = treedata,
+ .get_edge_verts = (Nearest2DGetEdgeVertsCallback)get_bedge_verts,
+ .copy_vert_no = (Nearest2DCopyVertNoCallback)copy_bvert_no,
+ .index = -1};
- if (BLI_bvhtree_ray_cast(
- treedata->tree, ray_start_local, ray_normal_local, 0.0f,
- &hit, treedata->raycast_callback, treedata) != -1)
- {
- hit.dist += len_diff;
- hit.dist /= local_scale;
- if (hit.dist <= *ray_depth) {
- *ray_depth = hit.dist;
- copy_v3_v3(r_loc, hit.co);
-
- /* back to worldspace */
- mul_m4_v3(obmat, r_loc);
-
- if (r_no) {
- copy_v3_v3(r_no, hit.no);
- mul_m3_v3(timat, r_no);
- normalize_v3(r_no);
- }
+ float lpmat[4][4];
+ mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
+ dist_squared_to_projected_aabb_precalc(
+ &neasrest2d.data_precalc, lpmat,
+ snapdata->view_proj == VIEW_PROJ_PERSP, snapdata->win_half,
+ (snapdata->depth_range[0] * local_scale), snapdata->mval,
+ ray_org_local, ray_normal_local);
- retval = true;
+ BVHTree_WalkLeafCallback cb_walk_leaf =
+ (snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ?
+ cb_walk_leaf_snap_vert : cb_walk_leaf_snap_edge;
- if (r_index) {
- *r_index = hit.index;
- }
- }
- }
- }
- }
- else {
- float ray_org_local[3];
- copy_v3_v3(ray_org_local, snapdata->ray_origin);
- mul_m4_v3(imat, ray_org_local);
-
- Nearest2dUserData neasrest2d = {
- .dist_px_sq = SQUARE(*dist_px),
- .r_axis_closest = {1.0f, 1.0f, 1.0f},
- .depth_range = {snapdata->depth_range[0], *ray_depth + snapdata->depth_range[0]},
- .userdata = treedata,
- .get_edge_verts = (Nearest2DGetEdgeVertsCallback)get_bedge_verts,
- .copy_vert_no = (Nearest2DCopyVertNoCallback)copy_bvert_no,
- .index = -1};
-
- float lpmat[4][4];
- mul_m4_m4m4(lpmat, snapdata->pmat, obmat);
- dist_squared_to_projected_aabb_precalc(
- &neasrest2d.data_precalc, lpmat,
- snapdata->view_proj == VIEW_PROJ_PERSP, snapdata->win_half,
- (snapdata->depth_range[0] * local_scale), snapdata->mval,
- ray_org_local, ray_normal_local);
-
- BVHTree_WalkLeafCallback cb_walk_leaf =
- (snapdata->snap_to == SCE_SNAP_MODE_VERTEX) ?
- cb_walk_leaf_snap_vert : cb_walk_leaf_snap_edge;
-
- BLI_bvhtree_walk_dfs(
- treedata->tree,
- cb_walk_parent_snap_project, cb_walk_leaf, cb_nearest_walk_order, &neasrest2d);
-
- if (neasrest2d.index != -1) {
- copy_v3_v3(r_loc, neasrest2d.co);
- mul_m4_v3(obmat, r_loc);
- if (r_no) {
- copy_v3_v3(r_no, neasrest2d.no);
- mul_m3_v3(timat, r_no);
- normalize_v3(r_no);
- }
- *dist_px = sqrtf(neasrest2d.dist_px_sq);
- *ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir);
+ BLI_bvhtree_walk_dfs(
+ treedata->tree,
+ cb_walk_parent_snap_project, cb_walk_leaf, cb_nearest_walk_order, &neasrest2d);
- retval = true;
+ if (neasrest2d.index != -1) {
+ copy_v3_v3(r_loc, neasrest2d.co);
+ mul_m4_v3(obmat, r_loc);
+ if (r_no) {
+ copy_v3_v3(r_no, neasrest2d.no);
+ mul_m3_v3(timat, r_no);
+ normalize_v3(r_no);
}
+ *dist_px = sqrtf(neasrest2d.dist_px_sq);
+ *ray_depth = depth_get(r_loc, snapdata->ray_start, snapdata->ray_dir);
+
+ retval = true;
}
return retval;
@@ -1638,14 +1944,13 @@ static bool snapEditMesh(
*/
static bool snapObject(
SnapObjectContext *sctx, SnapData *snapdata,
- Object *ob, float obmat[4][4], const unsigned int ob_index,
+ Object *ob, float obmat[4][4],
bool use_obedit,
/* read/write args */
float *ray_depth, float *dist_px,
/* return args */
- float r_loc[3], float r_no[3], int *r_index,
- Object **r_ob, float r_obmat[4][4],
- ListBase *r_hit_list)
+ float r_loc[3], float r_no[3],
+ Object **r_ob, float r_obmat[4][4])
{
bool retval = false;
@@ -1655,10 +1960,9 @@ static bool snapObject(
if (use_obedit) {
em = BKE_editmesh_from_object(ob);
retval = snapEditMesh(
- sctx, snapdata, ob, em, obmat, ob_index,
+ sctx, snapdata, ob, em, obmat,
ray_depth, dist_px,
- r_loc, r_no, r_index,
- r_hit_list);
+ r_loc, r_no);
}
else {
/* in this case we want the mesh from the editmesh, avoids stale data. see: T45978.
@@ -1672,10 +1976,9 @@ static bool snapObject(
dm = mesh_get_derived_final(sctx->scene, ob, CD_MASK_BAREMESH);
}
retval = snapDerivedMesh(
- sctx, snapdata, ob, dm, obmat, ob_index,
+ sctx, snapdata, ob, dm, obmat,
ray_depth, dist_px,
- r_loc, r_no,
- r_index, r_hit_list);
+ r_loc, r_no);
dm->release(dm);
}
@@ -1720,6 +2023,34 @@ static bool snapObject(
return retval;
}
+
+struct SnapObjUserData {
+ SnapData *snapdata;
+ /* read/write args */
+ float *ray_depth;
+ float *dist_px;
+ /* return args */
+ float *r_loc;
+ float *r_no;
+ Object **r_ob;
+ float (*r_obmat)[4];
+ bool ret;
+};
+
+static void sanp_obj_cb(SnapObjectContext *sctx, bool is_obedit, Object *ob, float obmat[4][4], void *data)
+{
+ struct SnapObjUserData *dt = data;
+ dt->ret |= snapObject(
+ sctx, dt->snapdata,
+ ob, obmat, is_obedit,
+ /* read/write args */
+ dt->ray_depth, dt->dist_px,
+ /* return args */
+ dt->r_loc, dt->r_no,
+ dt->r_ob, dt->r_obmat);
+}
+
+
/**
* Main Snapping Function
* ======================
@@ -1728,8 +2059,8 @@ static bool snapObject(
*
* \param sctx: Snap context to store data.
* \param snapdata: struct generated in `get_snapdata`.
- * \param snap_select: from enum SnapSelect.
- * \param use_object_edit_cage: Uses the coordinates of BMesh (if any) to do the snapping.
+ * \param snap_select : from enum SnapSelect.
+ * \param use_object_edit_cage : Uses the coordinates of BMesh(if any) to do the snapping.
*
* Read/Write Args
* ---------------
@@ -1746,89 +2077,33 @@ static bool snapObject(
* (currently only set to the polygon index when when using ``snap_to == SCE_SNAP_MODE_FACE``).
* \param r_ob: Hit object.
* \param r_obmat: Object matrix (may not be #Object.obmat with dupli-instances).
- * \param r_hit_list: List of #SnapObjectHitDepth (caller must free).
*
*/
static bool snapObjectsRay(
SnapObjectContext *sctx, SnapData *snapdata,
- const SnapSelect snap_select,
- const bool use_object_edit_cage,
+ const SnapSelect snap_select, const bool use_object_edit_cage,
/* read/write args */
float *ray_depth, float *dist_px,
/* return args */
- float r_loc[3], float r_no[3], int *r_index,
- Object **r_ob, float r_obmat[4][4],
- ListBase *r_hit_list)
+ float r_loc[3], float r_no[3],
+ Object **r_ob, float r_obmat[4][4])
{
- bool retval = false;
-
- unsigned int ob_index = 0;
Object *obedit = use_object_edit_cage ? sctx->scene->obedit : NULL;
- /* Need an exception for particle edit because the base is flagged with BA_HAS_RECALC_DATA
- * which makes the loop skip it, even the derived mesh will never change
- *
- * To solve that problem, we do it first as an exception.
- * */
- Base *base_act = sctx->scene->basact;
- if (base_act && base_act->object && base_act->object->mode & OB_MODE_PARTICLE_EDIT) {
- Object *ob = base_act->object;
-
- retval |= snapObject(
- sctx, snapdata, ob, ob->obmat, ob_index++, false,
- ray_depth, dist_px,
- r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list);
- }
-
- bool ignore_object_selected = false, ignore_object_active = false;
- switch (snap_select) {
- case SNAP_ALL:
- break;
- case SNAP_NOT_SELECTED:
- ignore_object_selected = true;
- break;
- case SNAP_NOT_ACTIVE:
- ignore_object_active = true;
- break;
- }
- for (Base *base = sctx->scene->base.first; base != NULL; base = base->next) {
- if ((BASE_VISIBLE_BGMODE(sctx->v3d_data.v3d, sctx->scene, base)) &&
- (base->flag & (BA_HAS_RECALC_OB | BA_HAS_RECALC_DATA)) == 0 &&
-
- !((ignore_object_selected && (base->flag & (SELECT | BA_WAS_SEL))) ||
- (ignore_object_active && base == base_act)))
- {
- Object *ob = base->object;
-
- if (ob->transflag & OB_DUPLI) {
- DupliObject *dupli_ob;
- ListBase *lb = object_duplilist(sctx->bmain->eval_ctx, sctx->scene, ob);
-
- for (dupli_ob = lb->first; dupli_ob; dupli_ob = dupli_ob->next) {
- bool use_obedit_dupli = (obedit && dupli_ob->ob->data == obedit->data);
- Object *dupli_snap = (use_obedit_dupli) ? obedit : dupli_ob->ob;
-
- retval |= snapObject(
- sctx, snapdata, dupli_snap, dupli_ob->mat,
- ob_index++, use_obedit_dupli,
- ray_depth, dist_px,
- r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list);
- }
-
- free_object_duplilist(lb);
- }
+ struct SnapObjUserData data = {
+ .snapdata = snapdata,
+ .ray_depth = ray_depth,
+ .dist_px = dist_px,
+ .r_loc = r_loc,
+ .r_no = r_no,
+ .r_ob = r_ob,
+ .r_obmat = r_obmat,
+ .ret = false,
+ };
- bool use_obedit = (obedit != NULL) && (ob->data == obedit->data);
- Object *ob_snap = use_obedit ? obedit : ob;
+ iter_snap_objects(sctx, snap_select, obedit, sanp_obj_cb, &data);
- retval |= snapObject(
- sctx, snapdata, ob_snap, ob->obmat, ob_index++, use_obedit,
- ray_depth, dist_px,
- r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list);
- }
- }
-
- return retval;
+ return data.ret;
}
/** \} */
@@ -1922,25 +2197,17 @@ void ED_transform_snap_object_context_set_editmesh_callbacks(
bool ED_transform_snap_object_project_ray_ex(
SnapObjectContext *sctx,
- const unsigned short snap_to,
const struct SnapObjectParams *params,
const float ray_start[3], const float ray_normal[3],
float *ray_depth,
float r_loc[3], float r_no[3], int *r_index,
Object **r_ob, float r_obmat[4][4])
{
- const float depth_range[2] = {0.0f, FLT_MAX};
-
- SnapData snapdata;
- snap_data_set(
- &snapdata, sctx->v3d_data.ar, snap_to, VIEW_PROJ_NONE,
- NULL, ray_start, ray_start, ray_normal, depth_range);
-
- return snapObjectsRay(
- sctx, &snapdata,
+ return raycastObjects(
+ sctx,
+ ray_start, ray_normal,
params->snap_select, params->use_object_edit_cage,
- ray_depth, NULL,
- r_loc, r_no, r_index, r_ob, r_obmat, NULL);
+ ray_depth, r_loc, r_no, r_index, r_ob, r_obmat, NULL);
}
/**
@@ -1952,13 +2219,11 @@ bool ED_transform_snap_object_project_ray_ex(
*/
bool ED_transform_snap_object_project_ray_all(
SnapObjectContext *sctx,
- const unsigned short snap_to,
const struct SnapObjectParams *params,
const float ray_start[3], const float ray_normal[3],
float ray_depth, bool sort,
ListBase *r_hit_list)
{
- const float depth_range[2] = {0.0f, FLT_MAX};
if (ray_depth == -1.0f) {
ray_depth = BVH_RAYCAST_DIST_MAX;
}
@@ -1967,15 +2232,11 @@ bool ED_transform_snap_object_project_ray_all(
float ray_depth_prev = ray_depth;
#endif
- SnapData snapdata;
- snap_data_set(&snapdata, sctx->v3d_data.ar, snap_to, VIEW_PROJ_NONE, NULL,
- ray_start, ray_start, ray_normal, depth_range);
-
- bool retval = snapObjectsRay(
- sctx, &snapdata,
+ bool retval = raycastObjects(
+ sctx,
+ ray_start, ray_normal,
params->snap_select, params->use_object_edit_cage,
- &ray_depth, NULL,
- NULL, NULL, NULL, NULL, NULL,
+ &ray_depth, NULL, NULL, NULL, NULL, NULL,
r_hit_list);
/* meant to be readonly for 'all' hits, ensure it is */
@@ -2008,7 +2269,6 @@ static bool transform_snap_context_project_ray_impl(
/* try snap edge, then face if it fails */
ret = ED_transform_snap_object_project_ray_ex(
sctx,
- SCE_SNAP_MODE_FACE,
params,
ray_start, ray_normal, ray_depth,
r_co, r_no, NULL,
@@ -2154,16 +2414,24 @@ bool ED_transform_snap_object_project_view3d_ex(
ray_depth = &ray_depth_fallback;
}
- SnapData snapdata;
- const enum eViewProj view_proj = ((RegionView3D *)ar->regiondata)->is_persp ? VIEW_PROJ_PERSP : VIEW_PROJ_ORTHO;
- snap_data_set(&snapdata, ar, snap_to, view_proj, mval,
- ray_origin, ray_start, ray_normal, depth_range);
+ if (snap_to == SCE_SNAP_MODE_FACE) {
+ return raycastObjects(
+ sctx,
+ ray_start, ray_normal,
+ params->snap_select, params->use_object_edit_cage,
+ ray_depth, r_loc, r_no, r_index, NULL, NULL, NULL);
+ }
+ else {
+ SnapData snapdata;
+ const enum eViewProj view_proj = ((RegionView3D *)ar->regiondata)->is_persp ? VIEW_PROJ_PERSP : VIEW_PROJ_ORTHO;
+ snap_data_set(&snapdata, ar, snap_to, view_proj, mval,
+ ray_origin, ray_start, ray_normal, depth_range);
- return snapObjectsRay(
- sctx, &snapdata,
- params->snap_select, params->use_object_edit_cage,
- ray_depth, dist_px,
- r_loc, r_no, r_index, NULL, NULL, NULL);
+ return snapObjectsRay(
+ sctx, &snapdata,
+ params->snap_select, params->use_object_edit_cage,
+ ray_depth, dist_px, r_loc, r_no, NULL, NULL);
+ }
}
bool ED_transform_snap_object_project_view3d(
@@ -2204,7 +2472,6 @@ bool ED_transform_snap_object_project_all_view3d_ex(
return ED_transform_snap_object_project_ray_all(
sctx,
- SCE_SNAP_MODE_FACE,
params,
ray_start, ray_normal, ray_depth, sort,
r_hit_list);
diff --git a/source/blender/editors/util/numinput.c b/source/blender/editors/util/numinput.c
index 3727be1842c..61142fdc887 100644
--- a/source/blender/editors/util/numinput.c
+++ b/source/blender/editors/util/numinput.c
@@ -296,7 +296,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
}
/* Else, common behavior with DELKEY, only difference is remove char(s) before/after the cursor. */
dir = STRCUR_DIR_PREV;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case DELKEY:
if ((n->val_flag[idx] & NUM_EDITED) && n->str[0]) {
int t_cur = cur = n->str_cur;
@@ -322,7 +322,7 @@ bool handleNumInput(bContext *C, NumInput *n, const wmEvent *event)
break;
case LEFTARROWKEY:
dir = STRCUR_DIR_PREV;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case RIGHTARROWKEY:
cur = n->str_cur;
if (event->ctrl) {
diff --git a/source/blender/editors/util/undo.c b/source/blender/editors/util/undo.c
index 4e021d4833e..419c15bf83f 100644
--- a/source/blender/editors/util/undo.c
+++ b/source/blender/editors/util/undo.c
@@ -334,6 +334,12 @@ static int ed_undo_redo_exec(bContext *C, wmOperator *UNUSED(op))
return ret ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
+static int ed_undo_redo_poll(bContext *C)
+{
+ wmOperator *last_op = WM_operator_last_redo(C);
+ return last_op && ED_operator_screenactive(C) &&
+ WM_operator_check_ui_enabled(C, last_op->type->name);
+}
/* ********************** */
@@ -385,7 +391,7 @@ void ED_OT_undo_redo(wmOperatorType *ot)
/* api callbacks */
ot->exec = ed_undo_redo_exec;
- ot->poll = ED_operator_screenactive;
+ ot->poll = ed_undo_redo_poll;
}
/* ui callbacks should call this rather than calling WM_operator_repeat() themselves */
diff --git a/source/blender/editors/uvedit/uvedit_draw.c b/source/blender/editors/uvedit/uvedit_draw.c
index 5c5e84ee5f0..15be6ab3b78 100644
--- a/source/blender/editors/uvedit/uvedit_draw.c
+++ b/source/blender/editors/uvedit/uvedit_draw.c
@@ -502,7 +502,7 @@ static void draw_uvs_texpaint(SpaceImage *sima, Scene *scene, Object *ob)
ma = give_current_material(ob, ob->actcol);
- if (me->mtpoly) {
+ if (me->mloopuv) {
MPoly *mpoly = me->mpoly;
MLoopUV *mloopuv, *mloopuv_base;
int a, b;
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 193b006cf0d..d7361f5a259 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -1136,8 +1136,13 @@ static void uv_select_linked(Scene *scene, Image *ima, BMEditMesh *em, const flo
BM_mesh_elem_table_ensure(em->bm, BM_FACE); /* we can use this too */
- /* use winding so we don't consider overlapping islands as connected, see T44320 */
- vmap = BM_uv_vert_map_create(em->bm, limit, !select_faces, true);
+ /* Note, we had 'use winding' so we don't consider overlapping islands as connected, see T44320
+ * this made *every* projection split the island into front/back islands.
+ * Keep 'use_winding' to false, see: T50970.
+ *
+ * Better solve this by having a delimit option for select-linked operator,
+ * keeping island-select working as is. */
+ vmap = BM_uv_vert_map_create(em->bm, limit, !select_faces, false);
if (vmap == NULL)
return;
diff --git a/source/blender/editors/uvedit/uvedit_parametrizer.c b/source/blender/editors/uvedit/uvedit_parametrizer.c
index bdfff123aa4..8c76d03035a 100644
--- a/source/blender/editors/uvedit/uvedit_parametrizer.c
+++ b/source/blender/editors/uvedit/uvedit_parametrizer.c
@@ -2859,7 +2859,7 @@ static PBool p_chart_symmetry_pins(PChart *chart, PEdge *outer, PVert **pin1, PV
PEdge *cure = NULL, *firste1 = NULL, *firste2 = NULL, *nextbe;
float maxlen = 0.0f, curlen = 0.0f, totlen = 0.0f, firstlen = 0.0f;
float len1, len2;
-
+
/* find longest series of verts split in the chart itself, these are
* marked during construction */
be = outer;
diff --git a/source/blender/editors/uvedit/uvedit_smart_stitch.c b/source/blender/editors/uvedit/uvedit_smart_stitch.c
index 50aec737c8e..d5233f0ed28 100644
--- a/source/blender/editors/uvedit/uvedit_smart_stitch.c
+++ b/source/blender/editors/uvedit/uvedit_smart_stitch.c
@@ -2116,6 +2116,7 @@ static int stitch_modal(bContext *C, wmOperator *op, const wmEvent *event)
}
break;
}
+ ATTR_FALLTHROUGH;
case PADENTER:
case RETKEY:
if (event->val == KM_PRESS) {
diff --git a/source/blender/freestyle/intern/application/AppView.cpp b/source/blender/freestyle/intern/application/AppView.cpp
index c331d1de9c9..9b1b02c8ee2 100644
--- a/source/blender/freestyle/intern/application/AppView.cpp
+++ b/source/blender/freestyle/intern/application/AppView.cpp
@@ -22,12 +22,6 @@
* \ingroup freestyle
*/
-/* This header file needs to be included first, in order to avoid a
- compilation with MinGW (see the commit log of revision 28253) */
-extern "C" {
-#include "BLI_jitter.h"
-}
-
#include <iostream>
#include "Controller.h"
diff --git a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
index f63cf771120..1dbac1848b7 100644
--- a/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
+++ b/source/blender/freestyle/intern/blender_interface/BlenderStrokeRenderer.cpp
@@ -524,7 +524,7 @@ void BlenderStrokeRenderer::RenderStrokeRepBasic(StrokeRep *iStrokeRep) const
// We'll generate both with tips and without tips
// coordinates, on two different UV layers.
- if (ma->mtex[a]->texflag & MTEX_TIPS) {
+ if (ma->mtex[a]->texflag & MTEX_TIPS) {
BLI_strncpy(ma->mtex[a]->uvname, uvNames[1], sizeof(ma->mtex[a]->uvname));
}
else {
diff --git a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
index 223bc607e21..ea22633c50e 100644
--- a/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
+++ b/source/blender/freestyle/intern/blender_interface/FRS_freestyle.cpp
@@ -448,15 +448,13 @@ static void prepare(Render *re, SceneRenderLayer *srl)
RenderLayer *rl = RE_GetRenderLayer(re->result, srl->name);
bool diffuse = false, z = false;
for (RenderPass *rpass = (RenderPass *)rl->passes.first; rpass; rpass = rpass->next) {
- switch (rpass->passtype) {
- case SCE_PASS_DIFFUSE:
+ if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) {
controller->setPassDiffuse(rpass->rect, rpass->rectx, rpass->recty);
diffuse = true;
- break;
- case SCE_PASS_Z:
+ }
+ if (STREQ(rpass->name, RE_PASSNAME_Z)) {
controller->setPassZ(rpass->rect, rpass->rectx, rpass->recty);
z = true;
- break;
}
}
if (G.debug & G_DEBUG_FREESTYLE) {
@@ -492,7 +490,7 @@ void FRS_composite_result(Render *re, SceneRenderLayer *srl, Render *freestyle_r
return;
}
- src = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, freestyle_render->viewname);
+ src = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, freestyle_render->viewname);
if (!src) {
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "No source result image to composite" << endl;
@@ -512,7 +510,7 @@ void FRS_composite_result(Render *re, SceneRenderLayer *srl, Render *freestyle_r
}
return;
}
- dest = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, re->viewname);
+ dest = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, re->viewname);
if (!dest) {
if (G.debug & G_DEBUG_FREESTYLE) {
cout << "No destination result image to composite to" << endl;
diff --git a/source/blender/freestyle/intern/geometry/matrix_util.h b/source/blender/freestyle/intern/geometry/matrix_util.h
index d65b0ea803b..444fd7c4785 100644
--- a/source/blender/freestyle/intern/geometry/matrix_util.h
+++ b/source/blender/freestyle/intern/geometry/matrix_util.h
@@ -50,15 +50,15 @@ namespace MatrixUtil {
/**
* computes the eigen values and eigen vectors of a semi definite symmetric matrix
*
- * @param matrix is stored in column symmetric storage, i.e.
+ * \param mat: The matrix stored in column symmetric storage, i.e.
* matrix = { m11, m12, m22, m13, m23, m33, m14, m24, m34, m44 ... }
* size = n(n+1)/2
*
- * @param eigen_vectors (return) = { v1, v2, v3, ..., vn }
+ * \param eigen_vec: (return) = { v1, v2, v3, ..., vn }
* where vk = vk0, vk1, ..., vkn
* size = n^2, must be allocated by caller
*
- * @param eigen_values (return) are in decreasing order
+ * \param eigen_val: (return) are in decreasing order
* size = n, must be allocated by caller
*/
void semi_definite_symmetric_eigen(const double *mat, int n, double *eigen_vec, double *eigen_val);
diff --git a/source/blender/gpu/GPU_buffers.h b/source/blender/gpu/GPU_buffers.h
index b693d473bd8..e4a837d0a5f 100644
--- a/source/blender/gpu/GPU_buffers.h
+++ b/source/blender/gpu/GPU_buffers.h
@@ -222,50 +222,53 @@ void GPU_interleaved_attrib_unbind(void);
typedef struct GPU_PBVH_Buffers GPU_PBVH_Buffers;
/* build */
-GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
+GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(
const int (*face_vert_indices)[3],
const struct MPoly *mpoly, const struct MLoop *mloop, const struct MLoopTri *looptri,
const struct MVert *verts,
const int *face_indices,
const int face_indices_len);
-GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(
+GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(
int *grid_indices, int totgrid, unsigned int **grid_hidden, int gridsize, const struct CCGKey *key,
struct GridCommonGPUBuffer **grid_common_gpu_buffer);
-GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(bool smooth_shading);
+GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading);
/* update */
-void GPU_update_mesh_pbvh_buffers(
+void GPU_pbvh_mesh_buffers_update(
GPU_PBVH_Buffers *buffers, const struct MVert *mvert,
const int *vert_indices, int totvert, const float *vmask,
const int (*face_vert_indices)[3], bool show_diffuse_color);
-void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
- struct BMesh *bm,
- struct GSet *bm_faces,
- struct GSet *bm_unique_verts,
- struct GSet *bm_other_verts,
- bool show_diffuse_color);
+void GPU_pbvh_bmesh_buffers_update(
+ GPU_PBVH_Buffers *buffers,
+ struct BMesh *bm,
+ struct GSet *bm_faces,
+ struct GSet *bm_unique_verts,
+ struct GSet *bm_other_verts,
+ bool show_diffuse_color);
-void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, struct CCGElem **grids,
- const struct DMFlagMat *grid_flag_mats,
- int *grid_indices, int totgrid, const struct CCGKey *key,
- bool show_diffuse_color);
+void GPU_pbvh_grid_buffers_update(
+ GPU_PBVH_Buffers *buffers, struct CCGElem **grids,
+ const struct DMFlagMat *grid_flag_mats,
+ int *grid_indices, int totgrid, const struct CCGKey *key,
+ bool show_diffuse_color);
/* draw */
-void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
- bool wireframe, bool fast);
+void GPU_pbvh_buffers_draw(
+ GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
+ bool wireframe, bool fast);
/* debug PBVH draw*/
-void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf);
-void GPU_end_draw_pbvh_BB(void);
-void GPU_init_draw_pbvh_BB(void);
+void GPU_pbvh_BB_draw(float min[3], float max[3], bool leaf);
+void GPU_pbvh_BB_draw_init(void);
+void GPU_pbvh_BB_draw_end(void);
bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, struct GSet *bm_faces, bool show_diffuse_color);
-void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers);
-void GPU_free_pbvh_buffer_multires(struct GridCommonGPUBuffer **grid_common_gpu_buffer);
+void GPU_pbvh_buffers_free(GPU_PBVH_Buffers *buffers);
+void GPU_pbvh_multires_buffers_free(struct GridCommonGPUBuffer **grid_common_gpu_buffer);
#endif
diff --git a/source/blender/gpu/GPU_material.h b/source/blender/gpu/GPU_material.h
index 0d92d22a173..6db23686832 100644
--- a/source/blender/gpu/GPU_material.h
+++ b/source/blender/gpu/GPU_material.h
@@ -98,6 +98,7 @@ typedef enum GPUBuiltin {
GPU_PARTICLE_ANG_VELOCITY = (1 << 12),
GPU_LOC_TO_VIEW_MATRIX = (1 << 13),
GPU_INVERSE_LOC_TO_VIEW_MATRIX = (1 << 14),
+ GPU_OBJECT_INFO = (1 << 15)
} GPUBuiltin;
typedef enum GPUOpenGLBuiltin {
@@ -213,6 +214,7 @@ bool GPU_stack_link(GPUMaterial *mat, const char *name, GPUNodeStack *in, GPUNod
void GPU_material_output_link(GPUMaterial *material, GPUNodeLink *link);
void GPU_material_enable_alpha(GPUMaterial *material);
+GPUBuiltin GPU_get_material_builtins(GPUMaterial *material);
GPUBlendMode GPU_material_alpha_blend(GPUMaterial *material, float obcol[4]);
/* High level functions to create and use GPU materials */
@@ -230,7 +232,7 @@ void GPU_material_bind(
float viewmat[4][4], float viewinv[4][4], float cameraborder[4], bool scenelock);
void GPU_material_bind_uniforms(
GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float obcol[4],
- float autobumpscale, GPUParticleInfo *pi);
+ float autobumpscale, GPUParticleInfo *pi, float object_info[3]);
void GPU_material_unbind(GPUMaterial *material);
bool GPU_material_bound(GPUMaterial *material);
struct Scene *GPU_material_scene(GPUMaterial *material);
@@ -345,6 +347,7 @@ struct GPUParticleInfo
float location[3];
float velocity[3];
float angular_velocity[3];
+ int random_id;
};
#ifdef WITH_OPENSUBDIV
diff --git a/source/blender/gpu/intern/gpu_basic_shader.c b/source/blender/gpu/intern/gpu_basic_shader.c
index a2b89239344..8505bd847a0 100644
--- a/source/blender/gpu/intern/gpu_basic_shader.c
+++ b/source/blender/gpu/intern/gpu_basic_shader.c
@@ -407,7 +407,7 @@ static GPUShader *gpu_basic_shader(int options)
return shader;
}
-static void GPU_basic_shader_uniform_autoset(GPUShader *shader, int options)
+static void gpu_basic_shader_uniform_autoset(GPUShader *shader, int options)
{
if (options & GPU_SHADER_LINE) {
glGetIntegerv(GL_VIEWPORT, &GPU_MATERIAL_STATE.viewport[0]);
@@ -443,7 +443,7 @@ void GPU_basic_shader_bind(int options)
if (shader) {
GPU_shader_bind(shader);
- GPU_basic_shader_uniform_autoset(shader, options);
+ gpu_basic_shader_uniform_autoset(shader, options);
}
}
else {
diff --git a/source/blender/gpu/intern/gpu_buffers.c b/source/blender/gpu/intern/gpu_buffers.c
index 370841327aa..9f1fe3a5a67 100644
--- a/source/blender/gpu/intern/gpu_buffers.c
+++ b/source/blender/gpu/intern/gpu_buffers.c
@@ -743,7 +743,7 @@ void GPU_triangle_setup(struct DerivedMesh *dm)
GLStates |= GPU_BUFFER_ELEMENT_STATE;
}
-static int GPU_typesize(int type)
+static int gpu_typesize(int type)
{
switch (type) {
case GL_FLOAT:
@@ -766,7 +766,7 @@ int GPU_attrib_element_size(GPUAttrib data[], int numdata)
int i, elementsize = 0;
for (i = 0; i < numdata; i++) {
- int typesize = GPU_typesize(data[i].type);
+ int typesize = gpu_typesize(data[i].type);
if (typesize != 0)
elementsize += typesize * data[i].size;
}
@@ -803,7 +803,7 @@ void GPU_interleaved_attrib_setup(GPUBuffer *buffer, GPUAttrib data[], int numda
glVertexAttribPointer(data[i].index, data[i].size, data[i].type,
GL_TRUE, elementsize, BUFFER_OFFSET(offset));
- offset += data[i].size * GPU_typesize(data[i].type);
+ offset += data[i].size * gpu_typesize(data[i].type);
attribData[i].index = data[i].index;
attribData[i].size = data[i].size;
@@ -1030,13 +1030,13 @@ static void gpu_color_from_mask_quad_copy(const CCGKey *key,
out[2] = diffuse_color[2] * mask_color;
}
-void GPU_update_mesh_pbvh_buffers(
+void GPU_pbvh_mesh_buffers_update(
GPU_PBVH_Buffers *buffers, const MVert *mvert,
const int *vert_indices, int totvert, const float *vmask,
const int (*face_vert_indices)[3], bool show_diffuse_color)
{
VertexBufferFormat *vert_data;
- int i, j;
+ int i;
buffers->vmask = vmask;
buffers->show_diffuse_color = show_diffuse_color;
@@ -1057,6 +1057,9 @@ void GPU_update_mesh_pbvh_buffers(
copy_v4_v4(buffers->diffuse_color, diffuse_color);
+ uchar diffuse_color_ub[4];
+ rgba_float_to_uchar(diffuse_color_ub, diffuse_color);
+
/* Build VBO */
if (buffers->vert_buf)
GPU_buffer_free(buffers->vert_buf);
@@ -1076,28 +1079,20 @@ void GPU_update_mesh_pbvh_buffers(
memcpy(out->no, v->no, sizeof(short) * 3);
}
-#define UPDATE_VERTEX(face, vertex, index, diffuse_color) \
- { \
- VertexBufferFormat *out = vert_data + face_vert_indices[face][index]; \
- if (vmask) \
- gpu_color_from_mask_copy(vmask[vertex], diffuse_color, out->color); \
- else \
- rgb_float_to_uchar(out->color, diffuse_color); \
- } (void)0
-
for (i = 0; i < buffers->face_indices_len; i++) {
const MLoopTri *lt = &buffers->looptri[buffers->face_indices[i]];
- const unsigned int vtri[3] = {
- buffers->mloop[lt->tri[0]].v,
- buffers->mloop[lt->tri[1]].v,
- buffers->mloop[lt->tri[2]].v,
- };
+ for (uint j = 0; j < 3; j++) {
+ VertexBufferFormat *out = vert_data + face_vert_indices[i][j];
- UPDATE_VERTEX(i, vtri[0], 0, diffuse_color);
- UPDATE_VERTEX(i, vtri[1], 1, diffuse_color);
- UPDATE_VERTEX(i, vtri[2], 2, diffuse_color);
+ if (vmask) {
+ uint v_index = buffers->mloop[lt->tri[j]].v;
+ gpu_color_from_mask_copy(vmask[v_index], diffuse_color, out->color);
+ }
+ else {
+ copy_v3_v3_uchar(out->color, diffuse_color_ub);
+ }
+ }
}
-#undef UPDATE_VERTEX
}
else {
/* calculate normal for each polygon only once */
@@ -1112,8 +1107,6 @@ void GPU_update_mesh_pbvh_buffers(
buffers->mloop[lt->tri[2]].v,
};
- float fmask;
-
if (paint_is_face_hidden(lt, mvert, buffers->mloop))
continue;
@@ -1126,23 +1119,22 @@ void GPU_update_mesh_pbvh_buffers(
mpoly_prev = lt->poly;
}
+ uchar color_ub[3];
if (vmask) {
- fmask = (vmask[vtri[0]] +
- vmask[vtri[1]] +
- vmask[vtri[2]]) / 3.0f;
+ float fmask = (vmask[vtri[0]] + vmask[vtri[1]] + vmask[vtri[2]]) / 3.0f;
+ gpu_color_from_mask_copy(fmask, diffuse_color, color_ub);
+ }
+ else {
+ copy_v3_v3_uchar(color_ub, diffuse_color_ub);
}
- for (j = 0; j < 3; j++) {
+ for (uint j = 0; j < 3; j++) {
const MVert *v = &mvert[vtri[j]];
VertexBufferFormat *out = vert_data;
copy_v3_v3(out->co, v->co);
copy_v3_v3_short(out->no, no);
-
- if (vmask)
- gpu_color_from_mask_copy(fmask, diffuse_color, out->color);
- else
- rgb_float_to_uchar(out->color, diffuse_color);
+ copy_v3_v3_uchar(out->color, color_ub);
vert_data++;
}
@@ -1160,7 +1152,7 @@ void GPU_update_mesh_pbvh_buffers(
buffers->mvert = mvert;
}
-GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
+GPU_PBVH_Buffers *GPU_pbvh_mesh_buffers_build(
const int (*face_vert_indices)[3],
const MPoly *mpoly, const MLoop *mloop, const MLoopTri *looptri,
const MVert *mvert,
@@ -1244,9 +1236,10 @@ GPU_PBVH_Buffers *GPU_build_mesh_pbvh_buffers(
return buffers;
}
-void GPU_update_grid_pbvh_buffers(GPU_PBVH_Buffers *buffers, CCGElem **grids,
- const DMFlagMat *grid_flag_mats, int *grid_indices,
- int totgrid, const CCGKey *key, bool show_diffuse_color)
+void GPU_pbvh_grid_buffers_update(
+ GPU_PBVH_Buffers *buffers, CCGElem **grids,
+ const DMFlagMat *grid_flag_mats, int *grid_indices,
+ int totgrid, const CCGKey *key, bool show_diffuse_color)
{
VertexBufferFormat *vert_data;
int i, j, k, x, y;
@@ -1466,7 +1459,7 @@ static GPUBuffer *gpu_get_grid_buffer(
} \
} (void)0
-GPU_PBVH_Buffers *GPU_build_grid_pbvh_buffers(
+GPU_PBVH_Buffers *GPU_pbvh_grid_buffers_build(
int *grid_indices, int totgrid, BLI_bitmap **grid_hidden, int gridsize, const CCGKey *key,
GridCommonGPUBuffer **grid_common_gpu_buffer)
{
@@ -1612,12 +1605,13 @@ static int gpu_bmesh_face_visible_count(GSet *bm_faces)
/* Creates a vertex buffer (coordinate, normal, color) and, if smooth
* shading, an element index buffer. */
-void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
- BMesh *bm,
- GSet *bm_faces,
- GSet *bm_unique_verts,
- GSet *bm_other_verts,
- bool show_diffuse_color)
+void GPU_pbvh_bmesh_buffers_update(
+ GPU_PBVH_Buffers *buffers,
+ BMesh *bm,
+ GSet *bm_faces,
+ GSet *bm_unique_verts,
+ GSet *bm_other_verts,
+ bool show_diffuse_color)
{
VertexBufferFormat *vert_data;
void *tri_data;
@@ -1803,7 +1797,7 @@ void GPU_update_bmesh_pbvh_buffers(GPU_PBVH_Buffers *buffers,
}
}
-GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(bool smooth_shading)
+GPU_PBVH_Buffers *GPU_pbvh_bmesh_buffers_build(bool smooth_shading)
{
GPU_PBVH_Buffers *buffers;
@@ -1816,8 +1810,9 @@ GPU_PBVH_Buffers *GPU_build_bmesh_pbvh_buffers(bool smooth_shading)
return buffers;
}
-void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
- bool wireframe, bool fast)
+void GPU_pbvh_buffers_draw(
+ GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
+ bool wireframe, bool fast)
{
bool do_fast = fast && buffers->index_buf_fast;
/* sets material from the first face, to solve properly face would need to
@@ -1956,7 +1951,8 @@ void GPU_draw_pbvh_buffers(GPU_PBVH_Buffers *buffers, DMSetMaterial setMaterial,
}
}
-bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces, bool show_diffuse_color)
+bool GPU_pbvh_buffers_diffuse_changed(
+ GPU_PBVH_Buffers *buffers, GSet *bm_faces, bool show_diffuse_color)
{
float diffuse_color[4];
bool use_matcaps = GPU_material_use_matcaps_get();
@@ -1999,7 +1995,7 @@ bool GPU_pbvh_buffers_diffuse_changed(GPU_PBVH_Buffers *buffers, GSet *bm_faces,
return !equals_v3v3(diffuse_color, buffers->diffuse_color);
}
-void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers)
+void GPU_pbvh_buffers_free(GPU_PBVH_Buffers *buffers)
{
if (buffers) {
if (buffers->vert_buf)
@@ -2017,7 +2013,7 @@ void GPU_free_pbvh_buffers(GPU_PBVH_Buffers *buffers)
}
}
-void GPU_free_pbvh_buffer_multires(GridCommonGPUBuffer **grid_common_gpu_buffer)
+void GPU_pbvh_multires_buffers_free(GridCommonGPUBuffer **grid_common_gpu_buffer)
{
GridCommonGPUBuffer *gridbuff = *grid_common_gpu_buffer;
@@ -2033,7 +2029,7 @@ void GPU_free_pbvh_buffer_multires(GridCommonGPUBuffer **grid_common_gpu_buffer)
}
/* debug function, draws the pbvh BB */
-void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf)
+void GPU_pbvh_BB_draw(float min[3], float max[3], bool leaf)
{
const float quads[4][4][3] = {
{
@@ -2074,7 +2070,7 @@ void GPU_draw_pbvh_BB(float min[3], float max[3], bool leaf)
glDrawArrays(GL_QUADS, 0, 16);
}
-void GPU_init_draw_pbvh_BB(void)
+void GPU_pbvh_BB_draw_init(void)
{
glPushAttrib(GL_ENABLE_BIT);
glDisable(GL_CULL_FACE);
@@ -2084,7 +2080,7 @@ void GPU_init_draw_pbvh_BB(void)
glEnable(GL_BLEND);
}
-void GPU_end_draw_pbvh_BB(void)
+void GPU_pbvh_BB_draw_end(void)
{
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glPopAttrib();
diff --git a/source/blender/gpu/intern/gpu_codegen.c b/source/blender/gpu/intern/gpu_codegen.c
index c3896fbd659..b5512aa108d 100644
--- a/source/blender/gpu/intern/gpu_codegen.c
+++ b/source/blender/gpu/intern/gpu_codegen.c
@@ -410,6 +410,8 @@ const char *GPU_builtin_name(GPUBuiltin builtin)
return "unfparticlevel";
else if (builtin == GPU_PARTICLE_ANG_VELOCITY)
return "unfparticleangvel";
+ else if (builtin == GPU_OBJECT_INFO)
+ return "unfobjectinfo";
else
return "";
}
diff --git a/source/blender/gpu/intern/gpu_compositing.c b/source/blender/gpu/intern/gpu_compositing.c
index 964c2b5051e..2f2a16f9e1d 100644
--- a/source/blender/gpu/intern/gpu_compositing.c
+++ b/source/blender/gpu/intern/gpu_compositing.c
@@ -798,7 +798,9 @@ bool GPU_fx_do_composite_pass(
ssao_shader = GPU_shader_get_builtin_fx_shader(GPU_SHADER_FX_SSAO, is_persp);
if (ssao_shader) {
const GPUSSAOSettings *fx_ssao = fx->settings.ssao;
- float ssao_params[4] = {fx_ssao->distance_max, fx_ssao->factor, fx_ssao->attenuation, 0.0f};
+ /* adjust attenuation to be scale invariant */
+ float attenuation = fx_ssao->attenuation / (fx_ssao->distance_max * fx_ssao->distance_max);
+ float ssao_params[4] = {fx_ssao->distance_max, fx_ssao->factor, attenuation, 0.0f};
float sample_params[3];
sample_params[0] = fx->ssao_sample_count_cache;
diff --git a/source/blender/gpu/intern/gpu_debug.c b/source/blender/gpu/intern/gpu_debug.c
index ba68d1a6a0f..7a0562617d6 100644
--- a/source/blender/gpu/intern/gpu_debug.c
+++ b/source/blender/gpu/intern/gpu_debug.c
@@ -29,6 +29,7 @@
* \ingroup gpu
*/
+#include "BLI_compiler_attrs.h"
#include "BLI_utildefines.h"
#include "BLI_sys_types.h"
#include "BLI_system.h"
@@ -219,7 +220,7 @@ static void APIENTRY gpu_debug_proc(
switch (severity) {
case GL_DEBUG_SEVERITY_HIGH:
backtrace = true;
- /* fall through */
+ ATTR_FALLTHROUGH;
case GL_DEBUG_SEVERITY_MEDIUM:
case GL_DEBUG_SEVERITY_LOW:
case GL_DEBUG_SEVERITY_NOTIFICATION: /* KHR has this, ARB does not */
@@ -249,7 +250,7 @@ static void APIENTRY gpu_debug_proc_amd(
switch (severity) {
case GL_DEBUG_SEVERITY_HIGH:
backtrace = true;
- /* fall through */
+ ATTR_FALLTHROUGH;
case GL_DEBUG_SEVERITY_MEDIUM:
case GL_DEBUG_SEVERITY_LOW:
fprintf(stderr, "GL %s: %s\n", category_name_amd(category), message);
diff --git a/source/blender/gpu/intern/gpu_draw.c b/source/blender/gpu/intern/gpu_draw.c
index 7936811ab4d..1583d16ca27 100644
--- a/source/blender/gpu/intern/gpu_draw.c
+++ b/source/blender/gpu/intern/gpu_draw.c
@@ -45,6 +45,7 @@
#include "BLI_math.h"
#include "BLI_threads.h"
#include "BLI_utildefines.h"
+#include "BLI_hash.h"
#include "DNA_lamp_types.h"
#include "DNA_material_types.h"
@@ -1203,7 +1204,7 @@ void GPU_paint_set_mipmap(bool mipmap)
/* check if image has been downscaled and do scaled partial update */
-static bool GPU_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x, int y, int w, int h)
+static bool gpu_check_scaled_image(ImBuf *ibuf, Image *ima, float *frect, int x, int y, int w, int h)
{
if ((!GPU_full_non_power_of_two_support() && !is_power_of_2_resolution(ibuf->x, ibuf->y)) ||
is_over_resolution_limit(GL_TEXTURE_2D, ibuf->x, ibuf->y))
@@ -1296,7 +1297,7 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i
bool is_data = (ima->tpageflag & IMA_GLBIND_IS_DATA) != 0;
IMB_partial_rect_from_float(ibuf, buffer, x, y, w, h, is_data);
- if (GPU_check_scaled_image(ibuf, ima, buffer, x, y, w, h)) {
+ if (gpu_check_scaled_image(ibuf, ima, buffer, x, y, w, h)) {
MEM_freeN(buffer);
BKE_image_release_ibuf(ima, ibuf, NULL);
return;
@@ -1320,7 +1321,7 @@ void GPU_paint_update_image(Image *ima, ImageUser *iuser, int x, int y, int w, i
return;
}
- if (GPU_check_scaled_image(ibuf, ima, NULL, x, y, w, h)) {
+ if (gpu_check_scaled_image(ibuf, ima, NULL, x, y, w, h)) {
BKE_image_release_ibuf(ima, ibuf, NULL);
return;
}
@@ -1870,7 +1871,7 @@ void GPU_begin_object_materials(
GPU_object_material_unbind();
}
-static int GPU_get_particle_info(GPUParticleInfo *pi)
+static int gpu_get_particle_info(GPUParticleInfo *pi)
{
DupliObject *dob = GMS.dob;
if (dob->particle_system) {
@@ -1899,6 +1900,21 @@ static int GPU_get_particle_info(GPUParticleInfo *pi)
return 0;
}
+static void GPU_get_object_info(float oi[3], Material *mat)
+{
+ Object *ob = GMS.gob;
+ oi[0] = ob->index;
+ oi[1] = mat->index;
+ unsigned int random;
+ if (GMS.dob) {
+ random = GMS.dob->random_id;
+ }
+ else {
+ random = BLI_hash_int_2d(BLI_hash_string(GMS.gob->id.name + 2), 0);
+ }
+ oi[2] = random * (1.0f / (float)0xFFFFFFFF);
+}
+
int GPU_object_material_bind(int nr, void *attribs)
{
GPUVertexAttribs *gattribs = attribs;
@@ -1958,21 +1974,27 @@ int GPU_object_material_bind(int nr, void *attribs)
/* bind glsl material and get attributes */
Material *mat = GMS.gmatbuf[nr];
GPUParticleInfo partile_info;
+ float object_info[3] = {0};
float auto_bump_scale;
GPUMaterial *gpumat = GPU_material_from_blender(GMS.gscene, mat, GMS.is_opensubdiv);
GPU_material_vertex_attributes(gpumat, gattribs);
- if (GMS.dob)
- GPU_get_particle_info(&partile_info);
+ if (GMS.dob) {
+ gpu_get_particle_info(&partile_info);
+ }
+
+ if (GPU_get_material_builtins(gpumat) & GPU_OBJECT_INFO) {
+ GPU_get_object_info(object_info, mat);
+ }
GPU_material_bind(
gpumat, GMS.gob->lay, GMS.glay, 1.0, !(GMS.gob->mode & OB_MODE_TEXTURE_PAINT),
GMS.gviewmat, GMS.gviewinv, GMS.gviewcamtexcofac, GMS.gscenelock);
auto_bump_scale = GMS.gob->derivedFinal != NULL ? GMS.gob->derivedFinal->auto_bump_scale : 1.0f;
- GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gob->col, auto_bump_scale, &partile_info);
+ GPU_material_bind_uniforms(gpumat, GMS.gob->obmat, GMS.gviewmat, GMS.gob->col, auto_bump_scale, &partile_info, object_info);
GMS.gboundmat = mat;
/* for glsl use alpha blend mode, unless it's set to solid and
diff --git a/source/blender/gpu/intern/gpu_framebuffer.c b/source/blender/gpu/intern/gpu_framebuffer.c
index f62ef677434..e7a8beae5cc 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.c
+++ b/source/blender/gpu/intern/gpu_framebuffer.c
@@ -52,7 +52,7 @@ struct GPUFrameBuffer {
GPUTexture *depthtex;
};
-static void GPU_print_framebuffer_error(GLenum status, char err_out[256])
+static void gpu_print_framebuffer_error(GLenum status, char err_out[256])
{
const char *err = "unknown";
@@ -164,7 +164,7 @@ int GPU_framebuffer_texture_attach(GPUFrameBuffer *fb, GPUTexture *tex, int slot
if (error == GL_INVALID_OPERATION) {
GPU_framebuffer_restore();
- GPU_print_framebuffer_error(error, err_out);
+ gpu_print_framebuffer_error(error, err_out);
return 0;
}
@@ -331,7 +331,7 @@ bool GPU_framebuffer_check_valid(GPUFrameBuffer *fb, char err_out[256])
if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
GPU_framebuffer_restore();
- GPU_print_framebuffer_error(status, err_out);
+ gpu_print_framebuffer_error(status, err_out);
return false;
}
diff --git a/source/blender/gpu/intern/gpu_material.c b/source/blender/gpu/intern/gpu_material.c
index 4e2043471b6..1f3ae7f708a 100644
--- a/source/blender/gpu/intern/gpu_material.c
+++ b/source/blender/gpu/intern/gpu_material.c
@@ -122,6 +122,8 @@ struct GPUMaterial {
int partvel;
int partangvel;
+ int objectinfoloc;
+
ListBase lamps;
bool bound;
@@ -225,7 +227,7 @@ static void gpu_material_set_attrib_id(GPUMaterial *material)
attribs->totlayer = b;
}
-static int GPU_material_construct_end(GPUMaterial *material, const char *passname)
+static int gpu_material_construct_end(GPUMaterial *material, const char *passname)
{
if (material->outlink) {
GPUNodeLink *outlink = material->outlink;
@@ -268,6 +270,8 @@ static int GPU_material_construct_end(GPUMaterial *material, const char *passnam
material->partvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_VELOCITY));
if (material->builtins & GPU_PARTICLE_ANG_VELOCITY)
material->partangvel = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_PARTICLE_ANG_VELOCITY));
+ if (material->builtins & GPU_OBJECT_INFO)
+ material->objectinfoloc = GPU_shader_get_uniform(shader, GPU_builtin_name(GPU_OBJECT_INFO));
return 1;
}
else {
@@ -398,9 +402,14 @@ void GPU_material_bind(
}
}
+GPUBuiltin GPU_get_material_builtins(GPUMaterial *material)
+{
+ return material->builtins;
+}
+
void GPU_material_bind_uniforms(
GPUMaterial *material, float obmat[4][4], float viewmat[4][4], float obcol[4],
- float autobumpscale, GPUParticleInfo *pi)
+ float autobumpscale, GPUParticleInfo *pi, float object_info[3])
{
if (material->pass) {
GPUShader *shader = GPU_pass_shader(material->pass);
@@ -449,6 +458,9 @@ void GPU_material_bind_uniforms(
if (material->builtins & GPU_PARTICLE_ANG_VELOCITY) {
GPU_shader_uniform_vector(shader, material->partangvel, 3, 1, pi->angular_velocity);
}
+ if (material->builtins & GPU_OBJECT_INFO) {
+ GPU_shader_uniform_vector(shader, material->objectinfoloc, 3, 1, object_info);
+ }
}
}
@@ -1891,7 +1903,7 @@ GPUMaterial *GPU_material_matcap(Scene *scene, Material *ma, bool use_opensubdiv
GPU_material_output_link(mat, outlink);
- GPU_material_construct_end(mat, "matcap_pass");
+ gpu_material_construct_end(mat, "matcap_pass");
/* note that even if building the shader fails in some way, we still keep
* it to avoid trying to compile again and again, and simple do not use
@@ -2044,7 +2056,7 @@ static void do_world_tex(GPUShadeInput *shi, struct World *wo, GPUNodeLink **hor
}
}
-static void GPU_material_old_world(struct GPUMaterial *mat, struct World *wo)
+static void gpu_material_old_world(struct GPUMaterial *mat, struct World *wo)
{
GPUShadeInput shi;
GPUShadeResult shr;
@@ -2112,17 +2124,18 @@ GPUMaterial *GPU_material_world(struct Scene *scene, struct World *wo)
mat->type = GPU_MATERIAL_TYPE_WORLD;
/* create nodes */
- if (BKE_scene_use_new_shading_nodes(scene) && wo->nodetree && wo->use_nodes)
+ if (BKE_scene_use_new_shading_nodes(scene) && wo->nodetree && wo->use_nodes) {
ntreeGPUMaterialNodes(wo->nodetree, mat, NODE_NEW_SHADING);
+ }
else {
- GPU_material_old_world(mat, wo);
+ gpu_material_old_world(mat, wo);
}
if (GPU_material_do_color_management(mat))
if (mat->outlink)
GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
- GPU_material_construct_end(mat, wo->id.name);
+ gpu_material_construct_end(mat, wo->id.name);
/* note that even if building the shader fails in some way, we still keep
* it to avoid trying to compile again and again, and simple do not use
@@ -2188,7 +2201,7 @@ GPUMaterial *GPU_material_from_blender(Scene *scene, Material *ma, bool use_open
if (mat->outlink)
GPU_link(mat, "linearrgb_to_srgb", mat->outlink, &mat->outlink);
- GPU_material_construct_end(mat, ma->id.name);
+ gpu_material_construct_end(mat, ma->id.name);
/* note that even if building the shader fails in some way, we still keep
* it to avoid trying to compile again and again, and simple do not use
diff --git a/source/blender/gpu/intern/gpu_select.c b/source/blender/gpu/intern/gpu_select.c
index 9496ff137dc..632b0cfee1b 100644
--- a/source/blender/gpu/intern/gpu_select.c
+++ b/source/blender/gpu/intern/gpu_select.c
@@ -75,6 +75,12 @@ static GPUSelectState g_select_state = {0};
*/
void GPU_select_begin(unsigned int *buffer, unsigned int bufsize, const rcti *input, char mode, int oldhits)
{
+ if (mode == GPU_SELECT_NEAREST_SECOND_PASS) {
+ /* In the case hits was '-1', don't start the second pass since it's not going to give useful results.
+ * As well as buffer overflow in 'gpu_select_query_load_id'. */
+ BLI_assert(oldhits != -1);
+ }
+
g_select_state.select_is_active = true;
g_select_state.use_gpu_select = GPU_select_query_check_active();
g_select_state.mode = mode;
diff --git a/source/blender/gpu/intern/gpu_select_sample_query.c b/source/blender/gpu/intern/gpu_select_sample_query.c
index ba5fefc5227..3d589986281 100644
--- a/source/blender/gpu/intern/gpu_select_sample_query.c
+++ b/source/blender/gpu/intern/gpu_select_sample_query.c
@@ -142,13 +142,17 @@ bool gpu_select_query_load_id(unsigned int id)
g_query_state.active_query++;
g_query_state.query_issued = true;
- if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS && g_query_state.index < g_query_state.oldhits) {
- if (g_query_state.buffer[g_query_state.index][3] == id) {
- g_query_state.index++;
- return true;
- }
- else {
- return false;
+ if (g_query_state.mode == GPU_SELECT_NEAREST_SECOND_PASS) {
+ /* Second pass should never run if first pass fails, can read past 'bufsize' in this case. */
+ BLI_assert(g_query_state.oldhits != -1);
+ if (g_query_state.index < g_query_state.oldhits) {
+ if (g_query_state.buffer[g_query_state.index][3] == id) {
+ g_query_state.index++;
+ return true;
+ }
+ else {
+ return false;
+ }
}
}
diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c
index 14f2764b009..b579f87698c 100644
--- a/source/blender/gpu/intern/gpu_shader.c
+++ b/source/blender/gpu/intern/gpu_shader.c
@@ -39,6 +39,7 @@
#include "GPU_glew.h"
#include "GPU_shader.h"
#include "GPU_texture.h"
+#include "GPU_material.h"
/* TODO(sergey): Find better default values for this constants. */
#define MAX_DEFINE_LENGTH 1024
diff --git a/source/blender/gpu/intern/gpu_texture.c b/source/blender/gpu/intern/gpu_texture.c
index 54f0003c086..1c97c2ce811 100644
--- a/source/blender/gpu/intern/gpu_texture.c
+++ b/source/blender/gpu/intern/gpu_texture.c
@@ -79,7 +79,7 @@ static unsigned char *GPU_texture_convert_pixels(int length, const float *fpixel
return pixels;
}
-static void GPU_glTexSubImageEmpty(GLenum target, GLenum format, int x, int y, int w, int h)
+static void gpu_glTexSubImageEmpty(GLenum target, GLenum format, int x, int y, int w, int h)
{
void *pixels = MEM_callocN(sizeof(char) * 4 * w * h, "GPUTextureEmptyPixels");
@@ -193,7 +193,7 @@ static GPUTexture *GPU_texture_create_nD(
pixels ? pixels : fpixels);
if (tex->w > w) {
- GPU_glTexSubImageEmpty(tex->target, format, w, 0, tex->w - w, 1);
+ gpu_glTexSubImageEmpty(tex->target, format, w, 0, tex->w - w, 1);
}
}
}
@@ -210,10 +210,12 @@ static GPUTexture *GPU_texture_create_nD(
glTexSubImage2D(tex->target, 0, 0, 0, w, h,
format, type, pixels ? pixels : fpixels);
- if (tex->w > w)
- GPU_glTexSubImageEmpty(tex->target, format, w, 0, tex->w - w, tex->h);
- if (tex->h > h)
- GPU_glTexSubImageEmpty(tex->target, format, 0, h, w, tex->h - h);
+ if (tex->w > w) {
+ gpu_glTexSubImageEmpty(tex->target, format, w, 0, tex->w - w, tex->h);
+ }
+ if (tex->h > h) {
+ gpu_glTexSubImageEmpty(tex->target, format, 0, h, w, tex->h - h);
+ }
}
}
diff --git a/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
index 50c8e255162..f19ff4ec65a 100644
--- a/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_fx_ssao_frag.glsl
@@ -75,7 +75,7 @@ float calculate_ssao_factor(float depth)
float f = dot(dir, normal);
/* use minor bias here to avoid self shadowing */
- if (f > 0.05 * len + 0.0001)
+ if (f > 0.05 * len)
factor += f * 1.0 / (len * (1.0 + len * len * ssao_params.z));
}
}
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 0f3ffa8244b..f14db57a26a 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -403,7 +403,7 @@ void math_modulo(float val1, float val2, out float outval)
/* change sign to match C convention, mod in GLSL will take absolute for negative numbers,
* see https://www.opengl.org/sdk/docs/man/html/mod.xhtml */
- outval = (val1 > 0.0) ? outval : -outval;
+ outval = (val1 > 0.0) ? outval : outval - val2;
}
void math_abs(float val1, out float outval)
@@ -2378,11 +2378,19 @@ void shade_alpha_obcolor(vec4 col, vec4 obcol, out vec4 outcol)
/*********** NEW SHADER UTILITIES **************/
-float fresnel_dielectric(vec3 Incoming, vec3 Normal, float eta)
+float fresnel_dielectric_0(float eta)
+{
+ /* compute fresnel reflactance at normal incidence => cosi = 1.0 */
+ float A = (eta - 1.0) / (eta + 1.0);
+
+ return A * A;
+}
+
+float fresnel_dielectric_cos(float cosi, float eta)
{
/* compute fresnel reflectance without explicitly computing
* the refracted direction */
- float c = abs(dot(Incoming, Normal));
+ float c = abs(cosi);
float g = eta * eta - 1.0 + c * c;
float result;
@@ -2399,6 +2407,13 @@ float fresnel_dielectric(vec3 Incoming, vec3 Normal, float eta)
return result;
}
+float fresnel_dielectric(vec3 Incoming, vec3 Normal, float eta)
+{
+ /* compute fresnel reflectance without explicitly computing
+ * the refracted direction */
+ return fresnel_dielectric_cos(dot(Incoming, Normal), eta);
+}
+
float hypot(float x, float y)
{
return sqrt(x * x + y * y);
@@ -2492,6 +2507,57 @@ float floorfrac(float x, out int i)
return x - i;
}
+
+/* Principled BSDF operations */
+
+float sqr(float a)
+{
+ return a*a;
+}
+
+float schlick_fresnel(float u)
+{
+ float m = clamp(1.0 - u, 0.0, 1.0);
+ float m2 = m * m;
+ return m2 * m2 * m; // pow(m,5)
+}
+
+float GTR1(float NdotH, float a)
+{
+ if (a >= 1.0) return M_1_PI;
+ float a2 = a*a;
+ float t = 1.0 + (a2 - 1.0) * NdotH*NdotH;
+ return (a2 - 1.0) / (M_PI * log(a2) * t);
+}
+
+float GTR2(float NdotH, float a)
+{
+ float a2 = a*a;
+ float t = 1.0 + (a2 - 1.0) * NdotH*NdotH;
+ return a2 / (M_PI * t*t);
+}
+
+float GTR2_aniso(float NdotH, float HdotX, float HdotY, float ax, float ay)
+{
+ return 1.0 / (M_PI * ax*ay * sqr(sqr(HdotX / ax) + sqr(HdotY / ay) + NdotH*NdotH));
+}
+
+float smithG_GGX(float NdotV, float alphaG)
+{
+ float a = alphaG*alphaG;
+ float b = NdotV*NdotV;
+ return 1.0 / (NdotV + sqrt(a + b - a * b));
+}
+
+vec3 rotate_vector(vec3 p, vec3 n, float theta) {
+ return (
+ p * cos(theta) + cross(n, p) *
+ sin(theta) + n * dot(p, n) *
+ (1.0 - cos(theta))
+ );
+}
+
+
/*********** NEW SHADER NODES ***************/
#define NUM_LIGHTS 3
@@ -2553,6 +2619,125 @@ void node_bsdf_toon(vec4 color, float size, float tsmooth, vec3 N, out vec4 resu
node_bsdf_diffuse(color, 0.0, N, result);
}
+void node_bsdf_principled(vec4 base_color, float subsurface, vec3 subsurface_radius, vec4 subsurface_color, float metallic, float specular,
+ float specular_tint, float roughness, float anisotropic, float anisotropic_rotation, float sheen, float sheen_tint, float clearcoat,
+ float clearcoat_roughness, float ior, float transmission, float transmission_roughness, vec3 N, vec3 CN, vec3 T, vec3 I, out vec4 result)
+{
+ /* ambient light */
+ // TODO: set ambient light to an appropriate value
+ vec3 L = mix(0.1, 0.03, metallic) * mix(base_color.rgb, subsurface_color.rgb, subsurface * (1.0 - metallic));
+
+ float eta = (2.0 / (1.0 - sqrt(0.08 * specular))) - 1.0;
+
+ /* set the viewing vector */
+ vec3 V = (gl_ProjectionMatrix[3][3] == 0.0) ? -normalize(I) : vec3(0.0, 0.0, 1.0);
+
+ /* get the tangent */
+ vec3 Tangent = T;
+ if (T == vec3(0.0)) {
+ // if no tangent is set, use a default tangent
+ if(N.x != N.y || N.x != N.z) {
+ Tangent = vec3(N.z-N.y, N.x-N.z, N.y-N.x); // (1,1,1) x N
+ }
+ else {
+ Tangent = vec3(N.z-N.y, N.x+N.z, -N.y-N.x); // (-1,1,1) x N
+ }
+ }
+
+ /* rotate tangent */
+ if (anisotropic_rotation != 0.0) {
+ Tangent = rotate_vector(Tangent, N, anisotropic_rotation * 2.0 * M_PI);
+ }
+
+ /* calculate the tangent and bitangent */
+ vec3 Y = normalize(cross(N, Tangent));
+ vec3 X = cross(Y, N);
+
+ /* fresnel normalization parameters */
+ float F0 = fresnel_dielectric_0(eta);
+ float F0_norm = 1.0 / (1.0 - F0);
+
+ /* directional lights */
+ for (int i = 0; i < NUM_LIGHTS; i++) {
+ vec3 light_position_world = gl_LightSource[i].position.xyz;
+ vec3 light_position = normalize(light_position_world);
+
+ vec3 H = normalize(light_position + V);
+
+ vec3 light_diffuse = gl_LightSource[i].diffuse.rgb;
+ vec3 light_specular = gl_LightSource[i].specular.rgb;
+
+ float NdotL = dot(N, light_position);
+ float NdotV = dot(N, V);
+ float LdotH = dot(light_position, H);
+
+ vec3 diffuse_and_specular_bsdf = vec3(0.0);
+ if (NdotL >= 0.0 && NdotV >= 0.0) {
+ float NdotH = dot(N, H);
+
+ float Cdlum = 0.3 * base_color.r + 0.6 * base_color.g + 0.1 * base_color.b; // luminance approx.
+
+ vec3 Ctint = Cdlum > 0 ? base_color.rgb / Cdlum : vec3(1.0); // normalize lum. to isolate hue+sat
+ vec3 Cspec0 = mix(specular * 0.08 * mix(vec3(1.0), Ctint, specular_tint), base_color.rgb, metallic);
+ vec3 Csheen = mix(vec3(1.0), Ctint, sheen_tint);
+
+ // Diffuse fresnel - go from 1 at normal incidence to .5 at grazing
+ // and mix in diffuse retro-reflection based on roughness
+
+ float FL = schlick_fresnel(NdotL), FV = schlick_fresnel(NdotV);
+ float Fd90 = 0.5 + 2.0 * LdotH*LdotH * roughness;
+ float Fd = mix(1.0, Fd90, FL) * mix(1.0, Fd90, FV);
+
+ // Based on Hanrahan-Krueger brdf approximation of isotropic bssrdf
+ // 1.25 scale is used to (roughly) preserve albedo
+ // Fss90 used to "flatten" retroreflection based on roughness
+ float Fss90 = LdotH*LdotH * roughness;
+ float Fss = mix(1.0, Fss90, FL) * mix(1.0, Fss90, FV);
+ float ss = 1.25 * (Fss * (1.0 / (NdotL + NdotV) - 0.5) + 0.5);
+
+ // specular
+ float aspect = sqrt(1.0 - anisotropic * 0.9);
+ float a = sqr(roughness);
+ float ax = max(0.001, a / aspect);
+ float ay = max(0.001, a * aspect);
+ float Ds = GTR2_aniso(NdotH, dot(H, X), dot(H, Y), ax, ay); //GTR2(NdotH, a);
+ float FH = (fresnel_dielectric_cos(LdotH, eta) - F0) * F0_norm;
+ vec3 Fs = mix(Cspec0, vec3(1.0), FH);
+ float roughg = sqr(roughness * 0.5 + 0.5);
+ float Gs = smithG_GGX(NdotL, roughg) * smithG_GGX(NdotV, roughg);
+
+ // sheen
+ vec3 Fsheen = schlick_fresnel(LdotH) * sheen * Csheen;
+
+ vec3 diffuse_bsdf = (mix(Fd * base_color.rgb, ss * subsurface_color.rgb, subsurface) + Fsheen) * light_diffuse;
+ vec3 specular_bsdf = Gs * Fs * Ds * light_specular;
+ diffuse_and_specular_bsdf = diffuse_bsdf * (1.0 - metallic) + specular_bsdf;
+ }
+ diffuse_and_specular_bsdf *= max(NdotL, 0.0);
+
+ float CNdotL = dot(CN, light_position);
+ float CNdotV = dot(CN, V);
+
+ vec3 clearcoat_bsdf = vec3(0.0);
+ if (CNdotL >= 0.0 && CNdotV >= 0.0 && clearcoat > 0.0) {
+ float CNdotH = dot(CN, H);
+ //float FH = schlick_fresnel(LdotH);
+
+ // clearcoat (ior = 1.5 -> F0 = 0.04)
+ float Dr = GTR1(CNdotH, sqr(clearcoat_roughness));
+ float Fr = fresnel_dielectric_cos(LdotH, 1.5); //mix(0.04, 1.0, FH);
+ float Gr = smithG_GGX(CNdotL, 0.25) * smithG_GGX(CNdotV, 0.25);
+
+ clearcoat_bsdf = clearcoat * Gr * Fr * Dr * vec3(0.25) * light_specular;
+ }
+ clearcoat_bsdf *= max(CNdotL, 0.0);
+
+ L += diffuse_and_specular_bsdf + clearcoat_bsdf;
+ }
+
+ result = vec4(L, 1.0);
+}
+
void node_bsdf_translucent(vec4 color, vec3 N, out vec4 result)
{
node_bsdf_diffuse(color, 0.0, N, result);
@@ -2846,10 +3031,10 @@ vec2 calc_brick_texture(vec3 p, float mortar_size, float mortar_smooth, float bi
float tint = clamp((integer_noise((rownum << 16) + (bricknum & 0xFFFF)) + bias), 0.0, 1.0);
float min_dist = min(min(x, y), min(brick_width - x, row_height - y));
- if(min_dist >= mortar_size) {
+ if (min_dist >= mortar_size) {
return vec2(tint, 0.0);
}
- else if(mortar_smooth == 0.0) {
+ else if (mortar_smooth == 0.0) {
return vec2(tint, 1.0);
}
else {
@@ -3563,12 +3748,12 @@ void node_light_falloff(float strength, float tsmooth, out float quadratic, out
constant = strength;
}
-void node_object_info(out vec3 location, out float object_index, out float material_index, out float random)
+void node_object_info(mat4 obmat, vec3 info, out vec3 location, out float object_index, out float material_index, out float random)
{
- location = vec3(0.0);
- object_index = 0.0;
- material_index = 0.0;
- random = 0.0;
+ location = obmat[3].xyz;
+ object_index = info.x;
+ material_index = info.y;
+ random = info.z;
}
void node_normal_map(vec4 tangent, vec3 normal, vec3 texnormal, out vec3 outnormal)
diff --git a/source/blender/ikplugin/intern/iksolver_plugin.c b/source/blender/ikplugin/intern/iksolver_plugin.c
index 6ea311b2c7b..f837789914e 100644
--- a/source/blender/ikplugin/intern/iksolver_plugin.c
+++ b/source/blender/ikplugin/intern/iksolver_plugin.c
@@ -217,9 +217,27 @@ static void where_is_ik_bone(bPoseChannel *pchan, float ik_mat[3][3]) // nr =
copy_m4_m3(ikmat, ik_mat);
if (pchan->parent)
- mul_m4_series(pchan->pose_mat, pchan->parent->pose_mat, pchan->chan_mat, ikmat);
+ mul_m4_m4m4(pchan->pose_mat, pchan->parent->pose_mat, pchan->chan_mat);
else
- mul_m4_m4m4(pchan->pose_mat, pchan->chan_mat, ikmat);
+ copy_m4_m4(pchan->pose_mat, pchan->chan_mat);
+
+#ifdef USE_NONUNIFORM_SCALE
+ /* apply IK mat, but as if the bones have uniform scale since the IK solver
+ * is not aware of non-uniform scale */
+ float scale[3];
+ mat4_to_size(scale, pchan->pose_mat);
+ normalize_v3_length(pchan->pose_mat[0], scale[1]);
+ normalize_v3_length(pchan->pose_mat[2], scale[1]);
+#endif
+
+ mul_m4_m4m4(pchan->pose_mat, pchan->pose_mat, ikmat);
+
+#ifdef USE_NONUNIFORM_SCALE
+ float ik_scale[3];
+ mat3_to_size(ik_scale, ik_mat);
+ normalize_v3_length(pchan->pose_mat[0], scale[0] * ik_scale[0]);
+ normalize_v3_length(pchan->pose_mat[2], scale[2] * ik_scale[2]);
+#endif
/* calculate head */
copy_v3_v3(pchan->pose_head, pchan->pose_mat[3]);
@@ -308,6 +326,10 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
/* change length based on bone size */
length = bone->length * len_v3(R_bonemat[1]);
+ /* basis must be pure rotation */
+ normalize_m3(R_bonemat);
+ normalize_m3(R_parmat);
+
/* compute rest basis and its inverse */
copy_m3_m3(rest_basis, bone->bone_mat);
transpose_m3_m3(irest_basis, bone->bone_mat);
@@ -317,11 +339,7 @@ static void execute_posetree(struct Scene *scene, Object *ob, PoseTree *tree)
mul_m3_m3m3(full_basis, iR_parmat, R_bonemat);
mul_m3_m3m3(basis, irest_basis, full_basis);
- /* basis must be pure rotation */
- normalize_m3(basis);
-
/* transform offset into local bone space */
- normalize_m3(iR_parmat);
mul_m3_v3(iR_parmat, start);
IK_SetTransform(seg, start, rest_basis, basis, length);
@@ -545,18 +563,6 @@ void iksolver_execute_tree(struct Scene *scene, Object *ob, bPoseChannel *pchan
tree->pchan[a]->flag |= POSE_CHAIN;
}
-#ifdef USE_NONUNIFORM_SCALE
- float (*pchan_scale_data)[3] = MEM_mallocN(sizeof(float[3]) * tree->totchannel, __func__);
-
- for (a = 0; a < tree->totchannel; a++) {
- mat4_to_size(pchan_scale_data[a], tree->pchan[a]->pose_mat);
-
- /* make uniform at y scale since this controls the length */
- normalize_v3_length(tree->pchan[a]->pose_mat[0], pchan_scale_data[a][1]);
- normalize_v3_length(tree->pchan[a]->pose_mat[2], pchan_scale_data[a][1]);
- }
-#endif
-
/* 5. execute the IK solver */
execute_posetree(scene, ob, tree);
@@ -571,14 +577,6 @@ void iksolver_execute_tree(struct Scene *scene, Object *ob, bPoseChannel *pchan
where_is_ik_bone(tree->pchan[a], tree->basis_change[a]);
}
-#ifdef USE_NONUNIFORM_SCALE
- for (a = 0; a < tree->totchannel; a++) {
- normalize_v3_length(tree->pchan[a]->pose_mat[0], pchan_scale_data[a][0]);
- normalize_v3_length(tree->pchan[a]->pose_mat[2], pchan_scale_data[a][2]);
- }
- MEM_freeN(pchan_scale_data);
-#endif
-
/* 7. and free */
BLI_remlink(&pchan_root->iktree, tree);
free_posetree(tree);
diff --git a/source/blender/imbuf/IMB_colormanagement.h b/source/blender/imbuf/IMB_colormanagement.h
index 4164f5fa75d..ff1784c54dd 100644
--- a/source/blender/imbuf/IMB_colormanagement.h
+++ b/source/blender/imbuf/IMB_colormanagement.h
@@ -162,7 +162,7 @@ void IMB_colormanagment_colorspace_from_ibuf_ftype(struct ColorManagedColorspace
/* ** RNA helper functions ** */
void IMB_colormanagement_display_items_add(struct EnumPropertyItem **items, int *totitem);
void IMB_colormanagement_view_items_add(struct EnumPropertyItem **items, int *totitem, const char *display_name);
-void IMB_colormanagement_look_items_add(struct EnumPropertyItem **items, int *totitem);
+void IMB_colormanagement_look_items_add(struct EnumPropertyItem **items, int *totitem, const char *view_name);
void IMB_colormanagement_colorspace_items_add(struct EnumPropertyItem **items, int *totitem);
/* ** Tile-based buffer management ** */
diff --git a/source/blender/imbuf/IMB_imbuf.h b/source/blender/imbuf/IMB_imbuf.h
index 93d2b3e0cd0..f1f36351e79 100644
--- a/source/blender/imbuf/IMB_imbuf.h
+++ b/source/blender/imbuf/IMB_imbuf.h
@@ -166,7 +166,7 @@ struct ImBuf *IMB_makeSingleUser(struct ImBuf *ibuf);
*
* \attention Defined in allocimbuf.c
*/
-struct ImBuf *IMB_dupImBuf(struct ImBuf *ibuf1);
+struct ImBuf *IMB_dupImBuf(const struct ImBuf *ibuf1);
/**
*
@@ -205,6 +205,7 @@ typedef enum IMB_BlendMode {
IMB_BLEND_SATURATION = 21,
IMB_BLEND_LUMINOSITY = 22,
IMB_BLEND_COLOR = 23,
+ IMB_BLEND_INTERPOLATE = 24,
IMB_BLEND_COPY = 1000,
IMB_BLEND_COPY_RGB = 1001,
diff --git a/source/blender/imbuf/IMB_imbuf_types.h b/source/blender/imbuf/IMB_imbuf_types.h
index f4b2539d7d7..1701c2ba307 100644
--- a/source/blender/imbuf/IMB_imbuf_types.h
+++ b/source/blender/imbuf/IMB_imbuf_types.h
@@ -237,9 +237,8 @@ typedef struct ImBuf {
/**
* \name Imbuf Component flags
* \brief These flags determine the components of an ImBuf struct.
- */
-/**@{*/
-/** \brief Flag defining the components of the ImBuf struct. */
+ *
+ * \{ */
#define IB_rect (1 << 0)
#define IB_test (1 << 1)
@@ -259,15 +258,20 @@ typedef struct ImBuf {
#define IB_thumbnail (1 << 15)
#define IB_multiview (1 << 16)
+/** \} */
+
/**
* \name Imbuf preset profile tags
* \brief Some predefined color space profiles that 8 bit imbufs can represent
- */
+ *
+ * \{ */
#define IB_PROFILE_NONE 0
#define IB_PROFILE_LINEAR_RGB 1
#define IB_PROFILE_SRGB 2
#define IB_PROFILE_CUSTOM 3
+/** \} */
+
/* dds */
#ifdef WITH_DDS
#ifndef DDS_MAKEFOURCC
@@ -298,8 +302,16 @@ extern const char *imb_ext_audio[];
/* image formats that can only be loaded via filepath */
extern const char *imb_ext_image_filepath_only[];
+/**
+ * \name Imbuf Color Management Flag
+ * \brief Used with #ImBuf.colormanage_flag
+ *
+ * \{ */
+
enum {
IMB_COLORMANAGE_IS_DATA = (1 << 0)
};
-#endif
+/** \} */
+
+#endif /* __IMB_IMBUF_TYPES_H__ */
diff --git a/source/blender/imbuf/intern/IMB_anim.h b/source/blender/imbuf/intern/IMB_anim.h
index d89393b9903..6d7ad7985f9 100644
--- a/source/blender/imbuf/intern/IMB_anim.h
+++ b/source/blender/imbuf/intern/IMB_anim.h
@@ -40,10 +40,7 @@
# include <mmsystem.h>
# include <memory.h>
# include <commdlg.h>
-
-# ifndef FREE_WINDOWS
-# include <vfw.h>
-# endif
+# include <vfw.h>
# undef AVIIF_KEYFRAME // redefined in AVI_avi.h
# undef AVIIF_LIST // redefined in AVI_avi.h
@@ -130,7 +127,7 @@ struct anim {
/* avi */
struct _AviMovie *avi;
-#if defined(_WIN32) && !defined(FREE_WINDOWS)
+#if defined(_WIN32)
/* windows avi */
int avistreams;
int firstvideo;
diff --git a/source/blender/imbuf/intern/IMB_colormanagement_intern.h b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
index b75f12b239d..0b4557e7bef 100644
--- a/source/blender/imbuf/intern/IMB_colormanagement_intern.h
+++ b/source/blender/imbuf/intern/IMB_colormanagement_intern.h
@@ -79,6 +79,8 @@ typedef struct ColorManagedLook {
struct ColorManagedLook *next, *prev;
int index;
char name[MAX_COLORSPACE_NAME];
+ char ui_name[MAX_COLORSPACE_NAME];
+ char view[MAX_COLORSPACE_NAME];
char process_space[MAX_COLORSPACE_NAME];
bool is_noop;
} ColorManagedLook;
diff --git a/source/blender/imbuf/intern/allocimbuf.c b/source/blender/imbuf/intern/allocimbuf.c
index 33750478bb4..6e9bfa1fc4e 100644
--- a/source/blender/imbuf/intern/allocimbuf.c
+++ b/source/blender/imbuf/intern/allocimbuf.c
@@ -506,7 +506,7 @@ bool IMB_initImBuf(struct ImBuf *ibuf,
}
/* does no zbuffers? */
-ImBuf *IMB_dupImBuf(ImBuf *ibuf1)
+ImBuf *IMB_dupImBuf(const ImBuf *ibuf1)
{
ImBuf *ibuf2, tbuf;
int flags = 0;
diff --git a/source/blender/imbuf/intern/anim_movie.c b/source/blender/imbuf/intern/anim_movie.c
index a40b257b75b..9806ff006d7 100644
--- a/source/blender/imbuf/intern/anim_movie.c
+++ b/source/blender/imbuf/intern/anim_movie.c
@@ -37,10 +37,7 @@
#include <mmsystem.h>
#include <memory.h>
#include <commdlg.h>
-
-#ifndef FREE_WINDOWS
#include <vfw.h>
-#endif
#undef AVIIF_KEYFRAME /* redefined in AVI_avi.h */
#undef AVIIF_LIST /* redefined in AVI_avi.h */
@@ -173,7 +170,7 @@ static void an_stringenc(char *string, const char *head, const char *tail, unsig
#ifdef WITH_AVI
static void free_anim_avi(struct anim *anim)
{
-#if defined(_WIN32) && !defined(FREE_WINDOWS)
+#if defined(_WIN32)
int i;
#endif
@@ -184,7 +181,7 @@ static void free_anim_avi(struct anim *anim)
MEM_freeN(anim->avi);
anim->avi = NULL;
-#if defined(_WIN32) && !defined(FREE_WINDOWS)
+#if defined(_WIN32)
if (anim->pgf) {
AVIStreamGetFrameClose(anim->pgf);
@@ -283,7 +280,7 @@ static int startavi(struct anim *anim)
{
AviError avierror;
-#if defined(_WIN32) && !defined(FREE_WINDOWS)
+#if defined(_WIN32)
HRESULT hr;
int i, firstvideo = -1;
int streamcount;
@@ -304,7 +301,7 @@ static int startavi(struct anim *anim)
avierror = AVI_open_movie(anim->name, anim->avi);
-#if defined(_WIN32) && !defined(FREE_WINDOWS)
+#if defined(_WIN32)
if (avierror == AVI_ERROR_COMPRESSION) {
AVIFileInit();
hr = AVIFileOpen(&anim->pfile, anim->name, OF_READ, 0L);
@@ -401,7 +398,7 @@ static ImBuf *avi_fetchibuf(struct anim *anim, int position)
return NULL;
}
-#if defined(_WIN32) && !defined(FREE_WINDOWS)
+#if defined(_WIN32)
if (anim->avistreams) {
LPBITMAPINFOHEADER lpbi;
diff --git a/source/blender/imbuf/intern/cineon/dpxlib.c b/source/blender/imbuf/intern/cineon/dpxlib.c
index 8b4e95ac452..429a19936a5 100644
--- a/source/blender/imbuf/intern/cineon/dpxlib.c
+++ b/source/blender/imbuf/intern/cineon/dpxlib.c
@@ -183,7 +183,7 @@ LogImageFile *dpxOpen(const unsigned char *byteStuff, int fromMemory, size_t buf
if (verbose) printf("DPX: File is LSB.\n");
}
else {
- if (verbose) {
+ if (verbose) {
printf("DPX: Bad magic number %u in \"%s\".\n",
header.fileHeader.magic_num, byteStuff);
}
diff --git a/source/blender/imbuf/intern/cineon/logImageCore.c b/source/blender/imbuf/intern/cineon/logImageCore.c
index 6fb1bccf491..600642f5e44 100644
--- a/source/blender/imbuf/intern/cineon/logImageCore.c
+++ b/source/blender/imbuf/intern/cineon/logImageCore.c
@@ -177,19 +177,18 @@ unsigned int getRowLength(int width, LogImageElement logElement)
return ((width * logElement.depth * 10 - 1) / 32 + 1) * 4;
else if (logElement.packing == 1 || logElement.packing == 2)
return ((width * logElement.depth - 1) / 3 + 1) * 4;
-
+ break;
case 12:
if (logElement.packing == 0)
return ((width * logElement.depth * 12 - 1) / 32 + 1) * 4;
else if (logElement.packing == 1 || logElement.packing == 2)
return width * logElement.depth * 2;
-
+ break;
case 16:
return width * logElement.depth * 2;
- default:
- return 0;
}
+ return 0;
}
@@ -572,20 +571,20 @@ static int logImageElementGetData(LogImageFile *logImage, LogImageElement logEle
return logImageElementGetData10Packed(logImage, logElement, data);
else if (logElement.packing == 1 || logElement.packing == 2)
return logImageElementGetData10(logImage, logElement, data);
+ break;
case 12:
if (logElement.packing == 0)
return logImageElementGetData12Packed(logImage, logElement, data);
else if (logElement.packing == 1 || logElement.packing == 2)
return logImageElementGetData12(logImage, logElement, data);
+ break;
case 16:
return logImageElementGetData16(logImage, logElement, data);
-
- default:
- /* format not supported */
- return 1;
}
+ /* format not supported */
+ return 1;
}
static int logImageElementGetData1(LogImageFile *logImage, LogImageElement logElement, float *data)
diff --git a/source/blender/imbuf/intern/colormanagement.c b/source/blender/imbuf/intern/colormanagement.c
index 48cba3e0800..03f71b5878c 100644
--- a/source/blender/imbuf/intern/colormanagement.c
+++ b/source/blender/imbuf/intern/colormanagement.c
@@ -63,6 +63,7 @@
#include "BKE_context.h"
#include "BKE_image.h"
#include "BKE_main.h"
+#include "BKE_sequencer.h"
#include "RNA_define.h"
@@ -214,7 +215,7 @@ typedef struct ColormanageCacheKey {
int display; /* display device name */
} ColormanageCacheKey;
-typedef struct ColormnaageCacheData {
+typedef struct ColormanageCacheData {
int flag; /* view flags of cached buffer */
int look; /* Additional artistics transform */
float exposure; /* exposure value cached buffer is calculated with */
@@ -222,12 +223,12 @@ typedef struct ColormnaageCacheData {
float dither; /* dither value cached buffer is calculated with */
CurveMapping *curve_mapping; /* curve mapping used for cached buffer */
int curve_mapping_timestamp; /* time stamp of curve mapping used for cached buffer */
-} ColormnaageCacheData;
+} ColormanageCacheData;
typedef struct ColormanageCache {
struct MovieCache *moviecache;
- ColormnaageCacheData *data;
+ ColormanageCacheData *data;
} ColormanageCache;
static struct MovieCache *colormanage_moviecache_get(const ImBuf *ibuf)
@@ -238,7 +239,7 @@ static struct MovieCache *colormanage_moviecache_get(const ImBuf *ibuf)
return ibuf->colormanage_cache->moviecache;
}
-static ColormnaageCacheData *colormanage_cachedata_get(const ImBuf *ibuf)
+static ColormanageCacheData *colormanage_cachedata_get(const ImBuf *ibuf)
{
if (!ibuf->colormanage_cache)
return NULL;
@@ -281,7 +282,7 @@ static struct MovieCache *colormanage_moviecache_ensure(ImBuf *ibuf)
return ibuf->colormanage_cache->moviecache;
}
-static void colormanage_cachedata_set(ImBuf *ibuf, ColormnaageCacheData *data)
+static void colormanage_cachedata_set(ImBuf *ibuf, ColormanageCacheData *data)
{
if (!ibuf->colormanage_cache)
ibuf->colormanage_cache = MEM_callocN(sizeof(ColormanageCache), "imbuf colormanage cache");
@@ -361,7 +362,7 @@ static unsigned char *colormanage_cache_get(ImBuf *ibuf, const ColormanageCacheV
cache_ibuf = colormanage_cache_get_ibuf(ibuf, &key, cache_handle);
if (cache_ibuf) {
- ColormnaageCacheData *cache_data;
+ ColormanageCacheData *cache_data;
BLI_assert(cache_ibuf->x == ibuf->x &&
cache_ibuf->y == ibuf->y);
@@ -402,7 +403,7 @@ static void colormanage_cache_put(ImBuf *ibuf, const ColormanageCacheViewSetting
{
ColormanageCacheKey key;
ImBuf *cache_ibuf;
- ColormnaageCacheData *cache_data;
+ ColormanageCacheData *cache_data;
int view_flag = 1 << (view_settings->view - 1);
struct MovieCache *moviecache = colormanage_moviecache_ensure(ibuf);
CurveMapping *curve_mapping = view_settings->curve_mapping;
@@ -421,7 +422,7 @@ static void colormanage_cache_put(ImBuf *ibuf, const ColormanageCacheViewSetting
cache_ibuf->flags |= IB_rect;
/* store data which is needed to check whether cached buffer could be used for color managed display settings */
- cache_data = MEM_callocN(sizeof(ColormnaageCacheData), "color manage cache imbuf data");
+ cache_data = MEM_callocN(sizeof(ColormanageCacheData), "color manage cache imbuf data");
cache_data->look = view_settings->look;
cache_data->exposure = view_settings->exposure;
cache_data->gamma = view_settings->gamma;
@@ -710,7 +711,7 @@ void colormanage_cache_free(ImBuf *ibuf)
}
if (ibuf->colormanage_cache) {
- ColormnaageCacheData *cache_data = colormanage_cachedata_get(ibuf);
+ ColormanageCacheData *cache_data = colormanage_cachedata_get(ibuf);
struct MovieCache *moviecache = colormanage_moviecache_get(ibuf);
if (cache_data) {
@@ -1112,6 +1113,7 @@ void IMB_colormanagement_check_file_config(Main *bmain)
for (scene = bmain->scene.first; scene; scene = scene->id.next) {
ColorManagedColorspaceSettings *sequencer_colorspace_settings;
+ /* check scene color management settings */
colormanage_check_display_settings(&scene->display_settings, "scene", default_display);
colormanage_check_view_settings(&scene->display_settings, &scene->view_settings, "scene");
@@ -1122,6 +1124,15 @@ void IMB_colormanagement_check_file_config(Main *bmain)
if (sequencer_colorspace_settings->name[0] == '\0') {
BLI_strncpy(sequencer_colorspace_settings->name, global_role_default_sequencer, MAX_COLORSPACE_NAME);
}
+
+ /* check sequencer strip input color space settings */
+ Sequence *seq;
+ SEQ_BEGIN (scene->ed, seq) {
+ if (seq->strip) {
+ colormanage_check_colorspace_settings(&seq->strip->colorspace_settings, "sequencer strip");
+ }
+ }
+ SEQ_END
}
/* ** check input color space settings ** */
@@ -1406,7 +1417,7 @@ static void *do_display_buffer_apply_thread(void *handle_v)
bool is_data = handle->is_data;
if (cm_processor == NULL) {
- if (display_buffer_byte) {
+ if (display_buffer_byte && display_buffer_byte != handle->byte_buffer) {
IMB_buffer_byte_from_byte(display_buffer_byte, handle->byte_buffer, IB_PROFILE_SRGB, IB_PROFILE_SRGB,
false, width, height, width, width);
}
@@ -1759,9 +1770,14 @@ void IMB_colormanagement_transform_from_byte_threaded(float *float_buffer, unsig
return;
}
if (STREQ(from_colorspace, to_colorspace)) {
- /* If source and destination color spaces are identical, skip
- * threading overhead and simply do nothing
+ /* Because this function always takes a byte buffer and returns a float buffer, it must
+ * always do byte-to-float conversion of some kind. To avoid threading overhead
+ * IMB_buffer_float_from_byte is used when color spaces are identical. See T51002.
*/
+ IMB_buffer_float_from_byte(float_buffer, byte_buffer,
+ IB_PROFILE_SRGB, IB_PROFILE_SRGB,
+ true,
+ width, height, width, width);
return;
}
cm_processor = IMB_colormanagement_colorspace_processor_new(from_colorspace, to_colorspace);
@@ -2060,6 +2076,10 @@ ImBuf *IMB_colormanagement_imbuf_for_write(ImBuf *ibuf, bool save_as_render, boo
}
}
+ if (colormanaged_ibuf != ibuf) {
+ IMB_metadata_copy(colormanaged_ibuf, ibuf);
+ }
+
return colormanaged_ibuf;
}
@@ -2568,9 +2588,17 @@ ColorManagedLook *colormanage_look_add(const char *name, const char *process_spa
look = MEM_callocN(sizeof(ColorManagedLook), "ColorManagedLook");
look->index = index + 1;
BLI_strncpy(look->name, name, sizeof(look->name));
+ BLI_strncpy(look->ui_name, name, sizeof(look->ui_name));
BLI_strncpy(look->process_space, process_space, sizeof(look->process_space));
look->is_noop = is_noop;
+ /* Detect view specific looks. */
+ const char *separator_offset = strstr(look->name, " - ");
+ if (separator_offset) {
+ BLI_strncpy(look->view, look->name, separator_offset - look->name + 1);
+ BLI_strncpy(look->ui_name, separator_offset + strlen(" - "), sizeof(look->ui_name));
+ }
+
BLI_addtail(&global_looks, look);
global_tot_looks++;
@@ -2671,15 +2699,27 @@ void IMB_colormanagement_view_items_add(EnumPropertyItem **items, int *totitem,
}
}
-void IMB_colormanagement_look_items_add(struct EnumPropertyItem **items, int *totitem)
+void IMB_colormanagement_look_items_add(struct EnumPropertyItem **items, int *totitem, const char *view_name)
{
ColorManagedLook *look;
+ const char *view_filter = NULL;
+
+ /* Test if this view transform is limited to specific looks. */
+ for (look = global_looks.first; look; look = look->next) {
+ if (STREQ(look->view, view_name)) {
+ view_filter = view_name;
+ }
+ }
for (look = global_looks.first; look; look = look->next) {
+ if (!look->is_noop && view_filter && !STREQ(look->view, view_filter)) {
+ continue;
+ }
+
EnumPropertyItem item;
item.value = look->index;
- item.name = look->name;
+ item.name = look->ui_name;
item.identifier = look->name;
item.icon = 0;
item.description = "";
diff --git a/source/blender/imbuf/intern/dds/dds_api.cpp b/source/blender/imbuf/intern/dds/dds_api.cpp
index 12e03f55450..67a0b0ffd00 100644
--- a/source/blender/imbuf/intern/dds/dds_api.cpp
+++ b/source/blender/imbuf/intern/dds/dds_api.cpp
@@ -37,7 +37,7 @@ extern "C" {
#include <stdio.h> // printf
#include <fstream>
-#if defined (WIN32) && !defined(FREE_WINDOWS)
+#if defined (WIN32)
#include "utfconv.h"
#endif
@@ -62,7 +62,7 @@ int imb_save_dds(struct ImBuf *ibuf, const char *name, int /*flags*/)
/* open file for writing */
std::ofstream fildes;
-#if defined (WIN32) && !defined(FREE_WINDOWS)
+#if defined (WIN32)
wchar_t *wname = alloc_utf16_from_8(name, 0);
fildes.open(wname);
free(wname);
diff --git a/source/blender/imbuf/intern/filter.c b/source/blender/imbuf/intern/filter.c
index 1987c6d2a9a..38609d0a342 100644
--- a/source/blender/imbuf/intern/filter.c
+++ b/source/blender/imbuf/intern/filter.c
@@ -406,7 +406,7 @@ void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter)
const int height = ibuf->y;
const int depth = 4; /* always 4 channels */
const int chsize = ibuf->rect_float ? sizeof(float) : sizeof(unsigned char);
- const int bsize = width * height * depth * chsize;
+ const size_t bsize = ((size_t)width) * height * depth * chsize;
const bool is_float = (ibuf->rect_float != NULL);
void *dstbuf = (void *) MEM_dupallocN(ibuf->rect_float ? (void *) ibuf->rect_float : (void *) ibuf->rect);
char *dstmask = mask == NULL ? NULL : (char *) MEM_dupallocN(mask);
@@ -499,7 +499,9 @@ void IMB_filter_extend(struct ImBuf *ibuf, char *mask, int filter)
/* keep the original buffer up to date. */
memcpy(srcbuf, dstbuf, bsize);
- if (dstmask != NULL) memcpy(srcmask, dstmask, width * height);
+ if (dstmask != NULL) {
+ memcpy(srcmask, dstmask, ((size_t)width) * height);
+ }
}
/* free memory */
diff --git a/source/blender/imbuf/intern/metadata.c b/source/blender/imbuf/intern/metadata.c
index 134bbe88f15..da39967a4fe 100644
--- a/source/blender/imbuf/intern/metadata.c
+++ b/source/blender/imbuf/intern/metadata.c
@@ -81,7 +81,9 @@ bool IMB_metadata_get_field(struct ImBuf *img, const char *key, char *field, con
void IMB_metadata_copy(struct ImBuf *dimb, struct ImBuf *simb)
{
+ BLI_assert(dimb != simb);
if (simb->metadata) {
+ IMB_metadata_free(dimb);
dimb->metadata = IDP_CopyProperty(simb->metadata);
}
}
diff --git a/source/blender/imbuf/intern/oiio/openimageio_api.cpp b/source/blender/imbuf/intern/oiio/openimageio_api.cpp
index 11bf45418d6..b123d508f99 100644
--- a/source/blender/imbuf/intern/oiio/openimageio_api.cpp
+++ b/source/blender/imbuf/intern/oiio/openimageio_api.cpp
@@ -31,7 +31,7 @@
#include <set>
-#if defined(WIN32) && !defined(FREE_WINDOWS)
+#if defined(WIN32)
#include "utfconv.h"
#endif
@@ -213,7 +213,7 @@ struct ImBuf *imb_load_photoshop(const char *filename, int flags, char colorspac
in = ImageInput::create(filename);
if (!in) {
std::cerr << __func__ << ": ImageInput::create() failed:" << std::endl
- << OpenImageIO::geterror() << std::endl;
+ << OIIO_NAMESPACE::geterror() << std::endl;
return NULL;
}
diff --git a/source/blender/imbuf/intern/openexr/openexr_api.cpp b/source/blender/imbuf/intern/openexr/openexr_api.cpp
index 89e796fb7ee..1fa3b943524 100644
--- a/source/blender/imbuf/intern/openexr/openexr_api.cpp
+++ b/source/blender/imbuf/intern/openexr/openexr_api.cpp
@@ -69,7 +69,7 @@
#include <openexr_api.h>
-#if defined (WIN32) && !defined(FREE_WINDOWS)
+#if defined (WIN32)
#include "utfconv.h"
#endif
@@ -77,7 +77,7 @@ extern "C"
{
// The following prevents a linking error in debug mode for MSVC using the libs in CVS
-#if defined(WITH_OPENEXR) && defined(_WIN32) && defined(DEBUG) && !defined(__MINGW32__) && _MSC_VER < 1900
+#if defined(WITH_OPENEXR) && defined(_WIN32) && defined(DEBUG) && _MSC_VER < 1900
_CRTIMP void __cdecl _invalid_parameter_noinfo(void)
{
}
@@ -180,7 +180,7 @@ public:
: IStream(filename)
{
/* utf-8 file path support on windows */
-#if defined (WIN32) && !defined(FREE_WINDOWS)
+#if defined (WIN32)
wchar_t *wfilename = alloc_utf16_from_8(filename, 0);
ifs.open(wfilename, std::ios_base::binary);
free(wfilename);
@@ -243,7 +243,7 @@ public:
: OStream(filename)
{
/* utf-8 file path support on windows */
-#if defined (WIN32) && !defined(FREE_WINDOWS)
+#if defined (WIN32)
wchar_t *wfilename = alloc_utf16_from_8(filename, 0);
ofs.open(wfilename, std::ios_base::binary);
free(wfilename);
@@ -1026,15 +1026,16 @@ void IMB_exr_set_channel(void *handle, const char *layname, const char *passname
ExrChannel *echan;
char name[EXR_TOT_MAXNAME + 1];
- if (layname) {
+ if (layname && layname[0] != '\0') {
char lay[EXR_LAY_MAXNAME + 1], pass[EXR_PASS_MAXNAME + 1];
BLI_strncpy(lay, layname, EXR_LAY_MAXNAME);
BLI_strncpy(pass, passname, EXR_PASS_MAXNAME);
BLI_snprintf(name, sizeof(name), "%s.%s", lay, pass);
}
- else
+ else {
BLI_strncpy(name, passname, EXR_TOT_MAXNAME - 1);
+ }
echan = (ExrChannel *)BLI_findstring(&data->channels, name, offsetof(ExrChannel, name));
@@ -1043,8 +1044,9 @@ void IMB_exr_set_channel(void *handle, const char *layname, const char *passname
echan->ystride = ystride;
echan->rect = rect;
}
- else
+ else {
printf("IMB_exr_set_channel error %s\n", name);
+ }
}
float *IMB_exr_channel_rect(void *handle, const char *layname, const char *passname, const char *viewname)
@@ -1102,7 +1104,7 @@ void IMB_exr_write_channels(void *handle)
if (data->channels.first) {
const size_t num_pixels = ((size_t)data->width) * data->height;
- half *rect_half = NULL, *current_rect_half;
+ half *rect_half = NULL, *current_rect_half = NULL;
/* We allocate teporary storage for half pixels for all the channels at once. */
if (data->num_half_channels != 0) {
diff --git a/source/blender/imbuf/intern/png.c b/source/blender/imbuf/intern/png.c
index 5192e3f2d26..503e63a3fb1 100644
--- a/source/blender/imbuf/intern/png.c
+++ b/source/blender/imbuf/intern/png.c
@@ -613,11 +613,12 @@ ImBuf *imb_loadpng(const unsigned char *mem, size_t size, int flags, char colors
int unit_type;
png_uint_32 xres, yres;
- if (png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type))
+ if (png_get_pHYs(png_ptr, info_ptr, &xres, &yres, &unit_type)) {
if (unit_type == PNG_RESOLUTION_METER) {
ibuf->ppm[0] = xres;
ibuf->ppm[1] = yres;
}
+ }
}
}
else {
diff --git a/source/blender/imbuf/intern/radiance_hdr.c b/source/blender/imbuf/intern/radiance_hdr.c
index 71e74928e20..a21468e474c 100644
--- a/source/blender/imbuf/intern/radiance_hdr.c
+++ b/source/blender/imbuf/intern/radiance_hdr.c
@@ -340,13 +340,14 @@ static int fwritecolrs(FILE *file, int width, int channels, unsigned char *ibufs
}
if (((beg - j) > 1) && ((beg - j) < MINRUN)) {
c2 = j + 1;
- while (rgbe_scan[c2++][i] == rgbe_scan[j][i])
+ while (rgbe_scan[c2++][i] == rgbe_scan[j][i]) {
if (c2 == beg) { /* short run */
putc((unsigned char)(128 + beg - j), file);
putc((unsigned char)(rgbe_scan[j][i]), file);
j = beg;
break;
}
+ }
}
while (j < beg) { /* write out non-run */
if ((c2 = beg - j) > 128) c2 = 128;
diff --git a/source/blender/imbuf/intern/rectop.c b/source/blender/imbuf/intern/rectop.c
index 3360fd7548e..c4325caac91 100644
--- a/source/blender/imbuf/intern/rectop.c
+++ b/source/blender/imbuf/intern/rectop.c
@@ -301,8 +301,8 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
int destx, int desty, int origx, int origy, int srcx, int srcy, int width, int height,
IMB_BlendMode mode, bool accumulate)
{
- unsigned int *drect = NULL, *orect, *srect = NULL, *dr, *or, *sr;
- float *drectf = NULL, *orectf, *srectf = NULL, *drf, *orf, *srf;
+ unsigned int *drect = NULL, *orect = NULL, *srect = NULL, *dr, *or, *sr;
+ float *drectf = NULL, *orectf = NULL, *srectf = NULL, *drf, *orf, *srf;
unsigned short *cmaskrect = curvemask, *cmr;
unsigned short *dmaskrect = dmask, *dmr;
unsigned short *texmaskrect = texmask, *tmr;
@@ -424,6 +424,7 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
else {
switch (mode) {
case IMB_BLEND_MIX:
+ case IMB_BLEND_INTERPOLATE:
func = blend_color_mix_byte;
func_float = blend_color_mix_float;
break;
@@ -563,9 +564,15 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
mask_src[0] = src[0];
mask_src[1] = src[1];
mask_src[2] = src[2];
- mask_src[3] = divide_round_i(src[3] * mask, 65535);
- func((unsigned char *)dr, (unsigned char *)or, mask_src);
+ if (mode == IMB_BLEND_INTERPOLATE) {
+ mask_src[3] = src[3];
+ blend_color_interpolate_byte((unsigned char *)dr, (unsigned char *)or, mask_src, mask / 65535.0f);
+ }
+ else {
+ mask_src[3] = divide_round_i(src[3] * mask, 65535);
+ func((unsigned char *)dr, (unsigned char *)or, mask_src);
+ }
}
}
}
@@ -588,9 +595,15 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
mask_src[0] = src[0];
mask_src[1] = src[1];
mask_src[2] = src[2];
- mask_src[3] = divide_round_i(src[3] * mask, 65535);
- func((unsigned char *)dr, (unsigned char *)or, mask_src);
+ if (mode == IMB_BLEND_INTERPOLATE) {
+ mask_src[3] = src[3];
+ blend_color_interpolate_byte((unsigned char *)dr, (unsigned char *)or, mask_src, mask / 65535.0f);
+ }
+ else {
+ mask_src[3] = divide_round_i(src[3] * mask, 65535);
+ func((unsigned char *)dr, (unsigned char *)or, mask_src);
+ }
}
}
}
@@ -642,12 +655,16 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
mask = min_ff(mask, 65535.0);
if (mask > *dmr) {
- float mask_srf[4];
-
*dmr = mask;
- mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
- func_float(drf, orf, mask_srf);
+ if (mode == IMB_BLEND_INTERPOLATE) {
+ blend_color_interpolate_float(drf, orf, srf, mask / 65535.0f);
+ }
+ else {
+ float mask_srf[4];
+ mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
+ func_float(drf, orf, mask_srf);
+ }
}
}
}
@@ -664,11 +681,15 @@ void IMB_rectblend(ImBuf *dbuf, ImBuf *obuf, ImBuf *sbuf, unsigned short *dmask,
mask = min_ff(mask, 65535.0);
if (srf[3] && (mask > 0.0f)) {
- float mask_srf[4];
-
- mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
+ if (mode == IMB_BLEND_INTERPOLATE) {
+ blend_color_interpolate_float(drf, orf, srf, mask / 65535.0f);
+ }
+ else {
+ float mask_srf[4];
+ mul_v4_v4fl(mask_srf, srf, mask / 65535.0f);
+ func_float(drf, orf, mask_srf);
+ }
- func_float(drf, orf, mask_srf);
}
}
}
diff --git a/source/blender/makesdna/DNA_ID.h b/source/blender/makesdna/DNA_ID.h
index 2c6f3d2fc66..da0f505c4f3 100644
--- a/source/blender/makesdna/DNA_ID.h
+++ b/source/blender/makesdna/DNA_ID.h
@@ -82,8 +82,6 @@ enum {
IDP_FLOAT = 2,
IDP_ARRAY = 5,
IDP_GROUP = 6,
- /* the ID link property type hasn't been implemented yet, this will require
- * some cleanup of blenkernel, most likely. */
IDP_ID = 7,
IDP_DOUBLE = 8,
IDP_IDPARRAY = 9,
diff --git a/source/blender/makesdna/DNA_cachefile_types.h b/source/blender/makesdna/DNA_cachefile_types.h
index 46b1adf2725..a353c94ae64 100644
--- a/source/blender/makesdna/DNA_cachefile_types.h
+++ b/source/blender/makesdna/DNA_cachefile_types.h
@@ -47,10 +47,12 @@ enum {
CACHEFILE_KEYFRAME_DRAWN = (1 << 0),
};
+/* Representation of an object's path inside the Alembic file.
+ * Note that this is not a file path. */
typedef struct AlembicObjectPath {
struct AlembicObjectPath *next, *prev;
- char path[1024]; /* 1024 = FILE_MAX, might use PATH_MAX in the future. */
+ char path[4096];
} AlembicObjectPath;
typedef struct CacheFile {
diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h
index 621807d111c..3676066a399 100644
--- a/source/blender/makesdna/DNA_meshdata_types.h
+++ b/source/blender/makesdna/DNA_meshdata_types.h
@@ -164,8 +164,8 @@ typedef struct MLoop {
* MEdge *ed = &medge[mloop[lt->tri[j]].e];
* unsigned int tri_edge[2] = {mloop[lt->tri[j]].v, mloop[lt->tri[j_next]].v};
*
- * if (ELEM(ed->v1, tri_edge[0], tri_edge[1]) &&
- * ELEM(ed->v2, tri_edge[0], tri_edge[1]))
+ * if (((ed->v1 == tri_edge[0]) && (ed->v1 == tri_edge[1])) ||
+ * ((ed->v1 == tri_edge[1]) && (ed->v1 == tri_edge[0])))
* {
* printf("real edge found %u %u\n", tri_edge[0], tri_edge[1]);
* }
diff --git a/source/blender/makesdna/DNA_node_types.h b/source/blender/makesdna/DNA_node_types.h
index 47677e50451..b922ac072b0 100644
--- a/source/blender/makesdna/DNA_node_types.h
+++ b/source/blender/makesdna/DNA_node_types.h
@@ -569,9 +569,9 @@ typedef struct NodeEllipseMask {
/* layer info for image node outputs */
typedef struct NodeImageLayer {
/* index in the Image->layers->passes lists */
- int pass_index;
- /* render pass flag, in case this is an original render pass */
- int pass_flag;
+ int pass_index DNA_DEPRECATED;
+ /* render pass name */
+ char pass_name[64]; /* amount defined in openexr_multi.h */
} NodeImageLayer;
typedef struct NodeBlurData {
diff --git a/source/blender/makesdna/DNA_object_fluidsim.h b/source/blender/makesdna/DNA_object_fluidsim.h
index a714195dd5d..846d5788d63 100644
--- a/source/blender/makesdna/DNA_object_fluidsim.h
+++ b/source/blender/makesdna/DNA_object_fluidsim.h
@@ -179,6 +179,7 @@ typedef struct FluidsimSettings {
#define OB_FLUIDSIM_ACTIVE (1 << 1)
#define OB_FLUIDSIM_OVERRIDE_TIME (1 << 2)
+#define OB_FLUIDSIM_SURF_DIR_DEFAULT "cache_fluid"
#define OB_FLUIDSIM_SURF_PREVIEW_OBJ_FNAME "fluidsurface_preview_####.bobj.gz"
#define OB_FLUIDSIM_SURF_FINAL_OBJ_FNAME "fluidsurface_final_####.bobj.gz"
#define OB_FLUIDSIM_SURF_FINAL_VEL_FNAME "fluidsurface_final_####.bvel.gz"
diff --git a/source/blender/makesdna/DNA_object_types.h b/source/blender/makesdna/DNA_object_types.h
index d24c7faa9f5..6d79e6d49f8 100644
--- a/source/blender/makesdna/DNA_object_types.h
+++ b/source/blender/makesdna/DNA_object_types.h
@@ -335,6 +335,8 @@ typedef struct DupliObject {
/* particle this dupli was generated from */
struct ParticleSystem *particle_system;
+ unsigned int random_id;
+ unsigned int pad;
} DupliObject;
/* **************** OBJECT ********************* */
diff --git a/source/blender/makesdna/DNA_particle_types.h b/source/blender/makesdna/DNA_particle_types.h
index 1deb9bf3787..f6bed37dfa2 100644
--- a/source/blender/makesdna/DNA_particle_types.h
+++ b/source/blender/makesdna/DNA_particle_types.h
@@ -323,7 +323,7 @@ typedef struct ParticleSystem {
struct ParticleDrawData *pdd;
float dt_frac; /* current time step, as a fraction of a frame */
- float _pad; /* spare capacity */
+ float lattice_strength; /* influence of the lattice modifier */
} ParticleSystem;
typedef enum eParticleDrawFlag {
diff --git a/source/blender/makesdna/DNA_scene_types.h b/source/blender/makesdna/DNA_scene_types.h
index 918d0f00040..c2711c465e1 100644
--- a/source/blender/makesdna/DNA_scene_types.h
+++ b/source/blender/makesdna/DNA_scene_types.h
@@ -229,7 +229,9 @@ typedef struct SceneRenderLayer {
int samples;
float pass_alpha_threshold;
-
+
+ IDProperty *prop;
+
struct FreestyleConfig freestyleConfig;
} SceneRenderLayer;
@@ -283,9 +285,43 @@ typedef enum ScenePassType {
SCE_PASS_SUBSURFACE_DIRECT = (1 << 28),
SCE_PASS_SUBSURFACE_INDIRECT = (1 << 29),
SCE_PASS_SUBSURFACE_COLOR = (1 << 30),
- SCE_PASS_DEBUG = (1 << 31), /* This is a virtual pass. */
} ScenePassType;
+#define RE_PASSNAME_COMBINED "Combined"
+#define RE_PASSNAME_Z "Depth"
+#define RE_PASSNAME_VECTOR "Vector"
+#define RE_PASSNAME_NORMAL "Normal"
+#define RE_PASSNAME_UV "UV"
+#define RE_PASSNAME_RGBA "Color"
+#define RE_PASSNAME_EMIT "Emit"
+#define RE_PASSNAME_DIFFUSE "Diffuse"
+#define RE_PASSNAME_SPEC "Spec"
+#define RE_PASSNAME_SHADOW "Shadow"
+
+#define RE_PASSNAME_AO "AO"
+#define RE_PASSNAME_ENVIRONMENT "Env"
+#define RE_PASSNAME_INDIRECT "Indirect"
+#define RE_PASSNAME_REFLECT "Reflect"
+#define RE_PASSNAME_REFRACT "Refract"
+#define RE_PASSNAME_INDEXOB "IndexOB"
+#define RE_PASSNAME_INDEXMA "IndexMA"
+#define RE_PASSNAME_MIST "Mist"
+
+#define RE_PASSNAME_RAYHITS "RayHits"
+#define RE_PASSNAME_DIFFUSE_DIRECT "DiffDir"
+#define RE_PASSNAME_DIFFUSE_INDIRECT "DiffInd"
+#define RE_PASSNAME_DIFFUSE_COLOR "DiffCol"
+#define RE_PASSNAME_GLOSSY_DIRECT "GlossDir"
+#define RE_PASSNAME_GLOSSY_INDIRECT "GlossInd"
+#define RE_PASSNAME_GLOSSY_COLOR "GlossCol"
+#define RE_PASSNAME_TRANSM_DIRECT "TransDir"
+#define RE_PASSNAME_TRANSM_INDIRECT "TransInd"
+#define RE_PASSNAME_TRANSM_COLOR "TransCol"
+
+#define RE_PASSNAME_SUBSURFACE_DIRECT "SubsurfaceDir"
+#define RE_PASSNAME_SUBSURFACE_INDIRECT "SubsurfaceInd"
+#define RE_PASSNAME_SUBSURFACE_COLOR "SubsurfaceCol"
+
/* note, srl->passflag is treestore element 'nr' in outliner, short still... */
/* View - MultiView */
diff --git a/source/blender/makesdna/DNA_space_types.h b/source/blender/makesdna/DNA_space_types.h
index 5e015544dc9..0e5d9bd33e6 100644
--- a/source/blender/makesdna/DNA_space_types.h
+++ b/source/blender/makesdna/DNA_space_types.h
@@ -1151,7 +1151,7 @@ typedef enum eSpaceNode_Flag {
SNODE_SHOW_G = (1 << 8),
SNODE_SHOW_B = (1 << 9),
SNODE_AUTO_RENDER = (1 << 5),
- SNODE_SHOW_HIGHLIGHT = (1 << 6),
+// SNODE_SHOW_HIGHLIGHT = (1 << 6), DNA_DEPRECATED
// SNODE_USE_HIDDEN_PREVIEW = (1 << 10), DNA_DEPRECATED December2013
SNODE_NEW_SHADERS = (1 << 11),
SNODE_PIN = (1 << 12),
diff --git a/source/blender/makesrna/RNA_access.h b/source/blender/makesrna/RNA_access.h
index f9aaec69ce7..a1af3f98274 100644
--- a/source/blender/makesrna/RNA_access.h
+++ b/source/blender/makesrna/RNA_access.h
@@ -767,6 +767,8 @@ void RNA_struct_blender_type_set(StructRNA *srna, void *blender_type);
struct IDProperty *RNA_struct_idprops(PointerRNA *ptr, bool create);
bool RNA_struct_idprops_check(StructRNA *srna);
bool RNA_struct_idprops_register_check(const StructRNA *type);
+bool RNA_struct_idprops_datablock_allowed(const StructRNA *type);
+bool RNA_struct_idprops_contains_datablock(const StructRNA *type);
bool RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier);
PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier);
diff --git a/source/blender/makesrna/RNA_define.h b/source/blender/makesrna/RNA_define.h
index 2a680b6eaeb..6e62313b00a 100644
--- a/source/blender/makesrna/RNA_define.h
+++ b/source/blender/makesrna/RNA_define.h
@@ -167,6 +167,7 @@ void RNA_def_property_editable_func(PropertyRNA *prop, const char *editable);
void RNA_def_property_editable_array_func(PropertyRNA *prop, const char *editable);
void RNA_def_property_update_runtime(PropertyRNA *prop, const void *func);
+void RNA_def_property_poll_runtime(PropertyRNA *prop, const void *func);
void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength);
void RNA_def_property_boolean_funcs(PropertyRNA *prop, const char *get, const char *set);
diff --git a/source/blender/makesrna/RNA_types.h b/source/blender/makesrna/RNA_types.h
index dee8df7d933..cd04f9e8a6d 100644
--- a/source/blender/makesrna/RNA_types.h
+++ b/source/blender/makesrna/RNA_types.h
@@ -434,6 +434,8 @@ typedef enum StructFlag {
STRUCT_GENERATED = (1 << 4),
STRUCT_FREE_POINTERS = (1 << 5),
STRUCT_NO_IDPROPERTIES = (1 << 6), /* Menus and Panels don't need properties */
+ STRUCT_NO_DATABLOCK_IDPROPERTIES = (1 << 7), /* e.g. for Operator */
+ STRUCT_CONTAINS_DATABLOCK_IDPROPERTIES = (1 << 8), /* for PropertyGroup which contains pointers to datablocks */
} StructFlag;
typedef int (*StructValidateFunc)(struct PointerRNA *ptr, void *data, int *have_function);
diff --git a/source/blender/makesrna/intern/CMakeLists.txt b/source/blender/makesrna/intern/CMakeLists.txt
index 0f3ea27a7f9..6a08d762920 100644
--- a/source/blender/makesrna/intern/CMakeLists.txt
+++ b/source/blender/makesrna/intern/CMakeLists.txt
@@ -176,9 +176,6 @@ set(INC_SYS
if(WITH_CYCLES)
add_definitions(-DWITH_CYCLES)
- if(WITH_CYCLES_DEBUG)
- add_definitions(-DWITH_CYCLES_DEBUG)
- endif()
endif()
if(WITH_PYTHON)
diff --git a/source/blender/makesrna/intern/makesrna.c b/source/blender/makesrna/intern/makesrna.c
index 9d68c05dda0..de436172bfd 100644
--- a/source/blender/makesrna/intern/makesrna.c
+++ b/source/blender/makesrna/intern/makesrna.c
@@ -3746,7 +3746,7 @@ static const char *cpp_classes = ""
"template<typename T, TBeginFunc Tbegin, TNextFunc Tnext, TEndFunc Tend>\n"
"class CollectionIterator {\n"
"public:\n"
-" CollectionIterator() : t(iter.ptr), init(false) { iter.valid = false; }\n"
+" CollectionIterator() : iter(), t(iter.ptr), init(false) { iter.valid = false; }\n"
" ~CollectionIterator(void) { if (init) Tend(&iter); };\n"
"\n"
" operator bool(void)\n"
diff --git a/source/blender/makesrna/intern/rna_ID.c b/source/blender/makesrna/intern/rna_ID.c
index 671902c5cc7..a74758a4f71 100644
--- a/source/blender/makesrna/intern/rna_ID.c
+++ b/source/blender/makesrna/intern/rna_ID.c
@@ -342,7 +342,7 @@ static void rna_ID_user_clear(ID *id)
static void rna_ID_user_remap(ID *id, Main *bmain, ID *new_id)
{
- if (GS(id->name) == GS(new_id->name)) {
+ if ((GS(id->name) == GS(new_id->name)) && (id != new_id)) {
/* For now, do not allow remapping data in linked data from here... */
BKE_libblock_remap(bmain, id, new_id, ID_REMAP_SKIP_INDIRECT_USAGE | ID_REMAP_SKIP_NEVER_NULL_USAGE);
}
@@ -802,7 +802,11 @@ static void rna_def_ID_properties(BlenderRNA *brna)
RNA_def_struct_name_property(srna, prop);
#endif
- /* IDP_ID -- not implemented yet in id properties */
+ /* IDP_ID */
+ prop = RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE);
+ RNA_def_property_flag(prop, PROP_EXPORT | PROP_IDPROPERTY | PROP_NEVER_UNLINK);
+ RNA_def_property_struct_type(prop, "ID");
+
/* ID property groups > level 0, since level 0 group is merged
* with native RNA properties. the builtin_properties will take
diff --git a/source/blender/makesrna/intern/rna_access.c b/source/blender/makesrna/intern/rna_access.c
index 7266cfb12d6..5a4db47d281 100644
--- a/source/blender/makesrna/intern/rna_access.c
+++ b/source/blender/makesrna/intern/rna_access.c
@@ -50,6 +50,7 @@
#include "BKE_idcode.h"
#include "BKE_idprop.h"
#include "BKE_fcurve.h"
+#include "BKE_library.h"
#include "BKE_main.h"
#include "BKE_report.h"
@@ -380,6 +381,7 @@ static bool rna_idproperty_verify_valid(PointerRNA *ptr, PropertyRNA *prop, IDPr
return false;
break;
case IDP_GROUP:
+ case IDP_ID:
if (prop->type != PROP_POINTER)
return false;
break;
@@ -395,7 +397,8 @@ static PropertyRNA *typemap[IDP_NUMTYPES] = {
(PropertyRNA *)&rna_PropertyGroupItem_int,
(PropertyRNA *)&rna_PropertyGroupItem_float,
NULL, NULL, NULL,
- (PropertyRNA *)&rna_PropertyGroupItem_group, NULL,
+ (PropertyRNA *)&rna_PropertyGroupItem_group,
+ (PropertyRNA *)&rna_PropertyGroupItem_id,
(PropertyRNA *)&rna_PropertyGroupItem_double,
(PropertyRNA *)&rna_PropertyGroupItem_idp_array
};
@@ -587,6 +590,21 @@ bool RNA_struct_idprops_register_check(const StructRNA *type)
return (type->flag & STRUCT_NO_IDPROPERTIES) == 0;
}
+bool RNA_struct_idprops_datablock_allowed(const StructRNA *type)
+{
+ return (type->flag & (STRUCT_NO_DATABLOCK_IDPROPERTIES | STRUCT_NO_IDPROPERTIES)) == 0;
+}
+
+/**
+ * Whether given type implies datablock usage by IDProperties.
+ * This is used to prevent classes allowed to have IDProperties, but not datablock ones, to indirectly use some
+ * (e.g. by assigning an IDP_GROUP containing some IDP_ID pointers...).
+ */
+bool RNA_struct_idprops_contains_datablock(const StructRNA *type)
+{
+ return (type->flag & (STRUCT_CONTAINS_DATABLOCK_IDPROPERTIES | STRUCT_ID)) != 0;
+}
+
/* remove an id-property */
bool RNA_struct_idprops_unset(PointerRNA *ptr, const char *identifier)
{
@@ -628,8 +646,11 @@ PropertyRNA *RNA_struct_find_property(PointerRNA *ptr, const char *identifier)
/* id prop lookup, not so common */
PropertyRNA *r_prop = NULL;
PointerRNA r_ptr; /* only support single level props */
- if (RNA_path_resolve(ptr, identifier, &r_ptr, &r_prop) && (r_ptr.type == ptr->type) && (r_ptr.data == ptr->data))
+ if (RNA_path_resolve_property(ptr, identifier, &r_ptr, &r_prop) &&
+ (r_ptr.type == ptr->type) && (r_ptr.data == ptr->data))
+ {
return r_prop;
+ }
}
else {
/* most common case */
@@ -1201,13 +1222,20 @@ int RNA_property_pointer_poll(PointerRNA *ptr, PropertyRNA *prop, PointerRNA *va
if (prop->type == PROP_POINTER) {
PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
- if (pprop->poll)
- return pprop->poll(ptr, *value);
+
+ if (pprop->poll) {
+ if (rna_idproperty_check(&prop, ptr)) {
+ return ((PropPointerPollFuncPy) pprop->poll)(ptr, *value, prop);
+ }
+ else {
+ return pprop->poll(ptr, *value);
+ }
+ }
return 1;
}
- printf("%s %s: is not a pointer property.\n", __func__, prop->identifier);
+ printf("%s: %s is not a pointer property.\n", __func__, prop->identifier);
return 0;
}
@@ -2967,6 +2995,10 @@ PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
if ((idprop = rna_idproperty_check(&prop, ptr))) {
pprop = (PointerPropertyRNA *)prop;
+ if (RNA_struct_is_ID(pprop->type)) {
+ return rna_pointer_inherit_refine(ptr, pprop->type, IDP_Id(idprop));
+ }
+
/* for groups, data is idprop itself */
if (pprop->typef)
return rna_pointer_inherit_refine(ptr, pprop->typef(ptr), idprop);
@@ -2989,22 +3021,32 @@ PointerRNA RNA_property_pointer_get(PointerRNA *ptr, PropertyRNA *prop)
void RNA_property_pointer_set(PointerRNA *ptr, PropertyRNA *prop, PointerRNA ptr_value)
{
- /*IDProperty *idprop;*/
-
+ PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
BLI_assert(RNA_property_type(prop) == PROP_POINTER);
- if ((/*idprop = */ rna_idproperty_check(&prop, ptr))) {
- /* not supported */
- /* rna_idproperty_touch(idprop); */
+ /* Check types */
+ if (ptr_value.type != NULL && !RNA_struct_is_a(ptr_value.type, pprop->type)) {
+ printf("%s: expected %s type, not %s.\n", __func__, pprop->type->identifier, ptr_value.type->identifier);
+ return;
}
- else {
- PointerPropertyRNA *pprop = (PointerPropertyRNA *)prop;
- if (pprop->set &&
- !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL) &&
- !((prop->flag & PROP_ID_SELF_CHECK) && ptr->id.data == ptr_value.id.data))
- {
- pprop->set(ptr, ptr_value);
+ /* RNA */
+ if (pprop->set &&
+ !((prop->flag & PROP_NEVER_NULL) && ptr_value.data == NULL) &&
+ !((prop->flag & PROP_ID_SELF_CHECK) && ptr->id.data == ptr_value.id.data))
+ {
+ pprop->set(ptr, ptr_value);
+ }
+ /* IDProperty */
+ else if (prop->flag & PROP_EDITABLE) {
+ IDPropertyTemplate val = {0};
+ IDProperty *group;
+
+ val.id = ptr_value.data;
+
+ group = RNA_struct_idprops(ptr, true);
+ if (group) {
+ IDP_ReplaceInGroup(group, IDP_New(IDP_ID, &val, prop->identifier));
}
}
}
@@ -5557,12 +5599,13 @@ static char *rna_pointer_as_string__bldata(PointerRNA *ptr)
}
}
-char *RNA_pointer_as_string(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *prop_ptr, PointerRNA *ptr_prop)
+char *RNA_pointer_as_string(bContext *C, PointerRNA *ptr, PropertyRNA *prop_ptr, PointerRNA *ptr_prop)
{
+ IDProperty *prop;
if (ptr_prop->data == NULL) {
return BLI_strdup("None");
}
- else if (RNA_property_flag(prop_ptr) & PROP_IDPROPERTY) {
+ else if ((prop = rna_idproperty_check(&prop_ptr, ptr)) && prop->type != IDP_ID) {
return RNA_pointer_as_string_id(C, ptr_prop);
}
else {
@@ -6403,7 +6446,7 @@ static int rna_function_parameter_parse(PointerRNA *ptr, PropertyRNA *prop, Prop
tid, fid, pid, RNA_struct_identifier(ptype), RNA_struct_identifier(srna));
return -1;
}
-
+
*((void **)dest) = *((void **)src);
break;
diff --git a/source/blender/makesrna/intern/rna_color.c b/source/blender/makesrna/intern/rna_color.c
index d3cd3d12c4d..5339df34a38 100644
--- a/source/blender/makesrna/intern/rna_color.c
+++ b/source/blender/makesrna/intern/rna_color.c
@@ -508,12 +508,13 @@ static void rna_ColorManagedViewSettings_look_set(PointerRNA *ptr, int value)
}
static EnumPropertyItem *rna_ColorManagedViewSettings_look_itemf(
- bContext *UNUSED(C), PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+ bContext *UNUSED(C), PointerRNA *ptr, PropertyRNA *UNUSED(prop), bool *r_free)
{
+ ColorManagedViewSettings *view = (ColorManagedViewSettings *) ptr->data;
EnumPropertyItem *items = NULL;
int totitem = 0;
- IMB_colormanagement_look_items_add(&items, &totitem);
+ IMB_colormanagement_look_items_add(&items, &totitem, view->view_transform);
RNA_enum_item_end(&items, &totitem);
*r_free = true;
diff --git a/source/blender/makesrna/intern/rna_define.c b/source/blender/makesrna/intern/rna_define.c
index 1d232d2df39..42c0344f46e 100644
--- a/source/blender/makesrna/intern/rna_define.c
+++ b/source/blender/makesrna/intern/rna_define.c
@@ -71,8 +71,8 @@ BlenderDefRNA DefRNA = {NULL, {NULL, NULL}, {NULL, NULL}, NULL, 0, 0, 0, 1, 1};
if (description && (description)[0]) { \
int i = strlen(description); \
if (i > 3 && (description)[i - 1] == '.' && (description)[i - 3] != '.') { \
- fprintf(stderr, "%s: '%s' '%s' description ends with a '.' !\n", \
- __func__, id1 ? id1 : "", id2 ? id2 : ""); \
+ fprintf(stderr, "%s: '%s' description from '%s' '%s' ends with a '.' !\n", \
+ __func__, description, id1 ? id1 : "", id2 ? id2 : ""); \
} \
} (void)0
@@ -2168,6 +2168,16 @@ void RNA_def_property_update_runtime(PropertyRNA *prop, const void *func)
prop->update = (void *)func;
}
+void RNA_def_property_poll_runtime(PropertyRNA *prop, const void *func)
+{
+ if (prop->type == PROP_POINTER) {
+ ((PointerPropertyRNA *)prop)->poll = func;
+ }
+ else {
+ fprintf(stderr, "%s: %s is not a Pointer Property.\n", __func__, prop->identifier);
+ }
+}
+
void RNA_def_property_dynamic_array_funcs(PropertyRNA *prop, const char *getlength)
{
if (!DefRNA.preprocess) {
@@ -2982,6 +2992,9 @@ PropertyRNA *RNA_def_pointer_runtime(StructOrFunctionRNA *cont_, const char *ide
prop = RNA_def_property(cont, identifier, PROP_POINTER, PROP_NONE);
RNA_def_property_struct_runtime(prop, type);
+ if ((type->flag & STRUCT_ID) != 0) {
+ prop->flag |= PROP_EDITABLE;
+ }
RNA_def_property_ui_text(prop, ui_name, ui_description);
return prop;
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index bccc47aa95d..ad63a652b12 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -765,6 +765,38 @@ static void rna_FModifierStepped_end_frame_range(PointerRNA *ptr, float *min, fl
*max = MAXFRAMEF;
}
+static void rna_FModifierStepped_frame_start_set(PointerRNA *ptr, float value)
+{
+ FModifier *fcm = (FModifier *)ptr->data;
+ FMod_Stepped *data = fcm->data;
+
+ float prop_clamp_min = -FLT_MAX, prop_clamp_max = FLT_MAX, prop_soft_min, prop_soft_max;
+ rna_FModifierStepped_start_frame_range(ptr, &prop_clamp_min, &prop_clamp_max, &prop_soft_min, &prop_soft_max);
+ value = CLAMPIS(value, prop_clamp_min, prop_clamp_max);
+
+ /* Need to set both step-data's start/end and the start/end on the base-data,
+ * or else Restrict-Range doesn't work due to RNA-property shadowing (T52009)
+ */
+ data->start_frame = value;
+ fcm->sfra = value;
+}
+
+static void rna_FModifierStepped_frame_end_set(PointerRNA *ptr, float value)
+{
+ FModifier *fcm = (FModifier *)ptr->data;
+ FMod_Stepped *data = fcm->data;
+
+ float prop_clamp_min = -FLT_MAX, prop_clamp_max = FLT_MAX, prop_soft_min, prop_soft_max;
+ rna_FModifierStepped_end_frame_range(ptr, &prop_clamp_min, &prop_clamp_max, &prop_soft_min, &prop_soft_max);
+ value = CLAMPIS(value, prop_clamp_min, prop_clamp_max);
+
+ /* Need to set both step-data's start/end and the start/end on the base-data,
+ * or else Restrict-Range doesn't work due to RNA-property shadowing (T52009)
+ */
+ data->end_frame = value;
+ fcm->efra = value;
+}
+
static BezTriple *rna_FKeyframe_points_insert(FCurve *fcu, float frame, float value, int keyframe_type, int flag)
{
int index = insert_vert_fcurve(fcu, frame, value, (char)keyframe_type, flag | INSERTKEY_NO_USERPREF);
@@ -1284,13 +1316,13 @@ static void rna_def_fmodifier_stepped(BlenderRNA *brna)
prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "start_frame");
- RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifierStepped_start_frame_range");
+ RNA_def_property_float_funcs(prop, NULL, "rna_FModifierStepped_frame_start_set", "rna_FModifierStepped_start_frame_range");
RNA_def_property_ui_text(prop, "Start Frame", "Frame that modifier's influence starts (if applicable)");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
prop = RNA_def_property(srna, "frame_end", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "end_frame");
- RNA_def_property_float_funcs(prop, NULL, NULL, "rna_FModifierStepped_end_frame_range");
+ RNA_def_property_float_funcs(prop, NULL, "rna_FModifierStepped_frame_end_set", "rna_FModifierStepped_end_frame_range");
RNA_def_property_ui_text(prop, "End Frame", "Frame that modifier's influence ends (if applicable)");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
}
diff --git a/source/blender/makesrna/intern/rna_fluidsim.c b/source/blender/makesrna/intern/rna_fluidsim.c
index 091950a8e66..8c3984e4b29 100644
--- a/source/blender/makesrna/intern/rna_fluidsim.c
+++ b/source/blender/makesrna/intern/rna_fluidsim.c
@@ -185,12 +185,16 @@ static void rna_DomainFluidSettings_memory_estimate_get(PointerRNA *ptr, char *v
#endif
}
-static int rna_DomainFluidSettings_memory_estimate_length(PointerRNA *UNUSED(ptr))
+static int rna_DomainFluidSettings_memory_estimate_length(PointerRNA *ptr)
{
#ifndef WITH_MOD_FLUID
+ UNUSED_VARS(ptr);
return 0;
#else
- return 31;
+ char value[32];
+
+ rna_DomainFluidSettings_memory_estimate_get(ptr, value);
+ return strlen(value);
#endif
}
diff --git a/source/blender/makesrna/intern/rna_image.c b/source/blender/makesrna/intern/rna_image.c
index f65aa90ea71..b6e84cf8ac3 100644
--- a/source/blender/makesrna/intern/rna_image.c
+++ b/source/blender/makesrna/intern/rna_image.c
@@ -871,7 +871,7 @@ static void rna_def_image(BlenderRNA *brna)
prop = RNA_def_property(srna, "has_data", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_funcs(prop, "rna_Image_has_data_get", NULL);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "Has data", "True if this image has data");
+ RNA_def_property_ui_text(prop, "Has Data", "True if the image data is loaded into memory");
prop = RNA_def_property(srna, "depth", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_funcs(prop, "rna_Image_depth_get", NULL, NULL);
diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h
index 76455adbc78..dfd5af788f6 100644
--- a/source/blender/makesrna/intern/rna_internal.h
+++ b/source/blender/makesrna/intern/rna_internal.h
@@ -344,6 +344,7 @@ extern IntPropertyRNA rna_PropertyGroupItem_int_array;
extern FloatPropertyRNA rna_PropertyGroupItem_float;
extern FloatPropertyRNA rna_PropertyGroupItem_float_array;
extern PointerPropertyRNA rna_PropertyGroupItem_group;
+extern PointerPropertyRNA rna_PropertyGroupItem_id;
extern CollectionPropertyRNA rna_PropertyGroupItem_collection;
extern CollectionPropertyRNA rna_PropertyGroupItem_idp_array;
extern FloatPropertyRNA rna_PropertyGroupItem_double;
diff --git a/source/blender/makesrna/intern/rna_internal_types.h b/source/blender/makesrna/intern/rna_internal_types.h
index fce81e6967e..df591659fdb 100644
--- a/source/blender/makesrna/intern/rna_internal_types.h
+++ b/source/blender/makesrna/intern/rna_internal_types.h
@@ -94,6 +94,7 @@ typedef PointerRNA (*PropPointerGetFunc)(struct PointerRNA *ptr);
typedef StructRNA *(*PropPointerTypeFunc)(struct PointerRNA *ptr);
typedef void (*PropPointerSetFunc)(struct PointerRNA *ptr, const PointerRNA value);
typedef int (*PropPointerPollFunc)(struct PointerRNA *ptr, const PointerRNA value);
+typedef int (*PropPointerPollFuncPy)(struct PointerRNA *ptr, const PointerRNA value, const PropertyRNA *prop);
typedef void (*PropCollectionBeginFunc)(struct CollectionPropertyIterator *iter, struct PointerRNA *ptr);
typedef void (*PropCollectionNextFunc)(struct CollectionPropertyIterator *iter);
typedef void (*PropCollectionEndFunc)(struct CollectionPropertyIterator *iter);
diff --git a/source/blender/makesrna/intern/rna_linestyle.c b/source/blender/makesrna/intern/rna_linestyle.c
index 1199cccc4e6..a163d9764c1 100644
--- a/source/blender/makesrna/intern/rna_linestyle.c
+++ b/source/blender/makesrna/intern/rna_linestyle.c
@@ -1620,6 +1620,7 @@ static void rna_def_linestyle(BlenderRNA *brna)
prop = RNA_def_property(srna, "panel", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_bitflag_sdna(prop, NULL, "panel");
RNA_def_property_enum_items(prop, panel_items);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
RNA_def_property_ui_text(prop, "Panel", "Select the property panel to be shown");
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR);
diff --git a/source/blender/makesrna/intern/rna_nla.c b/source/blender/makesrna/intern/rna_nla.c
index e44a6420045..d72c858a5d5 100644
--- a/source/blender/makesrna/intern/rna_nla.c
+++ b/source/blender/makesrna/intern/rna_nla.c
@@ -659,7 +659,10 @@ static void rna_def_nlastrip(BlenderRNA *brna)
prop = RNA_def_property(srna, "influence", PROP_FLOAT, PROP_NONE);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_text(prop, "Influence", "Amount the strip contributes to the current result");
- RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, "rna_NlaStrip_update");
+ /* XXX: Update temporarily disabled so that the property can be edited at all!
+ * Even autokey only applies after the curves have been re-evaluated, causing the unkeyed values to be lost
+ */
+ RNA_def_property_update(prop, NC_ANIMATION | ND_NLA | NA_EDITED, /*"rna_NlaStrip_update"*/ NULL);
prop = RNA_def_property(srna, "strip_time", PROP_FLOAT, PROP_TIME);
RNA_def_property_ui_text(prop, "Strip Time", "Frame of referenced Action to evaluate");
diff --git a/source/blender/makesrna/intern/rna_nodetree.c b/source/blender/makesrna/intern/rna_nodetree.c
index 8d42d746e1c..10422c85579 100644
--- a/source/blender/makesrna/intern/rna_nodetree.c
+++ b/source/blender/makesrna/intern/rna_nodetree.c
@@ -64,6 +64,8 @@
#include "RE_render_ext.h"
+#include "NOD_composite.h"
+
EnumPropertyItem rna_enum_node_socket_in_out_items[] = {
{ SOCK_IN, "IN", 0, "Input", "" },
{ SOCK_OUT, "OUT", 0, "Output", "" },
@@ -2608,7 +2610,7 @@ static void rna_Node_image_layer_update(Main *bmain, Scene *scene, PointerRNA *p
rna_Node_update(bmain, scene, ptr);
if (scene->nodetree != NULL) {
- ntreeCompositForceHidden(scene->nodetree);
+ ntreeCompositUpdateRLayers(scene->nodetree);
}
}
@@ -2747,7 +2749,7 @@ static void rna_Node_scene_layer_update(Main *bmain, Scene *scene, PointerRNA *p
{
rna_Node_update(bmain, scene, ptr);
if (scene->nodetree != NULL) {
- ntreeCompositForceHidden(scene->nodetree);
+ ntreeCompositUpdateRLayers(scene->nodetree);
}
}
@@ -2995,6 +2997,15 @@ static void rna_ShaderNodeScript_update(Main *bmain, Scene *scene, PointerRNA *p
ED_node_tag_update_nodetree(bmain, ntree, node);
}
+static void rna_ShaderNodePrincipled_update(Main *bmain, Scene *scene, PointerRNA *ptr)
+{
+ bNodeTree *ntree = (bNodeTree *)ptr->id.data;
+ bNode *node = (bNode *)ptr->data;
+
+ nodeUpdate(ntree, node);
+ rna_Node_update(bmain, scene, ptr);
+}
+
static void rna_ShaderNodeSubsurface_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
bNodeTree *ntree = (bNodeTree *)ptr->id.data;
@@ -3254,6 +3265,12 @@ static EnumPropertyItem node_script_mode_items[] = {
{0, NULL, 0, NULL, NULL}
};
+static EnumPropertyItem node_principled_distribution_items[] = {
+ { SHD_GLOSSY_GGX, "GGX", 0, "GGX", "" },
+ { SHD_GLOSSY_MULTI_GGX, "MULTI_GGX", 0, "Multiscatter GGX", "" },
+ { 0, NULL, 0, NULL, NULL }
+};
+
/* -- Common nodes ---------------------------------------------------------- */
static void def_group_input(StructRNA *srna)
@@ -4188,6 +4205,17 @@ static void def_glass(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_principled(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "distribution", PROP_ENUM, PROP_NONE);
+ RNA_def_property_enum_sdna(prop, NULL, "custom1");
+ RNA_def_property_enum_items(prop, node_principled_distribution_items);
+ RNA_def_property_ui_text(prop, "Distribution", "");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_ShaderNodePrincipled_update");
+}
+
static void def_refraction(StructRNA *srna)
{
PropertyRNA *prop;
@@ -4770,7 +4798,7 @@ static void def_cmp_render_layers(StructRNA *srna)
RNA_def_property_struct_type(prop, "Scene");
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Scene", "");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_scene_layer_update");
prop = RNA_def_property(srna, "layer", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "custom1");
@@ -5211,6 +5239,16 @@ static void def_cmp_luma_matte(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
+static void def_cmp_brightcontrast(StructRNA *srna)
+{
+ PropertyRNA *prop;
+
+ prop = RNA_def_property(srna, "use_premultiply", PROP_BOOLEAN, PROP_NONE);
+ RNA_def_property_boolean_sdna(prop, NULL, "custom1", 1);
+ RNA_def_property_ui_text(prop, "Convert Premul", "Keep output image premultiplied alpha");
+ RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
+}
+
static void def_cmp_chroma_matte(StructRNA *srna)
{
PropertyRNA *prop;
@@ -6282,14 +6320,8 @@ static void def_cmp_switch(StructRNA *srna)
RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
-static void def_cmp_switch_view(StructRNA *srna)
+static void def_cmp_switch_view(StructRNA *UNUSED(srna))
{
- PropertyRNA *prop;
-
- prop = RNA_def_property(srna, "check", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "custom1", 0);
- RNA_def_property_ui_text(prop, "Switch", "Off: first socket, On: second socket");
- RNA_def_property_update(prop, NC_NODE | NA_EDITED, "rna_Node_update");
}
static void def_cmp_colorcorrection(StructRNA *srna)
diff --git a/source/blender/makesrna/intern/rna_object.c b/source/blender/makesrna/intern/rna_object.c
index b3c166a6810..a167ab03ba1 100644
--- a/source/blender/makesrna/intern/rna_object.c
+++ b/source/blender/makesrna/intern/rna_object.c
@@ -432,11 +432,7 @@ static void rna_Object_parent_set(PointerRNA *ptr, PointerRNA value)
{
Object *ob = (Object *)ptr->data;
Object *par = (Object *)value.data;
-
-#ifdef FREE_WINDOWS
- /* NOTE: this dummy check here prevents this method causing weird runtime errors on mingw 4.6.2 */
- if (ob)
-#endif
+
{
ED_object_parent(ob, par, ob->partype, ob->parsubstr);
}
@@ -532,8 +528,9 @@ static void rna_Object_dup_group_set(PointerRNA *ptr, PointerRNA value)
* thus causing a cycle/infinite-recursion leading to crashes on load [#25298]
*/
if (BKE_group_object_exists(grp, ob) == 0) {
+ id_us_min(&ob->dup_group->id);
ob->dup_group = grp;
- id_lib_extern((ID *)grp);
+ id_us_plus(&ob->dup_group->id);
}
else {
BKE_report(NULL, RPT_ERROR,
@@ -2897,6 +2894,10 @@ static void rna_def_dupli_object(BlenderRNA *brna)
RNA_def_property_enum_items(prop, dupli_items);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Dupli Type", "Duplicator type that generated this dupli object");
+
+ prop = RNA_def_property(srna, "random_id", PROP_INT, PROP_UNSIGNED);
+ RNA_def_property_clear_flag(prop, PROP_ANIMATABLE | PROP_EDITABLE);
+ RNA_def_property_ui_text(prop, "Dupli random id", "Random id for this dupli object");
}
static void rna_def_object_base(BlenderRNA *brna)
diff --git a/source/blender/makesrna/intern/rna_object_api.c b/source/blender/makesrna/intern/rna_object_api.c
index c680abe71a4..9b9f0705bb4 100644
--- a/source/blender/makesrna/intern/rna_object_api.c
+++ b/source/blender/makesrna/intern/rna_object_api.c
@@ -321,49 +321,55 @@ static void rna_Object_ray_cast(
float origin[3], float direction[3], float distance,
int *r_success, float r_location[3], float r_normal[3], int *r_index)
{
- BVHTreeFromMesh treeData = {NULL};
-
+ bool success = false;
+
if (ob->derivedFinal == NULL) {
BKE_reportf(reports, RPT_ERROR, "Object '%s' has no mesh data to be used for ray casting", ob->id.name + 2);
return;
}
- /* no need to managing allocation or freeing of the BVH data. this is generated and freed as needed */
- bvhtree_from_mesh_looptri(&treeData, ob->derivedFinal, 0.0f, 4, 6);
+ /* Test BoundBox first (efficiency) */
+ BoundBox *bb = BKE_object_boundbox_get(ob);
+ float distmin;
+ if (!bb || (isect_ray_aabb_v3_simple(origin, direction, bb->vec[0], bb->vec[6], &distmin, NULL) && distmin <= distance)) {
- /* may fail if the mesh has no faces, in that case the ray-cast misses */
- if (treeData.tree != NULL) {
- BVHTreeRayHit hit;
+ BVHTreeFromMesh treeData = {NULL};
- hit.index = -1;
- hit.dist = distance;
-
- normalize_v3(direction);
+ /* no need to managing allocation or freeing of the BVH data. this is generated and freed as needed */
+ bvhtree_from_mesh_looptri(&treeData, ob->derivedFinal, 0.0f, 4, 6);
+
+ /* may fail if the mesh has no faces, in that case the ray-cast misses */
+ if (treeData.tree != NULL) {
+ BVHTreeRayHit hit;
+ hit.index = -1;
+ hit.dist = distance;
- if (BLI_bvhtree_ray_cast(treeData.tree, origin, direction, 0.0f, &hit,
- treeData.raycast_callback, &treeData) != -1)
- {
- if (hit.dist <= distance) {
- *r_success = true;
+ normalize_v3(direction);
- copy_v3_v3(r_location, hit.co);
- copy_v3_v3(r_normal, hit.no);
- *r_index = dm_looptri_to_poly_index(ob->derivedFinal, &treeData.looptri[hit.index]);
- goto finally;
+ if (BLI_bvhtree_ray_cast(treeData.tree, origin, direction, 0.0f, &hit,
+ treeData.raycast_callback, &treeData) != -1)
+ {
+ if (hit.dist <= distance) {
+ *r_success = success = true;
+
+ copy_v3_v3(r_location, hit.co);
+ copy_v3_v3(r_normal, hit.no);
+ *r_index = dm_looptri_to_poly_index(ob->derivedFinal, &treeData.looptri[hit.index]);
+ }
}
+
+ free_bvhtree_from_mesh(&treeData);
}
}
+ if (success == false) {
+ *r_success = false;
- *r_success = false;
-
- zero_v3(r_location);
- zero_v3(r_normal);
- *r_index = -1;
-
-finally:
- free_bvhtree_from_mesh(&treeData);
+ zero_v3(r_location);
+ zero_v3(r_normal);
+ *r_index = -1;
+ }
}
static void rna_Object_closest_point_on_mesh(
diff --git a/source/blender/makesrna/intern/rna_particle.c b/source/blender/makesrna/intern/rna_particle.c
index 95dab13571d..00104b8667d 100644
--- a/source/blender/makesrna/intern/rna_particle.c
+++ b/source/blender/makesrna/intern/rna_particle.c
@@ -446,10 +446,12 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys
int totpart;
int totchild = 0;
int totface;
+ int totvert;
int num = -1;
DM_ensure_tessface(modifier->dm_final); /* BMESH - UNTIL MODIFIER IS UPDATED FOR MPoly */
totface = modifier->dm_final->getNumTessFaces(modifier->dm_final);
+ totvert = modifier->dm_final->getNumVerts(modifier->dm_final);
/* 1. check that everything is ok & updated */
if (!particlesystem || !totface) {
@@ -484,13 +486,29 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys
return num;
}
}
+ else if (part->from == PART_FROM_VERT) {
+ if (num != DMCACHE_NOTFOUND && num < totvert) {
+ MFace *mface = modifier->dm_final->getTessFaceDataArray(modifier->dm_final, CD_MFACE);
+
+ *r_fuv = &particle->fuv;
+
+ /* This finds the first face to contain the emitting vertex,
+ * this is not ideal, but is mostly fine as UV seams generally
+ * map to equal-colored parts of a texture */
+ for (int i = 0; i < totface; i++, mface++) {
+ if (ELEM(num, mface->v1, mface->v2, mface->v3, mface->v4)) {
+ return i;
+ }
+ }
+ }
+ }
}
else {
ChildParticle *cpa = particlesystem->child + particle_no - totpart;
num = cpa->num;
if (part->childtype == PART_CHILD_FACES) {
- if (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME)) {
+ if (ELEM(part->from, PART_FROM_FACE, PART_FROM_VOLUME, PART_FROM_VERT)) {
if (num != DMCACHE_NOTFOUND && num < totface) {
*r_fuv = &cpa->fuv;
return num;
@@ -510,6 +528,22 @@ static int rna_ParticleSystem_tessfaceidx_on_emitter(ParticleSystem *particlesys
return num;
}
}
+ else if (part->from == PART_FROM_VERT) {
+ if (num != DMCACHE_NOTFOUND && num < totvert) {
+ MFace *mface = modifier->dm_final->getTessFaceDataArray(modifier->dm_final, CD_MFACE);
+
+ *r_fuv = &parent->fuv;
+
+ /* This finds the first face to contain the emitting vertex,
+ * this is not ideal, but is mostly fine as UV seams generally
+ * map to equal-colored parts of a texture */
+ for (int i = 0; i < totface; i++, mface++) {
+ if (ELEM(num, mface->v1, mface->v2, mface->v3, mface->v4)) {
+ return i;
+ }
+ }
+ }
+ }
}
}
@@ -2095,7 +2129,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Even Distribution",
"Use even distribution from faces based on face areas or edge lengths");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
-
+
prop = RNA_def_property(srna, "use_die_on_collision", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", PART_DIE_ON_COL);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
@@ -2300,7 +2334,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_render_adaptive", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_REN_ADAPT);
- RNA_def_property_ui_text(prop, "Adaptive render", "Draw steps of the particle path");
+ RNA_def_property_ui_text(prop, "Adaptive Render", "Draw steps of the particle path");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
prop = RNA_def_property(srna, "use_velocity_length", PROP_BOOLEAN, PROP_NONE);
@@ -2315,7 +2349,7 @@ static void rna_def_particle_settings(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_strand_primitive", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "draw", PART_DRAW_REN_STRAND);
- RNA_def_property_ui_text(prop, "Strand render", "Use the strand primitive for rendering");
+ RNA_def_property_ui_text(prop, "Strand Render", "Use the strand primitive for rendering");
RNA_def_property_update(prop, 0, "rna_Particle_redo");
prop = RNA_def_property(srna, "draw_method", PROP_ENUM, PROP_NONE);
@@ -2363,7 +2397,8 @@ static void rna_def_particle_settings(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Render", "How many steps paths are rendered with (power of 2)");
prop = RNA_def_property(srna, "hair_step", PROP_INT, PROP_NONE);
- RNA_def_property_range(prop, 2, 50);
+ RNA_def_property_range(prop, 2, SHRT_MAX);
+ RNA_def_property_ui_range(prop, 2, 50, 1, 1);
RNA_def_property_ui_text(prop, "Segments", "Number of hair segments");
RNA_def_property_update(prop, 0, "rna_Particle_reset");
diff --git a/source/blender/makesrna/intern/rna_render.c b/source/blender/makesrna/intern/rna_render.c
index 518c7efd915..44dcb72264a 100644
--- a/source/blender/makesrna/intern/rna_render.c
+++ b/source/blender/makesrna/intern/rna_render.c
@@ -26,6 +26,7 @@
#include <stdlib.h>
+#include "DNA_node_types.h"
#include "DNA_scene_types.h"
#include "DNA_object_types.h"
@@ -41,6 +42,7 @@
#include "RE_pipeline.h"
+/* Deprecated, only provided for API compatibility. */
EnumPropertyItem rna_enum_render_pass_type_items[] = {
{SCE_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
{SCE_PASS_Z, "Z", 0, "Z", ""},
@@ -77,18 +79,6 @@ EnumPropertyItem rna_enum_render_pass_type_items[] = {
{0, NULL, 0, NULL, NULL}
};
-EnumPropertyItem rna_enum_render_pass_debug_type_items[] = {
- {RENDER_PASS_DEBUG_BVH_TRAVERSED_NODES, "BVH_TRAVERSED_NODES", 0, "BVH Traversed Nodes",
- "Number of nodes traversed in BVH for the camera rays"},
- {RENDER_PASS_DEBUG_BVH_TRAVERSED_INSTANCES, "BVH_TRAVERSED_INSTANCES", 0, "BVH Traversed Instances",
- "Number of BVH instances traversed by camera rays"},
- {RENDER_PASS_DEBUG_BVH_INTERSECTIONS, "BVH_INTERSECTIONS", 0, "BVH Intersections",
- "Number of primitive intersections performed by the camera rays"},
- {RENDER_PASS_DEBUG_RAY_BOUNCES, "RAY_BOUNCES", 0, "Ray Steps",
- "Number of bounces done by the main integration loop"},
- {0, NULL, 0, NULL, NULL}
-};
-
EnumPropertyItem rna_enum_bake_pass_type_items[] = {
{SCE_PASS_COMBINED, "COMBINED", 0, "Combined", ""},
{SCE_PASS_AO, "AO", 0, "AO", ""},
@@ -261,6 +251,24 @@ static void engine_update_script_node(RenderEngine *engine, struct bNodeTree *nt
RNA_parameter_list_free(&list);
}
+static void engine_update_render_passes(RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl)
+{
+ extern FunctionRNA rna_RenderEngine_update_render_passes_func;
+ PointerRNA ptr;
+ ParameterList list;
+ FunctionRNA *func;
+
+ RNA_pointer_create(NULL, engine->type->ext.srna, engine, &ptr);
+ func = &rna_RenderEngine_update_render_passes_func;
+
+ RNA_parameter_list_create(&list, &ptr, func);
+ RNA_parameter_set_lookup(&list, "scene", &scene);
+ RNA_parameter_set_lookup(&list, "renderlayer", &srl);
+ engine->type->ext.call(NULL, &ptr, func, &list);
+
+ RNA_parameter_list_free(&list);
+}
+
/* RenderEngine registration */
static void rna_RenderEngine_unregister(Main *UNUSED(bmain), StructRNA *type)
@@ -281,7 +289,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
RenderEngineType *et, dummyet = {NULL};
RenderEngine dummyengine = {NULL};
PointerRNA dummyptr;
- int have_function[6];
+ int have_function[7];
/* setup dummy engine & engine type to store static properties in */
dummyengine.type = &dummyet;
@@ -323,6 +331,7 @@ static StructRNA *rna_RenderEngine_register(Main *bmain, ReportList *reports, vo
et->view_update = (have_function[3]) ? engine_view_update : NULL;
et->view_draw = (have_function[4]) ? engine_view_draw : NULL;
et->update_script_node = (have_function[5]) ? engine_update_script_node : NULL;
+ et->update_render_passes = (have_function[6]) ? engine_update_render_passes : NULL;
BLI_addtail(&R_engines, et);
@@ -419,6 +428,11 @@ static RenderPass *rna_RenderPass_find_by_type(RenderLayer *rl, int passtype, co
return RE_pass_find_by_type(rl, passtype, view);
}
+static RenderPass *rna_RenderPass_find_by_name(RenderLayer *rl, const char *name, const char *view)
+{
+ return RE_pass_find_by_name(rl, name, view);
+}
+
#else /* RNA_RUNTIME */
static void rna_def_render_engine(BlenderRNA *brna)
@@ -429,6 +443,13 @@ static void rna_def_render_engine(BlenderRNA *brna)
FunctionRNA *func;
PropertyRNA *parm;
+ static EnumPropertyItem render_pass_type_items[] = {
+ {SOCK_FLOAT, "VALUE", 0, "Value", ""},
+ {SOCK_VECTOR, "VECTOR", 0, "Vector", ""},
+ {SOCK_RGBA, "COLOR", 0, "Color", ""},
+ {0, NULL, 0, NULL, NULL}
+ };
+
srna = RNA_def_struct(brna, "RenderEngine", NULL);
RNA_def_struct_sdna(srna, "RenderEngine");
RNA_def_struct_ui_text(srna, "Render Engine", "Render engine");
@@ -497,6 +518,12 @@ static void rna_def_render_engine(BlenderRNA *brna)
func = RNA_def_function(srna, "tag_update", "engine_tag_update");
RNA_def_function_ui_description(func, "Request update call for viewport rendering");
+ func = RNA_def_function(srna, "update_render_passes", NULL);
+ RNA_def_function_ui_description(func, "Update the render passes that will be generated");
+ RNA_def_function_flag(func, FUNC_REGISTER_OPTIONAL | FUNC_ALLOW_WRITE);
+ parm = RNA_def_pointer(func, "scene", "Scene", "", "");
+ parm = RNA_def_pointer(func, "renderlayer", "SceneRenderLayer", "", "");
+
func = RNA_def_function(srna, "begin_result", "RE_engine_begin_result");
RNA_def_function_ui_description(func, "Create render result to write linear floating point render layers and passes");
parm = RNA_def_int(func, "x", 0, 0, INT_MAX, "X", "", 0, INT_MAX);
@@ -522,8 +549,20 @@ static void rna_def_render_engine(BlenderRNA *brna)
parm = RNA_def_pointer(func, "result", "RenderResult", "Result", "");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
RNA_def_boolean(func, "cancel", 0, "Cancel", "Don't mark tile as done, don't merge results unless forced");
+ RNA_def_boolean(func, "highlight", 0, "Highlight", "Don't mark tile as done yet");
RNA_def_boolean(func, "do_merge_results", 0, "Merge Results", "Merge results even if cancel=true");
+ func = RNA_def_function(srna, "add_pass", "RE_engine_add_pass");
+ RNA_def_function_ui_description(func, "Add a pass to the render layer");
+ parm = RNA_def_string(func, "name", NULL, 0, "Name", "Name of the Pass, without view or channel tag");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_int(func, "channels", 0, 0, INT_MAX, "Channels", "", 0, INT_MAX);
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_string(func, "chan_id", NULL, 0, "Channel IDs", "Channel names, one character per channel");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ RNA_def_string(func, "layer", NULL, 0, "Layer", "Single layer to add render pass to"); /* NULL ok here */
+
+
func = RNA_def_function(srna, "test_break", "RE_engine_test_break");
RNA_def_function_ui_description(func, "Test if the render operation should been canceled, this is a fast call that should be used regularly for responsiveness");
parm = RNA_def_boolean(func, "do_break", 0, "Break", "");
@@ -646,6 +685,21 @@ static void rna_def_render_engine(BlenderRNA *brna)
prop = RNA_def_property(srna, "use_highlight_tiles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", RE_ENGINE_HIGHLIGHT_TILES);
+ func = RNA_def_function(srna, "register_pass", "RE_engine_register_pass");
+ RNA_def_function_ui_description(func, "Register a render pass that will be part of the render with the current settings");
+ prop = RNA_def_pointer(func, "scene", "Scene", "", "");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ prop = RNA_def_pointer(func, "srl", "SceneRenderLayer", "", "");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ prop = RNA_def_string(func, "name", NULL, MAX_NAME, "Name", "");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ prop = RNA_def_int(func, "channels", 1, 1, 8, "Channels", "", 1, 4);
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ prop = RNA_def_string(func, "chanid", NULL, 8, "Channel IDs", "");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ prop = RNA_def_enum(func, "type", render_pass_type_items, SOCK_FLOAT, "Type", "");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+
/* registration */
prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
@@ -774,6 +828,15 @@ static void rna_def_render_passes(BlenderRNA *brna, PropertyRNA *cprop)
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
parm = RNA_def_pointer(func, "render_pass", "RenderPass", "", "The matching render pass");
RNA_def_function_return(func, parm);
+
+ func = RNA_def_function(srna, "find_by_name", "rna_RenderPass_find_by_name");
+ RNA_def_function_ui_description(func, "Get the render pass for a given name and view");
+ parm = RNA_def_string(func, "name", RE_PASSNAME_COMBINED, 0, "Pass", "");
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_string(func, "view", NULL, 0, "View", "Render view to get pass from"); /* NULL ok here */
+ RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
+ parm = RNA_def_pointer(func, "render_pass", "RenderPass", "", "The matching render pass");
+ RNA_def_function_return(func, parm);
}
static void rna_def_render_layer(BlenderRNA *brna)
@@ -822,6 +885,11 @@ static void rna_def_render_pass(BlenderRNA *brna)
RNA_define_verify_sdna(0);
+ prop = RNA_def_property(srna, "fullname", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "fullname");
+ RNA_def_property_clear_flag(prop, PROP_EDITABLE);
+ RNA_def_struct_name_property(srna, prop);
+
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "name");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
@@ -835,11 +903,6 @@ static void rna_def_render_pass(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "channels");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "passtype");
- RNA_def_property_enum_items(prop, rna_enum_render_pass_type_items);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
prop = RNA_def_property(srna, "rect", PROP_FLOAT, PROP_NONE);
RNA_def_property_flag(prop, PROP_DYNAMIC);
RNA_def_property_multi_array(prop, 2, NULL);
@@ -850,11 +913,6 @@ static void rna_def_render_pass(BlenderRNA *brna)
RNA_def_property_int_sdna(prop, NULL, "view_id");
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- prop = RNA_def_property(srna, "debug_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_sdna(prop, NULL, "debug_type");
- RNA_def_property_enum_items(prop, rna_enum_render_pass_debug_type_items);
- RNA_def_property_clear_flag(prop, PROP_EDITABLE);
-
RNA_define_verify_sdna(1);
}
diff --git a/source/blender/makesrna/intern/rna_scene.c b/source/blender/makesrna/intern/rna_scene.c
index 899466f05df..b9231574a24 100644
--- a/source/blender/makesrna/intern/rna_scene.c
+++ b/source/blender/makesrna/intern/rna_scene.c
@@ -88,7 +88,8 @@ EnumPropertyItem rna_enum_exr_codec_items[] = {
{R_IMF_EXR_CODEC_B44, "B44", 0, "B44 (lossy)", ""},
{R_IMF_EXR_CODEC_B44A, "B44A", 0, "B44A (lossy)", ""},
{R_IMF_EXR_CODEC_DWAA, "DWAA", 0, "DWAA (lossy)", ""},
- {R_IMF_EXR_CODEC_DWAB, "DWAB", 0, "DWAB (lossy)", ""},
+ /* NOTE: Commented out for until new OpenEXR is released, see T50673. */
+ /* {R_IMF_EXR_CODEC_DWAB, "DWAB", 0, "DWAB (lossy)", ""}, */
{0, NULL, 0, NULL, NULL}
};
#endif
@@ -448,6 +449,7 @@ EnumPropertyItem rna_enum_gpencil_interpolation_mode_items[] = {
#include "BKE_colortools.h"
#include "BKE_context.h"
#include "BKE_global.h"
+#include "BKE_idprop.h"
#include "BKE_image.h"
#include "BKE_main.h"
#include "BKE_node.h"
@@ -1608,6 +1610,18 @@ static void rna_Scene_use_view_map_cache_update(Main *UNUSED(bmain), Scene *UNUS
#endif
}
+static IDProperty *rna_SceneRenderLayer_idprops(PointerRNA *ptr, bool create)
+{
+ SceneRenderLayer *srl = (SceneRenderLayer *)ptr->data;
+
+ if (create && !srl->prop) {
+ IDPropertyTemplate val = {0};
+ srl->prop = IDP_New(IDP_GROUP, &val, "SceneRenderLayer ID properties");
+ }
+
+ return srl->prop;
+}
+
static void rna_SceneRenderLayer_name_set(PointerRNA *ptr, const char *value)
{
Scene *scene = (Scene *)ptr->id.data;
@@ -1712,11 +1726,18 @@ static void rna_SceneRenderLayer_pass_update(Main *bmain, Scene *activescene, Po
Scene *scene = (Scene *)ptr->id.data;
if (scene->nodetree)
- ntreeCompositForceHidden(scene->nodetree);
-
+ ntreeCompositUpdateRLayers(scene->nodetree);
+
rna_Scene_glsl_update(bmain, activescene, ptr);
}
+static void rna_SceneRenderLayer_update_render_passes(ID *id)
+{
+ Scene *scene = (Scene *)id;
+ if (scene->nodetree)
+ ntreeCompositUpdateRLayers(scene->nodetree);
+}
+
static void rna_Scene_use_nodes_update(bContext *C, PointerRNA *ptr)
{
Scene *scene = (Scene *)ptr->data;
@@ -1795,7 +1816,7 @@ static void object_simplify_update(Object *ob)
}
}
-static void rna_Scene_use_simplify_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
+static void rna_Scene_use_simplify_update(Main *bmain, Scene *scene, PointerRNA *ptr)
{
Scene *sce = ptr->id.data;
Scene *sce_iter;
@@ -1806,6 +1827,7 @@ static void rna_Scene_use_simplify_update(Main *bmain, Scene *UNUSED(scene), Poi
object_simplify_update(base->object);
WM_main_add_notifier(NC_GEOM | ND_DATA, NULL);
+ DAG_id_tag_update(&scene->id, 0);
}
static void rna_Scene_simplify_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *ptr)
@@ -5072,14 +5094,20 @@ static void rna_def_scene_render_layer(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
+ FunctionRNA *func;
srna = RNA_def_struct(brna, "SceneRenderLayer", NULL);
RNA_def_struct_ui_text(srna, "Scene Render Layer", "Render layer");
RNA_def_struct_ui_icon(srna, ICON_RENDERLAYERS);
RNA_def_struct_path_func(srna, "rna_SceneRenderLayer_path");
+ RNA_def_struct_idprops_func(srna, "rna_SceneRenderLayer_idprops");
rna_def_render_layer_common(srna, 1);
+ func = RNA_def_function(srna, "update_render_passes", "rna_SceneRenderLayer_update_render_passes");
+ RNA_def_function_ui_description(func, "Requery the enabled render passes from the render engine");
+ RNA_def_function_flag(func, FUNC_USE_SELF_ID | FUNC_NO_SELF);
+
/* Freestyle */
rna_def_freestyle_settings(brna);
@@ -6742,14 +6770,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "BakeSettings");
RNA_def_property_ui_text(prop, "Bake Data", "");
- /* Debugging settings. */
-#ifdef WITH_CYCLES_DEBUG
- prop = RNA_def_property(srna, "debug_pass_type", PROP_ENUM, PROP_NONE);
- RNA_def_property_enum_items(prop, rna_enum_render_pass_debug_type_items);
- RNA_def_property_ui_text(prop, "Debug Pass Type", "Type of the debug pass to use");
- RNA_def_property_update(prop, NC_SCENE | ND_RENDER_OPTIONS, NULL);
-#endif
-
/* Nestled Data */
/* *** Non-Animated *** */
RNA_define_animate_sdna(false);
@@ -6968,7 +6988,7 @@ static void rna_def_display_safe_areas(BlenderRNA *brna)
RNA_def_property_array(prop, 2);
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_float_array_default(prop, default_title);
- RNA_def_property_ui_text(prop, "Title Safe margins", "Safe area for text and graphics");
+ RNA_def_property_ui_text(prop, "Title Safe Margins", "Safe area for text and graphics");
RNA_def_property_update(prop, NC_SCENE | ND_DRAW_RENDER_VIEWPORT, NULL);
prop = RNA_def_property(srna, "action", PROP_FLOAT, PROP_XYZ);
@@ -6979,7 +6999,6 @@ static void rna_def_display_safe_areas(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Action Safe Margins", "Safe area for general elements");
RNA_def_property_update(prop, NC_SCENE | ND_DRAW_RENDER_VIEWPORT, NULL);
-
prop = RNA_def_property(srna, "title_center", PROP_FLOAT, PROP_XYZ);
RNA_def_property_float_sdna(prop, NULL, "title_center");
RNA_def_property_array(prop, 2);
diff --git a/source/blender/makesrna/intern/rna_scene_api.c b/source/blender/makesrna/intern/rna_scene_api.c
index 9b202120b82..ea7327cfa31 100644
--- a/source/blender/makesrna/intern/rna_scene_api.c
+++ b/source/blender/makesrna/intern/rna_scene_api.c
@@ -164,7 +164,6 @@ static void rna_Scene_ray_cast(
bool ret = ED_transform_snap_object_project_ray_ex(
sctx,
- SCE_SNAP_MODE_FACE,
&(const struct SnapObjectParams){
.snap_select = SNAP_ALL,
},
@@ -208,6 +207,8 @@ static void rna_Scene_alembic_export(
int renderable_only,
int face_sets,
int use_subdiv_schema,
+ int export_hair,
+ int export_particles,
int compression_type,
int packuv,
float scale,
@@ -225,8 +226,8 @@ static void rna_Scene_alembic_export(
.frame_start = frame_start,
.frame_end = frame_end,
- .frame_step_xform = 1.0 / (double)xform_samples,
- .frame_step_shape = 1.0 / (double)geom_samples,
+ .frame_samples_xform = xform_samples,
+ .frame_samples_shape = geom_samples,
.shutter_open = shutter_open,
.shutter_close = shutter_close,
@@ -241,6 +242,8 @@ static void rna_Scene_alembic_export(
.renderable_only = renderable_only,
.face_sets = face_sets,
.use_subdiv_schema = use_subdiv_schema,
+ .export_hair = export_hair,
+ .export_particles = export_particles,
.compression_type = compression_type,
.packuv = packuv,
.triangulate = triangulate,
@@ -250,7 +253,7 @@ static void rna_Scene_alembic_export(
.global_scale = scale,
};
- ABC_export(scene, C, filepath, &params);
+ ABC_export(scene, C, filepath, &params, true);
#ifdef WITH_PYTHON
BPy_END_ALLOW_THREADS;
@@ -276,8 +279,7 @@ static void rna_Scene_collada_export(
int include_shapekeys,
int deform_bones_only,
int active_uv_only,
- int include_uv_textures,
- int include_material_textures,
+ int export_texture_type,
int use_texture_copies,
int triangulate,
int use_object_instantiation,
@@ -301,8 +303,7 @@ static void rna_Scene_collada_export(
deform_bones_only,
active_uv_only,
- include_uv_textures,
- include_material_textures,
+ export_texture_type,
use_texture_copies,
triangulate,
@@ -399,11 +400,8 @@ void RNA_api_scene(StructRNA *srna)
RNA_def_boolean(func, "active_uv_only", false, "Only Selected UV Map", "Export only the selected UV Map");
- RNA_def_boolean(func, "include_uv_textures", false,
- "Include UV Textures", "Export textures assigned to the object UV Maps");
-
- RNA_def_boolean(func, "include_material_textures", false,
- "Include Material Textures", "Export textures assigned to the object Materials");
+ RNA_def_int(func, "export_texture_type", 0, INT_MIN, INT_MAX,
+ "Texture Type", "Type for exported Textures (UV or MAT)", INT_MIN, INT_MAX);
RNA_def_boolean(func, "use_texture_copies", true,
"Copy", "Copy textures to same folder where the .dae file is exported");
@@ -435,8 +433,9 @@ void RNA_api_scene(StructRNA *srna)
#endif
#ifdef WITH_ALEMBIC
+ /* XXX Deprecated, will be removed in 2.8 in favour of calling the export operator. */
func = RNA_def_function(srna, "alembic_export", "rna_Scene_alembic_export");
- RNA_def_function_ui_description(func, "Export to Alembic file");
+ RNA_def_function_ui_description(func, "Export to Alembic file (deprecated, use the Alembic export operator)");
parm = RNA_def_string(func, "filepath", NULL, FILE_MAX, "File Path", "File path to write Alembic file");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
@@ -458,6 +457,8 @@ void RNA_api_scene(StructRNA *srna)
RNA_def_boolean(func, "renderable_only" , 0, "Renderable objects only", "Export only objects marked renderable in the outliner");
RNA_def_boolean(func, "face_sets" , 0, "Facesets", "Export face sets");
RNA_def_boolean(func, "subdiv_schema", 0, "Use Alembic subdivision Schema", "Use Alembic subdivision Schema");
+ RNA_def_boolean(func, "export_hair", 1, "Export Hair", "Exports hair particle systems as animated curves");
+ RNA_def_boolean(func, "export_particles", 1, "Export Particles", "Exports non-hair particle systems");
RNA_def_enum(func, "compression_type", rna_enum_abc_compression_items, 0, "Compression", "");
RNA_def_boolean(func, "packuv" , 0, "Export with packed UV islands", "Export with packed UV islands");
RNA_def_float(func, "scale", 1.0f, 0.0001f, 1000.0f, "Scale", "Value by which to enlarge or shrink the objects with respect to the world's origin", 0.0001f, 1000.0f);
diff --git a/source/blender/makesrna/intern/rna_sequencer.c b/source/blender/makesrna/intern/rna_sequencer.c
index 3e6d8441363..f628c5f14d9 100644
--- a/source/blender/makesrna/intern/rna_sequencer.c
+++ b/source/blender/makesrna/intern/rna_sequencer.c
@@ -341,7 +341,7 @@ static void rna_Sequence_use_translation_set(PointerRNA *ptr, int value)
}
}
else {
- seq->flag ^= SEQ_USE_TRANSFORM;
+ seq->flag &= ~SEQ_USE_TRANSFORM;
}
}
@@ -355,7 +355,7 @@ static void rna_Sequence_use_crop_set(PointerRNA *ptr, int value)
}
}
else {
- seq->flag ^= SEQ_USE_CROP;
+ seq->flag &= ~SEQ_USE_CROP;
}
}
@@ -1095,7 +1095,7 @@ static void rna_def_strip_element(BlenderRNA *brna)
prop = RNA_def_property(srna, "filename", PROP_STRING, PROP_FILENAME);
RNA_def_property_string_sdna(prop, NULL, "name");
- RNA_def_property_ui_text(prop, "Filename", "");
+ RNA_def_property_ui_text(prop, "Filename", "Name of the source file");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceElement_update");
prop = RNA_def_property(srna, "orig_width", PROP_INT, PROP_NONE);
@@ -1120,25 +1120,25 @@ static void rna_def_strip_crop(BlenderRNA *brna)
prop = RNA_def_property(srna, "max_y", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "top");
- RNA_def_property_ui_text(prop, "Top", "");
+ RNA_def_property_ui_text(prop, "Top", "Number of pixels to crop from the top");
RNA_def_property_ui_range(prop, 0, 4096, 1, -1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update");
prop = RNA_def_property(srna, "min_y", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "bottom");
- RNA_def_property_ui_text(prop, "Bottom", "");
+ RNA_def_property_ui_text(prop, "Bottom", "Number of pixels to crop from the bottom");
RNA_def_property_ui_range(prop, 0, 4096, 1, -1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update");
prop = RNA_def_property(srna, "min_x", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "left");
- RNA_def_property_ui_text(prop, "Left", "");
+ RNA_def_property_ui_text(prop, "Left", "Number of pixels to crop from the left side");
RNA_def_property_ui_range(prop, 0, 4096, 1, -1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update");
prop = RNA_def_property(srna, "max_x", PROP_INT, PROP_UNSIGNED);
RNA_def_property_int_sdna(prop, NULL, "right");
- RNA_def_property_ui_text(prop, "Right", "");
+ RNA_def_property_ui_text(prop, "Right", "Number of pixels to crop from the right side");
RNA_def_property_ui_range(prop, 0, 4096, 1, -1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceCrop_update");
@@ -1156,13 +1156,13 @@ static void rna_def_strip_transform(BlenderRNA *brna)
prop = RNA_def_property(srna, "offset_x", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "xofs");
- RNA_def_property_ui_text(prop, "Offset X", "");
+ RNA_def_property_ui_text(prop, "Offset X", "Amount to move the input on the X axis within its boundaries");
RNA_def_property_ui_range(prop, -4096, 4096, 1, -1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
prop = RNA_def_property(srna, "offset_y", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "yofs");
- RNA_def_property_ui_text(prop, "Offset Y", "");
+ RNA_def_property_ui_text(prop, "Offset Y", "Amount to move the input on the Y axis within its boundaries");
RNA_def_property_ui_range(prop, -4096, 4096, 1, -1);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceTransform_update");
@@ -1246,7 +1246,7 @@ static void rna_def_strip_proxy(BlenderRNA *brna)
prop = RNA_def_property(srna, "timecode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "tc");
RNA_def_property_enum_items(prop, seq_tc_items);
- RNA_def_property_ui_text(prop, "Timecode", "");
+ RNA_def_property_ui_text(prop, "Timecode", "Method for reading the inputs timecode");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_tcindex_update");
prop = RNA_def_property(srna, "use_proxy_custom_directory", PROP_BOOLEAN, PROP_NONE);
@@ -1289,17 +1289,17 @@ static void rna_def_color_balance(BlenderRNA *brna)
prop = RNA_def_property(srna, "invert_gain", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_GAIN);
- RNA_def_property_ui_text(prop, "Inverse Gain", "");
+ RNA_def_property_ui_text(prop, "Inverse Gain", "Invert the gain color`");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
prop = RNA_def_property(srna, "invert_gamma", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_GAMMA);
- RNA_def_property_ui_text(prop, "Inverse Gamma", "");
+ RNA_def_property_ui_text(prop, "Inverse Gamma", "Invert the gamma color");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
prop = RNA_def_property(srna, "invert_lift", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_COLOR_BALANCE_INVERSE_LIFT);
- RNA_def_property_ui_text(prop, "Inverse Lift", "");
+ RNA_def_property_ui_text(prop, "Inverse Lift", "Invert the lift color");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceColorBalance_update");
/* not yet used */
@@ -1453,13 +1453,13 @@ static void rna_def_sequence(BlenderRNA *brna)
prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_MUTE);
RNA_def_property_ui_icon(prop, ICON_RESTRICT_VIEW_OFF, true);
- RNA_def_property_ui_text(prop, "Mute", "");
+ RNA_def_property_ui_text(prop, "Mute", "Disable strip so that it cannot be viewed in the output");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_mute_update");
prop = RNA_def_property(srna, "lock", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_LOCK);
RNA_def_property_ui_icon(prop, ICON_UNLOCKED, true);
- RNA_def_property_ui_text(prop, "Lock", "Lock strip so that it can't be transformed");
+ RNA_def_property_ui_text(prop, "Lock", "Lock strip so that it cannot be transformed");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, NULL);
/* strip positioning */
@@ -1481,7 +1481,7 @@ static void rna_def_sequence(BlenderRNA *brna)
prop = RNA_def_property(srna, "frame_start", PROP_INT, PROP_TIME);
RNA_def_property_int_sdna(prop, NULL, "start");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
- RNA_def_property_ui_text(prop, "Start Frame", "");
+ RNA_def_property_ui_text(prop, "Start Frame", "X position where the strip begins");
RNA_def_property_int_funcs(prop, NULL, "rna_Sequence_start_frame_set", NULL); /* overlap tests and calc_seq_disp */
RNA_def_property_editable_func(prop, "rna_Sequence_frame_editable");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
@@ -1552,12 +1552,12 @@ static void rna_def_sequence(BlenderRNA *brna)
prop = RNA_def_property(srna, "blend_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "blend_mode");
RNA_def_property_enum_items(prop, blend_mode_items);
- RNA_def_property_ui_text(prop, "Blend Mode", "");
+ RNA_def_property_ui_text(prop, "Blend Mode", "Method for controlling how the strip combines with other strips");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "blend_alpha", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_range(prop, 0.0f, 1.0f);
- RNA_def_property_ui_text(prop, "Blend Opacity", "");
+ RNA_def_property_ui_text(prop, "Blend Opacity", "Percentage of how much the strip's colors affect other strips");
/* stupid 0-100 -> 0-1 */
RNA_def_property_float_funcs(prop, "rna_Sequence_opacity_get", "rna_Sequence_opacity_set", NULL);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
@@ -1566,7 +1566,7 @@ static void rna_def_sequence(BlenderRNA *brna)
RNA_def_property_range(prop, 0.0f, 1.0f);
RNA_def_property_ui_range(prop, 0.0f, 1.0f, 0.1, 3);
RNA_def_property_float_sdna(prop, NULL, "effect_fader");
- RNA_def_property_ui_text(prop, "Effect fader position", "");
+ RNA_def_property_ui_text(prop, "Effect fader position", "Custom fade value");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "use_default_fade", PROP_BOOLEAN, PROP_NONE);
@@ -1714,7 +1714,7 @@ static void rna_def_filter_video(StructRNA *srna)
RNA_def_property_range(prop, 0.0f, 20.0f);
RNA_def_property_ui_range(prop, 0.0f, 2.0f, 3, 3);
RNA_def_property_float_default(prop, 1.0f);
- RNA_def_property_ui_text(prop, "Saturation", "");
+ RNA_def_property_ui_text(prop, "Saturation", "Adjust the intensity of the input's color");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "strobe", PROP_FLOAT, PROP_NONE);
@@ -2205,13 +2205,13 @@ static void rna_def_transform(StructRNA *srna)
prop = RNA_def_property(srna, "scale_start_x", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "ScalexIni");
- RNA_def_property_ui_text(prop, "Scale X", "");
+ RNA_def_property_ui_text(prop, "Scale X", "Amount to scale the input in the X axis");
RNA_def_property_ui_range(prop, 0, 10, 3, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "scale_start_y", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "ScaleyIni");
- RNA_def_property_ui_text(prop, "Scale Y", "");
+ RNA_def_property_ui_text(prop, "Scale Y", "Amount to scale the input in the Y axis");
RNA_def_property_ui_range(prop, 0, 10, 3, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
@@ -2222,33 +2222,33 @@ static void rna_def_transform(StructRNA *srna)
prop = RNA_def_property(srna, "translate_start_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "xIni");
- RNA_def_property_ui_text(prop, "Translate X", "");
+ RNA_def_property_ui_text(prop, "Translate X", "Amount to move the input on the X axis");
RNA_def_property_ui_range(prop, -4000.0f, 4000.0f, 3, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "translate_start_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "yIni");
- RNA_def_property_ui_text(prop, "Translate Y", "");
+ RNA_def_property_ui_text(prop, "Translate Y", "Amount to move the input on the Y axis");
RNA_def_property_ui_range(prop, -4000.0f, 4000.0f, 3, 6);
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "rotation_start", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "rotIni");
RNA_def_property_range(prop, -360.0f, 360.0f);
- RNA_def_property_ui_text(prop, "Rotation", "");
+ RNA_def_property_ui_text(prop, "Rotation", "Degrees to rotate the input");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "translation_unit", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "percent");
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* not meant to be animated */
RNA_def_property_enum_items(prop, translation_unit_items);
- RNA_def_property_ui_text(prop, "Translation Unit", "");
+ RNA_def_property_ui_text(prop, "Translation Unit", "Unit of measure to translate the input");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "interpolation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_items(prop, interpolation_items);
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE); /* not meant to be animated */
- RNA_def_property_ui_text(prop, "Interpolation", "");
+ RNA_def_property_ui_text(prop, "Interpolation", "Method to determine how missing pixels are created");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
}
@@ -2260,7 +2260,7 @@ static void rna_def_solid_color(StructRNA *srna)
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "col");
- RNA_def_property_ui_text(prop, "Color", "");
+ RNA_def_property_ui_text(prop, "Color", "Effect Strip color");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
}
@@ -2333,7 +2333,7 @@ static void rna_def_text(StructRNA *srna)
prop = RNA_def_property(srna, "color", PROP_FLOAT, PROP_COLOR_GAMMA);
RNA_def_property_float_sdna(prop, NULL, "color");
- RNA_def_property_ui_text(prop, "Color", "");
+ RNA_def_property_ui_text(prop, "Color", "Text color");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "shadow_color", PROP_FLOAT, PROP_COLOR_GAMMA);
@@ -2358,13 +2358,13 @@ static void rna_def_text(StructRNA *srna)
prop = RNA_def_property(srna, "align_x", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "align");
RNA_def_property_enum_items(prop, text_align_x_items);
- RNA_def_property_ui_text(prop, "Align X", "");
+ RNA_def_property_ui_text(prop, "Align X", "Align the text along the X axis");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "align_y", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "align_y");
RNA_def_property_enum_items(prop, text_align_y_items);
- RNA_def_property_ui_text(prop, "Align Y", "");
+ RNA_def_property_ui_text(prop, "Align Y", "Align the image along the Y axis");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_Sequence_update");
prop = RNA_def_property(srna, "text", PROP_STRING, PROP_NONE);
@@ -2512,7 +2512,7 @@ static void rna_def_colorbalance_modifier(BlenderRNA *brna)
RNA_def_property_float_sdna(prop, NULL, "color_multiply");
RNA_def_property_range(prop, 0.0f, 20.0f);
RNA_def_property_float_default(prop, 1.0f);
- RNA_def_property_ui_text(prop, "Multiply Colors", "");
+ RNA_def_property_ui_text(prop, "Multiply Colors", "Multiply the intensity of each pixel");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
}
@@ -2576,13 +2576,13 @@ static void rna_def_brightcontrast_modifier(BlenderRNA *brna)
prop = RNA_def_property(srna, "bright", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "bright");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
- RNA_def_property_ui_text(prop, "Bright", "");
+ RNA_def_property_ui_text(prop, "Bright", "Adjust the luminosity of the colors");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
prop = RNA_def_property(srna, "contrast", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "contrast");
RNA_def_property_range(prop, -FLT_MAX, FLT_MAX);
- RNA_def_property_ui_text(prop, "Contrast", "");
+ RNA_def_property_ui_text(prop, "Contrast", "Adjust the difference in luminosity between pixels");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
}
@@ -2599,13 +2599,12 @@ static void rna_def_tonemap_modifier(BlenderRNA *brna)
srna = RNA_def_struct(brna, "SequencerTonemapModifierData", "SequenceModifier");
RNA_def_struct_sdna(srna, "SequencerTonemapModifierData");
- RNA_def_struct_ui_text(srna, "SequencerTonemapModifierData",
- "Tone mapping modifier");
+ RNA_def_struct_ui_text(srna, "SequencerTonemapModifierData", "Tone mapping modifier");
prop = RNA_def_property(srna, "tonemap_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "type");
RNA_def_property_enum_items(prop, type_items);
- RNA_def_property_ui_text(prop, "Tonemap Type", "");
+ RNA_def_property_ui_text(prop, "Tonemap Type", "Tone mapping algorithm");
RNA_def_property_update(prop, NC_SCENE | ND_SEQUENCER, "rna_SequenceModifier_update");
prop = RNA_def_property(srna, "key", PROP_FLOAT, PROP_FACTOR);
diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c
index 5e364a3adf1..f2e856bf1ba 100644
--- a/source/blender/makesrna/intern/rna_space.c
+++ b/source/blender/makesrna/intern/rna_space.c
@@ -71,10 +71,10 @@ EnumPropertyItem rna_enum_space_type_items[] = {
{SPACE_NLA, "NLA_EDITOR", ICON_NLA, "NLA Editor", "Combine and layer Actions"},
{0, "", ICON_NONE, NULL, NULL},
{SPACE_IMAGE, "IMAGE_EDITOR", ICON_IMAGE_COL, "UV/Image Editor", "View and edit images and UV Maps"},
- {SPACE_SEQ, "SEQUENCE_EDITOR", ICON_SEQUENCE, "Video Sequence Editor", "Video editing tools"},
{SPACE_CLIP, "CLIP_EDITOR", ICON_CLIP, "Movie Clip Editor", "Motion tracking tools"},
- {SPACE_TEXT, "TEXT_EDITOR", ICON_TEXT, "Text Editor", "Edit scripts and in-file documentation"},
+ {SPACE_SEQ, "SEQUENCE_EDITOR", ICON_SEQUENCE, "Video Sequence Editor", "Video editing tools"},
{SPACE_NODE, "NODE_EDITOR", ICON_NODETREE, "Node Editor", "Editor for node-based shading and compositing tools"},
+ {SPACE_TEXT, "TEXT_EDITOR", ICON_TEXT, "Text Editor", "Edit scripts and in-file documentation"},
{SPACE_LOGIC, "LOGIC_EDITOR", ICON_LOGIC, "Logic Editor", "Game logic editing"},
{0, "", ICON_NONE, NULL, NULL},
{SPACE_BUTS, "PROPERTIES", ICON_BUTS, "Properties", "Edit properties of active object and related data-blocks"},
@@ -492,7 +492,7 @@ static void rna_View3D_CursorLocation_get(PointerRNA *ptr, float *values)
bScreen *sc = (bScreen *)ptr->id.data;
Scene *scene = (Scene *)sc->scene;
const float *loc = ED_view3d_cursor3d_get(scene, v3d);
-
+
copy_v3_v3(values, loc);
}
@@ -502,7 +502,7 @@ static void rna_View3D_CursorLocation_set(PointerRNA *ptr, const float *values)
bScreen *sc = (bScreen *)ptr->id.data;
Scene *scene = (Scene *)sc->scene;
float *cursor = ED_view3d_cursor3d_get(scene, v3d);
-
+
copy_v3_v3(cursor, values);
}
@@ -518,7 +518,7 @@ static float rna_View3D_GridScaleUnit_get(PointerRNA *ptr)
static void rna_SpaceView3D_layer_set(PointerRNA *ptr, const int *values)
{
View3D *v3d = (View3D *)(ptr->data);
-
+
v3d->lay = ED_view3d_scene_layer_set(v3d->lay, values, &v3d->layact);
}
@@ -545,16 +545,16 @@ static void rna_SpaceView3D_viewport_shade_update(Main *bmain, Scene *scene, Poi
static void rna_SpaceView3D_matcap_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
View3D *v3d = (View3D *)(ptr->data);
-
+
if (v3d->defmaterial) {
Material *ma = v3d->defmaterial;
-
+
if (ma->preview)
BKE_previewimg_free(&ma->preview);
-
+
if (ma->gpumaterial.first)
GPU_material_free(&ma->gpumaterial);
-
+
WM_main_add_notifier(NC_MATERIAL | ND_SHADING_DRAW, ma);
}
}
@@ -562,7 +562,7 @@ static void rna_SpaceView3D_matcap_update(Main *UNUSED(bmain), Scene *UNUSED(sce
static void rna_SpaceView3D_matcap_enable(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
View3D *v3d = (View3D *)(ptr->data);
-
+
if (v3d->matcap_icon < ICON_MATCAP_01 ||
v3d->matcap_icon > ICON_MATCAP_24)
{
@@ -719,7 +719,7 @@ static EnumPropertyItem *rna_SpaceView3D_viewport_shade_itemf(bContext *UNUSED(C
{
Scene *scene = ((bScreen *)ptr->id.data)->scene;
RenderEngineType *type = RE_engines_find(scene->r.engine);
-
+
EnumPropertyItem *item = NULL;
int totitem = 0;
@@ -728,7 +728,7 @@ static EnumPropertyItem *rna_SpaceView3D_viewport_shade_itemf(bContext *UNUSED(C
RNA_enum_items_add_value(&item, &totitem, rna_enum_viewport_shade_items, OB_SOLID);
RNA_enum_items_add_value(&item, &totitem, rna_enum_viewport_shade_items, OB_TEXTURE);
RNA_enum_items_add_value(&item, &totitem, rna_enum_viewport_shade_items, OB_MATERIAL);
-
+
if (type && type->view_draw)
RNA_enum_items_add_value(&item, &totitem, rna_enum_viewport_shade_items, OB_RENDER);
@@ -844,7 +844,7 @@ static EnumPropertyItem *rna_SpaceImageEditor_draw_channels_itemf(bContext *UNUS
int zbuf, alpha, totitem = 0;
ibuf = ED_space_image_acquire_buffer(sima, &lock);
-
+
alpha = ibuf && (ibuf->channels == 4);
zbuf = ibuf && (ibuf->zbuf || ibuf->zbuf_float || (ibuf->channels == 1));
@@ -895,14 +895,14 @@ static void rna_SpaceImageEditor_zoom_get(PointerRNA *ptr, float *values)
static void rna_SpaceImageEditor_cursor_location_get(PointerRNA *ptr, float *values)
{
SpaceImage *sima = (SpaceImage *)ptr->data;
-
+
if (sima->flag & SI_COORDFLOATS) {
copy_v2_v2(values, sima->cursor);
}
else {
int w, h;
ED_space_image_get_size(sima, &w, &h);
-
+
values[0] = sima->cursor[0] * w;
values[1] = sima->cursor[1] * h;
}
@@ -911,14 +911,14 @@ static void rna_SpaceImageEditor_cursor_location_get(PointerRNA *ptr, float *val
static void rna_SpaceImageEditor_cursor_location_set(PointerRNA *ptr, const float *values)
{
SpaceImage *sima = (SpaceImage *)ptr->data;
-
+
if (sima->flag & SI_COORDFLOATS) {
copy_v2_v2(sima->cursor, values);
}
else {
int w, h;
ED_space_image_get_size(sima, &w, &h);
-
+
sima->cursor[0] = values[0] / w;
sima->cursor[1] = values[1] / h;
}
@@ -947,7 +947,7 @@ static void rna_SpaceImageEditor_scopes_update(struct bContext *C, struct Pointe
SpaceImage *sima = (SpaceImage *)ptr->data;
ImBuf *ibuf;
void *lock;
-
+
ibuf = ED_space_image_acquire_buffer(sima, &lock);
if (ibuf) {
ED_space_image_scopes_update(C, sima, ibuf, true);
@@ -1026,12 +1026,12 @@ static void rna_SpaceProperties_pin_id_update(Main *UNUSED(bmain), Scene *UNUSED
{
SpaceButs *sbuts = (SpaceButs *)(ptr->data);
ID *id = sbuts->pinid;
-
+
if (id == NULL) {
sbuts->flag &= ~SB_PIN_CONTEXT;
return;
}
-
+
switch (GS(id->name)) {
case ID_MA:
WM_main_add_notifier(NC_MATERIAL | ND_SHADING, NULL);
@@ -1052,7 +1052,7 @@ static void rna_SpaceProperties_pin_id_update(Main *UNUSED(bmain), Scene *UNUSED
static void rna_SpaceProperties_context_set(PointerRNA *ptr, int value)
{
SpaceButs *sbuts = (SpaceButs *)(ptr->data);
-
+
sbuts->mainb = value;
sbuts->mainbuser = value;
}
@@ -1130,7 +1130,8 @@ static EnumPropertyItem *rna_SpaceProperties_context_itemf(bContext *UNUSED(C),
static void rna_SpaceProperties_context_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
SpaceButs *sbuts = (SpaceButs *)(ptr->data);
- if (ELEM(sbuts->mainb, BCONTEXT_WORLD, BCONTEXT_MATERIAL, BCONTEXT_TEXTURE)) {
+ /* XXX BCONTEXT_DATA is ugly, but required for lamps... See T51318. */
+ if (ELEM(sbuts->mainb, BCONTEXT_WORLD, BCONTEXT_MATERIAL, BCONTEXT_TEXTURE, BCONTEXT_DATA)) {
sbuts->preview = 1;
}
}
@@ -1203,7 +1204,7 @@ static void rna_ConsoleLine_body_set(PointerRNA *ptr, const char *value)
{
ConsoleLine *ci = (ConsoleLine *)ptr->data;
int len = strlen(value);
-
+
if ((len >= ci->len_alloc) || (len * 2 < ci->len_alloc) ) { /* allocate a new string */
MEM_freeN(ci->line);
ci->line = MEM_mallocN((len + 1) * sizeof(char), "rna_consoleline");
@@ -1231,7 +1232,7 @@ static void rna_SpaceDopeSheetEditor_action_set(PointerRNA *ptr, PointerRNA valu
{
SpaceAction *saction = (SpaceAction *)(ptr->data);
bAction *act = (bAction *)value.data;
-
+
if ((act == NULL) || (act->idroot == 0)) {
/* just set if we're clearing the action or if the action is "amorphous" still */
saction->action = act;
@@ -1268,7 +1269,7 @@ static void rna_SpaceDopeSheetEditor_action_update(Main *bmain, Scene *scene, Po
/* we must set this action to be the one used by active object (if not pinned) */
if (obact /* && saction->pin == 0*/) {
AnimData *adt = NULL;
-
+
if (saction->mode == SACTCONT_ACTION) {
/* TODO: context selector could help decide this with more control? */
adt = BKE_animdata_add_id(&obact->id); /* this only adds if non-existent */
@@ -1278,7 +1279,7 @@ static void rna_SpaceDopeSheetEditor_action_update(Main *bmain, Scene *scene, Po
if (key)
adt = BKE_animdata_add_id(&key->id); /* this only adds if non-existent */
}
-
+
/* set action */
// FIXME: this overlaps a lot with the BKE_animdata_set_action() API method
if (adt) {
@@ -1286,11 +1287,11 @@ static void rna_SpaceDopeSheetEditor_action_update(Main *bmain, Scene *scene, Po
if (adt->action != saction->action) {
/* NLA Tweak Mode needs special handling... */
if (adt->flag & ADT_NLA_EDIT_ON) {
- /* Exit editmode first - we cannot change actions while in tweakmode
+ /* Exit editmode first - we cannot change actions while in tweakmode
* NOTE: This will clear the action ref properly
*/
BKE_nla_tweakmode_exit(adt);
-
+
/* Assign new action, and adjust the usercounts accordingly */
adt->action = saction->action;
id_us_plus((ID *)adt->action);
@@ -1300,7 +1301,7 @@ static void rna_SpaceDopeSheetEditor_action_update(Main *bmain, Scene *scene, Po
if (adt->action) {
/* Fix id-count of action we're replacing */
id_us_min(&adt->action->id);
-
+
/* To prevent data loss (i.e. if users flip between actions using the Browse menu),
* stash this action if nothing else uses it.
*
@@ -1317,17 +1318,17 @@ static void rna_SpaceDopeSheetEditor_action_update(Main *bmain, Scene *scene, Po
BKE_nla_action_stash(adt);
}
}
-
+
/* Assign new action, and adjust the usercounts accordingly */
adt->action = saction->action;
id_us_plus((ID *)adt->action);
}
}
-
+
/* Force update of animdata */
adt->recalc |= ADT_RECALC_ANIM;
}
-
+
/* force depsgraph flush too */
DAG_id_tag_update(&obact->id, OB_RECALC_OB | OB_RECALC_DATA);
/* Update relations as well, so new time source dependency is added. */
@@ -1339,17 +1340,17 @@ static void rna_SpaceDopeSheetEditor_mode_update(Main *UNUSED(bmain), Scene *sce
{
SpaceAction *saction = (SpaceAction *)(ptr->data);
Object *obact = (scene->basact) ? scene->basact->object : NULL;
-
+
/* special exceptions for ShapeKey Editor mode */
if (saction->mode == SACTCONT_SHAPEKEY) {
Key *key = BKE_key_from_object(obact);
-
+
/* 1) update the action stored for the editor */
if (key)
saction->action = (key->adt) ? key->adt->action : NULL;
else
saction->action = NULL;
-
+
/* 2) enable 'show sliders' by default, since one of the main
* points of the ShapeKey Editor is to provide a one-stop shop
* for controlling the shapekeys, whose main control is the value
@@ -1365,7 +1366,7 @@ static void rna_SpaceDopeSheetEditor_mode_update(Main *UNUSED(bmain), Scene *sce
else
saction->action = NULL;
}
-
+
/* recalculate extents of channel list */
saction->flag |= SACTION_TEMP_NEEDCHANSYNC;
}
@@ -1375,7 +1376,7 @@ static void rna_SpaceDopeSheetEditor_mode_update(Main *UNUSED(bmain), Scene *sce
static void rna_SpaceGraphEditor_display_mode_update(Main *UNUSED(bmain), Scene *UNUSED(scene), PointerRNA *ptr)
{
ScrArea *sa = rna_area_from_space(ptr);
-
+
/* after changing view mode, must force recalculation of F-Curve colors
* which can only be achieved using refresh as opposed to redraw
*/
@@ -1465,7 +1466,7 @@ static int rna_SpaceNodeEditor_node_tree_poll(PointerRNA *ptr, const PointerRNA
{
SpaceNode *snode = (SpaceNode *)ptr->data;
bNodeTree *ntree = (bNodeTree *)value.data;
-
+
/* node tree type must match the selected type in node editor */
return (STREQ(snode->tree_idname, ntree->idname));
}
@@ -1544,7 +1545,7 @@ static void rna_SpaceNodeEditor_show_backdrop_update(Main *UNUSED(bmain), Scene
static void rna_SpaceNodeEditor_cursor_location_from_region(SpaceNode *snode, bContext *C, int x, int y)
{
ARegion *ar = CTX_wm_region(C);
-
+
UI_view2d_region_to_view(&ar->v2d, x, y, &snode->cursor[0], &snode->cursor[1]);
snode->cursor[0] /= UI_DPI_FAC;
snode->cursor[1] /= UI_DPI_FAC;
@@ -1896,12 +1897,12 @@ static void rna_def_space(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "Space", NULL);
RNA_def_struct_sdna(srna, "SpaceLink");
RNA_def_struct_ui_text(srna, "Space", "Space data for a screen area");
RNA_def_struct_refine_func(srna, "rna_Space_refine");
-
+
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "spacetype");
RNA_def_property_enum_items(prop, rna_enum_space_type_items);
@@ -2102,28 +2103,28 @@ static void rna_def_space_outliner(BlenderRNA *brna)
"Display data-blocks which are unused and/or will be lost when the file is reloaded"},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "SpaceOutliner", "Space");
RNA_def_struct_sdna(srna, "SpaceOops");
RNA_def_struct_ui_text(srna, "Space Outliner", "Outliner space data");
-
+
prop = RNA_def_property(srna, "display_mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "outlinevis");
RNA_def_property_enum_items(prop, display_mode_items);
RNA_def_property_ui_text(prop, "Display Mode", "Type of information to display");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
-
+
prop = RNA_def_property(srna, "filter_text", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "search_string");
RNA_def_property_ui_text(prop, "Display Filter", "Live search filtering string");
RNA_def_property_flag(prop, PROP_TEXTEDIT_UPDATE);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
-
+
prop = RNA_def_property(srna, "use_filter_case_sensitive", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "search_flags", SO_FIND_CASE_SENSITIVE);
RNA_def_property_ui_text(prop, "Case Sensitive Matches Only", "Only use case sensitive matches of search string");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_OUTLINER, NULL);
-
+
prop = RNA_def_property(srna, "use_filter_complete", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "search_flags", SO_FIND_COMPLETE);
RNA_def_property_ui_text(prop, "Complete Matches Only", "Only use complete matches of search string");
@@ -2219,17 +2220,17 @@ static void rna_def_background_image(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "cuser");
RNA_def_property_ui_text(prop, "Clip User", "Parameters defining which frame of the movie clip is displayed");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "offset_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "xof");
RNA_def_property_ui_text(prop, "X Offset", "Offset image horizontally from the world origin");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "offset_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "yof");
RNA_def_property_ui_text(prop, "Y Offset", "Offset image vertically from the world origin");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "size", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "size");
RNA_def_property_float_funcs(prop, "rna_BackgroundImage_size_get", "rna_BackgroundImage_size_set", NULL);
@@ -2349,7 +2350,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
{RV3D_CAMOB, "CAMERA", 0, "Camera", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
static EnumPropertyItem bundle_drawtype_items[] = {
{OB_PLAINAXES, "PLAIN_AXES", 0, "Plain Axes", ""},
{OB_ARROWS, "ARROWS", 0, "Arrows", ""},
@@ -2360,7 +2361,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
{OB_EMPTY_CONE, "CONE", 0, "Cone", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
static EnumPropertyItem view3d_matcap_items[] = {
{ICON_MATCAP_01, "01", ICON_MATCAP_01, "", ""},
{ICON_MATCAP_02, "02", ICON_MATCAP_02, "", ""},
@@ -2388,11 +2389,11 @@ static void rna_def_space_view3d(BlenderRNA *brna)
{ICON_MATCAP_24, "24", ICON_MATCAP_24, "", ""},
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "SpaceView3D", "Space");
RNA_def_struct_sdna(srna, "View3D");
RNA_def_struct_ui_text(srna, "3D View Space", "3D View space data");
-
+
prop = RNA_def_property(srna, "camera", PROP_POINTER, PROP_NONE);
RNA_def_property_flag(prop, PROP_EDITABLE);
RNA_def_property_pointer_sdna(prop, NULL, "camera");
@@ -2437,7 +2438,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "ob_centre");
RNA_def_property_ui_text(prop, "Lock to Object", "3D View center is locked to this object's position");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "lock_bone", PROP_STRING, PROP_NONE);
RNA_def_property_string_sdna(prop, NULL, "ob_centre_bone");
RNA_def_property_ui_text(prop, "Lock to Bone", "3D View center is locked to this bone's position");
@@ -2460,7 +2461,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_pointer_sdna(prop, NULL, "localvd");
RNA_def_property_ui_text(prop, "Local View",
"Display an isolated sub-set of objects, apart from the scene visibility");
-
+
prop = RNA_def_property(srna, "cursor_location", PROP_FLOAT, PROP_XYZ_LENGTH);
RNA_def_property_array(prop, 3);
RNA_def_property_float_funcs(prop, "rna_View3D_CursorLocation_get", "rna_View3D_CursorLocation_set", NULL);
@@ -2468,13 +2469,13 @@ static void rna_def_space_view3d(BlenderRNA *brna)
"3D cursor location for this view (dependent on local view setting)");
RNA_def_property_ui_range(prop, -10000.0, 10000.0, 1, RNA_TRANSLATION_PREC_DEFAULT);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "lens", PROP_FLOAT, PROP_UNIT_CAMERA);
RNA_def_property_float_sdna(prop, NULL, "lens");
RNA_def_property_ui_text(prop, "Lens", "Viewport lens angle");
RNA_def_property_range(prop, 1.0f, 250.0f);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "clip_start", PROP_FLOAT, PROP_DISTANCE);
RNA_def_property_float_sdna(prop, NULL, "near");
RNA_def_property_range(prop, 1e-6f, FLT_MAX);
@@ -2505,7 +2506,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_range(prop, 0, 1024);
RNA_def_property_int_default(prop, 16);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "grid_subdivisions", PROP_INT, PROP_NONE);
RNA_def_property_int_sdna(prop, NULL, "gridsubdiv");
RNA_def_property_ui_text(prop, "Grid Subdivisions", "Number of subdivisions between grid lines");
@@ -2522,28 +2523,28 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "gridflag", V3D_SHOW_FLOOR);
RNA_def_property_ui_text(prop, "Display Grid Floor", "Show the ground plane grid in perspective view");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "show_axis_x", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gridflag", V3D_SHOW_X);
RNA_def_property_ui_text(prop, "Display X Axis", "Show the X axis line in perspective view");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "show_axis_y", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gridflag", V3D_SHOW_Y);
RNA_def_property_ui_text(prop, "Display Y Axis", "Show the Y axis line in perspective view");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "show_axis_z", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "gridflag", V3D_SHOW_Z);
RNA_def_property_ui_text(prop, "Display Z Axis", "Show the Z axis line in perspective view");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "show_outline_selected", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_SELECT_OUTLINE);
RNA_def_property_ui_text(prop, "Outline Selected",
"Show an outline highlight around selected objects in non-wireframe views");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "show_all_objects_origin", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_DRAW_CENTERS);
RNA_def_property_ui_text(prop, "All Object Origins",
@@ -2555,7 +2556,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Relationship Lines",
"Show dashed lines indicating parent or constraint relationships");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SHOW_GPENCIL);
RNA_def_property_ui_text(prop, "Show Grease Pencil",
@@ -2591,7 +2592,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_RENDER_OVERRIDE);
RNA_def_property_ui_text(prop, "Only Render", "Display only objects which will be rendered");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "show_world", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag3", V3D_SHOW_WORLD);
RNA_def_property_ui_text(prop, "World Background", "Display world colors in the background");
@@ -2621,7 +2622,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_enum_items(prop, pivot_items_full);
RNA_def_property_ui_text(prop, "Pivot Point", "Pivot center for rotation/scaling");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_pivot_update");
-
+
prop = RNA_def_property(srna, "use_pivot_point_align", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", V3D_ALIGN);
RNA_def_property_ui_text(prop, "Align", "Manipulate center points (object, pose and weight paint mode only)");
@@ -2640,7 +2641,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_ENUM_FLAG);
RNA_def_property_ui_text(prop, "Transform Manipulators", "Transformation manipulators");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
prop = RNA_def_property(srna, "transform_orientation", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "twmode");
RNA_def_property_enum_items(prop, transform_orientation_items);
@@ -2678,7 +2679,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_array(prop, 8);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_ui_text(prop, "Local View Layers", "Local view layers visible in this 3D View");
-
+
prop = RNA_def_property(srna, "layers_used", PROP_BOOLEAN, PROP_LAYER_MEMBER);
RNA_def_property_boolean_sdna(prop, NULL, "lay_used", 1);
RNA_def_property_array(prop, 20);
@@ -2730,7 +2731,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag2", V3D_SOLID_MATCAP);
RNA_def_property_ui_text(prop, "Matcap", "Active Objects draw images mapped on normals, enhancing Solid Draw Mode");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_SpaceView3D_matcap_enable");
-
+
prop = RNA_def_property(srna, "matcap_icon", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "matcap_icon");
RNA_def_property_enum_items(prop, view3d_matcap_items);
@@ -2793,17 +2794,17 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "viewlock", RV3D_LOCKED);
RNA_def_property_ui_text(prop, "Lock", "Lock view rotation in side views");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_RegionView3D_quadview_update");
-
+
prop = RNA_def_property(srna, "show_sync_view", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "viewlock", RV3D_BOXVIEW);
RNA_def_property_ui_text(prop, "Box", "Sync view position between side views");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_RegionView3D_quadview_update");
-
+
prop = RNA_def_property(srna, "use_box_clip", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "viewlock", RV3D_BOXCLIP);
RNA_def_property_ui_text(prop, "Clip", "Clip objects based on what's visible in other side views");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, "rna_RegionView3D_quadview_clip_update");
-
+
prop = RNA_def_property(srna, "perspective_matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "persmat");
RNA_def_property_clear_flag(prop, PROP_EDITABLE); /* XXX: for now, it's too risky for users to do this */
@@ -2816,7 +2817,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
RNA_def_property_ui_text(prop, "Window Matrix", "Current window matrix");
-
+
prop = RNA_def_property(srna, "view_matrix", PROP_FLOAT, PROP_MATRIX);
RNA_def_property_float_sdna(prop, NULL, "viewmat");
RNA_def_property_multi_array(prop, 2, rna_matrix_dimsize_4x4);
@@ -2834,7 +2835,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "is_persp", 1);
RNA_def_property_ui_text(prop, "Is Perspective", "");
RNA_def_property_flag(prop, PROP_EDITABLE);
-
+
prop = RNA_def_property(srna, "view_location", PROP_FLOAT, PROP_TRANSLATION);
#if 0
RNA_def_property_float_sdna(prop, NULL, "ofs"); /* cant use because its negated */
@@ -2846,7 +2847,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "View Location", "View pivot location");
RNA_def_property_ui_range(prop, -10000.0, 10000.0, 10, RNA_TRANSLATION_PREC_DEFAULT);
RNA_def_property_update(prop, NC_WINDOW, NULL);
-
+
prop = RNA_def_property(srna, "view_rotation", PROP_FLOAT, PROP_QUATERNION); /* cant use because its inverted */
#if 0
RNA_def_property_float_sdna(prop, NULL, "viewquat");
@@ -2857,7 +2858,7 @@ static void rna_def_space_view3d(BlenderRNA *brna)
#endif
RNA_def_property_ui_text(prop, "View Rotation", "Rotation in quaternions (keep normalized)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_VIEW3D, NULL);
-
+
/* not sure we need rna access to these but adding anyway */
prop = RNA_def_property(srna, "view_distance", PROP_FLOAT, PROP_UNSIGNED);
RNA_def_property_float_sdna(prop, NULL, "dist");
@@ -2893,14 +2894,14 @@ static void rna_def_space_buttons(BlenderRNA *brna)
srna = RNA_def_struct(brna, "SpaceProperties", "Space");
RNA_def_struct_sdna(srna, "SpaceButs");
RNA_def_struct_ui_text(srna, "Properties Space", "Properties space data");
-
+
prop = RNA_def_property(srna, "context", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mainb");
RNA_def_property_enum_items(prop, buttons_context_items);
RNA_def_property_enum_funcs(prop, NULL, "rna_SpaceProperties_context_set", "rna_SpaceProperties_context_itemf");
RNA_def_property_ui_text(prop, "Context", "Type of active data to display and edit");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_PROPERTIES, "rna_SpaceProperties_context_update");
-
+
prop = RNA_def_property(srna, "align", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "align");
RNA_def_property_enum_items(prop, align_items);
@@ -2988,7 +2989,7 @@ static void rna_def_space_image(BlenderRNA *brna)
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_float_funcs(prop, "rna_SpaceImageEditor_zoom_get", NULL, NULL);
RNA_def_property_ui_text(prop, "Zoom", "Zoom factor");
-
+
/* image draw */
prop = RNA_def_property(srna, "show_repeat", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SI_DRAW_TILE);
@@ -3020,7 +3021,7 @@ static void rna_def_space_image(BlenderRNA *brna)
RNA_def_property_struct_type(prop, "SpaceUVEditor");
RNA_def_property_pointer_funcs(prop, "rna_SpaceImageEditor_uvedit_get", NULL, NULL, NULL);
RNA_def_property_ui_text(prop, "UV Editor", "UV editor settings");
-
+
/* mode */
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mode");
@@ -3050,7 +3051,7 @@ static void rna_def_space_image(BlenderRNA *brna)
RNA_def_property_flag(prop, PROP_EDITABLE | PROP_ID_REFCOUNT);
RNA_def_property_ui_text(prop, "Grease Pencil", "Grease pencil data for this space");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_IMAGE, NULL);
-
+
/* update */
prop = RNA_def_property(srna, "use_realtime_update", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "lock", 0);
@@ -3089,7 +3090,7 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static EnumPropertyItem view_type_items[] = {
{SEQ_VIEW_SEQUENCE, "SEQUENCER", ICON_SEQ_SEQUENCER, "Sequencer", ""},
{SEQ_VIEW_PREVIEW, "PREVIEW", ICON_SEQ_PREVIEW, "Image Preview", ""},
@@ -3143,7 +3144,7 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
srna = RNA_def_struct(brna, "SpaceSequenceEditor", "Space");
RNA_def_struct_sdna(srna, "SpaceSeq");
RNA_def_struct_ui_text(srna, "Space Sequence Editor", "Sequence editor space data");
-
+
/* view type, fairly important */
prop = RNA_def_property(srna, "view_type", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "view");
@@ -3164,17 +3165,17 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Frame Number Indicator",
"Show frame number beside the current frame indicator line");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
-
+
prop = RNA_def_property(srna, "show_frames", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_DRAWFRAMES);
RNA_def_property_ui_text(prop, "Draw Frames", "Draw frames rather than seconds");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
-
+
prop = RNA_def_property(srna, "use_marker_sync", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_MARKER_TRANS);
RNA_def_property_ui_text(prop, "Sync Markers", "Transform markers as well as strips");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
-
+
prop = RNA_def_property(srna, "show_separate_color", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_DRAW_COLOR_SEPARATED);
RNA_def_property_ui_text(prop, "Separate Colors", "Separate color channels in preview");
@@ -3199,7 +3200,7 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SEQ_DRAWFRAMES);
RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
-
+
prop = RNA_def_property(srna, "show_grease_pencil", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SEQ_SHOW_GPENCIL);
RNA_def_property_ui_text(prop, "Show Grease Pencil",
@@ -3230,14 +3231,14 @@ static void rna_def_space_sequencer(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Show Overexposed", "Show overexposed areas with zebra stripes");
RNA_def_property_range(prop, 0, 110);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
-
+
prop = RNA_def_property(srna, "proxy_render_size", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "render_size");
RNA_def_property_enum_items(prop, proxy_render_size_items);
RNA_def_property_ui_text(prop, "Proxy render size",
"Draw preview using full resolution or different proxy resolutions");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_SEQUENCER, NULL);
-
+
/* grease pencil */
prop = RNA_def_property(srna, "grease_pencil", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "gpd");
@@ -3298,7 +3299,7 @@ static void rna_def_space_text(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Syntax Highlight", "Syntax highlight for scripting");
RNA_def_property_ui_icon(prop, ICON_SYNTAX_OFF, 1);
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TEXT, NULL);
-
+
prop = RNA_def_property(srna, "show_line_highlight", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "line_hlight", 0);
RNA_def_property_ui_text(prop, "Highlight Line", "Highlight the current line");
@@ -3343,12 +3344,12 @@ static void rna_def_space_text(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "overwrite", 1);
RNA_def_property_ui_text(prop, "Overwrite", "Overwrite characters when typing rather than inserting them");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TEXT, NULL);
-
+
prop = RNA_def_property(srna, "use_live_edit", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "live_edit", 1);
RNA_def_property_ui_text(prop, "Live Edit", "Run python while editing");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TEXT, NULL);
-
+
/* find */
prop = RNA_def_property(srna, "use_find_all", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flags", ST_FIND_ALL);
@@ -3382,7 +3383,7 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
/* XXX: action-editor is currently for object-level only actions, so show that using object-icon hint */
static EnumPropertyItem mode_items[] = {
{SACTCONT_DOPESHEET, "DOPESHEET", ICON_OOPS, "Dope Sheet", "Edit all keyframes in scene"},
@@ -3393,8 +3394,8 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
{SACTCONT_CACHEFILE, "CACHEFILE", ICON_FILE, "Cache File", "Edit timings for Cache File data-blocks"},
{0, NULL, 0, NULL, NULL}
};
-
-
+
+
srna = RNA_def_struct(brna, "SpaceDopeSheetEditor", "Space");
RNA_def_struct_sdna(srna, "SpaceAction");
RNA_def_struct_ui_text(srna, "Space Dope Sheet Editor", "Dope Sheet space data");
@@ -3406,51 +3407,51 @@ static void rna_def_space_dopesheet(BlenderRNA *brna)
"rna_Action_actedit_assign_poll");
RNA_def_property_ui_text(prop, "Action", "Action displayed and edited in this space");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_SpaceDopeSheetEditor_action_update");
-
+
/* mode */
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, mode_items);
RNA_def_property_ui_text(prop, "Mode", "Editing context being displayed");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, "rna_SpaceDopeSheetEditor_mode_update");
-
+
/* display */
prop = RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SACTION_DRAWTIME);
RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL);
-
+
prop = RNA_def_property(srna, "show_frame_indicator", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SACTION_NODRAWCFRANUM);
RNA_def_property_ui_text(prop, "Show Frame Number Indicator",
"Show frame number beside the current frame indicator line");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL);
-
+
prop = RNA_def_property(srna, "show_sliders", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SACTION_SLIDERS);
RNA_def_property_ui_text(prop, "Show Sliders", "Show sliders beside F-Curve channels");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL);
-
+
prop = RNA_def_property(srna, "show_pose_markers", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SACTION_POSEMARKERS_SHOW);
RNA_def_property_ui_text(prop, "Show Pose Markers",
"Show markers belonging to the active action instead of Scene markers "
"(Action and Shape Key Editors only)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL);
-
+
prop = RNA_def_property(srna, "show_group_colors", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SACTION_NODRAWGCOLORS);
RNA_def_property_ui_text(prop, "Show Group Colors",
"Draw groups and channels with colors matching their corresponding groups "
"(pose bones only currently)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL);
-
+
/* editing */
prop = RNA_def_property(srna, "use_auto_merge_keyframes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SACTION_NOTRANSKEYCULL);
RNA_def_property_ui_text(prop, "AutoMerge Keyframes", "Automatically merge nearby keyframes");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_DOPESHEET, NULL);
-
+
prop = RNA_def_property(srna, "use_realtime_update", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SACTION_NOREALTIMEUPDATES);
RNA_def_property_ui_text(prop, "Realtime Updates",
@@ -3479,14 +3480,14 @@ static void rna_def_space_graph(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static EnumPropertyItem mode_items[] = {
{SIPO_MODE_ANIMATION, "FCURVES", ICON_IPO, "F-Curve",
"Edit animation/keyframes displayed as 2D curves"},
{SIPO_MODE_DRIVERS, "DRIVERS", ICON_DRIVER, "Drivers", "Edit drivers"},
{0, NULL, 0, NULL, NULL}
};
-
+
/* this is basically the same as the one for the 3D-View, but with some entries omitted */
static EnumPropertyItem gpivot_items[] = {
{V3D_AROUND_CENTER_BOUNDS, "BOUNDING_BOX_CENTER", ICON_ROTATE, "Bounding Box Center", ""},
@@ -3497,93 +3498,93 @@ static void rna_def_space_graph(BlenderRNA *brna)
{0, NULL, 0, NULL, NULL}
};
-
+
srna = RNA_def_struct(brna, "SpaceGraphEditor", "Space");
RNA_def_struct_sdna(srna, "SpaceIpo");
RNA_def_struct_ui_text(srna, "Space Graph Editor", "Graph Editor space data");
-
+
/* mode */
prop = RNA_def_property(srna, "mode", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "mode");
RNA_def_property_enum_items(prop, mode_items);
RNA_def_property_ui_text(prop, "Mode", "Editing context being displayed");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, "rna_SpaceGraphEditor_display_mode_update");
-
+
/* display */
prop = RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_DRAWTIME);
RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
prop = RNA_def_property(srna, "show_frame_indicator", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_NODRAWCFRANUM);
RNA_def_property_ui_text(prop, "Show Frame Number Indicator",
"Show frame number beside the current frame indicator line");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
prop = RNA_def_property(srna, "show_sliders", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_SLIDERS);
RNA_def_property_ui_text(prop, "Show Sliders", "Show sliders beside F-Curve channels");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
prop = RNA_def_property(srna, "show_handles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_NOHANDLES);
RNA_def_property_ui_text(prop, "Show Handles", "Show handles of Bezier control points");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
prop = RNA_def_property(srna, "use_only_selected_curves_handles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_SELCUVERTSONLY);
RNA_def_property_ui_text(prop, "Only Selected Curve Keyframes",
"Only keyframes of selected F-Curves are visible and editable");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
prop = RNA_def_property(srna, "use_only_selected_keyframe_handles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SIPO_SELVHANDLESONLY);
RNA_def_property_ui_text(prop, "Only Selected Keyframes Handles",
"Only show and edit handles of selected keyframes");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
prop = RNA_def_property(srna, "use_beauty_drawing", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_BEAUTYDRAW_OFF);
RNA_def_property_ui_text(prop, "Use High Quality Drawing",
"Draw F-Curves using Anti-Aliasing and other fancy effects "
"(disable for better performance)");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
prop = RNA_def_property(srna, "show_group_colors", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_NODRAWGCOLORS);
RNA_def_property_ui_text(prop, "Show Group Colors",
"Draw groups and channels with colors matching their corresponding groups");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
/* editing */
prop = RNA_def_property(srna, "use_auto_merge_keyframes", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_NOTRANSKEYCULL);
RNA_def_property_ui_text(prop, "AutoMerge Keyframes", "Automatically merge nearby keyframes");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
prop = RNA_def_property(srna, "use_realtime_update", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_NOREALTIMEUPDATES);
RNA_def_property_ui_text(prop, "Realtime Updates",
"When transforming keyframes, changes to the animation data are flushed to other views");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
/* cursor */
prop = RNA_def_property(srna, "show_cursor", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SIPO_NODRAWCURSOR);
RNA_def_property_ui_text(prop, "Show Cursor", "Show 2D cursor");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
prop = RNA_def_property(srna, "cursor_position_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "cursorTime");
RNA_def_property_ui_text(prop, "Cursor X-Value", "Graph Editor 2D-Value cursor - X-Value component");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
prop = RNA_def_property(srna, "cursor_position_y", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "cursorVal");
RNA_def_property_ui_text(prop, "Cursor Y-Value", "Graph Editor 2D-Value cursor - Y-Value component");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_GRAPH, NULL);
-
+
prop = RNA_def_property(srna, "pivot_point", PROP_ENUM, PROP_NONE);
RNA_def_property_enum_sdna(prop, NULL, "around");
RNA_def_property_enum_items(prop, gpivot_items);
@@ -3627,34 +3628,34 @@ static void rna_def_space_nla(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "SpaceNLA", "Space");
RNA_def_struct_sdna(srna, "SpaceNla");
RNA_def_struct_ui_text(srna, "Space Nla Editor", "NLA editor space data");
-
+
/* display */
prop = RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", SNLA_DRAWTIME);
RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NLA, NULL);
-
+
prop = RNA_def_property(srna, "show_frame_indicator", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SNLA_NODRAWCFRANUM);
RNA_def_property_ui_text(prop, "Show Frame Number Indicator",
"Show frame number beside the current frame indicator line");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NLA, NULL);
-
+
prop = RNA_def_property(srna, "show_strip_curves", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SNLA_NOSTRIPCURVES);
RNA_def_property_ui_text(prop, "Show Control F-Curves", "Show influence F-Curves on strips");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NLA, NULL);
-
+
prop = RNA_def_property(srna, "show_local_markers", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SNLA_NOLOCALMARKERS);
RNA_def_property_ui_text(prop, "Show Local Markers",
"Show action-local markers on the strips, useful when synchronizing timing across strips");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NLA, NULL);
-
+
/* editing */
prop = RNA_def_property(srna, "use_realtime_update", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", SNLA_NOREALTIMEUPDATES);
@@ -3680,54 +3681,54 @@ static void rna_def_space_time(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "SpaceTimeline", "Space");
RNA_def_struct_sdna(srna, "SpaceTime");
RNA_def_struct_ui_text(srna, "Space Timeline Editor", "Timeline editor space data");
-
+
/* view settings */
prop = RNA_def_property(srna, "show_frame_indicator", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", TIME_CFRA_NUM);
RNA_def_property_ui_text(prop, "Show Frame Number Indicator",
"Show frame number beside the current frame indicator line");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, NULL);
-
+
prop = RNA_def_property(srna, "show_seconds", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_negative_sdna(prop, NULL, "flag", TIME_DRAWFRAMES);
RNA_def_property_ui_text(prop, "Show Seconds", "Show timing in seconds not frames");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, NULL);
-
+
/* displaying cache status */
prop = RNA_def_property(srna, "show_cache", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cache_display", TIME_CACHE_DISPLAY);
RNA_def_property_ui_text(prop, "Show Cache", "Show the status of cached frames in the timeline");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, NULL);
-
+
prop = RNA_def_property(srna, "cache_softbody", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cache_display", TIME_CACHE_SOFTBODY);
RNA_def_property_ui_text(prop, "Softbody", "Show the active object's softbody point cache");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, NULL);
-
+
prop = RNA_def_property(srna, "cache_particles", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cache_display", TIME_CACHE_PARTICLES);
RNA_def_property_ui_text(prop, "Particles", "Show the active object's particle point cache");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, NULL);
-
+
prop = RNA_def_property(srna, "cache_cloth", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cache_display", TIME_CACHE_CLOTH);
RNA_def_property_ui_text(prop, "Cloth", "Show the active object's cloth point cache");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, NULL);
-
+
prop = RNA_def_property(srna, "cache_smoke", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cache_display", TIME_CACHE_SMOKE);
RNA_def_property_ui_text(prop, "Smoke", "Show the active object's smoke cache");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, NULL);
-
+
prop = RNA_def_property(srna, "cache_dynamicpaint", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cache_display", TIME_CACHE_DYNAMICPAINT);
RNA_def_property_ui_text(prop, "Dynamic Paint", "Show the active object's Dynamic Paint cache");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TIME, NULL);
-
+
prop = RNA_def_property(srna, "cache_rigidbody", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "cache_display", TIME_CACHE_RIGIDBODY);
RNA_def_property_ui_text(prop, "Rigid Body", "Show the active object's Rigid Body cache");
@@ -3746,17 +3747,17 @@ static void rna_def_console_line(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "ConsoleLine", NULL);
RNA_def_struct_ui_text(srna, "Console Input", "Input line for the interactive console");
-
+
prop = RNA_def_property(srna, "body", PROP_STRING, PROP_NONE);
RNA_def_property_string_funcs(prop, "rna_ConsoleLine_body_get", "rna_ConsoleLine_body_length",
"rna_ConsoleLine_body_set");
RNA_def_property_ui_text(prop, "Line", "Text in the line");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CONSOLE, NULL);
RNA_def_property_translation_context(prop, BLT_I18NCONTEXT_ID_TEXT);
-
+
prop = RNA_def_property(srna, "current_character", PROP_INT, PROP_NONE); /* copied from text editor */
RNA_def_property_int_sdna(prop, NULL, "cursor");
RNA_def_property_int_funcs(prop, NULL, NULL, "rna_ConsoleLine_cursor_index_range");
@@ -3767,16 +3768,16 @@ static void rna_def_console_line(BlenderRNA *brna)
RNA_def_property_enum_items(prop, console_line_type_items);
RNA_def_property_ui_text(prop, "Type", "Console line type when used in scrollback");
}
-
+
static void rna_def_space_console(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "SpaceConsole", "Space");
RNA_def_struct_sdna(srna, "SpaceConsole");
RNA_def_struct_ui_text(srna, "Space Console", "Interactive python console");
-
+
/* display */
prop = RNA_def_property(srna, "font_size", PROP_INT, PROP_NONE); /* copied from text editor */
RNA_def_property_int_sdna(prop, NULL, "lheight");
@@ -3788,14 +3789,14 @@ static void rna_def_space_console(BlenderRNA *brna)
prop = RNA_def_property(srna, "select_start", PROP_INT, PROP_UNSIGNED); /* copied from text editor */
RNA_def_property_int_sdna(prop, NULL, "sel_start");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CONSOLE, NULL);
-
+
prop = RNA_def_property(srna, "select_end", PROP_INT, PROP_UNSIGNED); /* copied from text editor */
RNA_def_property_int_sdna(prop, NULL, "sel_end");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_CONSOLE, NULL);
prop = RNA_def_property(srna, "prompt", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Prompt", "Command line prompt");
-
+
prop = RNA_def_property(srna, "language", PROP_STRING, PROP_NONE);
RNA_def_property_ui_text(prop, "Language", "Command line prompt language");
@@ -3803,7 +3804,7 @@ static void rna_def_space_console(BlenderRNA *brna)
RNA_def_property_collection_sdna(prop, NULL, "history", NULL);
RNA_def_property_struct_type(prop, "ConsoleLine");
RNA_def_property_ui_text(prop, "History", "Command history");
-
+
prop = RNA_def_property(srna, "scrollback", PROP_COLLECTION, PROP_NONE);
RNA_def_property_collection_sdna(prop, NULL, "scrollback", NULL);
RNA_def_property_struct_type(prop, "ConsoleLine");
@@ -3814,7 +3815,7 @@ static void rna_def_fileselect_params(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
static EnumPropertyItem file_display_items[] = {
{FILE_SHORTDISPLAY, "LIST_SHORT", ICON_SHORTDISPLAY, "Short List", "Display files as short list"},
{FILE_LONGDISPLAY, "LIST_LONG", ICON_LONGDISPLAY, "Long List", "Display files as a detailed list"},
@@ -4078,7 +4079,7 @@ static void rna_def_space_filebrowser(BlenderRNA *brna)
prop = RNA_def_property(srna, "params", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "params");
RNA_def_property_ui_text(prop, "Filebrowser Parameter", "Parameters and Settings for the Filebrowser");
-
+
prop = RNA_def_property(srna, "active_operator", PROP_POINTER, PROP_NONE);
RNA_def_property_pointer_sdna(prop, NULL, "op");
RNA_def_property_ui_text(prop, "Active Operator", "");
@@ -4159,28 +4160,28 @@ static void rna_def_space_info(BlenderRNA *brna)
srna = RNA_def_struct(brna, "SpaceInfo", "Space");
RNA_def_struct_sdna(srna, "SpaceInfo");
RNA_def_struct_ui_text(srna, "Space Info", "Info space data");
-
+
/* reporting display */
prop = RNA_def_property(srna, "show_report_debug", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "rpt_mask", INFO_RPT_DEBUG);
RNA_def_property_ui_text(prop, "Show Debug", "Display debug reporting info");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_INFO_REPORT, NULL);
-
+
prop = RNA_def_property(srna, "show_report_info", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "rpt_mask", INFO_RPT_INFO);
RNA_def_property_ui_text(prop, "Show Info", "Display general information");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_INFO_REPORT, NULL);
-
+
prop = RNA_def_property(srna, "show_report_operator", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "rpt_mask", INFO_RPT_OP);
RNA_def_property_ui_text(prop, "Show Operator", "Display the operator log");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_INFO_REPORT, NULL);
-
+
prop = RNA_def_property(srna, "show_report_warning", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "rpt_mask", INFO_RPT_WARN);
RNA_def_property_ui_text(prop, "Show Warn", "Display warnings");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_INFO_REPORT, NULL);
-
+
prop = RNA_def_property(srna, "show_report_error", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "rpt_mask", INFO_RPT_ERR);
RNA_def_property_ui_text(prop, "Show Error", "Display error text");
@@ -4196,7 +4197,7 @@ static void rna_def_space_userpref(BlenderRNA *brna)
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "SpaceUserPreferences", "Space");
RNA_def_struct_sdna(srna, "SpaceUserPref");
RNA_def_struct_ui_text(srna, "Space User Preferences", "User preferences space data");
@@ -4218,7 +4219,7 @@ static void rna_def_node_tree_path(BlenderRNA *brna)
{
StructRNA *srna;
PropertyRNA *prop;
-
+
srna = RNA_def_struct(brna, "NodeTreePath", NULL);
RNA_def_struct_sdna(srna, "bNodeTreePath");
RNA_def_struct_ui_text(srna, "Node Tree Path", "Element of the node space tree path");
@@ -4385,7 +4386,7 @@ static void rna_def_space_node(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_AUTO_RENDER);
RNA_def_property_ui_text(prop, "Auto Render", "Re-render and composite changed layers on 3D edits");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
-
+
prop = RNA_def_property(srna, "backdrop_zoom", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "zoom");
RNA_def_property_float_default(prop, 1.0f);
@@ -4393,7 +4394,7 @@ static void rna_def_space_node(BlenderRNA *brna)
RNA_def_property_ui_range(prop, 0.01, 100, 1, 2);
RNA_def_property_ui_text(prop, "Backdrop Zoom", "Backdrop zoom factor");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
-
+
prop = RNA_def_property(srna, "backdrop_x", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "xof");
RNA_def_property_ui_text(prop, "Backdrop X", "Backdrop X offset");
@@ -4410,11 +4411,6 @@ static void rna_def_space_node(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Draw Channels", "Channels of the image to draw");
RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
- prop = RNA_def_property(srna, "show_highlight", PROP_BOOLEAN, PROP_NONE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", SNODE_SHOW_HIGHLIGHT);
- RNA_def_property_ui_text(prop, "Highlight", "Highlight nodes that are being calculated");
- RNA_def_property_update(prop, NC_SPACE | ND_SPACE_NODE_VIEW, NULL);
-
/* the mx/my "cursor" in the node editor is used only by operators to store the mouse position */
prop = RNA_def_property(srna, "cursor_location", PROP_FLOAT, PROP_XYZ);
RNA_def_property_array(prop, 2);
@@ -4453,12 +4449,12 @@ static void rna_def_space_logic(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "scaflag", BUTS_SENS_SEL);
RNA_def_property_ui_text(prop, "Show Selected Object", "Show sensors of all selected objects");
RNA_def_property_update(prop, NC_LOGIC, NULL);
-
+
prop = RNA_def_property(srna, "show_sensors_active_object", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scaflag", BUTS_SENS_ACT);
RNA_def_property_ui_text(prop, "Show Active Object", "Show sensors of active object");
RNA_def_property_update(prop, NC_LOGIC, NULL);
-
+
prop = RNA_def_property(srna, "show_sensors_linked_controller", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scaflag", BUTS_SENS_LINK);
RNA_def_property_ui_text(prop, "Show Linked to Controller", "Show linked objects to the controller");
@@ -4474,7 +4470,7 @@ static void rna_def_space_logic(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "scaflag", BUTS_CONT_SEL);
RNA_def_property_ui_text(prop, "Show Selected Object", "Show controllers of all selected objects");
RNA_def_property_update(prop, NC_LOGIC, NULL);
-
+
prop = RNA_def_property(srna, "show_controllers_active_object", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scaflag", BUTS_CONT_ACT);
RNA_def_property_ui_text(prop, "Show Active Object", "Show controllers of active object");
@@ -4490,12 +4486,12 @@ static void rna_def_space_logic(BlenderRNA *brna)
RNA_def_property_boolean_sdna(prop, NULL, "scaflag", BUTS_ACT_SEL);
RNA_def_property_ui_text(prop, "Show Selected Object", "Show actuators of all selected objects");
RNA_def_property_update(prop, NC_LOGIC, NULL);
-
+
prop = RNA_def_property(srna, "show_actuators_active_object", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scaflag", BUTS_ACT_ACT);
RNA_def_property_ui_text(prop, "Show Active Object", "Show actuators of active object");
RNA_def_property_update(prop, NC_LOGIC, NULL);
-
+
prop = RNA_def_property(srna, "show_actuators_linked_controller", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "scaflag", BUTS_ACT_LINK);
RNA_def_property_ui_text(prop, "Show Linked to Actuator", "Show linked objects to the actuator");
diff --git a/source/blender/makesrna/intern/rna_space_api.c b/source/blender/makesrna/intern/rna_space_api.c
index c72d6d9e581..8f771eda99d 100644
--- a/source/blender/makesrna/intern/rna_space_api.c
+++ b/source/blender/makesrna/intern/rna_space_api.c
@@ -47,7 +47,7 @@ static void rna_RegionView3D_update(ID *id, RegionView3D *rv3d)
v3d = (View3D *)sa->spacedata.first;
- ED_view3d_update_viewmat(sc->scene, v3d, ar, NULL, NULL);
+ ED_view3d_update_viewmat(sc->scene, v3d, ar, NULL, NULL, NULL);
}
}
diff --git a/source/blender/makesrna/intern/rna_ui.c b/source/blender/makesrna/intern/rna_ui.c
index 7a3c862f04c..54b82fc89d6 100644
--- a/source/blender/makesrna/intern/rna_ui.c
+++ b/source/blender/makesrna/intern/rna_ui.c
@@ -1039,6 +1039,7 @@ static void rna_def_uilist(BlenderRNA *brna)
RNA_def_struct_refine_func(srna, "rna_UIList_refine");
RNA_def_struct_register_funcs(srna, "rna_UIList_register", "rna_UIList_unregister", NULL);
RNA_def_struct_idprops_func(srna, "rna_UIList_idprops");
+ RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES);
/* Registration */
prop = RNA_def_property(srna, "bl_idname", PROP_STRING, PROP_NONE);
diff --git a/source/blender/makesrna/intern/rna_ui_api.c b/source/blender/makesrna/intern/rna_ui_api.c
index 46775af21db..7d8d24670a7 100644
--- a/source/blender/makesrna/intern/rna_ui_api.c
+++ b/source/blender/makesrna/intern/rna_ui_api.c
@@ -557,8 +557,7 @@ void RNA_api_ui_layout(StructRNA *srna)
RNA_def_boolean(func, "emboss", true, "", "Draw the button itself, just the icon/text");
parm = RNA_def_property(func, "icon_value", PROP_INT, PROP_UNSIGNED);
RNA_def_property_ui_text(parm, "Icon Value", "Override automatic icon of the item");
- parm = RNA_def_pointer(func, "properties", "OperatorProperties", "",
- "Operator properties to fill in, return when 'properties' is set to true");
+ parm = RNA_def_pointer(func, "properties", "OperatorProperties", "", "Operator properties to fill in");
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED | PARM_RNAPTR);
RNA_def_function_return(func, parm);
RNA_def_function_ui_description(func, "Item. Places a button into the layout to call an Operator");
diff --git a/source/blender/makesrna/intern/rna_userdef.c b/source/blender/makesrna/intern/rna_userdef.c
index 4d70b87843a..7a978c35810 100644
--- a/source/blender/makesrna/intern/rna_userdef.c
+++ b/source/blender/makesrna/intern/rna_userdef.c
@@ -3156,6 +3156,7 @@ static void rna_def_userdef_addon_pref(BlenderRNA *brna)
RNA_def_struct_refine_func(srna, "rna_AddonPref_refine");
RNA_def_struct_register_funcs(srna, "rna_AddonPref_register", "rna_AddonPref_unregister", NULL);
RNA_def_struct_idprops_func(srna, "rna_AddonPref_idprops");
+ RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES); /* Mandatory! */
/* registration */
RNA_define_verify_sdna(0);
@@ -3316,7 +3317,7 @@ static void rna_def_userdef_view(BlenderRNA *brna)
prop = RNA_def_property(srna, "ui_scale", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_ui_text(prop, "UI Scale", "Changes the size of the fonts and buttons in the interface");
RNA_def_property_range(prop, 0.25f, 4.0f);
- RNA_def_property_ui_range(prop, 0.5f, 2.0f, 1, 1);
+ RNA_def_property_ui_range(prop, 0.5f, 2.0f, 1, 2);
RNA_def_property_float_default(prop, 1.0f);
RNA_def_property_update(prop, 0, "rna_userdef_dpi_update");
@@ -3925,12 +3926,18 @@ static void rna_def_userdef_system(BlenderRNA *brna)
prop = RNA_def_property(srna, "dpi", PROP_INT, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
- RNA_def_property_ui_text(prop, "DPI", "Font size and resolution for display");
+ RNA_def_property_ui_text(prop, "DPI",
+ "DPI for addons to use when drawing custom user interface elements. Controlled by "
+ "operating system settings and Blender UI scale, with a reference value of 72 DPI. "
+ "Note that since this value includes a user defined scale, it is not always the "
+ "actual monitor DPI");
prop = RNA_def_property(srna, "pixel_size", PROP_FLOAT, PROP_NONE);
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
RNA_def_property_float_sdna(prop, NULL, "pixelsize");
- RNA_def_property_ui_text(prop, "Pixel Size", "");
+ RNA_def_property_ui_text(prop, "Pixel Size",
+ "Suggested line thickness and point size in pixels, for addons drawing custom user "
+ "interface elements. Controlled by operating system settings and Blender UI scale");
prop = RNA_def_property(srna, "font_path_ui", PROP_STRING, PROP_FILEPATH);
RNA_def_property_string_sdna(prop, NULL, "font_path_ui");
diff --git a/source/blender/makesrna/intern/rna_wm.c b/source/blender/makesrna/intern/rna_wm.c
index 35c9c9bcc89..b5ecaf739c7 100644
--- a/source/blender/makesrna/intern/rna_wm.c
+++ b/source/blender/makesrna/intern/rna_wm.c
@@ -939,35 +939,8 @@ static void rna_wmClipboard_set(PointerRNA *UNUSED(ptr), const char *value)
}
#ifdef WITH_PYTHON
-static void rna_Operator_unregister(struct Main *bmain, StructRNA *type)
-{
- const char *idname;
- wmOperatorType *ot = RNA_struct_blender_type_get(type);
- wmWindowManager *wm;
-
- if (!ot)
- return;
-
- /* update while blender is running */
- wm = bmain->wm.first;
- if (wm) {
- WM_operator_stack_clear(wm);
- WM_operator_handlers_clear(wm, ot);
- }
- WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
-
- RNA_struct_free_extension(type, &ot->ext);
-
- idname = ot->idname;
- WM_operatortype_remove_ptr(ot);
- MEM_freeN((void *)idname);
-
- /* not to be confused with the RNA_struct_free that WM_operatortype_remove calls, they are 2 different srna's */
- RNA_struct_free(&BLENDER_RNA, type);
-}
-
-static int operator_poll(bContext *C, wmOperatorType *ot)
+static int rna_operator_poll_cb(bContext *C, wmOperatorType *ot)
{
extern FunctionRNA rna_Operator_poll_func;
@@ -992,7 +965,7 @@ static int operator_poll(bContext *C, wmOperatorType *ot)
return visible;
}
-static int operator_execute(bContext *C, wmOperator *op)
+static int rna_operator_execute_cb(bContext *C, wmOperator *op)
{
extern FunctionRNA rna_Operator_execute_func;
@@ -1018,7 +991,7 @@ static int operator_execute(bContext *C, wmOperator *op)
}
/* same as execute() but no return value */
-static bool operator_check(bContext *C, wmOperator *op)
+static bool rna_operator_check_cb(bContext *C, wmOperator *op)
{
extern FunctionRNA rna_Operator_check_func;
@@ -1043,7 +1016,7 @@ static bool operator_check(bContext *C, wmOperator *op)
return result;
}
-static int operator_invoke(bContext *C, wmOperator *op, const wmEvent *event)
+static int rna_operator_invoke_cb(bContext *C, wmOperator *op, const wmEvent *event)
{
extern FunctionRNA rna_Operator_invoke_func;
@@ -1070,7 +1043,7 @@ static int operator_invoke(bContext *C, wmOperator *op, const wmEvent *event)
}
/* same as invoke */
-static int operator_modal(bContext *C, wmOperator *op, const wmEvent *event)
+static int rna_operator_modal_cb(bContext *C, wmOperator *op, const wmEvent *event)
{
extern FunctionRNA rna_Operator_modal_func;
@@ -1096,7 +1069,7 @@ static int operator_modal(bContext *C, wmOperator *op, const wmEvent *event)
return result;
}
-static void operator_draw(bContext *C, wmOperator *op)
+static void rna_operator_draw_cb(bContext *C, wmOperator *op)
{
extern FunctionRNA rna_Operator_draw_func;
@@ -1115,7 +1088,7 @@ static void operator_draw(bContext *C, wmOperator *op)
}
/* same as exec(), but call cancel */
-static void operator_cancel(bContext *C, wmOperator *op)
+static void rna_operator_cancel_cb(bContext *C, wmOperator *op)
{
extern FunctionRNA rna_Operator_cancel_func;
@@ -1133,35 +1106,42 @@ static void operator_cancel(bContext *C, wmOperator *op)
RNA_parameter_list_free(&list);
}
-void operator_wrapper(wmOperatorType *ot, void *userdata);
-void macro_wrapper(wmOperatorType *ot, void *userdata);
+static void rna_Operator_unregister(struct Main *bmain, StructRNA *type);
-static char _operator_idname[OP_MAX_TYPENAME];
-static char _operator_name[OP_MAX_TYPENAME];
-static char _operator_descr[RNA_DYN_DESCR_MAX];
-static char _operator_ctxt[RNA_DYN_DESCR_MAX];
-static char _operator_undo_group[OP_MAX_TYPENAME];
-static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
- StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+/* bpy_operator_wrap.c */
+extern void BPY_RNA_operator_wrapper(wmOperatorType *ot, void *userdata);
+extern void BPY_RNA_operator_macro_wrapper(wmOperatorType *ot, void *userdata);
+
+static StructRNA *rna_Operator_register(
+ Main *bmain, ReportList *reports, void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
wmOperatorType dummyot = {NULL};
wmOperator dummyop = {NULL};
PointerRNA dummyotr;
int have_function[7];
+ struct {
+ char idname[OP_MAX_TYPENAME];
+ char name[OP_MAX_TYPENAME];
+ char descr[RNA_DYN_DESCR_MAX];
+ char ctxt[RNA_DYN_DESCR_MAX];
+ char undo_group[OP_MAX_TYPENAME];
+ } temp_buffers;
+
/* setup dummy operator & operator type to store static properties in */
dummyop.type = &dummyot;
- dummyot.idname = _operator_idname; /* only assigne the pointer, string is NULL'd */
- dummyot.name = _operator_name; /* only assigne the pointer, string is NULL'd */
- dummyot.description = _operator_descr; /* only assigne the pointer, string is NULL'd */
- dummyot.translation_context = _operator_ctxt; /* only assigne the pointer, string is NULL'd */
- dummyot.undo_group = _operator_undo_group; /* only assigne the pointer, string is NULL'd */
+ dummyot.idname = temp_buffers.idname; /* only assigne the pointer, string is NULL'd */
+ dummyot.name = temp_buffers.name; /* only assigne the pointer, string is NULL'd */
+ dummyot.description = temp_buffers.descr; /* only assigne the pointer, string is NULL'd */
+ dummyot.translation_context = temp_buffers.ctxt; /* only assigne the pointer, string is NULL'd */
+ dummyot.undo_group = temp_buffers.undo_group; /* only assigne the pointer, string is NULL'd */
RNA_pointer_create(NULL, &RNA_Operator, &dummyop, &dummyotr);
/* clear in case they are left unset */
- _operator_idname[0] = _operator_name[0] = _operator_descr[0] = _operator_undo_group[0] = '\0';
+ temp_buffers.idname[0] = temp_buffers.name[0] = temp_buffers.descr[0] = temp_buffers.undo_group[0] = '\0';
/* We have to set default op context! */
- strcpy(_operator_ctxt, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
+ strcpy(temp_buffers.ctxt, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
/* validate the python class */
if (validate(&dummyotr, data, have_function) != 0)
@@ -1172,7 +1152,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
/* inconveniently long name sanity check */
{
- char *ch = _operator_idname;
+ char *ch = temp_buffers.idname;
int i;
int dot = 0;
for (i = 0; *ch; i++) {
@@ -1185,7 +1165,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
else {
BKE_reportf(reports, RPT_ERROR,
"Registering operator class: '%s', invalid bl_idname '%s', at position %d",
- identifier, _operator_idname, i);
+ identifier, temp_buffers.idname, i);
return NULL;
}
@@ -1194,7 +1174,7 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
if (i > ((int)sizeof(dummyop.idname)) - 3) {
BKE_reportf(reports, RPT_ERROR, "Registering operator class: '%s', invalid bl_idname '%s', "
- "is too long, maximum length is %d", identifier, _operator_idname,
+ "is too long, maximum length is %d", identifier, temp_buffers.idname,
(int)sizeof(dummyop.idname) - 3);
return NULL;
}
@@ -1202,34 +1182,34 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
if (dot != 1) {
BKE_reportf(reports, RPT_ERROR,
"Registering operator class: '%s', invalid bl_idname '%s', must contain 1 '.' character",
- identifier, _operator_idname);
+ identifier, temp_buffers.idname);
return NULL;
}
}
/* end sanity check */
{
- int idlen = strlen(_operator_idname) + 4;
- int namelen = strlen(_operator_name) + 1;
- int desclen = strlen(_operator_descr) + 1;
- int ctxtlen = strlen(_operator_ctxt) + 1;
- int ugrouplen = strlen(_operator_undo_group) + 1;
- char *ch;
+ const uint idname_len = strlen(temp_buffers.idname) + 4;
+ const uint name_len = strlen(temp_buffers.name) + 1;
+ const uint desc_len = strlen(temp_buffers.descr) + 1;
+ const uint ctxt_len = strlen(temp_buffers.ctxt) + 1;
+ const uint undo_group_len = strlen(temp_buffers.undo_group) + 1;
/* 2 terminators and 3 to convert a.b -> A_OT_b */
- ch = MEM_callocN(sizeof(char) * (idlen + namelen + desclen + ctxtlen + ugrouplen), "_operator_idname");
- WM_operator_bl_idname(ch, _operator_idname); /* convert the idname from python */
+ char *ch = MEM_mallocN(
+ sizeof(char) * (idname_len + name_len + desc_len + ctxt_len + undo_group_len), __func__);
+ WM_operator_bl_idname(ch, temp_buffers.idname); /* convert the idname from python */
dummyot.idname = ch;
- ch += idlen;
- strcpy(ch, _operator_name);
+ ch += idname_len;
+ memcpy(ch, temp_buffers.name, name_len);
dummyot.name = ch;
- ch += namelen;
- strcpy(ch, _operator_descr);
+ ch += name_len;
+ memcpy(ch, temp_buffers.descr, desc_len);
dummyot.description = ch;
- ch += desclen;
- strcpy(ch, _operator_ctxt);
+ ch += desc_len;
+ memcpy(ch, temp_buffers.ctxt, ctxt_len);
dummyot.translation_context = ch;
- ch += ctxtlen;
- strcpy(ch, _operator_undo_group);
+ ch += ctxt_len;
+ memcpy(ch, temp_buffers.undo_group, undo_group_len);
dummyot.undo_group = ch;
}
}
@@ -1252,14 +1232,14 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
dummyot.ext.call = call;
dummyot.ext.free = free;
- dummyot.pyop_poll = (have_function[0]) ? operator_poll : NULL;
- dummyot.exec = (have_function[1]) ? operator_execute : NULL;
- dummyot.check = (have_function[2]) ? operator_check : NULL;
- dummyot.invoke = (have_function[3]) ? operator_invoke : NULL;
- dummyot.modal = (have_function[4]) ? operator_modal : NULL;
- dummyot.ui = (have_function[5]) ? operator_draw : NULL;
- dummyot.cancel = (have_function[6]) ? operator_cancel : NULL;
- WM_operatortype_append_ptr(operator_wrapper, (void *)&dummyot);
+ dummyot.pyop_poll = (have_function[0]) ? rna_operator_poll_cb : NULL;
+ dummyot.exec = (have_function[1]) ? rna_operator_execute_cb : NULL;
+ dummyot.check = (have_function[2]) ? rna_operator_check_cb : NULL;
+ dummyot.invoke = (have_function[3]) ? rna_operator_invoke_cb : NULL;
+ dummyot.modal = (have_function[4]) ? rna_operator_modal_cb : NULL;
+ dummyot.ui = (have_function[5]) ? rna_operator_draw_cb : NULL;
+ dummyot.cancel = (have_function[6]) ? rna_operator_cancel_cb : NULL;
+ WM_operatortype_append_ptr(BPY_RNA_operator_wrapper, (void *)&dummyot);
/* update while blender is running */
WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
@@ -1267,70 +1247,107 @@ static StructRNA *rna_Operator_register(Main *bmain, ReportList *reports, void *
return dummyot.ext.srna;
}
+static void rna_Operator_unregister(struct Main *bmain, StructRNA *type)
+{
+ const char *idname;
+ wmOperatorType *ot = RNA_struct_blender_type_get(type);
+ wmWindowManager *wm;
+
+ if (!ot)
+ return;
+
+ /* update while blender is running */
+ wm = bmain->wm.first;
+ if (wm) {
+ WM_operator_stack_clear(wm);
+
+ WM_operator_handlers_clear(wm, ot);
+ }
+ WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
+
+ RNA_struct_free_extension(type, &ot->ext);
+
+ idname = ot->idname;
+ WM_operatortype_remove_ptr(ot);
+ MEM_freeN((void *)idname);
+
+ /* not to be confused with the RNA_struct_free that WM_operatortype_remove calls, they are 2 different srna's */
+ RNA_struct_free(&BLENDER_RNA, type);
+}
+
static void **rna_Operator_instance(PointerRNA *ptr)
{
wmOperator *op = ptr->data;
return &op->py_instance;
}
-static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, void *data, const char *identifier,
- StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
+static StructRNA *rna_MacroOperator_register(
+ Main *bmain, ReportList *reports, void *data, const char *identifier,
+ StructValidateFunc validate, StructCallbackFunc call, StructFreeFunc free)
{
wmOperatorType dummyot = {NULL};
wmOperator dummyop = {NULL};
PointerRNA dummyotr;
int have_function[4];
+ struct {
+ char idname[OP_MAX_TYPENAME];
+ char name[OP_MAX_TYPENAME];
+ char descr[RNA_DYN_DESCR_MAX];
+ char ctxt[RNA_DYN_DESCR_MAX];
+ char undo_group[OP_MAX_TYPENAME];
+ } temp_buffers;
+
/* setup dummy operator & operator type to store static properties in */
dummyop.type = &dummyot;
- dummyot.idname = _operator_idname; /* only assigne the pointer, string is NULL'd */
- dummyot.name = _operator_name; /* only assigne the pointer, string is NULL'd */
- dummyot.description = _operator_descr; /* only assigne the pointer, string is NULL'd */
- dummyot.translation_context = _operator_ctxt; /* only assigne the pointer, string is NULL'd */
- dummyot.undo_group = _operator_undo_group; /* only assigne the pointer, string is NULL'd */
+ dummyot.idname = temp_buffers.idname; /* only assigne the pointer, string is NULL'd */
+ dummyot.name = temp_buffers.name; /* only assigne the pointer, string is NULL'd */
+ dummyot.description = temp_buffers.descr; /* only assigne the pointer, string is NULL'd */
+ dummyot.translation_context = temp_buffers.ctxt; /* only assigne the pointer, string is NULL'd */
+ dummyot.undo_group = temp_buffers.undo_group; /* only assigne the pointer, string is NULL'd */
RNA_pointer_create(NULL, &RNA_Macro, &dummyop, &dummyotr);
/* clear in case they are left unset */
- _operator_idname[0] = _operator_name[0] = _operator_descr[0] = _operator_undo_group[0] = '\0';
+ temp_buffers.idname[0] = temp_buffers.name[0] = temp_buffers.descr[0] = temp_buffers.undo_group[0] = '\0';
/* We have to set default op context! */
- strcpy(_operator_ctxt, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
+ strcpy(temp_buffers.ctxt, BLT_I18NCONTEXT_OPERATOR_DEFAULT);
/* validate the python class */
if (validate(&dummyotr, data, have_function) != 0)
return NULL;
+ if (strlen(identifier) >= sizeof(dummyop.idname)) {
+ BKE_reportf(reports, RPT_ERROR, "Registering operator class: '%s' is too long, maximum length is %d",
+ identifier, (int)sizeof(dummyop.idname));
+ return NULL;
+ }
+
{ /* convert foo.bar to FOO_OT_bar
* allocate the description and the idname in 1 go */
- int idlen = strlen(_operator_idname) + 4;
- int namelen = strlen(_operator_name) + 1;
- int desclen = strlen(_operator_descr) + 1;
- int ctxtlen = strlen(_operator_ctxt) + 1;
- int ugrouplen = strlen(_operator_undo_group) + 1;
- char *ch;
+ const uint idname_len = strlen(temp_buffers.idname) + 4;
+ const uint name_len = strlen(temp_buffers.name) + 1;
+ const uint desc_len = strlen(temp_buffers.descr) + 1;
+ const uint ctxt_len = strlen(temp_buffers.ctxt) + 1;
+ const uint undo_group_len = strlen(temp_buffers.undo_group) + 1;
/* 2 terminators and 3 to convert a.b -> A_OT_b */
- ch = MEM_callocN(sizeof(char) * (idlen + namelen + desclen + ctxtlen + ugrouplen), "_operator_idname");
- WM_operator_bl_idname(ch, _operator_idname); /* convert the idname from python */
+ char *ch = MEM_mallocN(
+ sizeof(char) * (idname_len + name_len + desc_len + ctxt_len + undo_group_len), __func__);
+ WM_operator_bl_idname(ch, temp_buffers.idname); /* convert the idname from python */
dummyot.idname = ch;
- ch += idlen;
- strcpy(ch, _operator_name);
+ ch += idname_len;
+ memcpy(ch, temp_buffers.name, name_len);
dummyot.name = ch;
- ch += namelen;
- strcpy(ch, _operator_descr);
+ ch += name_len;
+ memcpy(ch, temp_buffers.descr, desc_len);
dummyot.description = ch;
- ch += desclen;
- strcpy(ch, _operator_ctxt);
+ ch += desc_len;
+ memcpy(ch, temp_buffers.ctxt, ctxt_len);
dummyot.translation_context = ch;
- ch += ctxtlen;
- strcpy(ch, _operator_undo_group);
+ ch += ctxt_len;
+ memcpy(ch, temp_buffers.undo_group, undo_group_len);
dummyot.undo_group = ch;
}
- if (strlen(identifier) >= sizeof(dummyop.idname)) {
- BKE_reportf(reports, RPT_ERROR, "Registering operator class: '%s' is too long, maximum length is %d",
- identifier, (int)sizeof(dummyop.idname));
- return NULL;
- }
-
/* check if we have registered this operator type before, and remove it */
{
wmOperatorType *ot = WM_operatortype_find(dummyot.idname, true);
@@ -1348,10 +1365,10 @@ static StructRNA *rna_MacroOperator_register(Main *bmain, ReportList *reports, v
dummyot.ext.call = call;
dummyot.ext.free = free;
- dummyot.pyop_poll = (have_function[0]) ? operator_poll : NULL;
- dummyot.ui = (have_function[3]) ? operator_draw : NULL;
+ dummyot.pyop_poll = (have_function[0]) ? rna_operator_poll_cb : NULL;
+ dummyot.ui = (have_function[3]) ? rna_operator_draw_cb : NULL;
- WM_operatortype_append_macro_ptr(macro_wrapper, (void *)&dummyot);
+ WM_operatortype_append_macro_ptr(BPY_RNA_operator_macro_wrapper, (void *)&dummyot);
/* update while blender is running */
WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL);
@@ -1556,6 +1573,7 @@ static void rna_def_operator(BlenderRNA *brna)
RNA_def_struct_ui_text(srna, "Operator Properties", "Input properties of an Operator");
RNA_def_struct_refine_func(srna, "rna_OperatorProperties_refine");
RNA_def_struct_idprops_func(srna, "rna_OperatorProperties_idprops");
+ RNA_def_struct_flag(srna, STRUCT_NO_DATABLOCK_IDPROPERTIES);
}
static void rna_def_macro_operator(BlenderRNA *brna)
diff --git a/source/blender/modifiers/intern/MOD_array.c b/source/blender/modifiers/intern/MOD_array.c
index 2b739dc0093..874ac34b613 100644
--- a/source/blender/modifiers/intern/MOD_array.c
+++ b/source/blender/modifiers/intern/MOD_array.c
@@ -50,6 +50,7 @@
#include "BKE_curve.h"
#include "BKE_library_query.h"
#include "BKE_modifier.h"
+#include "BKE_mesh.h"
#include "MOD_util.h"
@@ -137,7 +138,7 @@ static void updateDepgraph(ModifierData *md, DagForest *forest,
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
- struct Scene *scene,
+ struct Scene *UNUSED(scene),
Object *UNUSED(ob),
struct DepsNodeHandle *node)
{
@@ -149,33 +150,15 @@ static void updateDepsgraph(ModifierData *md,
DEG_add_object_relation(node, amd->end_cap, DEG_OB_COMP_TRANSFORM, "Array Modifier End Cap");
}
if (amd->curve_ob) {
+ struct Depsgraph *depsgraph = DEG_get_graph_from_handle(node);
DEG_add_object_relation(node, amd->curve_ob, DEG_OB_COMP_GEOMETRY, "Array Modifier Curve");
- DEG_add_special_eval_flag(scene->depsgraph, &amd->curve_ob->id, DAG_EVAL_NEED_CURVE_PATH);
+ DEG_add_special_eval_flag(depsgraph, &amd->curve_ob->id, DAG_EVAL_NEED_CURVE_PATH);
}
if (amd->offset_ob != NULL) {
DEG_add_object_relation(node, amd->offset_ob, DEG_OB_COMP_TRANSFORM, "Array Modifier Offset");
}
}
-static float vertarray_size(const MVert *mvert, int numVerts, int axis)
-{
- int i;
- float min_co, max_co;
-
- /* if there are no vertices, width is 0 */
- if (numVerts == 0) return 0;
-
- /* find the minimum and maximum coordinates on the desired axis */
- min_co = max_co = mvert->co[axis];
- mvert++;
- for (i = 1; i < numVerts; ++i, ++mvert) {
- if (mvert->co[axis] < min_co) min_co = mvert->co[axis];
- if (mvert->co[axis] > max_co) max_co = mvert->co[axis];
- }
-
- return max_co - min_co;
-}
-
BLI_INLINE float sum_v3(const float v[3])
{
return v[0] + v[1] + v[2];
@@ -472,12 +455,22 @@ static DerivedMesh *arrayModifier_doArray(
unit_m4(offset);
src_mvert = dm->getVertArray(dm);
- if (amd->offset_type & MOD_ARR_OFF_CONST)
- add_v3_v3v3(offset[3], offset[3], amd->offset);
+ if (amd->offset_type & MOD_ARR_OFF_CONST) {
+ add_v3_v3(offset[3], amd->offset);
+ }
if (amd->offset_type & MOD_ARR_OFF_RELATIVE) {
- for (j = 0; j < 3; j++)
- offset[3][j] += amd->scale[j] * vertarray_size(src_mvert, chunk_nverts, j);
+ float min[3], max[3];
+ const MVert *src_mv;
+
+ INIT_MINMAX(min, max);
+ for (src_mv = src_mvert, j = chunk_nverts; j--; src_mv++) {
+ minmax_v3v3_v3(min, max, src_mv->co);
+ }
+
+ for (j = 3; j--; ) {
+ offset[3][j] += amd->scale[j] * (max[j] - min[j]);
+ }
}
if (use_offset_ob) {
diff --git a/source/blender/modifiers/intern/MOD_curve.c b/source/blender/modifiers/intern/MOD_curve.c
index 09444476bfe..3c6ba7acc88 100644
--- a/source/blender/modifiers/intern/MOD_curve.c
+++ b/source/blender/modifiers/intern/MOD_curve.c
@@ -111,7 +111,7 @@ static void updateDepgraph(ModifierData *md, DagForest *forest,
static void updateDepsgraph(ModifierData *md,
struct Main *UNUSED(bmain),
- struct Scene *scene,
+ struct Scene *UNUSED(scene),
Object *object,
struct DepsNodeHandle *node)
{
@@ -123,8 +123,9 @@ static void updateDepsgraph(ModifierData *md,
/* TODO(sergey): Currently path is evaluated as a part of modifier stack,
* might be changed in the future.
*/
+ struct Depsgraph *depsgraph = DEG_get_graph_from_handle(node);
DEG_add_object_relation(node, cmd->object, DEG_OB_COMP_GEOMETRY, "Curve Modifier");
- DEG_add_special_eval_flag(scene->depsgraph, &cmd->object->id, DAG_EVAL_NEED_CURVE_PATH);
+ DEG_add_special_eval_flag(depsgraph, &cmd->object->id, DAG_EVAL_NEED_CURVE_PATH);
}
DEG_add_object_relation(node, object, DEG_OB_COMP_TRANSFORM, "Curve Modifier");
diff --git a/source/blender/modifiers/intern/MOD_displace.c b/source/blender/modifiers/intern/MOD_displace.c
index 18f60bab490..3325f05025f 100644
--- a/source/blender/modifiers/intern/MOD_displace.c
+++ b/source/blender/modifiers/intern/MOD_displace.c
@@ -384,6 +384,7 @@ static void displaceModifier_do(
data.vert_clnors = vert_clnors;
if (dmd->texture != NULL) {
data.pool = BKE_image_pool_new();
+ BKE_texture_fetch_images_for_pool(dmd->texture, data.pool);
}
BLI_task_parallel_range(0, numVerts, &data, displaceModifier_do_task, numVerts > 512);
diff --git a/source/blender/modifiers/intern/MOD_dynamicpaint.c b/source/blender/modifiers/intern/MOD_dynamicpaint.c
index bb75d655802..83a42504180 100644
--- a/source/blender/modifiers/intern/MOD_dynamicpaint.c
+++ b/source/blender/modifiers/intern/MOD_dynamicpaint.c
@@ -36,6 +36,7 @@
#include "BKE_cdderivedmesh.h"
#include "BKE_dynamicpaint.h"
+#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_modifier.h"
@@ -58,6 +59,15 @@ static void copyData(ModifierData *md, ModifierData *target)
DynamicPaintModifierData *tpmd = (DynamicPaintModifierData *)target;
dynamicPaint_Modifier_copy(pmd, tpmd);
+
+ if (tpmd->canvas) {
+ for (DynamicPaintSurface *surface = tpmd->canvas->surfaces.first; surface; surface = surface->next) {
+ id_us_plus((ID *)surface->init_texture);
+ }
+ }
+ if (tpmd->brush) {
+ id_us_plus((ID *)tpmd->brush->mat);
+ }
}
static void freeData(ModifierData *md)
diff --git a/source/blender/modifiers/intern/MOD_fluidsim.c b/source/blender/modifiers/intern/MOD_fluidsim.c
index c202c5e1cb4..1964e940cb2 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim.c
@@ -68,12 +68,13 @@ static void copyData(ModifierData *md, ModifierData *target)
FluidsimModifierData *fluidmd = (FluidsimModifierData *) md;
FluidsimModifierData *tfluidmd = (FluidsimModifierData *) target;
- if (tfluidmd->fss)
- MEM_freeN(tfluidmd->fss);
-
- tfluidmd->fss = MEM_dupallocN(fluidmd->fss);
- if (tfluidmd->fss && (tfluidmd->fss->meshVelocities != NULL)) {
- tfluidmd->fss->meshVelocities = MEM_dupallocN(tfluidmd->fss->meshVelocities);
+ fluidsim_free(tfluidmd);
+
+ if (fluidmd->fss) {
+ tfluidmd->fss = MEM_dupallocN(fluidmd->fss);
+ if (tfluidmd->fss && (tfluidmd->fss->meshVelocities != NULL)) {
+ tfluidmd->fss->meshVelocities = MEM_dupallocN(tfluidmd->fss->meshVelocities);
+ }
}
}
diff --git a/source/blender/modifiers/intern/MOD_fluidsim_util.c b/source/blender/modifiers/intern/MOD_fluidsim_util.c
index ffbbb1b0745..3684e947fe0 100644
--- a/source/blender/modifiers/intern/MOD_fluidsim_util.c
+++ b/source/blender/modifiers/intern/MOD_fluidsim_util.c
@@ -78,8 +78,8 @@ void fluidsim_init(FluidsimModifierData *fluidmd)
fss->resolutionxyz = 65;
fss->previewresxyz = 45;
fss->realsize = 0.5;
- fss->guiDisplayMode = 2; // preview
- fss->renderDisplayMode = 3; // render
+ fss->guiDisplayMode = OB_FSDOM_PREVIEW;
+ fss->renderDisplayMode = OB_FSDOM_FINAL;
fss->viscosityValue = 1.0;
fss->viscosityExponent = 6;
@@ -98,7 +98,7 @@ void fluidsim_init(FluidsimModifierData *fluidmd)
/* fluid/inflow settings
* fss->iniVel --> automatically set to 0 */
- modifier_path_init(fss->surfdataPath, sizeof(fss->surfdataPath), "cache_fluid");
+ modifier_path_init(fss->surfdataPath, sizeof(fss->surfdataPath), OB_FLUIDSIM_SURF_DIR_DEFAULT);
/* first init of bounding box */
/* no bounding box needed */
@@ -150,9 +150,8 @@ void fluidsim_free(FluidsimModifierData *fluidmd)
if (fluidmd && fluidmd->fss) {
if (fluidmd->fss->meshVelocities) {
MEM_freeN(fluidmd->fss->meshVelocities);
- fluidmd->fss->meshVelocities = NULL;
}
- MEM_freeN(fluidmd->fss);
+ MEM_SAFE_FREE(fluidmd->fss);
}
return;
@@ -423,8 +422,6 @@ static void fluidsim_read_vel_cache(FluidsimModifierData *fluidmd, DerivedMesh *
static DerivedMesh *fluidsim_read_cache(Object *ob, DerivedMesh *orgdm,
FluidsimModifierData *fluidmd, int framenr, int useRenderParams)
{
- int displaymode = 0;
-
int curFrame = framenr /* - 1 */ /*scene->r.sfra*/; /* start with 0 at start frame */
/* why start with 0 as start frame?? Animations + time are frozen for frame 0 anyway. (See physics_fluid.c for that. - DG */
/* If we start with frame 0, we need to remap all animation channels, too, because they will all be 1 frame late if using frame-1! - DG */
@@ -435,25 +432,23 @@ static DerivedMesh *fluidsim_read_cache(Object *ob, DerivedMesh *orgdm,
MPoly *mpoly;
MPoly mp_example = {0};
- if (!useRenderParams) {
- displaymode = fss->guiDisplayMode;
- }
- else {
- displaymode = fss->renderDisplayMode;
- }
+ const int displaymode = useRenderParams ? fss->renderDisplayMode : fss->guiDisplayMode;
switch (displaymode) {
- case 1:
+ case OB_FSDOM_GEOM:
/* just display original object */
return NULL;
- case 2:
+ case OB_FSDOM_PREVIEW:
/* use preview mesh */
BLI_join_dirfile(targetFile, sizeof(targetFile), fss->surfdataPath, OB_FLUIDSIM_SURF_PREVIEW_OBJ_FNAME);
break;
- default: /* 3 */
- /* 3. use final mesh */
+ case OB_FSDOM_FINAL:
+ /* use final mesh */
BLI_join_dirfile(targetFile, sizeof(targetFile), fss->surfdataPath, OB_FLUIDSIM_SURF_FINAL_OBJ_FNAME);
break;
+ default:
+ BLI_assert(!"Wrong fluidsim display type");
+ return NULL;
}
/* offset baked frame */
@@ -494,7 +489,7 @@ static DerivedMesh *fluidsim_read_cache(Object *ob, DerivedMesh *orgdm,
/* load vertex velocities, if they exist...
* TODO? use generate flag as loading flag as well?
* warning, needs original .bobj.gz mesh loading filename */
- if (displaymode == 3) {
+ if (displaymode == OB_FSDOM_FINAL) {
fluidsim_read_vel_cache(fluidmd, dm, targetFile);
}
else {
diff --git a/source/blender/modifiers/intern/MOD_meshcache_mdd.c b/source/blender/modifiers/intern/MOD_meshcache_mdd.c
index 90fc750de3b..3dd3a5fc598 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_mdd.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_mdd.c
@@ -35,6 +35,9 @@
#ifdef __LITTLE_ENDIAN__
# include "BLI_endian_switch.h"
#endif
+#ifdef WIN32
+# include "BLI_winstuff.h"
+#endif
#include "MOD_meshcache_util.h" /* own include */
@@ -157,7 +160,7 @@ bool MOD_meshcache_read_mdd_index(FILE *fp,
return false;
}
- if (fseek(fp, index * mdd_head.verts_tot * sizeof(float) * 3, SEEK_CUR) != 0) {
+ if (fseek(fp, sizeof(float) * 3 * index * mdd_head.verts_tot, SEEK_CUR) != 0) {
*err_str = "Failed to seek frame";
return false;
}
diff --git a/source/blender/modifiers/intern/MOD_meshcache_pc2.c b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
index 219eae4ecca..8360c8ffda7 100644
--- a/source/blender/modifiers/intern/MOD_meshcache_pc2.c
+++ b/source/blender/modifiers/intern/MOD_meshcache_pc2.c
@@ -35,6 +35,10 @@
# include "BLI_endian_switch.h"
#endif
+#ifdef WIN32
+# include "BLI_winstuff.h"
+#endif
+
#include "MOD_meshcache_util.h" /* own include */
#include "DNA_modifier_types.h"
@@ -142,7 +146,7 @@ bool MOD_meshcache_read_pc2_index(FILE *fp,
return false;
}
- if (fseek(fp, index * pc2_head.verts_tot * sizeof(float) * 3, SEEK_CUR) != 0) {
+ if (fseek(fp, sizeof(float) * 3 * index * pc2_head.verts_tot , SEEK_CUR) != 0) {
*err_str = "Failed to seek frame";
return false;
}
diff --git a/source/blender/modifiers/intern/MOD_meshdeform.c b/source/blender/modifiers/intern/MOD_meshdeform.c
index 406ce398ee0..b1938395a7b 100644
--- a/source/blender/modifiers/intern/MOD_meshdeform.c
+++ b/source/blender/modifiers/intern/MOD_meshdeform.c
@@ -83,7 +83,7 @@ static void copyData(ModifierData *md, ModifierData *target)
MeshDeformModifierData *mmd = (MeshDeformModifierData *) md;
MeshDeformModifierData *tmmd = (MeshDeformModifierData *) target;
- *tmmd = *mmd;
+ modifier_copyData_generic(md, target);
if (mmd->bindinfluences) tmmd->bindinfluences = MEM_dupallocN(mmd->bindinfluences);
if (mmd->bindoffsets) tmmd->bindoffsets = MEM_dupallocN(mmd->bindoffsets);
@@ -91,8 +91,8 @@ static void copyData(ModifierData *md, ModifierData *target)
if (mmd->dyngrid) tmmd->dyngrid = MEM_dupallocN(mmd->dyngrid);
if (mmd->dyninfluences) tmmd->dyninfluences = MEM_dupallocN(mmd->dyninfluences);
if (mmd->dynverts) tmmd->dynverts = MEM_dupallocN(mmd->dynverts);
- if (mmd->bindweights) tmmd->dynverts = MEM_dupallocN(mmd->bindweights); /* deprecated */
- if (mmd->bindcos) tmmd->dynverts = MEM_dupallocN(mmd->bindcos); /* deprecated */
+ if (mmd->bindweights) tmmd->bindweights = MEM_dupallocN(mmd->bindweights); /* deprecated */
+ if (mmd->bindcos) tmmd->bindcos = MEM_dupallocN(mmd->bindcos); /* deprecated */
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
diff --git a/source/blender/modifiers/intern/MOD_ocean.c b/source/blender/modifiers/intern/MOD_ocean.c
index e77cc655c16..2c0bfc86e7d 100644
--- a/source/blender/modifiers/intern/MOD_ocean.c
+++ b/source/blender/modifiers/intern/MOD_ocean.c
@@ -160,40 +160,19 @@ static void freeData(ModifierData *md)
static void copyData(ModifierData *md, ModifierData *target)
{
#ifdef WITH_OCEANSIM
+#if 0
OceanModifierData *omd = (OceanModifierData *) md;
+#endif
OceanModifierData *tomd = (OceanModifierData *) target;
- tomd->geometry_mode = omd->geometry_mode;
- tomd->resolution = omd->resolution;
- tomd->spatial_size = omd->spatial_size;
-
- tomd->wind_velocity = omd->wind_velocity;
-
- tomd->damp = omd->damp;
- tomd->smallest_wave = omd->smallest_wave;
- tomd->depth = omd->depth;
+ freeData(target);
- tomd->wave_alignment = omd->wave_alignment;
- tomd->wave_direction = omd->wave_direction;
- tomd->wave_scale = omd->wave_scale;
-
- tomd->chop_amount = omd->chop_amount;
- tomd->foam_coverage = omd->foam_coverage;
- tomd->time = omd->time;
-
- tomd->seed = omd->seed;
- tomd->flag = omd->flag;
+ modifier_copyData_generic(md, target);
tomd->refresh = 0;
- tomd->size = omd->size;
- tomd->repeat_x = omd->repeat_x;
- tomd->repeat_y = omd->repeat_y;
-
/* XXX todo: copy cache runtime too */
tomd->cached = 0;
- tomd->bakestart = omd->bakestart;
- tomd->bakeend = omd->bakeend;
tomd->oceancache = NULL;
tomd->ocean = BKE_ocean_add();
diff --git a/source/blender/modifiers/intern/MOD_surfacedeform.c b/source/blender/modifiers/intern/MOD_surfacedeform.c
index 776cf02754e..b692137b604 100644
--- a/source/blender/modifiers/intern/MOD_surfacedeform.c
+++ b/source/blender/modifiers/intern/MOD_surfacedeform.c
@@ -138,7 +138,9 @@ static void copyData(ModifierData *md, ModifierData *target)
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
SurfaceDeformModifierData *tsmd = (SurfaceDeformModifierData *)target;
- *tsmd = *smd;
+ freeData(target);
+
+ modifier_copyData_generic(md, target);
if (smd->verts) {
tsmd->verts = MEM_dupallocN(smd->verts);
@@ -1120,6 +1122,11 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
tdm = smd->target->derivedFinal;
}
+ if (!tdm) {
+ modifier_setError(md, "No valid target mesh");
+ return;
+ }
+
tnumverts = tdm->getNumVerts(tdm);
tnumpoly = tdm->getNumPolys(tdm);
@@ -1139,19 +1146,19 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
/* Poly count checks */
if (smd->numverts != numverts) {
modifier_setError(md, "Verts changed from %u to %u", smd->numverts, numverts);
- tdm->release(tdm);
return;
}
else if (smd->numpoly != tnumpoly) {
modifier_setError(md, "Target polygons changed from %u to %u", smd->numpoly, tnumpoly);
- tdm->release(tdm);
return;
}
/* Actual vertex location update starts here */
- SDefDeformData data = {.bind_verts = smd->verts,
- .targetCos = MEM_mallocN(sizeof(float[3]) * tnumverts, "SDefTargetVertArray"),
- .vertexCos = vertexCos};
+ SDefDeformData data = {
+ .bind_verts = smd->verts,
+ .targetCos = MEM_mallocN(sizeof(float[3]) * tnumverts, "SDefTargetVertArray"),
+ .vertexCos = vertexCos,
+ };
if (data.targetCos != NULL) {
bool tdm_vert_alloc;
@@ -1170,8 +1177,6 @@ static void surfacedeformModifier_do(ModifierData *md, float (*vertexCos)[3], un
MEM_freeN(data.targetCos);
}
-
- tdm->release(tdm);
}
static void deformVerts(ModifierData *md, Object *ob,
@@ -1194,7 +1199,7 @@ static bool isDisabled(ModifierData *md, int UNUSED(useRenderParams))
{
SurfaceDeformModifierData *smd = (SurfaceDeformModifierData *)md;
- return !smd->target;
+ return !smd->target && !(smd->verts && !(smd->flags & MOD_SDEF_BIND));
}
ModifierTypeInfo modifierType_SurfaceDeform = {
diff --git a/source/blender/modifiers/intern/MOD_uvproject.c b/source/blender/modifiers/intern/MOD_uvproject.c
index 78dc1ea8bcb..01468c1143a 100644
--- a/source/blender/modifiers/intern/MOD_uvproject.c
+++ b/source/blender/modifiers/intern/MOD_uvproject.c
@@ -45,6 +45,7 @@
#include "BKE_camera.h"
+#include "BKE_library.h"
#include "BKE_library_query.h"
#include "BKE_mesh.h"
#include "BKE_DerivedMesh.h"
@@ -70,9 +71,12 @@ static void copyData(ModifierData *md, ModifierData *target)
{
#if 0
UVProjectModifierData *umd = (UVProjectModifierData *) md;
- UVProjectModifierData *tumd = (UVProjectModifierData *) target;
#endif
+ UVProjectModifierData *tumd = (UVProjectModifierData *) target;
+
modifier_copyData_generic(md, target);
+
+ id_us_plus((ID *)tumd->image);
}
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *UNUSED(md))
diff --git a/source/blender/modifiers/intern/MOD_warp.c b/source/blender/modifiers/intern/MOD_warp.c
index 92d44257d03..b340356467a 100644
--- a/source/blender/modifiers/intern/MOD_warp.c
+++ b/source/blender/modifiers/intern/MOD_warp.c
@@ -66,6 +66,10 @@ static void copyData(ModifierData *md, ModifierData *target)
WarpModifierData *wmd = (WarpModifierData *) md;
WarpModifierData *twmd = (WarpModifierData *) target;
+ if (twmd->curfalloff != NULL) {
+ curvemapping_free(twmd->curfalloff);
+ }
+
modifier_copyData_generic(md, target);
twmd->curfalloff = curvemapping_copy(wmd->curfalloff);
diff --git a/source/blender/modifiers/intern/MOD_weightvgedit.c b/source/blender/modifiers/intern/MOD_weightvgedit.c
index 2a822ac07b5..cd30b54350c 100644
--- a/source/blender/modifiers/intern/MOD_weightvgedit.c
+++ b/source/blender/modifiers/intern/MOD_weightvgedit.c
@@ -226,8 +226,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
if (!do_add)
return dm;
/* Else, add a valid data layer! */
- dvert = CustomData_add_layer_named(&dm->vertData, CD_MDEFORMVERT, CD_CALLOC,
- NULL, numVerts, wmd->defgrp_name);
+ dvert = CustomData_add_layer(&dm->vertData, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts);
/* Ultimate security check. */
if (!dvert)
return dm;
diff --git a/source/blender/modifiers/intern/MOD_weightvgmix.c b/source/blender/modifiers/intern/MOD_weightvgmix.c
index 9bff7bf11f1..1b3188c83b3 100644
--- a/source/blender/modifiers/intern/MOD_weightvgmix.c
+++ b/source/blender/modifiers/intern/MOD_weightvgmix.c
@@ -282,8 +282,7 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob, DerivedMesh *der
if (wmd->mix_set != MOD_WVG_SET_ALL)
return dm;
/* Else, add a valid data layer! */
- dvert = CustomData_add_layer_named(&dm->vertData, CD_MDEFORMVERT, CD_CALLOC,
- NULL, numVerts, wmd->defgrp_name_a);
+ dvert = CustomData_add_layer(&dm->vertData, CD_MDEFORMVERT, CD_CALLOC, NULL, numVerts);
/* Ultimate security check. */
if (!dvert)
return dm;
diff --git a/source/blender/nodes/CMakeLists.txt b/source/blender/nodes/CMakeLists.txt
index d20881df150..c5a3c70100b 100644
--- a/source/blender/nodes/CMakeLists.txt
+++ b/source/blender/nodes/CMakeLists.txt
@@ -163,6 +163,7 @@ set(SRC
shader/nodes/node_shader_background.c
shader/nodes/node_shader_bsdf_anisotropic.c
shader/nodes/node_shader_bsdf_diffuse.c
+ shader/nodes/node_shader_bsdf_principled.c
shader/nodes/node_shader_bsdf_glass.c
shader/nodes/node_shader_bsdf_glossy.c
shader/nodes/node_shader_bsdf_toon.c
@@ -288,8 +289,4 @@ if(WITH_FREESTYLE)
add_definitions(-DWITH_FREESTYLE)
endif()
-if(WITH_CYCLES AND WITH_CYCLES_DEBUG)
- add_definitions(-DWITH_CYCLES_DEBUG)
-endif()
-
blender_add_lib(bf_nodes "${SRC}" "${INC}" "${INC_SYS}")
diff --git a/source/blender/nodes/NOD_composite.h b/source/blender/nodes/NOD_composite.h
index 0215db1dd55..a5c2e604f46 100644
--- a/source/blender/nodes/NOD_composite.h
+++ b/source/blender/nodes/NOD_composite.h
@@ -139,6 +139,8 @@ void register_node_type_cmp_trackpos(void);
void register_node_type_cmp_planetrackdeform(void);
void register_node_type_cmp_cornerpin(void);
-void node_cmp_rlayers_force_hidden_passes(struct bNode *node);
+void node_cmp_rlayers_outputs(struct bNodeTree *ntree, struct bNode *node);
+void node_cmp_rlayers_register_pass(struct bNodeTree *ntree, struct bNode *node, struct Scene *scene, struct SceneRenderLayer *srl, const char *name, int type);
+const char *node_cmp_rlayers_sock_to_pass(int sock_index);
#endif
diff --git a/source/blender/nodes/NOD_shader.h b/source/blender/nodes/NOD_shader.h
index 4c0047f1d58..804c1897a27 100644
--- a/source/blender/nodes/NOD_shader.h
+++ b/source/blender/nodes/NOD_shader.h
@@ -106,6 +106,7 @@ void register_node_type_sh_bsdf_transparent(void);
void register_node_type_sh_bsdf_velvet(void);
void register_node_type_sh_bsdf_toon(void);
void register_node_type_sh_bsdf_anisotropic(void);
+void register_node_type_sh_bsdf_principled(void);
void register_node_type_sh_emission(void);
void register_node_type_sh_holdout(void);
void register_node_type_sh_volume_absorption(void);
diff --git a/source/blender/nodes/NOD_static_types.h b/source/blender/nodes/NOD_static_types.h
index a9c0df7d7e8..02422a8622a 100644
--- a/source/blender/nodes/NOD_static_types.h
+++ b/source/blender/nodes/NOD_static_types.h
@@ -80,6 +80,7 @@ DefNode( ShaderNode, SH_NODE_BACKGROUND, 0, "BA
DefNode( ShaderNode, SH_NODE_HOLDOUT, 0, "HOLDOUT", Holdout, "Holdout", "" )
DefNode( ShaderNode, SH_NODE_BSDF_ANISOTROPIC, def_anisotropic, "BSDF_ANISOTROPIC", BsdfAnisotropic, "Anisotropic BSDF", "" )
DefNode( ShaderNode, SH_NODE_BSDF_DIFFUSE, 0, "BSDF_DIFFUSE", BsdfDiffuse, "Diffuse BSDF", "" )
+DefNode( ShaderNode, SH_NODE_BSDF_PRINCIPLED, def_principled, "BSDF_PRINCIPLED", BsdfPrincipled, "Principled BSDF", "" )
DefNode( ShaderNode, SH_NODE_BSDF_GLOSSY, def_glossy, "BSDF_GLOSSY", BsdfGlossy, "Glossy BSDF", "" )
DefNode( ShaderNode, SH_NODE_BSDF_GLASS, def_glass, "BSDF_GLASS", BsdfGlass, "Glass BSDF", "" )
DefNode( ShaderNode, SH_NODE_BSDF_REFRACTION, def_refraction, "BSDF_REFRACTION", BsdfRefraction, "Refraction BSDF", "" )
@@ -178,7 +179,7 @@ DefNode( CompositorNode, CMP_NODE_DISPLACE, 0, "DISPL
DefNode( CompositorNode, CMP_NODE_COMBHSVA, 0, "COMBHSVA", CombHSVA, "Combine HSVA", "" )
DefNode( CompositorNode, CMP_NODE_MATH, def_math, "MATH", Math, "Math", "" )
DefNode( CompositorNode, CMP_NODE_LUMA_MATTE, def_cmp_luma_matte, "LUMA_MATTE", LumaMatte, "Luminance Key", "" )
-DefNode( CompositorNode, CMP_NODE_BRIGHTCONTRAST, 0, "BRIGHTCONTRAST", BrightContrast, "Bright/Contrast", "" )
+DefNode( CompositorNode, CMP_NODE_BRIGHTCONTRAST, def_cmp_brightcontrast, "BRIGHTCONTRAST", BrightContrast, "Bright/Contrast", "" )
DefNode( CompositorNode, CMP_NODE_GAMMA, 0, "GAMMA", Gamma, "Gamma", "" )
DefNode( CompositorNode, CMP_NODE_INVERT, def_cmp_invert, "INVERT", Invert, "Invert", "" )
DefNode( CompositorNode, CMP_NODE_NORMALIZE, 0, "NORMALIZE", Normalize, "Normalize", "" )
diff --git a/source/blender/nodes/composite/node_composite_tree.c b/source/blender/nodes/composite/node_composite_tree.c
index cb565bd5491..36778a18f77 100644
--- a/source/blender/nodes/composite/node_composite_tree.c
+++ b/source/blender/nodes/composite/node_composite_tree.c
@@ -240,8 +240,15 @@ void ntreeCompositExecTree(Scene *scene, bNodeTree *ntree, RenderData *rd, int r
/* *********************************************** */
-/* based on rules, force sockets hidden always */
-void ntreeCompositForceHidden(bNodeTree *ntree)
+/* Update the outputs of the render layer nodes.
+ * Since the outputs depend on the render engine, this part is a bit complex:
+ * - ntreeCompositUpdateRLayers is called and loops over all render layer nodes
+ * - Each render layer node calls the update function of the render engine that's used for its scene
+ * - The render engine calls RE_engine_register_pass for each pass
+ * - RE_engine_register_pass calls ntreeCompositRegisterPass,
+ * which calls node_cmp_rlayers_register_pass for every render layer node
+ */
+void ntreeCompositUpdateRLayers(bNodeTree *ntree)
{
bNode *node;
@@ -249,16 +256,20 @@ void ntreeCompositForceHidden(bNodeTree *ntree)
for (node = ntree->nodes.first; node; node = node->next) {
if (node->type == CMP_NODE_R_LAYERS)
- node_cmp_rlayers_force_hidden_passes(node);
-
- /* XXX this stuff is called all the time, don't want that.
- * Updates should only happen when actually necessary.
- */
-#if 0
- else if (node->type == CMP_NODE_IMAGE) {
- nodeUpdate(ntree, node);
- }
-#endif
+ node_cmp_rlayers_outputs(ntree, node);
+ }
+
+}
+
+void ntreeCompositRegisterPass(bNodeTree *ntree, Scene *scene, SceneRenderLayer *srl, const char *name, int type)
+{
+ bNode *node;
+
+ if (ntree == NULL) return;
+
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == CMP_NODE_R_LAYERS)
+ node_cmp_rlayers_register_pass(ntree, node, scene, srl, name, type);
}
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c
index 2ad097013ef..fde7dccb4ac 100644
--- a/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c
+++ b/source/blender/nodes/composite/nodes/node_composite_bilateralblur.c
@@ -47,6 +47,7 @@ static void node_composit_init_bilateralblur(bNodeTree *UNUSED(ntree), bNode *no
{
NodeBilateralBlurData *nbbd = MEM_callocN(sizeof(NodeBilateralBlurData), "node bilateral blur data");
node->storage = nbbd;
+ nbbd->iter = 1;
nbbd->sigma_color = 0.3;
nbbd->sigma_space = 5.0;
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_brightness.c b/source/blender/nodes/composite/nodes/node_composite_brightness.c
index 62f23f417b2..26e4d3a52c9 100644
--- a/source/blender/nodes/composite/nodes/node_composite_brightness.c
+++ b/source/blender/nodes/composite/nodes/node_composite_brightness.c
@@ -46,6 +46,10 @@ static bNodeSocketTemplate cmp_node_brightcontrast_out[] = {
{ -1, 0, "" }
};
+static void node_composit_init_brightcontrast(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->custom1 = 1;
+}
void register_node_type_cmp_brightcontrast(void)
{
@@ -53,6 +57,7 @@ void register_node_type_cmp_brightcontrast(void)
cmp_node_type_base(&ntype, CMP_NODE_BRIGHTCONTRAST, "Bright/Contrast", NODE_CLASS_OP_COLOR, 0);
node_type_socket_templates(&ntype, cmp_node_brightcontrast_in, cmp_node_brightcontrast_out);
+ node_type_init(&ntype, node_composit_init_brightcontrast);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_directionalblur.c b/source/blender/nodes/composite/nodes/node_composite_directionalblur.c
index 6eb27a228ad..336eb3409ff 100644
--- a/source/blender/nodes/composite/nodes/node_composite_directionalblur.c
+++ b/source/blender/nodes/composite/nodes/node_composite_directionalblur.c
@@ -46,6 +46,7 @@ static void node_composit_init_dblur(bNodeTree *UNUSED(ntree), bNode *node)
{
NodeDBlurData *ndbd = MEM_callocN(sizeof(NodeDBlurData), "node dblur data");
node->storage = ndbd;
+ ndbd->iter = 1;
ndbd->center_x = 0.5;
ndbd->center_y = 0.5;
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_image.c b/source/blender/nodes/composite/nodes/node_composite_image.c
index 4f02c106569..8139e29bade 100644
--- a/source/blender/nodes/composite/nodes/node_composite_image.c
+++ b/source/blender/nodes/composite/nodes/node_composite_image.c
@@ -32,192 +32,108 @@
#include "node_composite_util.h"
#include "BLI_utildefines.h"
+#include "BLI_linklist.h"
#include "DNA_scene_types.h"
+#include "RE_engine.h"
+
#include "BKE_context.h"
#include "BKE_global.h"
#include "BKE_main.h"
-#ifdef WITH_CYCLES_DEBUG
-# include "RE_pipeline.h"
-#endif
-
/* **************** IMAGE (and RenderResult, multilayer image) ******************** */
static bNodeSocketTemplate cmp_node_rlayers_out[] = {
- { SOCK_RGBA, 0, N_("Image"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 0, N_("Alpha"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 0, N_("Z"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_VECTOR, 0, N_("Normal"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_VECTOR, 0, N_("UV"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_VECTOR, 0, N_("Speed"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Diffuse"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Specular"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Shadow"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("AO"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Reflect"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Refract"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Indirect"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 0, N_("IndexOB"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 0, N_("IndexMA"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_FLOAT, 0, N_("Mist"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Emit"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Environment"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Diffuse Direct"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Diffuse Indirect"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Diffuse Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Glossy Direct"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Glossy Indirect"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Glossy Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Transmission Direct"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Transmission Indirect"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Transmission Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Subsurface Direct"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Subsurface Indirect"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
- { SOCK_RGBA, 0, N_("Subsurface Color"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-#ifdef WITH_CYCLES_DEBUG
- { SOCK_RGBA, 0, N_("Debug"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
-#endif
+ { SOCK_RGBA, 0, N_("Image"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 0, N_("Alpha"), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 0, N_(RE_PASSNAME_Z), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 0, N_(RE_PASSNAME_NORMAL), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 0, N_(RE_PASSNAME_UV), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_VECTOR, 0, N_(RE_PASSNAME_VECTOR), 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_RGBA), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_DIFFUSE), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_SPEC), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_SHADOW), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_AO), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_REFLECT), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_REFRACT), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_INDIRECT), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 0, N_(RE_PASSNAME_INDEXOB), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 0, N_(RE_PASSNAME_INDEXMA), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 0, N_(RE_PASSNAME_MIST), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_EMIT), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_ENVIRONMENT), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_DIFFUSE_DIRECT), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_DIFFUSE_INDIRECT), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_DIFFUSE_COLOR), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_GLOSSY_DIRECT), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_GLOSSY_INDIRECT), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_GLOSSY_COLOR), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_TRANSM_DIRECT), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_TRANSM_INDIRECT), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_TRANSM_COLOR), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_SUBSURFACE_DIRECT), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_SUBSURFACE_INDIRECT), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
+ { SOCK_RGBA, 0, N_(RE_PASSNAME_SUBSURFACE_COLOR), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f},
{ -1, 0, "" }
};
-static bNodeSocket *cmp_node_image_add_render_pass_output(bNodeTree *ntree, bNode *node, int pass, int rres_index)
+static void cmp_node_image_add_pass_output(bNodeTree *ntree, bNode *node,
+ const char *name, const char *passname,
+ int rres_index, int type, int is_rlayers,
+ LinkNodePair *available_sockets, int *prev_index)
{
bNodeSocket *sock;
- NodeImageLayer *sockdata;
-
- sock = node_add_socket_from_template(ntree, node, &cmp_node_rlayers_out[rres_index], SOCK_OUT);
- /* extra socket info */
- sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer");
- sock->storage = sockdata;
-
- sockdata->pass_flag = pass;
-
- return sock;
-}
-
-static void cmp_node_image_add_render_pass_outputs(bNodeTree *ntree, bNode *node, int passflag)
-{
- if (passflag & SCE_PASS_COMBINED) {
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_COMBINED, RRES_OUT_IMAGE);
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_COMBINED, RRES_OUT_ALPHA);
- }
-
- if (passflag & SCE_PASS_Z)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_Z, RRES_OUT_Z);
- if (passflag & SCE_PASS_NORMAL)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_NORMAL, RRES_OUT_NORMAL);
- if (passflag & SCE_PASS_VECTOR)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_VECTOR, RRES_OUT_VEC);
- if (passflag & SCE_PASS_UV)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_UV, RRES_OUT_UV);
- if (passflag & SCE_PASS_RGBA)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_RGBA, RRES_OUT_RGBA);
- if (passflag & SCE_PASS_DIFFUSE)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE, RRES_OUT_DIFF);
- if (passflag & SCE_PASS_SPEC)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SPEC, RRES_OUT_SPEC);
- if (passflag & SCE_PASS_SHADOW)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SHADOW, RRES_OUT_SHADOW);
- if (passflag & SCE_PASS_AO)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_AO, RRES_OUT_AO);
- if (passflag & SCE_PASS_REFLECT)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_REFLECT, RRES_OUT_REFLECT);
- if (passflag & SCE_PASS_REFRACT)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_REFRACT, RRES_OUT_REFRACT);
- if (passflag & SCE_PASS_INDIRECT)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDIRECT, RRES_OUT_INDIRECT);
- if (passflag & SCE_PASS_INDEXOB)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDEXOB, RRES_OUT_INDEXOB);
- if (passflag & SCE_PASS_INDEXMA)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_INDEXMA, RRES_OUT_INDEXMA);
- if (passflag & SCE_PASS_MIST)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_MIST, RRES_OUT_MIST);
- if (passflag & SCE_PASS_EMIT)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_EMIT, RRES_OUT_EMIT);
- if (passflag & SCE_PASS_ENVIRONMENT)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_ENVIRONMENT, RRES_OUT_ENV);
-
- if (passflag & SCE_PASS_DIFFUSE_DIRECT)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE_DIRECT, RRES_OUT_DIFF_DIRECT);
- if (passflag & SCE_PASS_DIFFUSE_INDIRECT)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE_INDIRECT, RRES_OUT_DIFF_INDIRECT);
- if (passflag & SCE_PASS_DIFFUSE_COLOR)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DIFFUSE_COLOR, RRES_OUT_DIFF_COLOR);
-
- if (passflag & SCE_PASS_GLOSSY_DIRECT)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOSSY_DIRECT, RRES_OUT_GLOSSY_DIRECT);
- if (passflag & SCE_PASS_GLOSSY_INDIRECT)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOSSY_INDIRECT, RRES_OUT_GLOSSY_INDIRECT);
- if (passflag & SCE_PASS_GLOSSY_COLOR)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_GLOSSY_COLOR, RRES_OUT_GLOSSY_COLOR);
-
- if (passflag & SCE_PASS_TRANSM_DIRECT)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_DIRECT, RRES_OUT_TRANSM_DIRECT);
- if (passflag & SCE_PASS_TRANSM_INDIRECT)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_INDIRECT, RRES_OUT_TRANSM_INDIRECT);
- if (passflag & SCE_PASS_TRANSM_COLOR)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_TRANSM_COLOR, RRES_OUT_TRANSM_COLOR);
-
- if (passflag & SCE_PASS_SUBSURFACE_DIRECT)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_DIRECT, RRES_OUT_SUBSURFACE_DIRECT);
- if (passflag & SCE_PASS_SUBSURFACE_INDIRECT)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_INDIRECT, RRES_OUT_SUBSURFACE_INDIRECT);
- if (passflag & SCE_PASS_SUBSURFACE_COLOR)
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_SUBSURFACE_COLOR, RRES_OUT_SUBSURFACE_COLOR);
-
-#ifdef WITH_CYCLES_DEBUG
- cmp_node_image_add_render_pass_output(ntree, node, SCE_PASS_DEBUG, RRES_OUT_DEBUG);
-#endif
-}
-
-static void cmp_node_image_add_multilayer_outputs(bNodeTree *ntree, bNode *node, RenderLayer *rl)
-{
- bNodeSocket *sock;
- NodeImageLayer *sockdata;
- RenderPass *rpass;
- int index;
- int passflag = 0;
- for (rpass = rl->passes.first, index = 0; rpass; rpass = rpass->next, ++index) {
- int type;
- if (rpass->channels == 1)
- type = SOCK_FLOAT;
- else
- type = SOCK_RGBA;
-
- /* we only need one socket per type */
- if (passflag & rpass->passtype)
- continue;
-
- passflag |= rpass->passtype;
-
- sock = nodeAddStaticSocket(ntree, node, SOCK_OUT, type, PROP_NONE, rpass->internal_name, rpass->internal_name);
+ int sock_index = BLI_findstringindex(&node->outputs, name, offsetof(bNodeSocket, name));
+
+ if (sock_index < 0) {
+ /* The first 31 sockets always are the legacy hardcoded sockets.
+ * Any dynamically allocated sockets follow afterwards, and are sorted in the order in which they were stored in the RenderResult.
+ * Therefore, we remember the index of the last matched socket. New sockets are placed behind the previously traversed one, but always after the first 31. */
+ int after_index = *prev_index;
+ if (is_rlayers && after_index < 30)
+ after_index = 30;
+
+ if (rres_index >= 0) {
+ sock = node_add_socket_from_template(ntree, node, &cmp_node_rlayers_out[rres_index], SOCK_OUT);
+ }
+ else {
+ sock = nodeAddStaticSocket(ntree, node, SOCK_OUT, type, PROP_NONE, name, name);
+ }
/* extra socket info */
- sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer");
+ NodeImageLayer *sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer");
sock->storage = sockdata;
-
- sockdata->pass_index = index;
- sockdata->pass_flag = rpass->passtype;
-
- if (rpass->passtype == SCE_PASS_COMBINED) {
- sock = nodeAddStaticSocket(ntree, node, SOCK_OUT, SOCK_FLOAT, PROP_NONE, "Alpha", "Alpha");
- sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer");
- sock->storage = sockdata;
- sockdata->pass_index = index;
- sockdata->pass_flag = rpass->passtype;
+
+ BLI_strncpy(sockdata->pass_name, passname, sizeof(sockdata->pass_name));
+
+ sock_index = BLI_listbase_count(&node->outputs) - 1;
+ if (sock_index != after_index + 1) {
+ bNodeSocket *after_sock = BLI_findlink(&node->outputs, after_index);
+ BLI_remlink(&node->outputs, sock);
+ BLI_insertlinkafter(&node->outputs, after_sock, sock);
+ }
+ }
+ else {
+ sock = BLI_findlink(&node->outputs, sock_index);
+ NodeImageLayer *sockdata = sock->storage;
+ if (sockdata) {
+ BLI_strncpy(sockdata->pass_name, passname, sizeof(sockdata->pass_name));
}
}
+
+ BLI_linklist_append(available_sockets, sock);
+ *prev_index = sock_index;
}
-static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node)
+static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node, LinkNodePair *available_sockets)
{
Image *ima = (Image *)node->id;
+ ImBuf *ibuf;
+ int prev_index = -1;
if (ima) {
ImageUser *iuser = node->storage;
ImageUser load_iuser = {NULL};
- ImBuf *ibuf;
int offset = BKE_image_sequence_guess_offset(ima);
/* It is possible that image user in this node is not
@@ -238,104 +154,144 @@ static void cmp_node_image_create_outputs(bNodeTree *ntree, bNode *node)
RenderLayer *rl = BLI_findlink(&ima->rr->layers, iuser->layer);
if (rl) {
- if (ima->type != IMA_TYPE_MULTILAYER)
- cmp_node_image_add_render_pass_outputs(ntree, node, rl->passflag);
- else
- cmp_node_image_add_multilayer_outputs(ntree, node, rl);
+ RenderPass *rpass;
+ for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
+ int type;
+ if (rpass->channels == 1)
+ type = SOCK_FLOAT;
+ else
+ type = SOCK_RGBA;
+
+ cmp_node_image_add_pass_output(ntree, node, rpass->name, rpass->name, -1, type, false, available_sockets, &prev_index);
+ /* Special handling for the Combined pass to ensure compatibility. */
+ if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) {
+ cmp_node_image_add_pass_output(ntree, node, "Alpha", rpass->name, -1, SOCK_FLOAT, false, available_sockets, &prev_index);
+ }
+ }
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+ return;
}
- else
- cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE | RRES_OUT_ALPHA);
}
- else
- cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE | RRES_OUT_ALPHA | RRES_OUT_Z);
-
+ }
+
+ cmp_node_image_add_pass_output(ntree, node, "Image", RE_PASSNAME_COMBINED, -1, SOCK_RGBA, false, available_sockets, &prev_index);
+ cmp_node_image_add_pass_output(ntree, node, "Alpha", RE_PASSNAME_COMBINED, -1, SOCK_FLOAT, false, available_sockets, &prev_index);
+
+ if (ima) {
BKE_image_release_ibuf(ima, ibuf, NULL);
}
- else
- cmp_node_image_add_render_pass_outputs(ntree, node, RRES_OUT_IMAGE | RRES_OUT_ALPHA);
}
-static bNodeSocket *cmp_node_image_output_find_match(bNode *UNUSED(node), bNodeSocket *newsock, ListBase *oldsocklist)
-{
- bNodeSocket *sock;
-
- for (sock = oldsocklist->first; sock; sock = sock->next)
- if (STREQ(sock->name, newsock->name))
- return sock;
- return NULL;
-}
+typedef struct RLayerUpdateData {
+ LinkNodePair *available_sockets;
+ int prev_index;
+} RLayerUpdateData;
-static bNodeSocket *cmp_node_image_output_relink(bNode *node, bNodeSocket *oldsock, int oldindex)
+void node_cmp_rlayers_register_pass(bNodeTree *ntree, bNode *node, Scene *scene, SceneRenderLayer *srl, const char *name, int type)
{
- bNodeSocket *sock;
-
- /* first try to find matching socket name */
- for (sock = node->outputs.first; sock; sock = sock->next)
- if (STREQ(sock->name, oldsock->name))
- return sock;
-
- /* no matching name, simply link to same index */
- return BLI_findlink(&node->outputs, oldindex);
+ RLayerUpdateData *data = node->storage;
+
+ if (scene == NULL || srl == NULL || data == NULL || node->id != (ID *)scene) {
+ return;
+ }
+
+ SceneRenderLayer *node_srl = BLI_findlink(&scene->r.layers, node->custom1);
+ if (node_srl != srl) {
+ return;
+ }
+
+ /* Special handling for the Combined pass to ensure compatibility. */
+ if (STREQ(name, RE_PASSNAME_COMBINED)) {
+ cmp_node_image_add_pass_output(ntree, node, "Image", name, -1, type, true, data->available_sockets, &data->prev_index);
+ cmp_node_image_add_pass_output(ntree, node, "Alpha", name, -1, SOCK_FLOAT, true, data->available_sockets, &data->prev_index);
+ }
+ else {
+ cmp_node_image_add_pass_output(ntree, node, name, name, -1, type, true, data->available_sockets, &data->prev_index);
+ }
}
-static void cmp_node_image_sync_output(bNode *UNUSED(node), bNodeSocket *UNUSED(newsock), bNodeSocket *UNUSED(oldsock))
+static void cmp_node_rlayer_create_outputs(bNodeTree *ntree, bNode *node, LinkNodePair *available_sockets)
{
- /* pass */
+ Scene *scene = (Scene *)node->id;
+
+ if (scene) {
+ RenderEngineType *engine_type = RE_engines_find(scene->r.engine);
+ if (engine_type && engine_type->update_render_passes) {
+ SceneRenderLayer *srl = BLI_findlink(&scene->r.layers, node->custom1);
+ if (srl) {
+ RLayerUpdateData *data = MEM_mallocN(sizeof(RLayerUpdateData), "render layer update data");
+ data->available_sockets = available_sockets;
+ data->prev_index = -1;
+ node->storage = data;
+
+ RenderEngine *engine = RE_engine_create(engine_type);
+ engine_type->update_render_passes(engine, scene, srl);
+ RE_engine_free(engine);
+
+ MEM_freeN(data);
+ node->storage = NULL;
+
+ return;
+ }
+ }
+ }
+
+ int prev_index = -1;
+ cmp_node_image_add_pass_output(ntree, node, "Image", RE_PASSNAME_COMBINED, RRES_OUT_IMAGE, SOCK_RGBA, true, available_sockets, &prev_index);
+ cmp_node_image_add_pass_output(ntree, node, "Alpha", RE_PASSNAME_COMBINED, RRES_OUT_ALPHA, SOCK_FLOAT, true, available_sockets, &prev_index);
}
/* XXX make this into a generic socket verification function for dynamic socket replacement (multilayer, groups, static templates) */
-static void cmp_node_image_verify_outputs(bNodeTree *ntree, bNode *node)
+static void cmp_node_image_verify_outputs(bNodeTree *ntree, bNode *node, bool rlayer)
{
- bNodeSocket *newsock, *oldsock, *oldsock_next;
- ListBase oldsocklist;
- int oldindex;
- bNodeLink *link;
-
- /* store current nodes in oldsocklist, then clear socket list */
- oldsocklist = node->outputs;
- BLI_listbase_clear(&node->outputs);
+ bNodeSocket *sock, *sock_next;
+ LinkNodePair available_sockets = {NULL, NULL};
+ int sock_index;
/* XXX make callback */
- cmp_node_image_create_outputs(ntree, node);
-
- for (newsock = node->outputs.first; newsock; newsock = newsock->next) {
- /* XXX make callback */
- oldsock = cmp_node_image_output_find_match(node, newsock, &oldsocklist);
- if (oldsock) {
- /* XXX make callback */
- cmp_node_image_sync_output(node, newsock, oldsock);
+ if (rlayer)
+ cmp_node_rlayer_create_outputs(ntree, node, &available_sockets);
+ else
+ cmp_node_image_create_outputs(ntree, node, &available_sockets);
+
+ /* Get rid of sockets whose passes are not available in the image.
+ * If sockets that are not available would be deleted, the connections to them would be lost
+ * when e.g. opening a file (since there's no render at all yet).
+ * Therefore, sockets with connected links will just be set as unavailable.
+ *
+ * Another important detail comes from compatibility with the older socket model, where there
+ * was a fixed socket per pass type that was just hidden or not. Therefore, older versions expect
+ * the first 31 passes to belong to a specific pass type.
+ * So, we keep those 31 always allocated before the others as well, even if they have no links attached. */
+ sock_index = 0;
+ for (sock = node->outputs.first; sock; sock = sock_next, sock_index++) {
+ sock_next = sock->next;
+ if (BLI_linklist_index(available_sockets.list, sock) >= 0) {
+ sock->flag &= ~(SOCK_UNAVAIL | SOCK_HIDDEN);
}
- }
-
- /* move links to new socket */
- for (oldsock = oldsocklist.first, oldindex = 0; oldsock; oldsock = oldsock->next, ++oldindex) {
- newsock = cmp_node_image_output_relink(node, oldsock, oldindex);
-
- if (newsock) {
+ else {
+ bNodeLink *link;
for (link = ntree->links.first; link; link = link->next) {
- if (link->fromsock == oldsock)
- link->fromsock = newsock;
+ if (link->fromsock == sock) break;
+ }
+ if (!link && (!rlayer || sock_index > 30)) {
+ MEM_freeN(sock->storage);
+ nodeRemoveSocket(ntree, node, sock);
+ }
+ else {
+ sock->flag |= SOCK_UNAVAIL;
}
}
}
-
- /* delete old sockets
- * XXX oldsock is not actually in the node->outputs list any more,
- * but the nodeRemoveSocket function works anyway. In future this
- * should become part of the core code, so can take care of this behavior.
- */
- for (oldsock = oldsocklist.first; oldsock; oldsock = oldsock_next) {
- oldsock_next = oldsock->next;
- MEM_freeN(oldsock->storage);
- nodeRemoveSocket(ntree, node, oldsock);
- }
+
+ BLI_linklist_free(available_sockets.list, NULL);
}
static void cmp_node_image_update(bNodeTree *ntree, bNode *node)
{
/* avoid unnecessary updates, only changes to the image/image user data are of interest */
if (node->update & NODE_UPDATE_ID)
- cmp_node_image_verify_outputs(ntree, node);
+ cmp_node_image_verify_outputs(ntree, node, false);
}
static void node_composit_init_image(bNodeTree *ntree, bNode *node)
@@ -348,7 +304,7 @@ static void node_composit_init_image(bNodeTree *ntree, bNode *node)
iuser->ok = 1;
/* setup initial outputs */
- cmp_node_image_verify_outputs(ntree, node);
+ cmp_node_image_verify_outputs(ntree, node, false);
}
static void node_composit_free_image(bNode *node)
@@ -388,87 +344,44 @@ void register_node_type_cmp_image(void)
/* **************** RENDER RESULT ******************** */
-static void set_output_visible(bNode *node, int passflag, int index, int pass)
+void node_cmp_rlayers_outputs(bNodeTree *ntree, bNode *node)
{
- bNodeSocket *sock = BLI_findlink(&node->outputs, index);
- bool pass_enabled = ((passflag & pass) != 0);
-#ifdef WITH_CYCLES_DEBUG
- pass_enabled |= (pass == SCE_PASS_DEBUG);
-#endif
- /* clear the SOCK_HIDDEN flag as well, in case a socket was hidden before */
- if (pass_enabled)
- sock->flag &= ~(SOCK_HIDDEN | SOCK_UNAVAIL);
- else
- sock->flag |= SOCK_UNAVAIL;
+ cmp_node_image_verify_outputs(ntree, node, true);
}
-/* clumsy checking... should do dynamic outputs once */
-void node_cmp_rlayers_force_hidden_passes(bNode *node)
+const char *node_cmp_rlayers_sock_to_pass(int sock_index)
{
- Scene *scene = (Scene *)node->id;
- SceneRenderLayer *srl;
- int passflag;
- bNodeSocket *sock;
-
- /* must always have valid scene pointer */
- if (!scene)
- return;
-
- srl = BLI_findlink(&scene->r.layers, node->custom1);
- if (!srl)
- return;
-
- passflag = srl->passflag;
-
- for (sock = node->outputs.first; sock; sock = sock->next)
- sock->flag &= ~SOCK_UNAVAIL;
-
- set_output_visible(node, passflag, RRES_OUT_IMAGE, SCE_PASS_COMBINED);
- set_output_visible(node, passflag, RRES_OUT_ALPHA, SCE_PASS_COMBINED);
-
- set_output_visible(node, passflag, RRES_OUT_Z, SCE_PASS_Z);
- set_output_visible(node, passflag, RRES_OUT_NORMAL, SCE_PASS_NORMAL);
- set_output_visible(node, passflag, RRES_OUT_VEC, SCE_PASS_VECTOR);
- set_output_visible(node, passflag, RRES_OUT_UV, SCE_PASS_UV);
- set_output_visible(node, passflag, RRES_OUT_RGBA, SCE_PASS_RGBA);
- set_output_visible(node, passflag, RRES_OUT_DIFF, SCE_PASS_DIFFUSE);
- set_output_visible(node, passflag, RRES_OUT_SPEC, SCE_PASS_SPEC);
- set_output_visible(node, passflag, RRES_OUT_SHADOW, SCE_PASS_SHADOW);
- set_output_visible(node, passflag, RRES_OUT_AO, SCE_PASS_AO);
- set_output_visible(node, passflag, RRES_OUT_REFLECT, SCE_PASS_REFLECT);
- set_output_visible(node, passflag, RRES_OUT_REFRACT, SCE_PASS_REFRACT);
- set_output_visible(node, passflag, RRES_OUT_INDIRECT, SCE_PASS_INDIRECT);
- set_output_visible(node, passflag, RRES_OUT_INDEXOB, SCE_PASS_INDEXOB);
- set_output_visible(node, passflag, RRES_OUT_INDEXMA, SCE_PASS_INDEXMA);
- set_output_visible(node, passflag, RRES_OUT_MIST, SCE_PASS_MIST);
- set_output_visible(node, passflag, RRES_OUT_EMIT, SCE_PASS_EMIT);
- set_output_visible(node, passflag, RRES_OUT_ENV, SCE_PASS_ENVIRONMENT);
- set_output_visible(node, passflag, RRES_OUT_DIFF_DIRECT, SCE_PASS_DIFFUSE_DIRECT);
- set_output_visible(node, passflag, RRES_OUT_DIFF_INDIRECT, SCE_PASS_DIFFUSE_INDIRECT);
- set_output_visible(node, passflag, RRES_OUT_DIFF_COLOR, SCE_PASS_DIFFUSE_COLOR);
- set_output_visible(node, passflag, RRES_OUT_GLOSSY_DIRECT, SCE_PASS_GLOSSY_DIRECT);
- set_output_visible(node, passflag, RRES_OUT_GLOSSY_INDIRECT, SCE_PASS_GLOSSY_INDIRECT);
- set_output_visible(node, passflag, RRES_OUT_GLOSSY_COLOR, SCE_PASS_GLOSSY_COLOR);
- set_output_visible(node, passflag, RRES_OUT_TRANSM_DIRECT, SCE_PASS_TRANSM_DIRECT);
- set_output_visible(node, passflag, RRES_OUT_TRANSM_INDIRECT, SCE_PASS_TRANSM_INDIRECT);
- set_output_visible(node, passflag, RRES_OUT_TRANSM_COLOR, SCE_PASS_TRANSM_COLOR);
- set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_DIRECT, SCE_PASS_SUBSURFACE_DIRECT);
- set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_INDIRECT, SCE_PASS_SUBSURFACE_INDIRECT);
- set_output_visible(node, passflag, RRES_OUT_SUBSURFACE_COLOR, SCE_PASS_SUBSURFACE_COLOR);
-
-#ifdef WITH_CYCLES_DEBUG
- set_output_visible(node, passflag, RRES_OUT_DEBUG, SCE_PASS_DEBUG);
-#endif
+ const char *sock_to_passname[] = {
+ RE_PASSNAME_COMBINED, RE_PASSNAME_COMBINED,
+ RE_PASSNAME_Z, RE_PASSNAME_NORMAL, RE_PASSNAME_UV, RE_PASSNAME_VECTOR, RE_PASSNAME_RGBA,
+ RE_PASSNAME_DIFFUSE, RE_PASSNAME_SPEC, RE_PASSNAME_SHADOW, RE_PASSNAME_AO,
+ RE_PASSNAME_REFLECT, RE_PASSNAME_REFRACT, RE_PASSNAME_INDIRECT,
+ RE_PASSNAME_INDEXOB, RE_PASSNAME_INDEXMA, RE_PASSNAME_MIST, RE_PASSNAME_EMIT, RE_PASSNAME_ENVIRONMENT,
+ RE_PASSNAME_DIFFUSE_DIRECT, RE_PASSNAME_DIFFUSE_INDIRECT, RE_PASSNAME_DIFFUSE_COLOR,
+ RE_PASSNAME_GLOSSY_DIRECT, RE_PASSNAME_GLOSSY_INDIRECT, RE_PASSNAME_GLOSSY_COLOR,
+ RE_PASSNAME_TRANSM_DIRECT, RE_PASSNAME_TRANSM_INDIRECT, RE_PASSNAME_TRANSM_COLOR,
+ RE_PASSNAME_SUBSURFACE_DIRECT, RE_PASSNAME_SUBSURFACE_INDIRECT, RE_PASSNAME_SUBSURFACE_COLOR
+ };
+ if (sock_index > 30) {
+ return NULL;
+ }
+ return sock_to_passname[sock_index];
}
static void node_composit_init_rlayers(const bContext *C, PointerRNA *ptr)
{
Scene *scene = CTX_data_scene(C);
bNode *node = ptr->data;
-
+ int sock_index = 0;
+
node->id = &scene->id;
-
- node_cmp_rlayers_force_hidden_passes(node);
+
+ for (bNodeSocket *sock = node->outputs.first; sock; sock = sock->next, sock_index++) {
+ NodeImageLayer *sockdata = MEM_callocN(sizeof(NodeImageLayer), "node image layer");
+ sock->storage = sockdata;
+
+ BLI_strncpy(sockdata->pass_name, node_cmp_rlayers_sock_to_pass(sock_index), sizeof(sockdata->pass_name));
+ }
}
static int node_composit_poll_rlayers(bNodeType *UNUSED(ntype), bNodeTree *ntree)
@@ -489,6 +402,29 @@ static int node_composit_poll_rlayers(bNodeType *UNUSED(ntype), bNodeTree *ntree
return false;
}
+static void node_composit_free_rlayers(bNode *node)
+{
+ bNodeSocket *sock;
+
+ /* free extra socket info */
+ for (sock = node->outputs.first; sock; sock = sock->next)
+ MEM_freeN(sock->storage);
+}
+
+static void node_composit_copy_rlayers(bNodeTree *UNUSED(dest_ntree), bNode *UNUSED(dest_node), bNode *src_node)
+{
+ bNodeSocket *sock;
+
+ /* copy extra socket info */
+ for (sock = src_node->outputs.first; sock; sock = sock->next)
+ sock->new_sock->storage = MEM_dupallocN(sock->storage);
+}
+
+static void cmp_node_rlayers_update(bNodeTree *ntree, bNode *node)
+{
+ cmp_node_image_verify_outputs(ntree, node, true);
+}
+
void register_node_type_cmp_rlayers(void)
{
static bNodeType ntype;
@@ -497,6 +433,9 @@ void register_node_type_cmp_rlayers(void)
node_type_socket_templates(&ntype, NULL, cmp_node_rlayers_out);
ntype.initfunc_api = node_composit_init_rlayers;
ntype.poll = node_composit_poll_rlayers;
+ node_type_storage(&ntype, NULL, node_composit_free_rlayers, node_composit_copy_rlayers);
+ node_type_update(&ntype, cmp_node_rlayers_update, NULL);
+ node_type_init(&ntype, node_cmp_rlayers_outputs);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/nodes/composite/nodes/node_composite_switchview.c b/source/blender/nodes/composite/nodes/node_composite_switchview.c
index d805cf4d87f..e0d9fa33f13 100644
--- a/source/blender/nodes/composite/nodes/node_composite_switchview.c
+++ b/source/blender/nodes/composite/nodes/node_composite_switchview.c
@@ -137,7 +137,6 @@ static void init_switch_view(const bContext *C, PointerRNA *ptr)
cmp_node_switch_view_sanitycheck(ntree, node);
}
-/* custom1 = mix type */
void register_node_type_cmp_switch_view(void)
{
static bNodeType ntype;
diff --git a/source/blender/nodes/intern/node_exec.c b/source/blender/nodes/intern/node_exec.c
index 2347564c696..0cf131adbdc 100644
--- a/source/blender/nodes/intern/node_exec.c
+++ b/source/blender/nodes/intern/node_exec.c
@@ -78,7 +78,8 @@ void node_get_stack(bNode *node, bNodeStack *stack, bNodeStack **in, bNodeStack
static void node_init_input_index(bNodeSocket *sock, int *index)
{
- if (sock->link && sock->link->fromsock) {
+ /* Only consider existing link if from socket is valid! */
+ if (sock->link && sock->link->fromsock && sock->link->fromsock->stack_index >= 0) {
sock->stack_index = sock->link->fromsock->stack_index;
}
else {
diff --git a/source/blender/nodes/shader/node_shader_util.c b/source/blender/nodes/shader/node_shader_util.c
index 9bd43f331fb..5bc97f13b41 100644
--- a/source/blender/nodes/shader/node_shader_util.c
+++ b/source/blender/nodes/shader/node_shader_util.c
@@ -142,28 +142,40 @@ void node_gpu_stack_from_data(struct GPUNodeStack *gs, int type, bNodeStack *ns)
{
memset(gs, 0, sizeof(*gs));
- nodestack_get_vec(gs->vec, type, ns);
- gs->link = ns->data;
-
- if (type == SOCK_FLOAT)
- gs->type = GPU_FLOAT;
- else if (type == SOCK_VECTOR)
- gs->type = GPU_VEC3;
- else if (type == SOCK_RGBA)
- gs->type = GPU_VEC4;
- else if (type == SOCK_SHADER)
- gs->type = GPU_VEC4;
- else
+ if (ns == NULL) {
+ /* node_get_stack() will generate NULL bNodeStack pointers for unknown/unsuported types of sockets... */
+ zero_v4(gs->vec);
+ gs->link = NULL;
gs->type = GPU_NONE;
+ gs->name = "";
+ gs->hasinput = false;
+ gs->hasoutput = false;
+ gs->sockettype = type;
+ }
+ else {
+ nodestack_get_vec(gs->vec, type, ns);
+ gs->link = ns->data;
- gs->name = "";
- gs->hasinput = ns->hasinput && ns->data;
- /* XXX Commented out the ns->data check here, as it seems it's not always set,
- * even though there *is* a valid connection/output... But that might need
- * further investigation.
- */
- gs->hasoutput = ns->hasoutput /*&& ns->data*/;
- gs->sockettype = ns->sockettype;
+ if (type == SOCK_FLOAT)
+ gs->type = GPU_FLOAT;
+ else if (type == SOCK_VECTOR)
+ gs->type = GPU_VEC3;
+ else if (type == SOCK_RGBA)
+ gs->type = GPU_VEC4;
+ else if (type == SOCK_SHADER)
+ gs->type = GPU_VEC4;
+ else
+ gs->type = GPU_NONE;
+
+ gs->name = "";
+ gs->hasinput = ns->hasinput && ns->data;
+ /* XXX Commented out the ns->data check here, as it seems it's not always set,
+ * even though there *is* a valid connection/output... But that might need
+ * further investigation.
+ */
+ gs->hasoutput = ns->hasoutput /*&& ns->data*/;
+ gs->sockettype = ns->sockettype;
+ }
}
void node_data_from_gpu_stack(bNodeStack *ns, GPUNodeStack *gs)
diff --git a/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
new file mode 100644
index 00000000000..e0330d110ca
--- /dev/null
+++ b/source/blender/nodes/shader/nodes/node_shader_bsdf_principled.c
@@ -0,0 +1,114 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * The Original Code is Copyright (C) 2005 Blender Foundation.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include "../node_shader_util.h"
+
+/* **************** OUTPUT ******************** */
+
+static bNodeSocketTemplate sh_node_bsdf_principled_in[] = {
+ { SOCK_RGBA, 1, N_("Base Color"), 0.8f, 0.8f, 0.8f, 1.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Subsurface"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_VECTOR, 1, N_("Subsurface Radius"), 1.0f, 1.0f, 1.0f, 0.0f, 0.0f, 100.0f},
+ { SOCK_RGBA, 1, N_("Subsurface Color"), 0.7f, 0.1f, 0.1f, 1.0f, 0.0f, 1.0f},
+ { SOCK_FLOAT, 1, N_("Metallic"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Specular"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Specular Tint"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Roughness"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Anisotropic"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Anisotropic Rotation"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Sheen"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Sheen Tint"), 0.5f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Clearcoat"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Clearcoat Roughness"), 0.03f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("IOR"), 1.45f, 0.0f, 0.0f, 0.0f, 0.0f, 1000.0f},
+ { SOCK_FLOAT, 1, N_("Transmission"), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_FLOAT, 1, N_("Transmission Roughness"),0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 1.0f, PROP_FACTOR},
+ { SOCK_VECTOR, 1, N_("Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_VECTOR, 1, N_("Clearcoat Normal"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { SOCK_VECTOR, 1, N_("Tangent"), 0.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, PROP_NONE, SOCK_HIDE_VALUE},
+ { -1, 0, "" }
+};
+
+static bNodeSocketTemplate sh_node_bsdf_principled_out[] = {
+ { SOCK_SHADER, 0, N_("BSDF")},
+ { -1, 0, "" }
+};
+
+static void node_shader_init_principled(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ node->custom1 = SHD_GLOSSY_MULTI_GGX;
+}
+
+static int node_shader_gpu_bsdf_principled(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
+{
+ // normal
+ if (!in[17].link)
+ in[17].link = GPU_builtin(GPU_VIEW_NORMAL);
+ else
+ GPU_link(mat, "direction_transform_m4v3", in[17].link, GPU_builtin(GPU_VIEW_MATRIX), &in[17].link);
+
+ // clearcoat normal
+ if (!in[18].link)
+ in[18].link = GPU_builtin(GPU_VIEW_NORMAL);
+ else
+ GPU_link(mat, "direction_transform_m4v3", in[18].link, GPU_builtin(GPU_VIEW_MATRIX), &in[18].link);
+
+ return GPU_stack_link(mat, "node_bsdf_principled", in, out, GPU_builtin(GPU_VIEW_POSITION));
+}
+
+static void node_shader_update_principled(bNodeTree *UNUSED(ntree), bNode *node)
+{
+ bNodeSocket *sock;
+ int distribution = node->custom1;
+
+ for (sock = node->inputs.first; sock; sock = sock->next) {
+ if (STREQ(sock->name, "Transmission Roughness")) {
+ if (distribution == SHD_GLOSSY_GGX)
+ sock->flag &= ~SOCK_UNAVAIL;
+ else
+ sock->flag |= SOCK_UNAVAIL;
+
+ }
+ }
+}
+
+/* node type definition */
+void register_node_type_sh_bsdf_principled(void)
+{
+ static bNodeType ntype;
+
+ sh_node_type_base(&ntype, SH_NODE_BSDF_PRINCIPLED, "Principled BSDF", NODE_CLASS_SHADER, 0);
+ node_type_compatibility(&ntype, NODE_NEW_SHADING);
+ node_type_socket_templates(&ntype, sh_node_bsdf_principled_in, sh_node_bsdf_principled_out);
+ node_type_size_preset(&ntype, NODE_SIZE_MIDDLE);
+ node_type_init(&ntype, node_shader_init_principled);
+ node_type_storage(&ntype, "", NULL, NULL);
+ node_type_gpu(&ntype, node_shader_gpu_bsdf_principled);
+ node_type_update(&ntype, node_shader_update_principled, NULL);
+
+ nodeRegisterType(&ntype);
+}
diff --git a/source/blender/nodes/shader/nodes/node_shader_normal_map.c b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
index e0bf34f42e4..36d7522e3e6 100644
--- a/source/blender/nodes/shader/nodes/node_shader_normal_map.c
+++ b/source/blender/nodes/shader/nodes/node_shader_normal_map.c
@@ -46,8 +46,10 @@ static void node_shader_init_normal_map(bNodeTree *UNUSED(ntree), bNode *node)
node->storage = attr;
}
-static void node_shader_exec_normal_map(void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata), bNodeStack **in, bNodeStack **out)
- {
+static void node_shader_exec_normal_map(
+ void *data, int UNUSED(thread), bNode *node, bNodeExecData *UNUSED(execdata),
+ bNodeStack **in, bNodeStack **out)
+{
if (data) {
ShadeInput *shi = ((ShaderCallData *)data)->shi;
diff --git a/source/blender/nodes/shader/nodes/node_shader_object_info.c b/source/blender/nodes/shader/nodes/node_shader_object_info.c
index d1905246fd4..63d3bac88a0 100644
--- a/source/blender/nodes/shader/nodes/node_shader_object_info.c
+++ b/source/blender/nodes/shader/nodes/node_shader_object_info.c
@@ -39,7 +39,16 @@ static bNodeSocketTemplate sh_node_object_info_out[] = {
static int node_shader_gpu_object_info(GPUMaterial *mat, bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out)
{
- return GPU_stack_link(mat, "node_object_info", in, out);
+ return GPU_stack_link(mat, "node_object_info", in, out, GPU_builtin(GPU_OBJECT_MATRIX), GPU_builtin(GPU_OBJECT_INFO));
+}
+
+static void node_shader_exec_object_info(void *data, int UNUSED(thread), bNode *UNUSED(node), bNodeExecData *UNUSED(execdata), bNodeStack **UNUSED(in), bNodeStack **out)
+{
+ ShaderCallData *scd = (ShaderCallData *)data;
+ copy_v4_v4(out[0]->vec, RE_object_instance_get_matrix(scd->shi->obi, RE_OBJECT_INSTANCE_MATRIX_OB)[3]);
+ out[1]->vec[0] = RE_object_instance_get_object_pass_index(scd->shi->obi);
+ out[2]->vec[0] = scd->shi->mat->index;
+ out[3]->vec[0] = RE_object_instance_get_random_id(scd->shi->obi) * (1.0f / (float)0xFFFFFFFF);
}
/* node type definition */
@@ -53,6 +62,7 @@ void register_node_type_sh_object_info(void)
node_type_init(&ntype, NULL);
node_type_storage(&ntype, "", NULL, NULL);
node_type_gpu(&ntype, node_shader_gpu_object_info);
+ node_type_exec(&ntype, NULL, NULL, node_shader_exec_object_info);
nodeRegisterType(&ntype);
}
diff --git a/source/blender/python/generic/bpy_internal_import.c b/source/blender/python/generic/bpy_internal_import.c
index ed2752d8372..7ab6447d21a 100644
--- a/source/blender/python/generic/bpy_internal_import.c
+++ b/source/blender/python/generic/bpy_internal_import.c
@@ -248,8 +248,17 @@ PyObject *bpy_text_reimport(PyObject *module, int *found)
if ((name = PyModule_GetName(module)) == NULL)
return NULL;
- if ((filepath = (char *)PyModule_GetFilename(module)) == NULL)
- return NULL;
+ {
+ PyObject *module_file = PyModule_GetFilenameObject(module);
+ if (module_file == NULL) {
+ return NULL;
+ }
+ filepath = (char *)_PyUnicode_AsString(module_file);
+ Py_DECREF(module_file);
+ if (filepath == NULL) {
+ return NULL;
+ }
+ }
/* look up the text object */
text = BLI_findstring(&maggie->text, BLI_path_basename(filepath), offsetof(ID, name) + 2);
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index 0a9931f2683..5d6a7c578a2 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -43,6 +43,9 @@
#include "python_utildefines.h"
+extern bool pyrna_id_FromPyObject(PyObject *obj, ID **id);
+extern PyObject *pyrna_id_CreatePyObject(ID *id);
+extern bool pyrna_id_CheckPyObject(PyObject *obj);
/*********************** ID Property Main Wrapper Stuff ***************/
@@ -88,6 +91,11 @@ static PyObject *idprop_py_from_idp_group(ID *id, IDProperty *prop, IDProperty *
return (PyObject *)group;
}
+static PyObject *idprop_py_from_idp_id(IDProperty *prop)
+{
+ return pyrna_id_CreatePyObject(prop->data.pointer);
+}
+
static PyObject *idprop_py_from_idp_array(ID *id, IDProperty *prop)
{
BPy_IDProperty *array = PyObject_New(BPy_IDProperty, &BPy_IDArray_Type);
@@ -148,6 +156,7 @@ PyObject *BPy_IDGroup_WrapData(ID *id, IDProperty *prop, IDProperty *parent)
case IDP_GROUP: return idprop_py_from_idp_group(id, prop, parent);
case IDP_ARRAY: return idprop_py_from_idp_array(id, prop);
case IDP_IDPARRAY: return idprop_py_from_idp_idparray(id, prop); /* this could be better a internal type */
+ case IDP_ID: return idprop_py_from_idp_id(prop);
default: Py_RETURN_NONE;
}
}
@@ -586,8 +595,15 @@ static IDProperty *idp_from_PyMapping(const char *name, PyObject *ob)
return prop;
}
+static IDProperty *idp_from_DatablockPointer(const char *name, PyObject *ob, IDPropertyTemplate *val)
+{
+ pyrna_id_FromPyObject(ob, &val->id);
+ return IDP_New(IDP_ID, val, name);
+}
+
static IDProperty *idp_from_PyObject(PyObject *name_obj, PyObject *ob)
{
+ IDPropertyTemplate val = {0};
const char *name = idp_try_read_name(name_obj);
if (name == NULL) {
return NULL;
@@ -608,6 +624,9 @@ static IDProperty *idp_from_PyObject(PyObject *name_obj, PyObject *ob)
else if (PySequence_Check(ob)) {
return idp_from_PySequence(name, ob);
}
+ else if (ob == Py_None || pyrna_id_CheckPyObject(ob)) {
+ return idp_from_DatablockPointer(name, ob, &val);
+ }
else if (PyMapping_Check(ob)) {
return idp_from_PyMapping(name, ob);
}
@@ -732,6 +751,8 @@ static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
return idprop_py_from_idp_float(prop);
case IDP_DOUBLE:
return idprop_py_from_idp_double(prop);
+ case IDP_ID:
+ return idprop_py_from_idp_id(prop);
case IDP_ARRAY:
{
PyObject *seq = PyList_New(prop->len);
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index 2e789d6d4b3..861e2dbb0df 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -300,7 +300,14 @@ void PyC_FileAndNum(const char **filename, int *lineno)
if (mod_name) {
PyObject *mod = PyDict_GetItem(PyImport_GetModuleDict(), mod_name);
if (mod) {
- *filename = PyModule_GetFilename(mod);
+ PyObject *mod_file = PyModule_GetFilenameObject(mod);
+ if (mod_file) {
+ *filename = _PyUnicode_AsString(mod_name);
+ Py_DECREF(mod_file);
+ }
+ else {
+ PyErr_Clear();
+ }
}
/* unlikely, fallback */
diff --git a/source/blender/python/intern/CMakeLists.txt b/source/blender/python/intern/CMakeLists.txt
index 038c1e7eb10..be4db6477fe 100644
--- a/source/blender/python/intern/CMakeLists.txt
+++ b/source/blender/python/intern/CMakeLists.txt
@@ -55,6 +55,7 @@ set(SRC
bpy_app_handlers.c
bpy_app_ocio.c
bpy_app_oiio.c
+ bpy_app_opensubdiv.c
bpy_app_openvdb.c
bpy_app_sdl.c
bpy_app_translations.c
@@ -89,6 +90,7 @@ set(SRC
bpy_app_handlers.h
bpy_app_ocio.h
bpy_app_oiio.h
+ bpy_app_opensubdiv.h
bpy_app_openvdb.h
bpy_app_sdl.h
bpy_app_translations.h
@@ -295,6 +297,13 @@ if(WITH_OPENIMAGEIO)
)
endif()
+if(WITH_OPENSUBDIV)
+ add_definitions(-DWITH_OPENSUBDIV)
+ list(APPEND INC
+ ../../../../intern/opensubdiv
+ )
+endif()
+
if(WITH_PLAYER)
add_definitions(-DWITH_PLAYER)
endif()
diff --git a/source/blender/python/intern/bpy_app.c b/source/blender/python/intern/bpy_app.c
index ed7cec2f2d5..e47bf21f04b 100644
--- a/source/blender/python/intern/bpy_app.c
+++ b/source/blender/python/intern/bpy_app.c
@@ -37,6 +37,7 @@
#include "bpy_app_ffmpeg.h"
#include "bpy_app_ocio.h"
#include "bpy_app_oiio.h"
+#include "bpy_app_opensubdiv.h"
#include "bpy_app_openvdb.h"
#include "bpy_app_sdl.h"
#include "bpy_app_build_options.h"
@@ -88,6 +89,7 @@ static PyStructSequence_Field app_info_fields[] = {
{(char *)"version_cycle", (char *)"The release status of this build alpha/beta/rc/release"},
{(char *)"binary_path", (char *)"The location of blenders executable, useful for utilities that spawn new instances"},
{(char *)"background", (char *)"Boolean, True when blender is running without a user interface (started with -b)"},
+ {(char *)"factory_startup", (char *)"Boolean, True when blender is running with --factory-startup)"},
/* buildinfo */
{(char *)"build_date", (char *)"The date this blender instance was built"},
@@ -109,6 +111,7 @@ static PyStructSequence_Field app_info_fields[] = {
{(char *)"ffmpeg", (char *)"FFmpeg library information backend"},
{(char *)"ocio", (char *)"OpenColorIO library information backend"},
{(char *)"oiio", (char *)"OpenImageIO library information backend"},
+ {(char *)"opensubdiv", (char *)"OpenSubdiv library information backend"},
{(char *)"openvdb", (char *)"OpenVDB library information backend"},
{(char *)"sdl", (char *)"SDL library information backend"},
{(char *)"build_options", (char *)"A set containing most important enabled optional build features"},
@@ -117,9 +120,21 @@ static PyStructSequence_Field app_info_fields[] = {
{NULL},
};
+PyDoc_STRVAR(bpy_app_doc,
+"This module contains application values that remain unchanged during runtime.\n"
+"\n"
+"Submodules:\n"
+"\n"
+".. toctree::\n"
+" :maxdepth: 1\n"
+"\n"
+" bpy.app.handlers.rst\n"
+" bpy.app.translations.rst\n"
+);
+
static PyStructSequence_Desc app_info_desc = {
(char *)"bpy.app", /* name */
- (char *)"This module contains application values that remain unchanged during runtime.", /* doc */
+ bpy_app_doc, /* doc */
app_info_fields, /* fields */
ARRAY_SIZE(app_info_fields) - 1
};
@@ -151,6 +166,7 @@ static PyObject *make_app_info(void)
SetStrItem(STRINGIFY(BLENDER_VERSION_CYCLE));
SetStrItem(BKE_appdir_program_path());
SetObjItem(PyBool_FromLong(G.background));
+ SetObjItem(PyBool_FromLong(G.factory_startup));
/* build info, use bytes since we can't assume _any_ encoding:
* see patch [#30154] for issue */
@@ -188,6 +204,7 @@ static PyObject *make_app_info(void)
SetObjItem(BPY_app_ffmpeg_struct());
SetObjItem(BPY_app_ocio_struct());
SetObjItem(BPY_app_oiio_struct());
+ SetObjItem(BPY_app_opensubdiv_struct());
SetObjItem(BPY_app_openvdb_struct());
SetObjItem(BPY_app_sdl_struct());
SetObjItem(BPY_app_build_options_struct());
diff --git a/source/blender/python/intern/bpy_app_handlers.c b/source/blender/python/intern/bpy_app_handlers.c
index 1cc2d6f1307..fdc2371c259 100644
--- a/source/blender/python/intern/bpy_app_handlers.c
+++ b/source/blender/python/intern/bpy_app_handlers.c
@@ -126,7 +126,7 @@ static PyObject *bpy_app_handlers_persistent_new(PyTypeObject *UNUSED(type), PyO
/* dummy type because decorators can't be PyCFunctions */
static PyTypeObject BPyPersistent_Type = {
-#if defined(_MSC_VER) || defined(FREE_WINDOWS)
+#if defined(_MSC_VER)
PyVarObject_HEAD_INIT(NULL, 0)
#else
PyVarObject_HEAD_INIT(&PyType_Type, 0)
@@ -206,7 +206,7 @@ PyObject *BPY_app_handlers_struct(void)
{
PyObject *ret;
-#if defined(_MSC_VER) || defined(FREE_WINDOWS)
+#if defined(_MSC_VER)
BPyPersistent_Type.ob_base.ob_base.ob_type = &PyType_Type;
#endif
diff --git a/source/blender/python/intern/bpy_app_opensubdiv.c b/source/blender/python/intern/bpy_app_opensubdiv.c
new file mode 100644
index 00000000000..7f269baf2b0
--- /dev/null
+++ b/source/blender/python/intern/bpy_app_opensubdiv.c
@@ -0,0 +1,109 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Sergey Sharybin
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/python/intern/bpy_app_opensubdiv.c
+ * \ingroup pythonintern
+ */
+
+#include <Python.h>
+#include "BLI_utildefines.h"
+
+#include "bpy_app_opensubdiv.h"
+
+#ifdef WITH_OPENSUBDIV
+# include "opensubdiv_capi.h"
+#endif
+
+static PyTypeObject BlenderAppOpenSubdivType;
+
+static PyStructSequence_Field app_opensubdiv_info_fields[] = {
+ {(char *)"supported", (char *)("Boolean, True when Blender is built with OpenSubdiv support")},
+ {(char *)("version"), (char *)("The OpenSubdiv version as a tuple of 3 numbers")},
+ {(char *)("version_string"), (char *)("The OpenSubdiv version formatted as a string")},
+ {NULL}
+};
+
+static PyStructSequence_Desc app_opensubdiv_info_desc = {
+ (char *)"bpy.app.opensubdiv", /* name */
+ (char *)"This module contains information about OpenSubdiv blender is linked against", /* doc */
+ app_opensubdiv_info_fields, /* fields */
+ ARRAY_SIZE(app_opensubdiv_info_fields) - 1
+};
+
+static PyObject *make_opensubdiv_info(void)
+{
+ PyObject *opensubdiv_info;
+ int pos = 0;
+
+ opensubdiv_info = PyStructSequence_New(&BlenderAppOpenSubdivType);
+ if (opensubdiv_info == NULL) {
+ return NULL;
+ }
+
+#ifndef WITH_OPENSUBDIV
+#define SetStrItem(str) \
+ PyStructSequence_SET_ITEM(opensubdiv_info, pos++, PyUnicode_FromString(str))
+#endif
+
+#define SetObjItem(obj) \
+ PyStructSequence_SET_ITEM(opensubdiv_info, pos++, obj)
+
+#ifdef WITH_OPENSUBDIV
+ int curversion = openSubdiv_getVersionHex();
+ SetObjItem(PyBool_FromLong(1));
+ SetObjItem(Py_BuildValue("(iii)",
+ curversion / 10000, (curversion / 100) % 100, curversion % 100));
+ SetObjItem(PyUnicode_FromFormat("%2d, %2d, %2d",
+ curversion / 10000, (curversion / 100) % 100, curversion % 100));
+#else
+ SetObjItem(PyBool_FromLong(0));
+ SetObjItem(Py_BuildValue("(iii)", 0, 0, 0));
+ SetStrItem("Unknown");
+#endif
+
+ if (PyErr_Occurred()) {
+ Py_CLEAR(opensubdiv_info);
+ return NULL;
+ }
+
+#undef SetStrItem
+#undef SetObjItem
+
+ return opensubdiv_info;
+}
+
+PyObject *BPY_app_opensubdiv_struct(void)
+{
+ PyObject *ret;
+
+ PyStructSequence_InitType(&BlenderAppOpenSubdivType, &app_opensubdiv_info_desc);
+
+ ret = make_opensubdiv_info();
+
+ /* prevent user from creating new instances */
+ BlenderAppOpenSubdivType.tp_init = NULL;
+ BlenderAppOpenSubdivType.tp_new = NULL;
+ /* without this we can't do set(sys.modules) [#29635] */
+ BlenderAppOpenSubdivType.tp_hash = (hashfunc)_Py_HashPointer;
+
+ return ret;
+}
diff --git a/source/blender/depsgraph/util/deg_util_hash.h b/source/blender/python/intern/bpy_app_opensubdiv.h
index e490be1a7a1..b1da218b168 100644
--- a/source/blender/depsgraph/util/deg_util_hash.h
+++ b/source/blender/python/intern/bpy_app_opensubdiv.h
@@ -15,27 +15,18 @@
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
- * The Original Code is Copyright (C) 2014 Blender Foundation.
- * All rights reserved.
- *
- * Original Author: Brecht van Lommel
- * Contributor(s): Lukas Toenne
+ * Contributor(s): Sergey Sharybin
*
* ***** END GPL LICENSE BLOCK *****
*/
-/** \file blender/depsgraph/util/deg_util_hash.h
- * \ingroup depsgraph
+/** \file blender/python/intern/bpy_app_opensubdiv.h
+ * \ingroup pythonintern
*/
-#pragma once
-
-#include "BLI_utildefines.h"
+#ifndef __BPY_APP_OPENSUBDIV_H__
+#define __BPY_APP_OPENSUBDIV_H__
-#include "BLI_ghash.h"
+PyObject *BPY_app_opensubdiv_struct(void);
-/* XXX this might require 2 different variants for sizeof(size_t) (32 vs 64 bit) */
-BLI_INLINE size_t hash_combine(size_t hash_a, size_t hash_b)
-{
- return hash_a ^ (hash_b + 0x9e3779b9 + (hash_a << 6) + (hash_a >> 2));
-}
+#endif /* __BPY_APP_OPENSUBDIV_H__ */
diff --git a/source/blender/python/intern/bpy_app_sdl.c b/source/blender/python/intern/bpy_app_sdl.c
index 2f4d8e6c325..76dab775953 100644
--- a/source/blender/python/intern/bpy_app_sdl.c
+++ b/source/blender/python/intern/bpy_app_sdl.c
@@ -56,7 +56,7 @@ static PyStructSequence_Field app_sdl_info_fields[] = {
{(char *)"available", (char *)("Boolean, True when SDL is available. This is False when "
"either *supported* is False, or *dynload* is True and "
"Blender cannot find the correct library.")},
- {NULL}
+ {NULL}
};
static PyStructSequence_Desc app_sdl_info_desc = {
diff --git a/source/blender/python/intern/bpy_interface.c b/source/blender/python/intern/bpy_interface.c
index 55e477b0214..20cfd364a0c 100644
--- a/source/blender/python/intern/bpy_interface.c
+++ b/source/blender/python/intern/bpy_interface.c
@@ -480,11 +480,20 @@ static bool python_script_exec(
* object, but as written in the Python/C API Ref Manual, chapter 2,
* 'FILE structs for different C libraries can be different and
* incompatible'.
- * So now we load the script file data to a buffer */
+ * So now we load the script file data to a buffer.
+ *
+ * Note on use of 'globals()', it's important not copy the dictionary because
+ * tools may inspect 'sys.modules["__main__"]' for variables defined in the code
+ * where using a copy of 'globals()' causes code execution
+ * to leave the main namespace untouched. see: T51444
+ *
+ * This leaves us with the problem of variables being included,
+ * currently this is worked around using 'dict.__del__' it's ugly but works.
+ */
{
const char *pystring =
- "ns = globals().copy()\n"
- "with open(__file__, 'rb') as f: exec(compile(f.read(), __file__, 'exec'), ns)";
+ "with open(__file__, 'rb') as f:"
+ "exec(compile(f.read(), __file__, 'exec'), globals().__delitem__('f') or globals())";
fclose(fp);
@@ -860,6 +869,7 @@ static void bpy_module_delay_init(PyObject *bpy_proxy)
BLI_strncpy(filename_abs, filename_rel, sizeof(filename_abs));
BLI_path_cwd(filename_abs, sizeof(filename_abs));
+ Py_DECREF(filename_obj);
argv[0] = filename_abs;
argv[1] = NULL;
diff --git a/source/blender/python/intern/bpy_operator_wrap.c b/source/blender/python/intern/bpy_operator_wrap.c
index 11e27ca3e3c..90719905a79 100644
--- a/source/blender/python/intern/bpy_operator_wrap.c
+++ b/source/blender/python/intern/bpy_operator_wrap.c
@@ -118,7 +118,7 @@ static void operator_properties_init(wmOperatorType *ot)
}
-void operator_wrapper(wmOperatorType *ot, void *userdata)
+void BPY_RNA_operator_wrapper(wmOperatorType *ot, void *userdata)
{
/* take care not to overwrite anything set in
* WM_operatortype_append_ptr before opfunc() is called */
@@ -134,7 +134,7 @@ void operator_wrapper(wmOperatorType *ot, void *userdata)
operator_properties_init(ot);
}
-void macro_wrapper(wmOperatorType *ot, void *userdata)
+void BPY_RNA_operator_macro_wrapper(wmOperatorType *ot, void *userdata)
{
wmOperatorType *data = (wmOperatorType *)userdata;
diff --git a/source/blender/python/intern/bpy_operator_wrap.h b/source/blender/python/intern/bpy_operator_wrap.h
index 05a566a1485..0828c58e2bd 100644
--- a/source/blender/python/intern/bpy_operator_wrap.h
+++ b/source/blender/python/intern/bpy_operator_wrap.h
@@ -33,7 +33,7 @@ struct wmOperatorType;
PyObject *PYOP_wrap_macro_define(PyObject *self, PyObject *args);
/* exposed to rna/wm api */
-void operator_wrapper(struct wmOperatorType *ot, void *userdata);
-void macro_wrapper(struct wmOperatorType *ot, void *userdata);
+void BPY_RNA_operator_wrapper(struct wmOperatorType *ot, void *userdata);
+void BPY_RNA_operator_macro_wrapper(struct wmOperatorType *ot, void *userdata);
#endif
diff --git a/source/blender/python/intern/bpy_props.c b/source/blender/python/intern/bpy_props.c
index f7348ac2250..362c0281b36 100644
--- a/source/blender/python/intern/bpy_props.c
+++ b/source/blender/python/intern/bpy_props.c
@@ -50,11 +50,13 @@
#include "../generic/py_capi_utils.h"
/* initial definition of callback slots we'll probably have more than 1 */
-#define BPY_DATA_CB_SLOT_SIZE 3
-
-#define BPY_DATA_CB_SLOT_UPDATE 0
-#define BPY_DATA_CB_SLOT_GET 1
-#define BPY_DATA_CB_SLOT_SET 2
+enum {
+ BPY_DATA_CB_SLOT_UPDATE = 0,
+ BPY_DATA_CB_SLOT_GET = 1,
+ BPY_DATA_CB_SLOT_SET = 2,
+ BPY_DATA_CB_SLOT_POLL = 3,
+ BPY_DATA_CB_SLOT_SIZE = 4,
+};
extern BPy_StructRNA *bpy_context_module;
@@ -71,6 +73,9 @@ static EnumPropertyItem property_flag_items[] = {
" :arg options: Enumerator in ['HIDDEN', 'SKIP_SAVE', 'ANIMATABLE', 'LIBRARY_EDITABLE', 'PROPORTIONAL'," \
"'TEXTEDIT_UPDATE'].\n" \
" :type options: set\n" \
+" :arg poll: function to be called to determine whether an item is valid for this property.\n" \
+" The function must take 2 values (self,object) and return Bool.\n" \
+" :type poll: function\n" \
static EnumPropertyItem property_flag_enum_items[] = {
{PROP_HIDDEN, "HIDDEN", 0, "Hidden", ""},
@@ -389,6 +394,51 @@ static void bpy_prop_boolean_set_cb(struct PointerRNA *ptr, struct PropertyRNA *
}
}
+static int bpy_prop_poll_cb(struct PointerRNA *self, PointerRNA candidate, struct PropertyRNA *prop)
+{
+ PyObject *py_self;
+ PyObject *py_candidate;
+ PyObject *py_func;
+ PyObject **py_data = RNA_property_py_data_get(prop);
+ PyObject *args;
+ PyObject *ret;
+ bool result;
+ const int is_write_ok = pyrna_write_check();
+ PyGILState_STATE gilstate = PyGILState_Ensure();
+
+ BLI_assert(self != NULL);
+
+ py_self = pyrna_struct_as_instance(self);
+ py_candidate = pyrna_struct_as_instance(&candidate);
+ py_func = py_data[BPY_DATA_CB_SLOT_POLL];
+
+ if (!is_write_ok)
+ pyrna_write_set(true);
+
+ args = PyTuple_New(2);
+ PyTuple_SET_ITEM(args, 0, py_self);
+ PyTuple_SET_ITEM(args, 1, py_candidate);
+
+ ret = PyObject_CallObject(py_func, args);
+
+ Py_DECREF(args);
+
+ if (ret == NULL) {
+ printf_func_error(py_func);
+ result = false;
+ }
+ else {
+ result = PyObject_IsTrue(ret);
+ Py_DECREF(ret);
+ }
+
+ PyGILState_Release(gilstate);
+ if (!is_write_ok)
+ pyrna_write_set(false);
+
+ return result;
+}
+
static void bpy_prop_boolean_array_get_cb(struct PointerRNA *ptr, struct PropertyRNA *prop, int *values)
{
PyObject **py_data = RNA_property_py_data_get(prop);
@@ -1598,6 +1648,16 @@ static void bpy_prop_callback_assign_update(struct PropertyRNA *prop, PyObject *
}
}
+static void bpy_prop_callback_assign_pointer(struct PropertyRNA *prop, PyObject *poll_cb)
+{
+ if (poll_cb && poll_cb != Py_None) {
+ PyObject **py_data = bpy_prop_py_data_get(prop);
+
+ RNA_def_property_poll_runtime(prop, (void *) bpy_prop_poll_cb);
+ py_data[BPY_DATA_CB_SLOT_POLL] = poll_cb;
+ }
+}
+
static void bpy_prop_callback_assign_boolean(struct PropertyRNA *prop, PyObject *get_cb, PyObject *set_cb)
{
BooleanPropertyGetFunc rna_get_cb = NULL;
@@ -1904,7 +1964,7 @@ static void bpy_prop_callback_assign_enum(struct PropertyRNA *prop, PyObject *ge
" :type set: function\n" \
#define BPY_PROPDEF_TYPE_DOC \
-" :arg type: A subclass of :class:`bpy.types.PropertyGroup`.\n" \
+" :arg type: A subclass of :class:`bpy.types.PropertyGroup` or :class:`bpy.types.ID`.\n" \
" :type type: class\n" \
#if 0
@@ -2637,7 +2697,8 @@ PyDoc_STRVAR(BPy_EnumProperty_doc,
" :icon: An icon string identifier or integer icon value\n"
" (e.g. returned by :class:`bpy.types.UILayout.icon`)\n"
" :number: Unique value used as the identifier for this item (stored in file data).\n"
-" Use when the identifier may need to change.\n"
+" Use when the identifier may need to change. If the *ENUM_FLAG* option is used,\n"
+" the values are bitmasks and should be powers of two.\n"
"\n"
" When an item only contains 4 items they define ``(identifier, name, description, number)``.\n"
"\n"
@@ -2772,7 +2833,7 @@ static PyObject *BPy_EnumProperty(PyObject *self, PyObject *args, PyObject *kw)
Py_RETURN_NONE;
}
-static StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix)
+StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix)
{
StructRNA *srna;
@@ -2782,25 +2843,18 @@ static StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix
PyObject *msg = PyC_ExceptionBuffer();
const char *msg_char = _PyUnicode_AsString(msg);
PyErr_Format(PyExc_TypeError,
- "%.200s expected an RNA type derived from PropertyGroup, failed with: %s",
+ "%.200s expected an RNA type, failed with: %s",
error_prefix, msg_char);
Py_DECREF(msg);
}
else {
PyErr_Format(PyExc_TypeError,
- "%.200s expected an RNA type derived from PropertyGroup, failed with type '%s'",
+ "%.200s expected an RNA type, failed with type '%s'",
error_prefix, Py_TYPE(value)->tp_name);
}
return NULL;
}
- if (!RNA_struct_is_a(srna, &RNA_PropertyGroup)) {
- PyErr_Format(PyExc_TypeError,
- "%.200s expected an RNA type derived from PropertyGroup",
- error_prefix);
- return NULL;
- }
-
return srna;
}
@@ -2809,6 +2863,7 @@ PyDoc_STRVAR(BPy_PointerProperty_doc,
"name=\"\", "
"description=\"\", "
"options={'ANIMATABLE'}, "
+ "poll=None, "
"update=None)\n"
"\n"
" Returns a new pointer property definition.\n"
@@ -2819,14 +2874,14 @@ BPY_PROPDEF_DESC_DOC
BPY_PROPDEF_OPTIONS_DOC
BPY_PROPDEF_UPDATE_DOC
);
-static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
+PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
BPY_PROPDEF_HEAD(PointerProperty);
if (srna) {
- static const char *kwlist[] = {"attr", "type", "name", "description", "options", "update", NULL};
+ static const char *kwlist[] = {"attr", "type", "name", "description", "options", "poll", "update", NULL};
const char *id = NULL, *name = NULL, *description = "";
int id_len;
PropertyRNA *prop;
@@ -2834,33 +2889,47 @@ static PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *k
PyObject *type = Py_None;
PyObject *pyopts = NULL;
int opts = 0;
- PyObject *update_cb = NULL;
+ PyObject *update_cb = NULL, *poll_cb = NULL;
if (!PyArg_ParseTupleAndKeywords(args, kw,
- "s#O|ssO!O:PointerProperty",
+ "s#O|ssO!OOO:PointerProperty",
(char **)kwlist, &id, &id_len,
&type, &name, &description,
&PySet_Type, &pyopts,
- &update_cb))
+ &poll_cb, &update_cb))
{
return NULL;
}
BPY_PROPDEF_CHECK(PointerProperty, property_flag_items);
- ptype = pointer_type_from_py(type, "PointerProperty(...):");
+ ptype = pointer_type_from_py(type, "PointerProperty(...)");
if (!ptype)
return NULL;
-
+ if (!RNA_struct_is_a(ptype, &RNA_PropertyGroup) && !RNA_struct_is_ID(ptype)) {
+ PyErr_Format(PyExc_TypeError,
+ "PointerProperty(...) expected an RNA type derived from %.200s or %.200s",
+ RNA_struct_ui_name(&RNA_ID), RNA_struct_ui_name(&RNA_PropertyGroup));
+ return NULL;
+ }
if (bpy_prop_callback_check(update_cb, "update", 2) == -1) {
return NULL;
}
-
+ if (bpy_prop_callback_check(poll_cb, "poll", 2) == -1) {
+ return NULL;
+ }
prop = RNA_def_pointer_runtime(srna, id, ptype, name ? name : id, description);
if (pyopts) {
bpy_prop_assign_flag(prop, opts);
}
+
+ if (RNA_struct_idprops_contains_datablock(ptype)) {
+ if (RNA_struct_is_a(srna, &RNA_PropertyGroup)) {
+ RNA_def_struct_flag(srna, STRUCT_CONTAINS_DATABLOCK_IDPROPERTIES);
+ }
+ }
bpy_prop_callback_assign_update(prop, update_cb);
+ bpy_prop_callback_assign_pointer(prop, poll_cb);
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
@@ -2879,7 +2948,7 @@ BPY_PROPDEF_NAME_DOC
BPY_PROPDEF_DESC_DOC
BPY_PROPDEF_OPTIONS_DOC
);
-static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
+PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw)
{
StructRNA *srna;
@@ -2910,17 +2979,30 @@ static PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject
if (!ptype)
return NULL;
+ if (!RNA_struct_is_a(ptype, &RNA_PropertyGroup)) {
+ PyErr_Format(PyExc_TypeError,
+ "CollectionProperty(...) expected an RNA type derived from %.200s",
+ RNA_struct_ui_name(&RNA_ID), RNA_struct_ui_name(&RNA_PropertyGroup));
+ return NULL;
+ }
+
prop = RNA_def_collection_runtime(srna, id, ptype, name ? name : id, description);
if (pyopts) {
bpy_prop_assign_flag(prop, opts);
}
+
+ if (RNA_struct_idprops_contains_datablock(ptype)) {
+ if (RNA_struct_is_a(srna, &RNA_PropertyGroup)) {
+ RNA_def_struct_flag(srna, STRUCT_CONTAINS_DATABLOCK_IDPROPERTIES);
+ }
+ }
RNA_def_property_duplicate_pointers(srna, prop);
}
Py_RETURN_NONE;
}
PyDoc_STRVAR(BPy_RemoveProperty_doc,
-".. function:: RemoveProperty(cls, attr="")\n"
+".. function:: RemoveProperty(cls, attr)\n"
"\n"
" Removes a dynamically defined property.\n"
"\n"
diff --git a/source/blender/python/intern/bpy_props.h b/source/blender/python/intern/bpy_props.h
index c9934ca0cf3..614c1b4b708 100644
--- a/source/blender/python/intern/bpy_props.h
+++ b/source/blender/python/intern/bpy_props.h
@@ -30,6 +30,10 @@
PyObject *BPY_rna_props(void);
+PyObject *BPy_PointerProperty(PyObject *self, PyObject *args, PyObject *kw);
+PyObject *BPy_CollectionProperty(PyObject *self, PyObject *args, PyObject *kw);
+StructRNA *pointer_type_from_py(PyObject *value, const char *error_prefix);
+
#define PYRNA_STACK_ARRAY 32
#endif
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 2fd46ab94f0..eda880d4dce 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -806,7 +806,7 @@ static PyObject *pyrna_struct_richcmp(PyObject *a, PyObject *b, int op)
switch (op) {
case Py_NE:
ok = !ok;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case Py_EQ:
res = ok ? Py_False : Py_True;
break;
@@ -836,7 +836,7 @@ static PyObject *pyrna_prop_richcmp(PyObject *a, PyObject *b, int op)
switch (op) {
case Py_NE:
ok = !ok;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case Py_EQ:
res = ok ? Py_False : Py_True;
break;
@@ -1934,16 +1934,10 @@ static int pyrna_py_to_prop(
}
else {
/* data == NULL, assign to RNA */
- if (value == Py_None) {
- PointerRNA valueptr = {{NULL}};
- RNA_property_pointer_set(ptr, prop, valueptr);
- }
- else if (RNA_struct_is_a(param->ptr.type, ptr_type)) {
- RNA_property_pointer_set(ptr, prop, param->ptr);
- }
- else {
+ if (value == Py_None || RNA_struct_is_a(param->ptr.type, ptr_type))
+ RNA_property_pointer_set(ptr, prop, value == Py_None ? PointerRNA_NULL : param->ptr);
+ else
raise_error = true;
- }
}
if (raise_error) {
@@ -3277,6 +3271,20 @@ static int pyrna_struct_ass_subscript(BPy_StructRNA *self, PyObject *key, PyObje
return -1;
}
+ if (value && BPy_StructRNA_Check(value)) {
+ BPy_StructRNA *val = (BPy_StructRNA *)value;
+ if (val && self->ptr.type && val->ptr.type) {
+ if (!RNA_struct_idprops_datablock_allowed(self->ptr.type) &&
+ RNA_struct_idprops_contains_datablock(val->ptr.type))
+ {
+ PyErr_SetString(
+ PyExc_TypeError,
+ "bpy_struct[key] = val: datablock id properties not supported for this type");
+ return -1;
+ }
+ }
+ }
+
return BPy_Wrap_SetMapItem(group, key, value);
}
@@ -5160,7 +5168,7 @@ static PyObject *pyrna_param_to_py(PointerRNA *ptr, PropertyRNA *prop, void *dat
ret = Matrix_CreatePyObject(data, 3, 3, NULL);
break;
}
- /* fall-through */
+ ATTR_FALLTHROUGH;
#endif
default:
ret = PyTuple_New(len);
@@ -5684,7 +5692,7 @@ PyTypeObject pyrna_struct_meta_idprop_Type = {
NULL, /* struct PyMethodDef *tp_methods; */
NULL, /* struct PyMemberDef *tp_members; */
NULL, /* struct PyGetSetDef *tp_getset; */
-#if defined(_MSC_VER) || defined(FREE_WINDOWS)
+#if defined(_MSC_VER)
NULL, /* defer assignment */
#else
&PyType_Type, /* struct _typeobject *tp_base; */
@@ -6259,7 +6267,7 @@ static PyTypeObject pyrna_prop_collection_iter_Type = {
NULL, /* reprfunc tp_str; */
/* will only use these if this is a subtype of a py class */
-#if defined(_MSC_VER) || defined(FREE_WINDOWS)
+#if defined(_MSC_VER)
NULL, /* defer assignment */
#else
PyObject_GenericGetAttr, /* getattrofunc tp_getattro; */
@@ -6292,7 +6300,7 @@ static PyTypeObject pyrna_prop_collection_iter_Type = {
#endif
/*** Added in release 2.2 ***/
/* Iterators */
-#if defined(_MSC_VER) || defined(FREE_WINDOWS)
+#if defined(_MSC_VER)
NULL, /* defer assignment */
#else
PyObject_SelfIter, /* getiterfunc tp_iter; */
@@ -6745,7 +6753,7 @@ PyObject *pyrna_id_CreatePyObject(ID *id)
bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
{
- if (BPy_StructRNA_Check(obj) && (RNA_struct_is_ID(((BPy_StructRNA *)obj)->ptr.type))) {
+ if (pyrna_id_CheckPyObject(obj)) {
*id = ((BPy_StructRNA *)obj)->ptr.id.data;
return true;
}
@@ -6755,6 +6763,11 @@ bool pyrna_id_FromPyObject(PyObject *obj, ID **id)
}
}
+bool pyrna_id_CheckPyObject(PyObject *obj)
+{
+ return BPy_StructRNA_Check(obj) && (RNA_struct_is_ID(((BPy_StructRNA *) obj)->ptr.type));
+}
+
void BPY_rna_init(void)
{
#ifdef USE_MATHUTILS /* register mathutils callbacks, ok to run more than once. */
@@ -6763,7 +6776,7 @@ void BPY_rna_init(void)
#endif
/* for some reason MSVC complains of these */
-#if defined(_MSC_VER) || defined(FREE_WINDOWS)
+#if defined(_MSC_VER)
pyrna_struct_meta_idprop_Type.tp_base = &PyType_Type;
pyrna_prop_collection_iter_Type.tp_iter = PyObject_SelfIter;
@@ -7089,6 +7102,21 @@ static int deferred_register_prop(StructRNA *srna, PyObject *key, PyObject *item
args_fake = PyTuple_New(1);
PyTuple_SET_ITEM(args_fake, 0, py_srna_cobject);
+ PyObject *type = PyDict_GetItemString(py_kw, "type");
+ StructRNA *type_srna = srna_from_self(type, "");
+ if (type_srna) {
+ if (!RNA_struct_idprops_datablock_allowed(srna) &&
+ (*(PyCFunctionWithKeywords)PyCFunction_GET_FUNCTION(py_func) == BPy_PointerProperty ||
+ *(PyCFunctionWithKeywords)PyCFunction_GET_FUNCTION(py_func) == BPy_CollectionProperty) &&
+ RNA_struct_idprops_contains_datablock(type_srna))
+ {
+ PyErr_Format(PyExc_ValueError,
+ "bpy_struct \"%.200s\" doesn't support datablock properties \n",
+ RNA_struct_identifier(srna));
+ return -1;
+ }
+ }
+
py_ret = PyObject_Call(py_func, args_fake, py_kw);
if (py_ret) {
@@ -7237,15 +7265,12 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
{
const ListBase *lb;
Link *link;
- FunctionRNA *func;
- PropertyRNA *prop;
const char *class_type = RNA_struct_identifier(srna);
StructRNA *srna_base = RNA_struct_base(srna);
PyObject *py_class = (PyObject *)py_data;
PyObject *base_class = RNA_struct_py_type_get(srna);
PyObject *item;
- int i, flag, arg_count, func_arg_count, func_arg_min_count = 0;
- bool is_staticmethod;
+ int i, arg_count, func_arg_count, func_arg_min_count = 0;
const char *py_class_name = ((PyTypeObject *)py_class)->tp_name; /* __name__ */
if (srna_base) {
@@ -7266,9 +7291,12 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
lb = RNA_struct_type_functions(srna);
i = 0;
for (link = lb->first; link; link = link->next) {
- func = (FunctionRNA *)link;
- flag = RNA_function_flag(func);
- is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
+ FunctionRNA *func = (FunctionRNA *)link;
+ const int flag = RNA_function_flag(func);
+ /* TODO(campbell): this is used for classmethod's too,
+ * even though class methods should have 'FUNC_USE_SELF_TYPE' set, see Operator.poll for eg.
+ * Keep this as-is since its working but we should be using 'FUNC_USE_SELF_TYPE' for many functions. */
+ const bool is_staticmethod = (flag & FUNC_NO_SELF) && !(flag & FUNC_USE_SELF_TYPE);
if (!(flag & FUNC_REGISTER))
continue;
@@ -7294,7 +7322,8 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
if (is_staticmethod) {
if (PyMethod_Check(item) == 0) {
PyErr_Format(PyExc_TypeError,
- "expected %.200s, %.200s class \"%.200s\" attribute to be a method, not a %.200s",
+ "expected %.200s, %.200s class \"%.200s\" "
+ "attribute to be a static/class method, not a %.200s",
class_type, py_class_name, RNA_function_identifier(func), Py_TYPE(item)->tp_name);
return -1;
}
@@ -7303,7 +7332,8 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
else {
if (PyFunction_Check(item) == 0) {
PyErr_Format(PyExc_TypeError,
- "expected %.200s, %.200s class \"%.200s\" attribute to be a function, not a %.200s",
+ "expected %.200s, %.200s class \"%.200s\" "
+ "attribute to be a function, not a %.200s",
class_type, py_class_name, RNA_function_identifier(func), Py_TYPE(item)->tp_name);
return -1;
}
@@ -7315,7 +7345,7 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
arg_count = ((PyCodeObject *)PyFunction_GET_CODE(item))->co_argcount;
/* note, the number of args we check for and the number of args we give to
- * @staticmethods are different (quirk of python),
+ * '@staticmethods' are different (quirk of python),
* this is why rna_function_arg_count() doesn't return the value -1*/
if (is_staticmethod) {
func_arg_count++;
@@ -7346,8 +7376,8 @@ static int bpy_class_validate_recursive(PointerRNA *dummyptr, StructRNA *srna, v
lb = RNA_struct_type_properties(srna);
for (link = lb->first; link; link = link->next) {
const char *identifier;
- prop = (PropertyRNA *)link;
- flag = RNA_property_flag(prop);
+ PropertyRNA *prop = (PropertyRNA *)link;
+ const int flag = RNA_property_flag(prop);
if (!(flag & PROP_REGISTER))
continue;
diff --git a/source/blender/python/intern/bpy_rna.h b/source/blender/python/intern/bpy_rna.h
index e38d4f095d6..605f79b1ad8 100644
--- a/source/blender/python/intern/bpy_rna.h
+++ b/source/blender/python/intern/bpy_rna.h
@@ -179,6 +179,7 @@ PyObject *pyrna_prop_CreatePyObject(PointerRNA *ptr, PropertyRNA *prop);
/* extern'd by other modules which don't deal closely with RNA */
PyObject *pyrna_id_CreatePyObject(struct ID *id);
bool pyrna_id_FromPyObject(PyObject *obj, struct ID **id);
+bool pyrna_id_CheckPyObject(PyObject *obj);
/* operators also need this to set args */
int pyrna_pydict_to_props(PointerRNA *ptr, PyObject *kw, const bool all_args, const char *error_prefix);
diff --git a/source/blender/python/mathutils/mathutils.c b/source/blender/python/mathutils/mathutils.c
index 5c505247a97..1afb1d7be90 100644
--- a/source/blender/python/mathutils/mathutils.c
+++ b/source/blender/python/mathutils/mathutils.c
@@ -1,4 +1,4 @@
-/*
+/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
@@ -38,18 +38,31 @@
#endif
PyDoc_STRVAR(M_Mathutils_doc,
-"This module provides access to the math classes:\n"
+"This module provides access to math operations.\n"
+"\n"
+".. note::\n"
+"\n"
+" Classes, methods and attributes that accept vectors also accept other numeric sequences,\n"
+" such as tuples, lists."
+"\n\n"
+"Submodules:\n"
+"\n"
+".. toctree::\n"
+" :maxdepth: 1\n"
+"\n"
+" mathutils.geometry.rst\n"
+" mathutils.bvhtree.rst\n"
+" mathutils.kdtree.rst\n"
+" mathutils.interpolate.rst\n"
+" mathutils.noise.rst\n"
+"\n"
+"The :mod:`mathutils` module provides the following classes:\n"
"\n"
"- :class:`Color`,\n"
"- :class:`Euler`,\n"
"- :class:`Matrix`,\n"
"- :class:`Quaternion`,\n"
"- :class:`Vector`,\n"
-"\n"
-".. note::\n"
-"\n"
-" Classes, methods and attributes that accept vectors also accept other numeric sequences,\n"
-" such as tuples, lists."
);
static int mathutils_array_parse_fast(float *array,
int size,
@@ -219,7 +232,7 @@ int mathutils_array_parse_alloc(float **array, int array_min, PyObject *value, c
error_prefix, size, array_min);
return -1;
}
-
+
*array = PyMem_Malloc(size * sizeof(float));
memcpy(*array, ((BaseMathObject *)value)->data, size * sizeof(float));
return size;
@@ -422,7 +435,7 @@ static Mathutils_Callback *mathutils_callbacks[MATHUTILS_TOT_CB] = {NULL};
unsigned char Mathutils_RegisterCallback(Mathutils_Callback *cb)
{
unsigned char i;
-
+
/* find the first free slot */
for (i = 0; mathutils_callbacks[i]; i++) {
if (mathutils_callbacks[i] == cb) /* already registered? */
@@ -625,14 +638,14 @@ PyMODINIT_FUNC PyInit_mathutils(void)
return NULL;
mod = PyModule_Create(&M_Mathutils_module_def);
-
+
/* each type has its own new() function */
PyModule_AddObject(mod, vector_Type.tp_name, (PyObject *)&vector_Type);
PyModule_AddObject(mod, matrix_Type.tp_name, (PyObject *)&matrix_Type);
PyModule_AddObject(mod, euler_Type.tp_name, (PyObject *)&euler_Type);
PyModule_AddObject(mod, quaternion_Type.tp_name, (PyObject *)&quaternion_Type);
PyModule_AddObject(mod, color_Type.tp_name, (PyObject *)&color_Type);
-
+
/* submodule */
PyModule_AddObject(mod, "geometry", (submodule = PyInit_mathutils_geometry()));
/* XXX, python doesnt do imports with this usefully yet
diff --git a/source/blender/python/mathutils/mathutils_Color.c b/source/blender/python/mathutils/mathutils_Color.c
index add8c2451ff..9997cd9c1f5 100644
--- a/source/blender/python/mathutils/mathutils_Color.c
+++ b/source/blender/python/mathutils/mathutils_Color.c
@@ -173,7 +173,7 @@ static PyObject *Color_richcmpr(PyObject *a, PyObject *b, int op)
switch (op) {
case Py_NE:
ok = !ok;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case Py_EQ:
res = ok ? Py_False : Py_True;
break;
diff --git a/source/blender/python/mathutils/mathutils_Euler.c b/source/blender/python/mathutils/mathutils_Euler.c
index 54adc826af7..9492b6d67f3 100644
--- a/source/blender/python/mathutils/mathutils_Euler.c
+++ b/source/blender/python/mathutils/mathutils_Euler.c
@@ -65,7 +65,7 @@ static PyObject *Euler_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
case 2:
if ((order = euler_order_from_string(order_str, "mathutils.Euler()")) == -1)
return NULL;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case 1:
if (mathutils_array_parse(eul, EULER_SIZE, EULER_SIZE, seq, "mathutils.Euler()") == -1)
return NULL;
@@ -370,7 +370,7 @@ static PyObject *Euler_richcmpr(PyObject *a, PyObject *b, int op)
switch (op) {
case Py_NE:
ok = !ok;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case Py_EQ:
res = ok ? Py_False : Py_True;
break;
diff --git a/source/blender/python/mathutils/mathutils_Matrix.c b/source/blender/python/mathutils/mathutils_Matrix.c
index bd44e77e7c6..e368e8871f3 100644
--- a/source/blender/python/mathutils/mathutils_Matrix.c
+++ b/source/blender/python/mathutils/mathutils_Matrix.c
@@ -1641,9 +1641,9 @@ static PyObject *Matrix_rotate(MatrixObject *self, PyObject *value)
PyDoc_STRVAR(Matrix_decompose_doc,
".. method:: decompose()\n"
"\n"
-" Return the location, rotation and scale components of this matrix.\n"
+" Return the translation, rotation and scale components of this matrix.\n"
"\n"
-" :return: loc, rot, scale triple.\n"
+" :return: trans, rot, scale triple.\n"
" :rtype: (:class:`Vector`, :class:`Quaternion`, :class:`Vector`)"
);
static PyObject *Matrix_decompose(MatrixObject *self)
@@ -1709,10 +1709,10 @@ static PyObject *Matrix_lerp(MatrixObject *self, PyObject *args)
/* TODO, different sized matrix */
if (self->num_col == 4 && self->num_row == 4) {
- blend_m4_m4m4((float (*)[4])mat, (float (*)[4])self->matrix, (float (*)[4])mat2->matrix, fac);
+ interp_m4_m4m4((float (*)[4])mat, (float (*)[4])self->matrix, (float (*)[4])mat2->matrix, fac);
}
else if (self->num_col == 3 && self->num_row == 3) {
- blend_m3_m3m3((float (*)[3])mat, (float (*)[3])self->matrix, (float (*)[3])mat2->matrix, fac);
+ interp_m3_m3m3((float (*)[3])mat, (float (*)[3])self->matrix, (float (*)[3])mat2->matrix, fac);
}
else {
PyErr_SetString(PyExc_ValueError,
@@ -2034,7 +2034,7 @@ static PyObject *Matrix_richcmpr(PyObject *a, PyObject *b, int op)
switch (op) {
case Py_NE:
ok = !ok;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case Py_EQ:
res = ok ? Py_False : Py_True;
break;
diff --git a/source/blender/python/mathutils/mathutils_Quaternion.c b/source/blender/python/mathutils/mathutils_Quaternion.c
index 71b3cf8ddac..d283c717a46 100644
--- a/source/blender/python/mathutils/mathutils_Quaternion.c
+++ b/source/blender/python/mathutils/mathutils_Quaternion.c
@@ -552,7 +552,7 @@ static PyObject *Quaternion_richcmpr(PyObject *a, PyObject *b, int op)
switch (op) {
case Py_NE:
ok = !ok;
- /* fall-through */
+ ATTR_FALLTHROUGH;
case Py_EQ:
res = ok ? Py_False : Py_True;
break;
diff --git a/source/blender/render/CMakeLists.txt b/source/blender/render/CMakeLists.txt
index 569b207c966..a12bdd910c3 100644
--- a/source/blender/render/CMakeLists.txt
+++ b/source/blender/render/CMakeLists.txt
@@ -34,6 +34,7 @@ set(INC
../depsgraph
../makesdna
../makesrna
+ ../nodes
../physics
../../../intern/atomic
../../../intern/guardedalloc
@@ -165,10 +166,6 @@ if(WITH_INTERNATIONAL)
add_definitions(-DWITH_INTERNATIONAL)
endif()
-if(WITH_CYCLES AND WITH_CYCLES_DEBUG)
- add_definitions(-DWITH_CYCLES_DEBUG)
-endif()
-
if(APPLE)
# SSE math is enabled by default on x86_64
if(CMAKE_OSX_ARCHITECTURES MATCHES "i386")
diff --git a/source/blender/render/extern/include/RE_engine.h b/source/blender/render/extern/include/RE_engine.h
index f83a210275f..52491673612 100644
--- a/source/blender/render/extern/include/RE_engine.h
+++ b/source/blender/render/extern/include/RE_engine.h
@@ -96,6 +96,7 @@ typedef struct RenderEngineType {
void (*view_draw)(struct RenderEngine *engine, const struct bContext *context);
void (*update_script_node)(struct RenderEngine *engine, struct bNodeTree *ntree, struct bNode *node);
+ void (*update_render_passes)(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl);
/* RNA integration */
ExtensionRNA ext;
@@ -139,7 +140,8 @@ void RE_result_load_from_file(struct RenderResult *result, struct ReportList *re
struct RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w, int h, const char *layername, const char *viewname);
void RE_engine_update_result(RenderEngine *engine, struct RenderResult *result);
-void RE_engine_end_result(RenderEngine *engine, struct RenderResult *result, int cancel, int merge_results);
+void RE_engine_add_pass(RenderEngine *engine, const char *name, int channels, const char *chan_id, const char *layername);
+void RE_engine_end_result(RenderEngine *engine, struct RenderResult *result, int cancel, int highlight, int merge_results);
const char *RE_engine_active_view_get(RenderEngine *engine);
void RE_engine_active_view_set(RenderEngine *engine, const char *viewname);
@@ -160,6 +162,9 @@ bool RE_engine_is_external(struct Render *re);
void RE_engine_frame_set(struct RenderEngine *engine, int frame, float subframe);
+void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl,
+ const char *name, int channels, const char *chanid, int type);
+
/* Engine Types */
void RE_engines_init(void);
diff --git a/source/blender/render/extern/include/RE_pipeline.h b/source/blender/render/extern/include/RE_pipeline.h
index f535aa5aa71..0d2e29ba4c8 100644
--- a/source/blender/render/extern/include/RE_pipeline.h
+++ b/source/blender/render/extern/include/RE_pipeline.h
@@ -83,25 +83,19 @@ typedef struct RenderView {
typedef struct RenderPass {
struct RenderPass *next, *prev;
- int passtype, channels;
+ int channels;
char name[64]; /* amount defined in openexr_multi.h */
char chan_id[8]; /* amount defined in openexr_multi.h */
float *rect;
int rectx, recty;
- char internal_name[64]; /* EXR_PASS_MAXNAME */
+ char fullname[64]; /* EXR_PASS_MAXNAME */
char view[64]; /* EXR_VIEW_MAXNAME */
int view_id; /* quick lookup */
- int debug_type;
+ int pad;
} RenderPass;
-enum {
- RENDER_PASS_DEBUG_BVH_TRAVERSED_NODES = 0,
- RENDER_PASS_DEBUG_BVH_TRAVERSED_INSTANCES = 1,
- RENDER_PASS_DEBUG_RAY_BOUNCES = 2,
- RENDER_PASS_DEBUG_BVH_INTERSECTIONS = 3,
-};
/* a renderlayer is a full image, but with all passes and samples */
/* size of the rects is defined in RenderResult */
@@ -236,7 +230,7 @@ void RE_render_result_rect_from_ibuf(
struct ImBuf *ibuf, const int view_id);
struct RenderLayer *RE_GetRenderLayer(struct RenderResult *rr, const char *name);
-float *RE_RenderLayerGetPass(volatile struct RenderLayer *rl, int passtype, const char *viewname);
+float *RE_RenderLayerGetPass(volatile struct RenderLayer *rl, const char *name, const char *viewname);
/* add passes for grease pencil */
struct RenderPass *RE_create_gp_pass(struct RenderResult *rr, const char *layername, const char *viewname);
@@ -345,6 +339,7 @@ int RE_seq_render_active(struct Scene *scene, struct RenderData *rd);
bool RE_layers_have_name(struct RenderResult *result);
+struct RenderPass *RE_pass_find_by_name(volatile struct RenderLayer *rl, const char *name, const char *viewname);
struct RenderPass *RE_pass_find_by_type(volatile struct RenderLayer *rl, int passtype, const char *viewname);
/* shaded view or baking options */
@@ -381,7 +376,7 @@ bool RE_allow_render_generic_object(struct Object *ob);
/* RE_updateRenderInstances flag */
enum {
RE_OBJECT_INSTANCES_UPDATE_VIEW = (1 << 0),
- RE_OBJECT_INSTANCES_UPDATE_OBMAT = (1 << 1),
+ RE_OBJECT_INSTANCES_UPDATE_OBMAT = (1 << 1)
};
void RE_updateRenderInstances(Render *re, int flag);
@@ -394,13 +389,5 @@ struct RenderView *RE_RenderViewGetByName(struct RenderResult *res, const char *
RenderResult *RE_DuplicateRenderResult(RenderResult *rr);
-/******* Debug pass helper functions *********/
-
-#ifdef WITH_CYCLES_DEBUG
-int RE_debug_pass_num_channels_get(int pass_type);
-const char *RE_debug_pass_name_get(int pass_type);
-int RE_debug_pass_type_get(struct Render *re);
-#endif
-
#endif /* __RE_PIPELINE_H__ */
diff --git a/source/blender/render/extern/include/RE_shader_ext.h b/source/blender/render/extern/include/RE_shader_ext.h
index ae389fdfd2e..b64c0c8fc52 100644
--- a/source/blender/render/extern/include/RE_shader_ext.h
+++ b/source/blender/render/extern/include/RE_shader_ext.h
@@ -178,6 +178,7 @@ typedef struct ShadeInput {
unsigned int lay;
int layflag, passflag, combinedflag;
+ short object_pass_index;
struct Group *light_override;
struct Material *mat_override;
@@ -241,6 +242,9 @@ enum {
const float (*RE_object_instance_get_matrix(struct ObjectInstanceRen *obi, int matrix_id))[4];
+float RE_object_instance_get_object_pass_index(struct ObjectInstanceRen *obi);
+float RE_object_instance_get_random_id(struct ObjectInstanceRen *obi);
+
enum {
RE_VIEW_MATRIX,
RE_VIEWINV_MATRIX,
diff --git a/source/blender/render/intern/include/render_result.h b/source/blender/render/intern/include/render_result.h
index 0c4f4e20325..4057d8c1052 100644
--- a/source/blender/render/intern/include/render_result.h
+++ b/source/blender/render/intern/include/render_result.h
@@ -67,6 +67,11 @@ void render_result_views_new(struct RenderResult *rr, struct RenderData *rd);
void render_result_merge(struct RenderResult *rr, struct RenderResult *rrpart);
+/* Add Passes */
+
+void render_result_clone_passes(struct Render *re, struct RenderResult *rr, const char *viewname);
+void render_result_add_pass(struct RenderResult *rr, const char *name, int channels, const char *chan_id, const char *layername, const char *viewname);
+
/* Free */
void render_result_free(struct RenderResult *rr);
@@ -84,7 +89,7 @@ void render_result_exr_file_begin(struct Render *re);
void render_result_exr_file_end(struct Render *re);
/* render pass wrapper for gpencil */
-struct RenderPass *gp_add_pass(struct RenderResult *rr, struct RenderLayer *rl, int channels, int passtype, const char *viewname);
+struct RenderPass *gp_add_pass(struct RenderResult *rr, struct RenderLayer *rl, int channels, const char *name, const char *viewname);
void render_result_exr_file_merge(struct RenderResult *rr, struct RenderResult *rrpart, const char *viewname);
diff --git a/source/blender/render/intern/include/render_types.h b/source/blender/render/intern/include/render_types.h
index b3a5ccdae17..f9942bef61f 100644
--- a/source/blender/render/intern/include/render_types.h
+++ b/source/blender/render/intern/include/render_types.h
@@ -335,7 +335,7 @@ typedef struct ObjectRen {
char (*mcol)[MAX_CUSTOMDATA_LAYER_NAME];
int actmtface, actmcol, bakemtface;
- char tangent_mask; /* which tangent layer should be calculated */
+ short tangent_mask; /* which tangent layer should be calculated */
float obmat[4][4]; /* only used in convertblender.c, for instancing */
@@ -382,6 +382,8 @@ typedef struct ObjectInstanceRen {
float part_co[3];
float part_vel[3];
float part_avel[3];
+
+ unsigned int random_id;
} ObjectInstanceRen;
/* ------------------------------------------------------------------------- */
diff --git a/source/blender/render/intern/include/rendercore.h b/source/blender/render/intern/include/rendercore.h
index 7254fd25ee6..f4c4a50ac27 100644
--- a/source/blender/render/intern/include/rendercore.h
+++ b/source/blender/render/intern/include/rendercore.h
@@ -34,6 +34,12 @@
#include "render_types.h"
+#include "RE_engine.h"
+
+#include "DNA_node_types.h"
+
+#include "NOD_composite.h"
+
struct ShadeInput;
struct ShadeResult;
struct World;
@@ -77,6 +83,8 @@ void zbufshade_sss_tile(struct RenderPart *pa);
int get_sample_layers(struct RenderPart *pa, struct RenderLayer *rl, struct RenderLayer **rlpp);
+void render_internal_update_passes(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl);
+
/* -------- ray.c ------- */
diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
index 81e41a20f2e..103fa3e6034 100644
--- a/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
+++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.cpp
@@ -59,6 +59,7 @@ static void rtbuild_init(RTBuilder *b)
b->primitives.begin = NULL;
b->primitives.end = NULL;
b->primitives.maxsize = 0;
+ b->depth = 0;
for (int i = 0; i < RTBUILD_MAX_CHILDS; i++)
b->child_offset[i] = 0;
@@ -178,6 +179,8 @@ RTBuilder *rtbuild_get_child(RTBuilder *b, int child, RTBuilder *tmp)
{
rtbuild_init(tmp);
+ tmp->depth = b->depth + 1;
+
for (int i = 0; i < 3; i++)
if (b->sorted_begin[i]) {
tmp->sorted_begin[i] = b->sorted_begin[i] + b->child_offset[child];
@@ -336,6 +339,15 @@ int rtbuild_heuristic_object_split(RTBuilder *b, int nchilds)
int baxis = -1, boffset = 0;
if (size > nchilds) {
+ if (b->depth > RTBUILD_MAX_SAH_DEPTH) {
+ // for degenerate cases we avoid running out of stack space
+ // by simply splitting the children in the middle
+ b->child_offset[0] = 0;
+ b->child_offset[1] = (size+1)/2;
+ b->child_offset[2] = size;
+ return 2;
+ }
+
float bcost = FLT_MAX;
baxis = -1;
boffset = size / 2;
diff --git a/source/blender/render/intern/raytrace/rayobject_rtbuild.h b/source/blender/render/intern/raytrace/rayobject_rtbuild.h
index 9e296da144b..83042ef3d7e 100644
--- a/source/blender/render/intern/raytrace/rayobject_rtbuild.h
+++ b/source/blender/render/intern/raytrace/rayobject_rtbuild.h
@@ -49,7 +49,8 @@ extern "C" {
* generate with simple calls, and then convert to the theirs
* specific structure on the fly.
*/
-#define RTBUILD_MAX_CHILDS 32
+#define RTBUILD_MAX_CHILDS 32
+#define RTBUILD_MAX_SAH_DEPTH 256
typedef struct RTBuilder {
@@ -79,6 +80,8 @@ typedef struct RTBuilder {
float bb[6];
+ /* current depth */
+ int depth;
} RTBuilder;
/* used during creation */
diff --git a/source/blender/render/intern/source/bake_api.c b/source/blender/render/intern/source/bake_api.c
index 73424a4e846..588c327ab91 100644
--- a/source/blender/render/intern/source/bake_api.c
+++ b/source/blender/render/intern/source/bake_api.c
@@ -684,6 +684,10 @@ void RE_bake_pixels_populate(
int mat_nr = mp->mat_nr;
int image_id = bake_images->lookup[mat_nr];
+ if (image_id < 0) {
+ continue;
+ }
+
bd.bk_image = &bake_images->data[image_id];
bd.primitive_id = ++p_id;
diff --git a/source/blender/render/intern/source/convertblender.c b/source/blender/render/intern/source/convertblender.c
index 263ea3d4ef2..9633d95855e 100644
--- a/source/blender/render/intern/source/convertblender.c
+++ b/source/blender/render/intern/source/convertblender.c
@@ -3439,10 +3439,9 @@ static void init_render_mesh(Render *re, ObjectRen *obr, int timeoffset)
if (need_nmap_tangent_concrete || need_tangent) {
int uv_start = CustomData_get_layer_index(&dm->faceData, CD_MTFACE);
int uv_index = CustomData_get_named_layer_index(&dm->faceData, CD_MTFACE, layer->name);
- BLI_assert(uv_start >= 0 && uv_index >= 0);
- if ((uv_start < 0 || uv_index < 0))
- continue;
- int n = uv_index - uv_start;
+
+ /* if there are no UVs, orco tangents are in first slot */
+ int n = (uv_start >= 0 && uv_index >= 0) ? uv_index - uv_start : 0;
const float *tangent = (const float *) layer->data;
float *ftang = RE_vlakren_get_nmap_tangent(obr, vlr, n, true);
@@ -4658,14 +4657,22 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *
index= (dob)? dob->persistent_id[0]: 0;
+ /* It seems that we may generate psys->renderdata recursively in some nasty intricated cases of
+ * several levels of bupliobject (see T51524).
+ * For now, basic rule is, do not restore psys if it was already in 'render state'.
+ * Another, more robust solution could be to add some reference counting to that renderdata... */
+ bool psys_has_renderdata = false;
+
/* the emitter has to be processed first (render levels of modifiers) */
/* so here we only check if the emitter should be rendered */
if (ob->particlesystem.first) {
show_emitter= 0;
for (psys=ob->particlesystem.first; psys; psys=psys->next) {
show_emitter += psys->part->draw & PART_DRAW_EMITTER;
- if (!(re->r.scemode & R_VIEWPORT_PREVIEW))
+ if (!(re->r.scemode & R_VIEWPORT_PREVIEW)) {
+ psys_has_renderdata |= (psys->renderdata != NULL);
psys_render_set(ob, psys, re->viewmat, re->winmat, re->winx, re->winy, timeoffset);
+ }
}
/* if no psys has "show emitter" selected don't render emitter */
@@ -4712,8 +4719,9 @@ static void add_render_object(Render *re, Object *ob, Object *par, DupliObject *
if (dob)
psys->flag |= PSYS_USE_IMAT;
init_render_object_data(re, obr, timeoffset);
- if (!(re->r.scemode & R_VIEWPORT_PREVIEW))
+ if (!(re->r.scemode & R_VIEWPORT_PREVIEW) && !psys_has_renderdata) {
psys_render_restore(ob, psys);
+ }
psys->flag &= ~PSYS_USE_IMAT;
/* only add instance for objects that have not been used for dupli */
diff --git a/source/blender/render/intern/source/envmap.c b/source/blender/render/intern/source/envmap.c
index d97e18d6511..156b4215992 100644
--- a/source/blender/render/intern/source/envmap.c
+++ b/source/blender/render/intern/source/envmap.c
@@ -61,6 +61,7 @@
#include "renderpipeline.h"
#include "texture.h"
#include "zbuf.h"
+#include "render_result.h"
/* ------------------------------------------------------------------------- */
@@ -142,8 +143,8 @@ static Render *envmap_render_copy(Render *re, EnvMap *env)
/* set up renderdata */
render_copy_renderdata(&envre->r, &re->r);
envre->r.mode &= ~(R_BORDER | R_PANORAMA | R_ORTHO | R_MBLUR);
- BLI_listbase_clear(&envre->r.layers);
- BLI_listbase_clear(&envre->r.views);
+ BLI_freelistN(&envre->r.layers);
+ BLI_freelistN(&envre->r.views);
envre->r.filtertype = 0;
envre->r.tilex = envre->r.xsch / 2;
envre->r.tiley = envre->r.ysch / 2;
@@ -493,13 +494,20 @@ static void render_envmap(Render *re, EnvMap *env)
env_rotate_scene(envre, tmat, 0);
if (re->test_break(re->tbh) == 0) {
- RenderLayer *rl = envre->result->layers.first;
int y;
float *alpha;
float *rect;
+ if (envre->result->do_exr_tile) {
+ BLI_rw_mutex_lock(&envre->resultmutex, THREAD_LOCK_WRITE);
+ render_result_exr_file_end(envre);
+ BLI_rw_mutex_unlock(&envre->resultmutex);
+ }
+
+ RenderLayer *rl = envre->result->layers.first;
+
/* envmap is rendered independently of multiview */
- rect = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, "");
+ rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, "");
ibuf = IMB_allocImBuf(envre->rectx, envre->recty, 24, IB_rect | IB_rectfloat);
memcpy(ibuf->rect_float, rect, ibuf->channels * ibuf->x * ibuf->y * sizeof(float));
diff --git a/source/blender/render/intern/source/external_engine.c b/source/blender/render/intern/source/external_engine.c
index fd9d95c63b6..a581f7bd198 100644
--- a/source/blender/render/intern/source/external_engine.c
+++ b/source/blender/render/intern/source/external_engine.c
@@ -62,13 +62,14 @@
#include "renderpipeline.h"
#include "render_types.h"
#include "render_result.h"
+#include "rendercore.h"
/* Render Engine Types */
static RenderEngineType internal_render_type = {
NULL, NULL,
"BLENDER_RENDER", N_("Blender Render"), RE_INTERNAL,
- NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, render_internal_update_passes,
{NULL, NULL, NULL}
};
@@ -77,7 +78,7 @@ static RenderEngineType internal_render_type = {
static RenderEngineType internal_game_type = {
NULL, NULL,
"BLENDER_GAME", N_("Blender Game"), RE_INTERNAL | RE_GAME,
- NULL, NULL, NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL,
{NULL, NULL, NULL}
};
@@ -212,6 +213,8 @@ RenderResult *RE_engine_begin_result(RenderEngine *engine, int x, int y, int w,
/* can be NULL if we CLAMP the width or height to 0 */
if (result) {
+ render_result_clone_passes(re, result, viewname);
+
RenderPart *pa;
/* Copy EXR tile settings, so pipeline knows whether this is a result
@@ -245,7 +248,18 @@ void RE_engine_update_result(RenderEngine *engine, RenderResult *result)
}
}
-void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel, int merge_results)
+void RE_engine_add_pass(RenderEngine *engine, const char *name, int channels, const char *chan_id, const char *layername)
+{
+ Render *re = engine->re;
+
+ if (!re || !re->result) {
+ return;
+ }
+
+ render_result_add_pass(re->result, name, channels, chan_id, layername, NULL);
+}
+
+void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel, int highlight, int merge_results)
{
Render *re = engine->re;
@@ -254,7 +268,7 @@ void RE_engine_end_result(RenderEngine *engine, RenderResult *result, int cancel
}
/* merge. on break, don't merge in result for preview renders, looks nicer */
- if (!cancel) {
+ if (!highlight) {
/* for exr tile render, detect tiles that are done */
RenderPart *pa = get_part_from_result(re, result);
@@ -760,3 +774,22 @@ int RE_engine_render(Render *re, int do_all)
return 1;
}
+void RE_engine_register_pass(struct RenderEngine *engine, struct Scene *scene, struct SceneRenderLayer *srl,
+ const char *name, int UNUSED(channels), const char *UNUSED(chanid), int type)
+{
+ /* The channel information is currently not used, but is part of the API in case it's needed in the future. */
+
+ if (!(scene && srl && engine)) {
+ return;
+ }
+
+ /* Register the pass in all scenes that have a render layer node for this layer.
+ * Since multiple scenes can be used in the compositor, the code must loop over all scenes
+ * and check whether their nodetree has a node that needs to be updated. */
+ Scene *sce;
+ for (sce = G.main->scene.first; sce; sce = sce->id.next) {
+ if (sce->nodetree) {
+ ntreeCompositRegisterPass(sce->nodetree, scene, srl, name, type);
+ }
+ }
+}
diff --git a/source/blender/render/intern/source/pipeline.c b/source/blender/render/intern/source/pipeline.c
index 52eca5f7005..e078365e1ed 100644
--- a/source/blender/render/intern/source/pipeline.c
+++ b/source/blender/render/intern/source/pipeline.c
@@ -239,9 +239,9 @@ void RE_FreeRenderResult(RenderResult *res)
render_result_free(res);
}
-float *RE_RenderLayerGetPass(volatile RenderLayer *rl, int passtype, const char *viewname)
+float *RE_RenderLayerGetPass(volatile RenderLayer *rl, const char *name, const char *viewname)
{
- RenderPass *rpass = RE_pass_find_by_type(rl, passtype, viewname);
+ RenderPass *rpass = RE_pass_find_by_name(rl, name, viewname);
return rpass ? rpass->rect : NULL;
}
@@ -382,13 +382,13 @@ void RE_AcquireResultImageViews(Render *re, RenderResult *rr)
if (rl) {
if (rv->rectf == NULL) {
for (rview = (RenderView *)rr->views.first; rview; rview = rview->next) {
- rview->rectf = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, rview->name);
+ rview->rectf = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, rview->name);
}
}
if (rv->rectz == NULL) {
for (rview = (RenderView *)rr->views.first; rview; rview = rview->next) {
- rview->rectz = RE_RenderLayerGetPass(rl, SCE_PASS_Z, rview->name);
+ rview->rectz = RE_RenderLayerGetPass(rl, RE_PASSNAME_Z, rview->name);
}
}
}
@@ -442,10 +442,10 @@ void RE_AcquireResultImage(Render *re, RenderResult *rr, const int view_id)
if (rl) {
if (rv->rectf == NULL)
- rr->rectf = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, rv->name);
+ rr->rectf = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, rv->name);
if (rv->rectz == NULL)
- rr->rectz = RE_RenderLayerGetPass(rl, SCE_PASS_Z, rv->name);
+ rr->rectz = RE_RenderLayerGetPass(rl, RE_PASSNAME_Z, rv->name);
}
rr->have_combined = (rv->rectf != NULL);
@@ -723,6 +723,8 @@ void RE_InitState(Render *re, Render *source, RenderData *rd,
re->r.size = source->r.size;
}
+ re_init_resolution(re, source, winx, winy, disprect);
+
/* disable border if it's a full render anyway */
if (re->r.border.xmin == 0.0f && re->r.border.xmax == 1.0f &&
re->r.border.ymin == 0.0f && re->r.border.ymax == 1.0f)
@@ -730,8 +732,6 @@ void RE_InitState(Render *re, Render *source, RenderData *rd,
re->r.mode &= ~R_BORDER;
}
- re_init_resolution(re, source, winx, winy, disprect);
-
if (re->rectx < 1 || re->recty < 1 || (BKE_imtype_is_movie(rd->im_format.imtype) &&
(re->rectx < 16 || re->recty < 16) ))
{
@@ -842,7 +842,7 @@ static void render_result_rescale(Render *re)
if (src_rectf == NULL) {
RenderLayer *rl = render_get_active_layer(re, re->result);
if (rl != NULL) {
- src_rectf = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, NULL);
+ src_rectf = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, NULL);
}
}
@@ -861,7 +861,7 @@ static void render_result_rescale(Render *re)
RenderLayer *rl;
rl = render_get_active_layer(re, re->result);
if (rl != NULL) {
- dst_rectf = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, NULL);
+ dst_rectf = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, NULL);
}
}
@@ -1655,7 +1655,7 @@ static void merge_renderresult_blur(RenderResult *rr, RenderResult *brr, float b
/* passes are allocated in sync */
rpass1 = rl1->passes.first;
for (rpass = rl->passes.first; rpass && rpass1; rpass = rpass->next, rpass1 = rpass1->next) {
- if ((rpass->passtype & SCE_PASS_COMBINED) && key_alpha)
+ if (STREQ(rpass->name, RE_PASSNAME_COMBINED) && key_alpha)
addblur_rect_key(rr, rpass->rect, rpass1->rect, blurfac);
else
addblur_rect(rr, rpass->rect, rpass1->rect, blurfac, rpass->channels);
@@ -1855,6 +1855,8 @@ static void render_result_uncrop(Render *re)
rres = render_result_new(re, &re->disprect, 0, RR_USE_MEM, RR_ALL_LAYERS, RR_ALL_VIEWS);
+ render_result_clone_passes(re, rres, NULL);
+
render_result_merge(rres, re->result);
render_result_free(re->result);
re->result = rres;
@@ -3887,7 +3889,7 @@ void RE_layer_load_from_file(RenderLayer *layer, ReportList *reports, const char
/* multiview: since the API takes no 'view', we use the first combined pass found */
for (rpass = layer->passes.first; rpass; rpass = rpass->next)
- if (rpass->passtype == SCE_PASS_COMBINED)
+ if (STREQ(rpass->name, RE_PASSNAME_COMBINED))
break;
if (rpass == NULL)
@@ -4013,13 +4015,12 @@ bool RE_layers_have_name(struct RenderResult *rr)
return false;
}
-RenderPass *RE_pass_find_by_type(volatile RenderLayer *rl, int passtype, const char *viewname)
+RenderPass *RE_pass_find_by_name(volatile RenderLayer *rl, const char *name, const char *viewname)
{
RenderPass *rp = NULL;
for (rp = rl->passes.last; rp; rp = rp->prev) {
- if (rp->passtype == passtype) {
-
+ if (STREQ(rp->name, name)) {
if (viewname == NULL || viewname[0] == '\0')
break;
else if (STREQ(rp->view, viewname))
@@ -4029,6 +4030,50 @@ RenderPass *RE_pass_find_by_type(volatile RenderLayer *rl, int passtype, const c
return rp;
}
+/* Only provided for API compatibility, don't use this in new code! */
+RenderPass *RE_pass_find_by_type(volatile RenderLayer *rl, int passtype, const char *viewname)
+{
+#define CHECK_PASS(NAME) \
+ if (passtype == SCE_PASS_ ## NAME) \
+ return RE_pass_find_by_name(rl, RE_PASSNAME_ ## NAME, viewname);
+
+ CHECK_PASS(COMBINED);
+ CHECK_PASS(Z);
+ CHECK_PASS(VECTOR);
+ CHECK_PASS(NORMAL);
+ CHECK_PASS(UV);
+ CHECK_PASS(RGBA);
+ CHECK_PASS(EMIT);
+ CHECK_PASS(DIFFUSE);
+ CHECK_PASS(SPEC);
+ CHECK_PASS(SHADOW);
+ CHECK_PASS(AO);
+ CHECK_PASS(ENVIRONMENT);
+ CHECK_PASS(INDIRECT);
+ CHECK_PASS(REFLECT);
+ CHECK_PASS(REFRACT);
+ CHECK_PASS(INDEXOB);
+ CHECK_PASS(INDEXMA);
+ CHECK_PASS(MIST);
+ CHECK_PASS(RAYHITS);
+ CHECK_PASS(DIFFUSE_DIRECT);
+ CHECK_PASS(DIFFUSE_INDIRECT);
+ CHECK_PASS(DIFFUSE_COLOR);
+ CHECK_PASS(GLOSSY_DIRECT);
+ CHECK_PASS(GLOSSY_INDIRECT);
+ CHECK_PASS(GLOSSY_COLOR);
+ CHECK_PASS(TRANSM_DIRECT);
+ CHECK_PASS(TRANSM_INDIRECT);
+ CHECK_PASS(TRANSM_COLOR);
+ CHECK_PASS(SUBSURFACE_DIRECT);
+ CHECK_PASS(SUBSURFACE_INDIRECT);
+ CHECK_PASS(SUBSURFACE_COLOR);
+
+#undef CHECK_PASS
+
+ return NULL;
+}
+
/* create a renderlayer and renderpass for grease pencil layer */
RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const char *viewname)
{
@@ -4046,7 +4091,7 @@ RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const cha
}
/* clear previous pass if exist or the new image will be over previous one*/
- RenderPass *rp = RE_pass_find_by_type(rl, SCE_PASS_COMBINED, viewname);
+ RenderPass *rp = RE_pass_find_by_name(rl, RE_PASSNAME_COMBINED, viewname);
if (rp) {
if (rp->rect) {
MEM_freeN(rp->rect);
@@ -4054,5 +4099,5 @@ RenderPass *RE_create_gp_pass(RenderResult *rr, const char *layername, const cha
BLI_freelinkN(&rl->passes, rp);
}
/* create a totally new pass */
- return gp_add_pass(rr, rl, 4, SCE_PASS_COMBINED, viewname);
+ return gp_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, viewname);
}
diff --git a/source/blender/render/intern/source/render_result.c b/source/blender/render/intern/source/render_result.c
index f276c01e86a..8e6e6c9bb7d 100644
--- a/source/blender/render/intern/source/render_result.c
+++ b/source/blender/render/intern/source/render_result.c
@@ -173,363 +173,72 @@ void render_result_views_shallowdelete(RenderResult *rr)
}
}
-static const char *name_from_passtype(int passtype, int channel)
-{
- if (passtype == SCE_PASS_COMBINED) {
- if (channel == -1) return "Combined";
- if (channel == 0) return "Combined.R";
- if (channel == 1) return "Combined.G";
- if (channel == 2) return "Combined.B";
- return "Combined.A";
- }
- if (passtype == SCE_PASS_Z) {
- if (channel == -1) return "Depth";
- return "Depth.Z";
- }
- if (passtype == SCE_PASS_VECTOR) {
- if (channel == -1) return "Vector";
- if (channel == 0) return "Vector.X";
- if (channel == 1) return "Vector.Y";
- if (channel == 2) return "Vector.Z";
- return "Vector.W";
- }
- if (passtype == SCE_PASS_NORMAL) {
- if (channel == -1) return "Normal";
- if (channel == 0) return "Normal.X";
- if (channel == 1) return "Normal.Y";
- return "Normal.Z";
- }
- if (passtype == SCE_PASS_UV) {
- if (channel == -1) return "UV";
- if (channel == 0) return "UV.U";
- if (channel == 1) return "UV.V";
- return "UV.A";
- }
- if (passtype == SCE_PASS_RGBA) {
- if (channel == -1) return "Color";
- if (channel == 0) return "Color.R";
- if (channel == 1) return "Color.G";
- if (channel == 2) return "Color.B";
- return "Color.A";
- }
- if (passtype == SCE_PASS_EMIT) {
- if (channel == -1) return "Emit";
- if (channel == 0) return "Emit.R";
- if (channel == 1) return "Emit.G";
- return "Emit.B";
- }
- if (passtype == SCE_PASS_DIFFUSE) {
- if (channel == -1) return "Diffuse";
- if (channel == 0) return "Diffuse.R";
- if (channel == 1) return "Diffuse.G";
- return "Diffuse.B";
- }
- if (passtype == SCE_PASS_SPEC) {
- if (channel == -1) return "Spec";
- if (channel == 0) return "Spec.R";
- if (channel == 1) return "Spec.G";
- return "Spec.B";
- }
- if (passtype == SCE_PASS_SHADOW) {
- if (channel == -1) return "Shadow";
- if (channel == 0) return "Shadow.R";
- if (channel == 1) return "Shadow.G";
- return "Shadow.B";
- }
- if (passtype == SCE_PASS_AO) {
- if (channel == -1) return "AO";
- if (channel == 0) return "AO.R";
- if (channel == 1) return "AO.G";
- return "AO.B";
- }
- if (passtype == SCE_PASS_ENVIRONMENT) {
- if (channel == -1) return "Env";
- if (channel == 0) return "Env.R";
- if (channel == 1) return "Env.G";
- return "Env.B";
- }
- if (passtype == SCE_PASS_INDIRECT) {
- if (channel == -1) return "Indirect";
- if (channel == 0) return "Indirect.R";
- if (channel == 1) return "Indirect.G";
- return "Indirect.B";
- }
- if (passtype == SCE_PASS_REFLECT) {
- if (channel == -1) return "Reflect";
- if (channel == 0) return "Reflect.R";
- if (channel == 1) return "Reflect.G";
- return "Reflect.B";
- }
- if (passtype == SCE_PASS_REFRACT) {
- if (channel == -1) return "Refract";
- if (channel == 0) return "Refract.R";
- if (channel == 1) return "Refract.G";
- return "Refract.B";
- }
- if (passtype == SCE_PASS_INDEXOB) {
- if (channel == -1) return "IndexOB";
- return "IndexOB.X";
- }
- if (passtype == SCE_PASS_INDEXMA) {
- if (channel == -1) return "IndexMA";
- return "IndexMA.X";
- }
- if (passtype == SCE_PASS_MIST) {
- if (channel == -1) return "Mist";
- return "Mist.Z";
- }
- if (passtype == SCE_PASS_RAYHITS) {
- if (channel == -1) return "Rayhits";
- if (channel == 0) return "Rayhits.R";
- if (channel == 1) return "Rayhits.G";
- return "Rayhits.B";
- }
- if (passtype == SCE_PASS_DIFFUSE_DIRECT) {
- if (channel == -1) return "DiffDir";
- if (channel == 0) return "DiffDir.R";
- if (channel == 1) return "DiffDir.G";
- return "DiffDir.B";
- }
- if (passtype == SCE_PASS_DIFFUSE_INDIRECT) {
- if (channel == -1) return "DiffInd";
- if (channel == 0) return "DiffInd.R";
- if (channel == 1) return "DiffInd.G";
- return "DiffInd.B";
- }
- if (passtype == SCE_PASS_DIFFUSE_COLOR) {
- if (channel == -1) return "DiffCol";
- if (channel == 0) return "DiffCol.R";
- if (channel == 1) return "DiffCol.G";
- return "DiffCol.B";
- }
- if (passtype == SCE_PASS_GLOSSY_DIRECT) {
- if (channel == -1) return "GlossDir";
- if (channel == 0) return "GlossDir.R";
- if (channel == 1) return "GlossDir.G";
- return "GlossDir.B";
- }
- if (passtype == SCE_PASS_GLOSSY_INDIRECT) {
- if (channel == -1) return "GlossInd";
- if (channel == 0) return "GlossInd.R";
- if (channel == 1) return "GlossInd.G";
- return "GlossInd.B";
- }
- if (passtype == SCE_PASS_GLOSSY_COLOR) {
- if (channel == -1) return "GlossCol";
- if (channel == 0) return "GlossCol.R";
- if (channel == 1) return "GlossCol.G";
- return "GlossCol.B";
- }
- if (passtype == SCE_PASS_TRANSM_DIRECT) {
- if (channel == -1) return "TransDir";
- if (channel == 0) return "TransDir.R";
- if (channel == 1) return "TransDir.G";
- return "TransDir.B";
- }
- if (passtype == SCE_PASS_TRANSM_INDIRECT) {
- if (channel == -1) return "TransInd";
- if (channel == 0) return "TransInd.R";
- if (channel == 1) return "TransInd.G";
- return "TransInd.B";
- }
- if (passtype == SCE_PASS_TRANSM_COLOR) {
- if (channel == -1) return "TransCol";
- if (channel == 0) return "TransCol.R";
- if (channel == 1) return "TransCol.G";
- return "TransCol.B";
- }
- if (passtype == SCE_PASS_SUBSURFACE_DIRECT) {
- if (channel == -1) return "SubsurfaceDir";
- if (channel == 0) return "SubsurfaceDir.R";
- if (channel == 1) return "SubsurfaceDir.G";
- return "SubsurfaceDir.B";
- }
- if (passtype == SCE_PASS_SUBSURFACE_INDIRECT) {
- if (channel == -1) return "SubsurfaceInd";
- if (channel == 0) return "SubsurfaceInd.R";
- if (channel == 1) return "SubsurfaceInd.G";
- return "SubsurfaceInd.B";
- }
- if (passtype == SCE_PASS_SUBSURFACE_COLOR) {
- if (channel == -1) return "SubsurfaceCol";
- if (channel == 0) return "SubsurfaceCol.R";
- if (channel == 1) return "SubsurfaceCol.G";
- return "SubsurfaceCol.B";
- }
- return "Unknown";
-}
-static int passtype_from_name(const char *str, int passflag)
+static char* set_pass_name(char *outname, const char *name, int channel, const char *chan_id)
{
- /* We do not really support several pass of the same types, so in case we are opening an EXR file with several pass
- * names detected as same pass type, only return that pass type the first time, and return 'uknown' for the others.
- * See T48466. */
-#define RETURN_PASS(_passtype) return (passflag & (_passtype)) ? 0 : (_passtype)
-
- if (STRPREFIX(str, "Combined"))
- RETURN_PASS(SCE_PASS_COMBINED);
-
- if (STRPREFIX(str, "Depth"))
- RETURN_PASS(SCE_PASS_Z);
-
- if (STRPREFIX(str, "Vector"))
- RETURN_PASS(SCE_PASS_VECTOR);
-
- if (STRPREFIX(str, "Normal"))
- RETURN_PASS(SCE_PASS_NORMAL);
-
- if (STRPREFIX(str, "UV"))
- RETURN_PASS(SCE_PASS_UV);
-
- if (STRPREFIX(str, "Color"))
- RETURN_PASS(SCE_PASS_RGBA);
-
- if (STRPREFIX(str, "Emit"))
- RETURN_PASS(SCE_PASS_EMIT);
-
- if (STRPREFIX(str, "Diffuse"))
- RETURN_PASS(SCE_PASS_DIFFUSE);
-
- if (STRPREFIX(str, "Spec"))
- RETURN_PASS(SCE_PASS_SPEC);
-
- if (STRPREFIX(str, "Shadow"))
- RETURN_PASS(SCE_PASS_SHADOW);
-
- if (STRPREFIX(str, "AO"))
- RETURN_PASS(SCE_PASS_AO);
-
- if (STRPREFIX(str, "Env"))
- RETURN_PASS(SCE_PASS_ENVIRONMENT);
-
- if (STRPREFIX(str, "Indirect"))
- RETURN_PASS(SCE_PASS_INDIRECT);
-
- if (STRPREFIX(str, "Reflect"))
- RETURN_PASS(SCE_PASS_REFLECT);
-
- if (STRPREFIX(str, "Refract"))
- RETURN_PASS(SCE_PASS_REFRACT);
-
- if (STRPREFIX(str, "IndexOB"))
- RETURN_PASS(SCE_PASS_INDEXOB);
-
- if (STRPREFIX(str, "IndexMA"))
- RETURN_PASS(SCE_PASS_INDEXMA);
-
- if (STRPREFIX(str, "Mist"))
- RETURN_PASS(SCE_PASS_MIST);
-
- if (STRPREFIX(str, "RayHits"))
- RETURN_PASS(SCE_PASS_RAYHITS);
-
- if (STRPREFIX(str, "DiffDir"))
- RETURN_PASS(SCE_PASS_DIFFUSE_DIRECT);
-
- if (STRPREFIX(str, "DiffInd"))
- RETURN_PASS(SCE_PASS_DIFFUSE_INDIRECT);
-
- if (STRPREFIX(str, "DiffCol"))
- RETURN_PASS(SCE_PASS_DIFFUSE_COLOR);
-
- if (STRPREFIX(str, "GlossDir"))
- RETURN_PASS(SCE_PASS_GLOSSY_DIRECT);
-
- if (STRPREFIX(str, "GlossInd"))
- RETURN_PASS(SCE_PASS_GLOSSY_INDIRECT);
-
- if (STRPREFIX(str, "GlossCol"))
- RETURN_PASS(SCE_PASS_GLOSSY_COLOR);
-
- if (STRPREFIX(str, "TransDir"))
- RETURN_PASS(SCE_PASS_TRANSM_DIRECT);
-
- if (STRPREFIX(str, "TransInd"))
- RETURN_PASS(SCE_PASS_TRANSM_INDIRECT);
-
- if (STRPREFIX(str, "TransCol"))
- RETURN_PASS(SCE_PASS_TRANSM_COLOR);
-
- if (STRPREFIX(str, "SubsurfaceDir"))
- RETURN_PASS(SCE_PASS_SUBSURFACE_DIRECT);
-
- if (STRPREFIX(str, "SubsurfaceInd"))
- RETURN_PASS(SCE_PASS_SUBSURFACE_INDIRECT);
-
- if (STRPREFIX(str, "SubsurfaceCol"))
- RETURN_PASS(SCE_PASS_SUBSURFACE_COLOR);
-
- return 0;
-
-#undef RETURN_PASS
+ BLI_strncpy(outname, name, EXR_PASS_MAXNAME);
+ if (channel >= 0) {
+ char token[3] = {'.', chan_id[channel], '\0'};
+ strncat(outname, token, EXR_PASS_MAXNAME);
+ }
+ return outname;
}
-
-static void set_pass_name(char *passname, int passtype, int channel, const char *view)
+static void set_pass_full_name(char *fullname, const char *name, int channel, const char *view, const char *chan_id)
{
- const char delims[] = {'.', '\0'};
- const char *sep;
- const char *token;
- size_t len;
-
- const char *passtype_name = name_from_passtype(passtype, channel);
-
- if (view == NULL || view[0] == '\0') {
- BLI_strncpy(passname, passtype_name, EXR_PASS_MAXNAME);
- return;
- }
-
- len = BLI_str_rpartition(passtype_name, delims, &sep, &token);
-
- if (sep) {
- BLI_snprintf(passname, EXR_PASS_MAXNAME, "%.*s.%s.%s", (int)len, passtype_name, view, token);
+ BLI_strncpy(fullname, name, EXR_PASS_MAXNAME);
+ if (view && view[0]) {
+ strncat(fullname, ".", EXR_PASS_MAXNAME);
+ strncat(fullname, view, EXR_PASS_MAXNAME);
}
- else {
- BLI_snprintf(passname, EXR_PASS_MAXNAME, "%s.%s", passtype_name, view);
+ if (channel >= 0) {
+ char token[3] = {'.', chan_id[channel], '\0'};
+ strncat(fullname, token, EXR_PASS_MAXNAME);
}
}
/********************************** New **************************************/
-static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype, const char *viewname)
+static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int channels, const char *name, const char *viewname, const char *chan_id)
{
const int view_id = BLI_findstringindex(&rr->views, viewname, offsetof(RenderView, name));
- const char *typestr = name_from_passtype(passtype, -1);
- RenderPass *rpass = MEM_callocN(sizeof(RenderPass), typestr);
+ RenderPass *rpass = MEM_callocN(sizeof(RenderPass), name);
size_t rectsize = ((size_t)rr->rectx) * rr->recty * channels;
- rpass->passtype = passtype;
rpass->channels = channels;
rpass->rectx = rl->rectx;
rpass->recty = rl->recty;
rpass->view_id = view_id;
- set_pass_name(rpass->name, rpass->passtype, -1, viewname);
- BLI_strncpy(rpass->internal_name, typestr, sizeof(rpass->internal_name));
+ BLI_strncpy(rpass->name, name, sizeof(rpass->name));
+ BLI_strncpy(rpass->chan_id, chan_id, sizeof(rpass->chan_id));
BLI_strncpy(rpass->view, viewname, sizeof(rpass->view));
+ set_pass_full_name(rpass->fullname, rpass->name, -1, rpass->view, rpass->chan_id);
if (rl->exrhandle) {
int a;
- for (a = 0; a < channels; a++)
- IMB_exr_add_channel(rl->exrhandle, rl->name, name_from_passtype(passtype, a), viewname, 0, 0, NULL, false);
+ for (a = 0; a < channels; a++) {
+ char passname[EXR_PASS_MAXNAME];
+ IMB_exr_add_channel(rl->exrhandle, rl->name, set_pass_name(passname, rpass->name, a, rpass->chan_id), viewname, 0, 0, NULL, false);
+ }
}
else {
float *rect;
int x;
- rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, typestr);
+ rpass->rect = MEM_mapallocN(sizeof(float) * rectsize, name);
if (rpass->rect == NULL) {
MEM_freeN(rpass);
return NULL;
}
- if (passtype == SCE_PASS_VECTOR) {
+ if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
/* initialize to max speed */
rect = rpass->rect;
for (x = rectsize - 1; x >= 0; x--)
rect[x] = PASS_VECTOR_MAX;
}
- else if (passtype == SCE_PASS_Z) {
+ else if (STREQ(rpass->name, RE_PASSNAME_Z)) {
rect = rpass->rect;
for (x = rectsize - 1; x >= 0; x--)
rect[x] = 10e10;
@@ -541,58 +250,10 @@ static RenderPass *render_layer_add_pass(RenderResult *rr, RenderLayer *rl, int
return rpass;
}
/* wrapper called from render_opengl */
-RenderPass *gp_add_pass(RenderResult *rr, RenderLayer *rl, int channels, int passtype, const char *viewname)
-{
- return render_layer_add_pass(rr, rl, channels, passtype, viewname);
-}
-
-#ifdef WITH_CYCLES_DEBUG
-const char *RE_debug_pass_name_get(int debug_type)
-{
- switch (debug_type) {
- case RENDER_PASS_DEBUG_BVH_TRAVERSED_NODES:
- return "BVH Traversed Nodes";
- case RENDER_PASS_DEBUG_BVH_TRAVERSED_INSTANCES:
- return "BVH Traversed Instances";
- case RENDER_PASS_DEBUG_BVH_INTERSECTIONS:
- return "BVH Primitive Intersections";
- case RENDER_PASS_DEBUG_RAY_BOUNCES:
- return "Ray Bounces";
- }
- return "Unknown";
-}
-
-int RE_debug_pass_num_channels_get(int UNUSED(debug_type))
-{
- /* Only single case currently, might be handy for further debug passes. */
- return 1;
-}
-
-static RenderPass *render_layer_add_debug_pass(RenderResult *rr,
- RenderLayer *rl,
- int pass_type,
- int debug_type,
- const char *view)
-{
- const char *name = RE_debug_pass_name_get(debug_type);
- int channels = RE_debug_pass_num_channels_get(debug_type);
- RenderPass *rpass = render_layer_add_pass(rr, rl, channels, pass_type, view);
- if (rpass == NULL) {
- return NULL;
- }
- rpass->debug_type = debug_type;
- BLI_strncpy(rpass->name,
- name,
- sizeof(rpass->name));
- BLI_strncpy(rpass->internal_name, rpass->name, sizeof(rpass->internal_name));
- return rpass;
-}
-
-int RE_debug_pass_type_get(Render *re)
+RenderPass *gp_add_pass(RenderResult *rr, RenderLayer *rl, int channels, const char *name, const char *viewname)
{
- return re->r.debug_pass_type;
+ return render_layer_add_pass(rr, rl, channels, name, viewname, "RGBA");
}
-#endif
/* called by main render as well for parts */
/* will read info from Render *re to define layers */
@@ -683,89 +344,77 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
if (rr->do_exr_tile)
IMB_exr_add_view(rl->exrhandle, view);
-#define RENDER_LAYER_ADD_PASS_SAFE(rr, rl, channels, passtype, viewname) \
+#define RENDER_LAYER_ADD_PASS_SAFE(rr, rl, channels, name, viewname, chan_id) \
do { \
- if (render_layer_add_pass(rr, rl, channels, passtype, viewname) == NULL) { \
+ if (render_layer_add_pass(rr, rl, channels, name, viewname, chan_id) == NULL) { \
render_result_free(rr); \
return NULL; \
} \
} while (false)
/* a renderlayer should always have a Combined pass*/
- render_layer_add_pass(rr, rl, 4, SCE_PASS_COMBINED, view);
+ render_layer_add_pass(rr, rl, 4, "Combined", view, "RGBA");
if (srl->passflag & SCE_PASS_Z)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, SCE_PASS_Z, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_Z, view, "Z");
if (srl->passflag & SCE_PASS_VECTOR)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, SCE_PASS_VECTOR, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, RE_PASSNAME_VECTOR, view, "XYZW");
if (srl->passflag & SCE_PASS_NORMAL)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_NORMAL, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_NORMAL, view, "XYZ");
if (srl->passflag & SCE_PASS_UV)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_UV, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_UV, view, "UVA");
if (srl->passflag & SCE_PASS_RGBA)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, SCE_PASS_RGBA, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, RE_PASSNAME_RGBA, view, "RGBA");
if (srl->passflag & SCE_PASS_EMIT)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_EMIT, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_EMIT, view, "RGB");
if (srl->passflag & SCE_PASS_DIFFUSE)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_DIFFUSE, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE, view, "RGB");
if (srl->passflag & SCE_PASS_SPEC)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SPEC, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SPEC, view, "RGB");
if (srl->passflag & SCE_PASS_AO)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_AO, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_AO, view, "RGB");
if (srl->passflag & SCE_PASS_ENVIRONMENT)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_ENVIRONMENT, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_ENVIRONMENT, view, "RGB");
if (srl->passflag & SCE_PASS_INDIRECT)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_INDIRECT, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_INDIRECT, view, "RGB");
if (srl->passflag & SCE_PASS_SHADOW)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SHADOW, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SHADOW, view, "RGB");
if (srl->passflag & SCE_PASS_REFLECT)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_REFLECT, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_REFLECT, view, "RGB");
if (srl->passflag & SCE_PASS_REFRACT)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_REFRACT, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_REFRACT, view, "RGB");
if (srl->passflag & SCE_PASS_INDEXOB)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, SCE_PASS_INDEXOB, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_INDEXOB, view, "X");
if (srl->passflag & SCE_PASS_INDEXMA)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, SCE_PASS_INDEXMA, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_INDEXMA, view, "X");
if (srl->passflag & SCE_PASS_MIST)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, SCE_PASS_MIST, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 1, RE_PASSNAME_MIST, view, "Z");
if (rl->passflag & SCE_PASS_RAYHITS)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, SCE_PASS_RAYHITS, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 4, RE_PASSNAME_RAYHITS, view, "RGB");
if (srl->passflag & SCE_PASS_DIFFUSE_DIRECT)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_DIFFUSE_DIRECT, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_DIRECT, view, "RGB");
if (srl->passflag & SCE_PASS_DIFFUSE_INDIRECT)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_DIFFUSE_INDIRECT, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_INDIRECT, view, "RGB");
if (srl->passflag & SCE_PASS_DIFFUSE_COLOR)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_DIFFUSE_COLOR, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_DIFFUSE_COLOR, view, "RGB");
if (srl->passflag & SCE_PASS_GLOSSY_DIRECT)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_GLOSSY_DIRECT, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_DIRECT, view, "RGB");
if (srl->passflag & SCE_PASS_GLOSSY_INDIRECT)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_GLOSSY_INDIRECT, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_INDIRECT, view, "RGB");
if (srl->passflag & SCE_PASS_GLOSSY_COLOR)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_GLOSSY_COLOR, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_GLOSSY_COLOR, view, "RGB");
if (srl->passflag & SCE_PASS_TRANSM_DIRECT)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_TRANSM_DIRECT, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_DIRECT, view, "RGB");
if (srl->passflag & SCE_PASS_TRANSM_INDIRECT)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_TRANSM_INDIRECT, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_INDIRECT, view, "RGB");
if (srl->passflag & SCE_PASS_TRANSM_COLOR)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_TRANSM_COLOR, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_TRANSM_COLOR, view, "RGB");
if (srl->passflag & SCE_PASS_SUBSURFACE_DIRECT)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SUBSURFACE_DIRECT, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_DIRECT, view, "RGB");
if (srl->passflag & SCE_PASS_SUBSURFACE_INDIRECT)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SUBSURFACE_INDIRECT, view);
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_INDIRECT, view, "RGB");
if (srl->passflag & SCE_PASS_SUBSURFACE_COLOR)
- RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, SCE_PASS_SUBSURFACE_COLOR, view);
-
-#ifdef WITH_CYCLES_DEBUG
- if (BKE_scene_use_new_shading_nodes(re->scene)) {
- if (render_layer_add_debug_pass(rr, rl, SCE_PASS_DEBUG,
- re->r.debug_pass_type, view) == NULL)
- {
- render_result_free(rr);
- return NULL;
- }
- }
-#endif
-
+ RENDER_LAYER_ADD_PASS_SAFE(rr, rl, 3, RE_PASSNAME_SUBSURFACE_COLOR, view, "RGB");
#undef RENDER_LAYER_ADD_PASS_SAFE
}
}
@@ -794,7 +443,7 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
IMB_exr_add_view(rl->exrhandle, view);
/* a renderlayer should always have a Combined pass */
- render_layer_add_pass(rr, rl, 4, SCE_PASS_COMBINED, view);
+ render_layer_add_pass(rr, rl, 4, RE_PASSNAME_COMBINED, view, "RGBA");
}
/* note, this has to be in sync with scene.c */
@@ -813,6 +462,60 @@ RenderResult *render_result_new(Render *re, rcti *partrct, int crop, int savebuf
return rr;
}
+void render_result_clone_passes(Render *re, RenderResult *rr, const char *viewname)
+{
+ RenderLayer *rl;
+ RenderPass *main_rp;
+
+ for (rl = rr->layers.first; rl; rl = rl->next) {
+ RenderLayer *main_rl = BLI_findstring(&re->result->layers, rl->name, offsetof(RenderLayer, name));
+ if (!main_rl) {
+ continue;
+ }
+
+ for (main_rp = main_rl->passes.first; main_rp; main_rp = main_rp->next) {
+ if (viewname && viewname[0] && !STREQ(main_rp->view, viewname)) {
+ continue;
+ }
+
+ /* Compare fullname to make sure that the view also is equal. */
+ RenderPass *rp = BLI_findstring(&rl->passes, main_rp->fullname, offsetof(RenderPass, fullname));
+ if (!rp) {
+ render_layer_add_pass(rr, rl, main_rp->channels, main_rp->name, main_rp->view, main_rp->chan_id);
+ }
+ }
+ }
+}
+
+void render_result_add_pass(RenderResult *rr, const char *name, int channels, const char *chan_id, const char *layername, const char *viewname)
+{
+ RenderLayer *rl;
+ RenderPass *rp;
+ RenderView *rv;
+
+ for (rl = rr->layers.first; rl; rl = rl->next) {
+ if (layername && layername[0] && !STREQ(rl->name, layername)) {
+ continue;
+ }
+
+ for (rv = rr->views.first; rv; rv = rv->next) {
+ const char *view = rv->name;
+
+ if (viewname && viewname[0] && !STREQ(view, viewname)) continue;
+
+ /* Ensure that the pass doesn't exist yet. */
+ for (rp = rl->passes.first; rp; rp = rp->next) {
+ if (!STREQ(rp->name, name)) continue;
+ if (!STREQ(rp->view, view)) continue;
+ }
+
+ if (!rp) {
+ render_layer_add_pass(rr, rl, channels, name, view, chan_id);
+ }
+ }
+ }
+}
+
/* allocate osa new results for samples */
RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *partrct, int crop, int savebuffers, const char *viewname)
{
@@ -830,6 +533,50 @@ RenderResult *render_result_new_full_sample(Render *re, ListBase *lb, rcti *part
return lb->first;
}
+static int passtype_from_name(const char *name)
+{
+ const char delim[] = {'.', '\0'};
+ const char *sep, *suf;
+ int len = BLI_str_partition(name, delim, &sep, &suf);
+
+#define CHECK_PASS(NAME) if (STREQLEN(name, RE_PASSNAME_ ## NAME, len)) return SCE_PASS_ ## NAME
+
+ CHECK_PASS(COMBINED);
+ CHECK_PASS(Z);
+ CHECK_PASS(VECTOR);
+ CHECK_PASS(NORMAL);
+ CHECK_PASS(UV);
+ CHECK_PASS(RGBA);
+ CHECK_PASS(EMIT);
+ CHECK_PASS(DIFFUSE);
+ CHECK_PASS(SPEC);
+ CHECK_PASS(SHADOW);
+ CHECK_PASS(AO);
+ CHECK_PASS(ENVIRONMENT);
+ CHECK_PASS(INDIRECT);
+ CHECK_PASS(REFLECT);
+ CHECK_PASS(REFRACT);
+ CHECK_PASS(INDEXOB);
+ CHECK_PASS(INDEXMA);
+ CHECK_PASS(MIST);
+ CHECK_PASS(RAYHITS);
+ CHECK_PASS(DIFFUSE_DIRECT);
+ CHECK_PASS(DIFFUSE_INDIRECT);
+ CHECK_PASS(DIFFUSE_COLOR);
+ CHECK_PASS(GLOSSY_DIRECT);
+ CHECK_PASS(GLOSSY_INDIRECT);
+ CHECK_PASS(GLOSSY_COLOR);
+ CHECK_PASS(TRANSM_DIRECT);
+ CHECK_PASS(TRANSM_INDIRECT);
+ CHECK_PASS(TRANSM_COLOR);
+ CHECK_PASS(SUBSURFACE_DIRECT);
+ CHECK_PASS(SUBSURFACE_INDIRECT);
+ CHECK_PASS(SUBSURFACE_COLOR);
+
+#undef CHECK_PASS
+ return 0;
+}
+
/* callbacks for render_result_new_from_exr */
static void *ml_addlayer_cb(void *base, const char *str)
{
@@ -843,36 +590,30 @@ static void *ml_addlayer_cb(void *base, const char *str)
return rl;
}
-static void ml_addpass_cb(void *base, void *lay, const char *str, float *rect, int totchan, const char *chan_id, const char *view)
+static void ml_addpass_cb(void *base, void *lay, const char *name, float *rect, int totchan, const char *chan_id, const char *view)
{
RenderResult *rr = base;
RenderLayer *rl = lay;
RenderPass *rpass = MEM_callocN(sizeof(RenderPass), "loaded pass");
- int a;
-
+
BLI_addtail(&rl->passes, rpass);
rpass->channels = totchan;
- rpass->passtype = passtype_from_name(str, rl->passflag);
- if (rpass->passtype == 0)
- printf("unknown pass %s\n", str);
- rl->passflag |= rpass->passtype;
-
+ rl->passflag |= passtype_from_name(name);
+
/* channel id chars */
- for (a = 0; a < totchan; a++)
- rpass->chan_id[a] = chan_id[a];
+ BLI_strncpy(rpass->chan_id, chan_id, sizeof(rpass->chan_id));
rpass->rect = rect;
+ BLI_strncpy(rpass->name, name, EXR_PASS_MAXNAME);
+ BLI_strncpy(rpass->view, view, sizeof(rpass->view));
+ set_pass_full_name(rpass->fullname, name, -1, view, rpass->chan_id);
+
if (view[0] != '\0') {
- BLI_snprintf(rpass->name, sizeof(rpass->name), "%s.%s", str, view);
rpass->view_id = BLI_findstringindex(&rr->views, view, offsetof(RenderView, name));
}
else {
- BLI_strncpy(rpass->name, str, sizeof(rpass->name));
rpass->view_id = 0;
}
-
- BLI_strncpy(rpass->view, view, sizeof(rpass->view));
- BLI_strncpy(rpass->internal_name, str, sizeof(rpass->internal_name));
}
static void *ml_addview_cb(void *base, const char *str)
@@ -912,12 +653,30 @@ static int order_render_passes(const void *a, const void *b)
// 1 if a is after b
RenderPass *rpa = (RenderPass *) a;
RenderPass *rpb = (RenderPass *) b;
+ unsigned int passtype_a = passtype_from_name(rpa->name);
+ unsigned int passtype_b = passtype_from_name(rpb->name);
- if (rpa->passtype > rpb->passtype)
+ /* Render passes with default type always go first. */
+ if (passtype_b && !passtype_a)
return 1;
- else if (rpa->passtype < rpb->passtype)
+ if (passtype_a && !passtype_b)
return 0;
+ if (passtype_a && passtype_b) {
+ if (passtype_a > passtype_b)
+ return 1;
+ else if (passtype_a < passtype_b)
+ return 0;
+ }
+ else {
+ int cmp = strncmp(rpa->name, rpb->name, EXR_PASS_MAXNAME);
+ if (cmp > 0)
+ return 1;
+ if (cmp < 0)
+ return 0;
+ }
+
+
/* they have the same type */
/* left first */
if (STREQ(rpa->view, STEREO_LEFT_NAME))
@@ -1049,7 +808,7 @@ void render_result_merge(RenderResult *rr, RenderResult *rrpart)
rpass = rpass->next)
{
/* renderresult have all passes, renderpart only the active view's passes */
- if (strcmp(rpassp->name, rpass->name) != 0)
+ if (strcmp(rpassp->fullname, rpass->fullname) != 0)
continue;
do_merge_tile(rr, rrpart, rpass->rect, rpassp->rect, rpass->channels);
@@ -1061,21 +820,6 @@ void render_result_merge(RenderResult *rr, RenderResult *rrpart)
}
}
-/* for passes read from files, these have names stored */
-static char *make_pass_name(RenderPass *rpass, int chan)
-{
- static char name[EXR_PASS_MAXNAME];
- int len;
-
- BLI_strncpy(name, rpass->name, EXR_PASS_MAXNAME);
- len = strlen(name);
- name[len] = '.';
- name[len + 1] = rpass->chan_id[chan];
- name[len + 2] = 0;
-
- return name;
-}
-
/* called from within UI and render pipeline, saves both rendered result as a file-read result
* if multiview is true saves all views in a multiview exr
* else if view is not NULL saves single view
@@ -1136,8 +880,10 @@ bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *fil
IMB_exr_add_view(exrhandle, rview->name);
if (rview->rectf) {
+ char passname[EXR_PASS_MAXNAME];
for (a = 0; a < 4; a++) {
- IMB_exr_add_channel(exrhandle, "Composite", name_from_passtype(SCE_PASS_COMBINED, a),
+ set_pass_name(passname, RE_PASSNAME_COMBINED, a, "RGBA");
+ IMB_exr_add_channel(exrhandle, RE_PASSNAME_COMBINED, passname,
chan_view, 4, 4 * width, rview->rectf + a,
use_half_float);
}
@@ -1150,6 +896,7 @@ bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *fil
/* passes are allocated in sync */
for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
const int xstride = rpass->channels;
+ char passname[EXR_PASS_MAXNAME];
if (is_mono) {
if (!STREQ(view, rpass->view)) {
@@ -1163,16 +910,10 @@ bool RE_WriteRenderResult(ReportList *reports, RenderResult *rr, const char *fil
}
for (a = 0; a < xstride; a++) {
- if (rpass->passtype) {
- IMB_exr_add_channel(exrhandle, rl->name, name_from_passtype(rpass->passtype, a), chan_view,
- xstride, xstride * width, rpass->rect + a,
- rpass->passtype == SCE_PASS_Z ? false : use_half_float);
- }
- else {
- IMB_exr_add_channel(exrhandle, rl->name, make_pass_name(rpass, a), chan_view,
- xstride, xstride * width, rpass->rect + a,
- use_half_float);
- }
+ set_pass_name(passname, rpass->name, a, rpass->chan_id);
+ IMB_exr_add_channel(exrhandle, rl->name, passname, chan_view,
+ xstride, xstride * width, rpass->rect + a,
+ STREQ(rpass->name, RE_PASSNAME_Z) ? false : use_half_float);
}
}
}
@@ -1281,12 +1022,12 @@ static void save_render_result_tile(RenderResult *rr, RenderResult *rrpart, cons
for (rpassp = rlp->passes.first; rpassp; rpassp = rpassp->next) {
const int xstride = rpassp->channels;
int a;
- char passname[EXR_PASS_MAXNAME];
+ char fullname[EXR_PASS_MAXNAME];
for (a = 0; a < xstride; a++) {
- set_pass_name(passname, rpassp->passtype, a, rpassp->view);
+ set_pass_full_name(fullname, rpassp->name, a, viewname, rpassp->chan_id);
- IMB_exr_set_channel(rl->exrhandle, rlp->name, passname,
+ IMB_exr_set_channel(rl->exrhandle, rlp->name, fullname,
xstride, xstride * rrpart->rectx, rpassp->rect + a + xstride * offs);
}
}
@@ -1449,15 +1190,15 @@ int render_result_exr_file_read_path(RenderResult *rr, RenderLayer *rl_single, c
for (rpass = rl->passes.first; rpass; rpass = rpass->next) {
const int xstride = rpass->channels;
int a;
- char passname[EXR_PASS_MAXNAME];
+ char fullname[EXR_PASS_MAXNAME];
for (a = 0; a < xstride; a++) {
- set_pass_name(passname, rpass->passtype, a, rpass->view);
- IMB_exr_set_channel(exrhandle, rl->name, passname,
+ set_pass_full_name(fullname, rpass->name, a, rpass->view, rpass->chan_id);
+ IMB_exr_set_channel(exrhandle, rl->name, fullname,
xstride, xstride * rectx, rpass->rect + a);
}
- set_pass_name(rpass->name, rpass->passtype, -1, rpass->view);
+ set_pass_full_name(rpass->fullname, rpass->name, -1, rpass->view, rpass->chan_id);
}
}
diff --git a/source/blender/render/intern/source/render_texture.c b/source/blender/render/intern/source/render_texture.c
index 42e4d4f27f6..22dc2b28900 100644
--- a/source/blender/render/intern/source/render_texture.c
+++ b/source/blender/render/intern/source/render_texture.c
@@ -1495,6 +1495,7 @@ void texture_rgb_blend(float in[3], const float tex[3], const float out[3], floa
case MTEX_SUB:
fact= -fact;
+ ATTR_FALLTHROUGH;
case MTEX_ADD:
fact*= facg;
in[0]= (fact*tex[0] + out[0]);
@@ -1609,6 +1610,7 @@ float texture_value_blend(float tex, float out, float fact, float facg, int blen
case MTEX_SUB:
fact= -fact;
+ ATTR_FALLTHROUGH;
case MTEX_ADD:
in= fact*tex + out;
break;
diff --git a/source/blender/render/intern/source/rendercore.c b/source/blender/render/intern/source/rendercore.c
index 910ea16607e..77f399d08d1 100644
--- a/source/blender/render/intern/source/rendercore.c
+++ b/source/blender/render/intern/source/rendercore.c
@@ -180,11 +180,12 @@ static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, in
flarec= 0;
if (fullsample) {
- for (sample=0; sample<totsample; sample++)
+ for (sample=0; sample<totsample; sample++) {
if (ps->mask & (1 << sample)) {
- float *pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+ float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
addalphaAddfacFloat(pass + od*4, col, har->add);
}
+ }
}
else {
fac= ((float)amountm)/(float)R.osa;
@@ -215,11 +216,12 @@ static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, in
}
if (fullsample) {
- for (sample=0; sample<totsample; sample++)
+ for (sample=0; sample<totsample; sample++) {
if (!(mask & (1 << sample))) {
- float *pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+ float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
addalphaAddfacFloat(pass + od*4, col, har->add);
}
+ }
}
else {
col[0]= accol[0];
@@ -228,7 +230,7 @@ static void halo_pixelstruct(HaloRen *har, RenderLayer **rlpp, int totsample, in
col[3]= accol[3];
for (sample=0; sample<totsample; sample++) {
- float *pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+ float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
addalphaAddfacFloat(pass + od*4, col, har->add);
}
}
@@ -312,7 +314,7 @@ static void halo_tile(RenderPart *pa, RenderLayer *rl)
if ((zz> har->zs) || (har->mat && (har->mat->mode & MA_HALO_SOFT))) {
if (shadeHaloFloat(har, col, zz, dist, xn, yn, har->flarec)) {
for (sample=0; sample<totsample; sample++) {
- float * rect= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+ float * rect= RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
addalphaAddfacFloat(rect + od*4, col, har->add);
}
}
@@ -367,7 +369,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
if (fullsample) {
for (sample=0; sample<totsample; sample++) {
if (ps->mask & (1 << sample)) {
- pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+ pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
pass += od * 4;
pass[0]+= col[0];
pass[1]+= col[1];
@@ -379,7 +381,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
}
else {
fac= ((float)count)/(float)R.osa;
- pass = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname);
+ pass = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
pass += od * 4;
pass[0]+= fac*col[0];
pass[1]+= fac*col[1];
@@ -401,7 +403,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
for (sample=0; sample<totsample; sample++) {
if (!(mask & (1 << sample))) {
- pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+ pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
pass += od * 4;
pass[0]+= col[0];
pass[1]+= col[1];
@@ -413,7 +415,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
}
else {
fac= ((float)R.osa-totsamp)/(float)R.osa;
- pass = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname);
+ pass = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
pass += od * 4;
pass[0]+= fac*col[0];
pass[1]+= fac*col[1];
@@ -433,7 +435,7 @@ static void lamphalo_tile(RenderPart *pa, RenderLayer *rl)
renderspothalo(&shi, col, 1.0f);
for (sample=0; sample<totsample; sample++) {
- pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+ pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
pass += od * 4;
pass[0]+= col[0];
pass[1]+= col[1];
@@ -462,101 +464,96 @@ static void add_filt_passes(RenderLayer *rl, int curmask, int rectx, int offset,
float *fp, *col= NULL;
int pixsize= 3;
- switch (rpass->passtype) {
- case SCE_PASS_COMBINED:
- add_filt_fmask(curmask, shr->combined, rpass->rect + 4*offset, rectx);
- break;
- case SCE_PASS_Z:
- fp= rpass->rect + offset;
- *fp= shr->z;
- break;
- case SCE_PASS_RGBA:
- col= shr->col;
- pixsize= 4;
- break;
- case SCE_PASS_EMIT:
- col= shr->emit;
- break;
- case SCE_PASS_DIFFUSE:
- col= shr->diff;
- break;
- case SCE_PASS_SPEC:
- col= shr->spec;
- break;
- case SCE_PASS_SHADOW:
- col= shr->shad;
- break;
- case SCE_PASS_AO:
- col= shr->ao;
- break;
- case SCE_PASS_ENVIRONMENT:
- col= shr->env;
- break;
- case SCE_PASS_INDIRECT:
- col= shr->indirect;
- break;
- case SCE_PASS_REFLECT:
- col= shr->refl;
- break;
- case SCE_PASS_REFRACT:
- col= shr->refr;
- break;
- case SCE_PASS_NORMAL:
- col= shr->nor;
- break;
- case SCE_PASS_UV:
- /* box filter only, gauss will screwup UV too much */
- if (shi->totuv) {
- float mult= (float)count_mask(curmask)/(float)R.osa;
- fp= rpass->rect + 3*offset;
- fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]);
- fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]);
- fp[2]+= mult;
- }
- break;
- case SCE_PASS_INDEXOB:
- /* no filter */
- if (shi->vlr) {
- fp= rpass->rect + offset;
+ if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) {
+ add_filt_fmask(curmask, shr->combined, rpass->rect + 4*offset, rectx);
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_Z)) {
+ fp = rpass->rect + offset;
+ *fp = shr->z;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_RGBA)) {
+ col = shr->col;
+ pixsize = 4;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) {
+ col = shr->emit;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) {
+ col = shr->diff;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) {
+ col = shr->spec;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) {
+ col = shr->shad;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_AO)) {
+ col = shr->ao;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) {
+ col = shr->env;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) {
+ col = shr->indirect;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) {
+ col = shr->refl;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) {
+ col = shr->refr;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) {
+ col = shr->nor;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_UV)) {
+ /* box filter only, gauss will screwup UV too much */
+ if (shi->totuv) {
+ float mult = (float)count_mask(curmask)/(float)R.osa;
+ fp = rpass->rect + 3*offset;
+ fp[0]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[0]);
+ fp[1]+= mult*(0.5f + 0.5f*shi->uv[shi->actuv].uv[1]);
+ fp[2]+= mult;
+ }
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_INDEXOB)) {
+ /* no filter */
+ if (shi->vlr) {
+ fp = rpass->rect + offset;
+ if (*fp==0.0f)
+ *fp = (float)shi->obr->ob->index;
+ }
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_INDEXMA)) {
+ /* no filter */
+ if (shi->vlr) {
+ fp = rpass->rect + offset;
if (*fp==0.0f)
- *fp= (float)shi->obr->ob->index;
- }
- break;
- case SCE_PASS_INDEXMA:
- /* no filter */
- if (shi->vlr) {
- fp= rpass->rect + offset;
- if (*fp==0.0f)
- *fp= (float)shi->mat->index;
- }
- break;
- case SCE_PASS_MIST:
- /* */
- col= &shr->mist;
- pixsize= 1;
- break;
-
- case SCE_PASS_VECTOR:
- {
- /* add minimum speed in pixel, no filter */
- fp= rpass->rect + 4*offset;
- if ( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
- fp[0]= shr->winspeed[0];
- fp[1]= shr->winspeed[1];
- }
- if ( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
- fp[2]= shr->winspeed[2];
- fp[3]= shr->winspeed[3];
- }
-
- break;
+ *fp = (float)shi->mat->index;
+ }
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_MIST)) {
+ /* */
+ col = &shr->mist;
+ pixsize = 1;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
+ /* add minimum speed in pixel, no filter */
+ fp = rpass->rect + 4*offset;
+ if ( (ABS(shr->winspeed[0]) + ABS(shr->winspeed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
+ fp[0] = shr->winspeed[0];
+ fp[1] = shr->winspeed[1];
+ }
+ if ( (ABS(shr->winspeed[2]) + ABS(shr->winspeed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
+ fp[2] = shr->winspeed[2];
+ fp[3] = shr->winspeed[3];
}
- case SCE_PASS_RAYHITS:
- /* */
- col= shr->rayhits;
- pixsize= 4;
- break;
}
+ else if (STREQ(rpass->name, RE_PASSNAME_RAYHITS)) {
+ /* */
+ col = shr->rayhits;
+ pixsize= 4;
+ }
+
if (col) {
fp= rpass->rect + pixsize*offset;
add_filt_fmask_pixsize(curmask, col, fp, rectx, pixsize);
@@ -574,86 +571,85 @@ static void add_passes(RenderLayer *rl, int offset, ShadeInput *shi, ShadeResult
float *col= NULL, uvcol[3];
int a, pixsize= 3;
- switch (rpass->passtype) {
- case SCE_PASS_COMBINED:
- /* copy combined to use for preview */
- copy_v4_v4(rpass->rect + 4*offset, shr->combined);
- break;
- case SCE_PASS_Z:
- fp= rpass->rect + offset;
- *fp= shr->z;
- break;
- case SCE_PASS_RGBA:
- col= shr->col;
- pixsize= 4;
- break;
- case SCE_PASS_EMIT:
- col= shr->emit;
- break;
- case SCE_PASS_DIFFUSE:
- col= shr->diff;
- break;
- case SCE_PASS_SPEC:
- col= shr->spec;
- break;
- case SCE_PASS_SHADOW:
- col= shr->shad;
- break;
- case SCE_PASS_AO:
- col= shr->ao;
- break;
- case SCE_PASS_ENVIRONMENT:
- col= shr->env;
- break;
- case SCE_PASS_INDIRECT:
- col= shr->indirect;
- break;
- case SCE_PASS_REFLECT:
- col= shr->refl;
- break;
- case SCE_PASS_REFRACT:
- col= shr->refr;
- break;
- case SCE_PASS_NORMAL:
- col= shr->nor;
- break;
- case SCE_PASS_UV:
- if (shi->totuv) {
- uvcol[0]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[0];
- uvcol[1]= 0.5f + 0.5f*shi->uv[shi->actuv].uv[1];
- uvcol[2]= 1.0f;
- col= uvcol;
- }
- break;
- case SCE_PASS_VECTOR:
- col= shr->winspeed;
- pixsize= 4;
- break;
- case SCE_PASS_INDEXOB:
- if (shi->vlr) {
- fp= rpass->rect + offset;
- *fp= (float)shi->obr->ob->index;
- }
- break;
- case SCE_PASS_INDEXMA:
- if (shi->vlr) {
- fp= rpass->rect + offset;
- *fp= (float)shi->mat->index;
- }
- break;
- case SCE_PASS_MIST:
- fp= rpass->rect + offset;
- *fp= shr->mist;
- break;
- case SCE_PASS_RAYHITS:
- col= shr->rayhits;
- pixsize= 4;
- break;
+ if (STREQ(rpass->name, RE_PASSNAME_COMBINED)) {
+ /* copy combined to use for preview */
+ copy_v4_v4(rpass->rect + 4*offset, shr->combined);
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_Z)) {
+ fp = rpass->rect + offset;
+ *fp = shr->z;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_RGBA)) {
+ col = shr->col;
+ pixsize = 4;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) {
+ col = shr->emit;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) {
+ col = shr->diff;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) {
+ col = shr->spec;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) {
+ col = shr->shad;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_AO)) {
+ col = shr->ao;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) {
+ col = shr->env;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) {
+ col = shr->indirect;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) {
+ col = shr->refl;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) {
+ col = shr->refr;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) {
+ col = shr->nor;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_UV)) {
+ if (shi->totuv) {
+ uvcol[0] = 0.5f + 0.5f*shi->uv[shi->actuv].uv[0];
+ uvcol[1] = 0.5f + 0.5f*shi->uv[shi->actuv].uv[1];
+ uvcol[2] = 1.0f;
+ col = uvcol;
+ }
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
+ col = shr->winspeed;
+ pixsize = 4;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_INDEXOB)) {
+ if (shi->vlr) {
+ fp = rpass->rect + offset;
+ *fp = (float)shi->obr->ob->index;
+ }
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_INDEXMA)) {
+ if (shi->vlr) {
+ fp = rpass->rect + offset;
+ *fp = (float)shi->mat->index;
+ }
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_MIST)) {
+ fp = rpass->rect + offset;
+ *fp = shr->mist;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_RAYHITS)) {
+ col = shr->rayhits;
+ pixsize = 4;
}
+
if (col) {
- fp= rpass->rect + pixsize*offset;
+ fp = rpass->rect + pixsize*offset;
for (a=0; a<pixsize; a++)
- fp[a]= col[a];
+ fp[a] = col[a];
}
}
}
@@ -696,7 +692,7 @@ static void sky_tile(RenderPart *pa, RenderLayer *rl)
bool done = false;
for (sample= 0; sample<totsample; sample++) {
- float *pass = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+ float *pass = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
pass += od;
if (pass[3]<1.0f) {
@@ -737,7 +733,7 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
/* check that z pass is enabled */
if (pa->rectz==NULL) return;
for (zpass= rl->passes.first; zpass; zpass= zpass->next)
- if (zpass->passtype==SCE_PASS_Z)
+ if (STREQ(zpass->name, RE_PASSNAME_Z))
break;
if (zpass==NULL) return;
@@ -758,8 +754,8 @@ static void atm_tile(RenderPart *pa, RenderLayer *rl)
int sample;
for (sample=0; sample<totsample; sample++) {
- const float *zrect = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_Z, R.viewname) + od;
- float *rgbrect = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname) + 4*od;
+ const float *zrect = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_Z, R.viewname) + od;
+ float *rgbrect = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname) + 4*od;
float rgb[3] = {0};
bool done = false;
@@ -994,7 +990,7 @@ static void clamp_alpha_rgb_range(RenderPart *pa, RenderLayer *rl)
return;
for (sample= 0; sample<totsample; sample++) {
- float *rectf = RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_COMBINED, R.viewname);
+ float *rectf = RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_COMBINED, R.viewname);
for (y= pa->rectx*pa->recty; y>0; y--, rectf+=4) {
rectf[0] = MAX2(rectf[0], 0.0f);
@@ -1076,7 +1072,7 @@ static void reset_sky_speed(RenderPart *pa, RenderLayer *rl)
totsample= get_sample_layers(pa, rl, rlpp);
for (sample= 0; sample<totsample; sample++) {
- fp= RE_RenderLayerGetPass(rlpp[sample], SCE_PASS_VECTOR, R.viewname);
+ fp= RE_RenderLayerGetPass(rlpp[sample], RE_PASSNAME_VECTOR, R.viewname);
if (fp==NULL) break;
for (a= 4*pa->rectx*pa->recty - 1; a>=0; a--)
@@ -1187,7 +1183,7 @@ void zbufshadeDA_tile(RenderPart *pa)
pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp");
pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
for (rl= rr->layers.first; rl; rl= rl->next) {
- float *rect = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname);
+ float *rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
if ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
@@ -1339,7 +1335,7 @@ void zbufshade_tile(RenderPart *pa)
pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz");
for (rl= rr->layers.first; rl; rl= rl->next) {
- float *rect= RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname);
+ float *rect= RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
if ((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK))
pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask");
@@ -1676,7 +1672,7 @@ void zbufshade_sss_tile(RenderPart *pa)
return;
}
- fcol= RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname);
+ fcol= RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
co= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSCo");
color= MEM_mallocN(sizeof(float)*3*handle.totps, "SSSColor");
@@ -1969,7 +1965,7 @@ void add_halo_flare(Render *re)
if ((rl->layflag & SCE_LAY_HALO) == 0)
continue;
- rect = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, re->viewname);
+ rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, re->viewname);
if (rect==NULL)
continue;
@@ -1998,3 +1994,37 @@ void add_halo_flare(Render *re)
}
}
+void render_internal_update_passes(RenderEngine *engine, Scene *scene, SceneRenderLayer *srl)
+{
+ int type;
+
+ RE_engine_register_pass(engine, scene, srl, RE_PASSNAME_COMBINED, 4, "RGBA", SOCK_RGBA);
+
+#define CHECK_PASS(name, channels, chanid) \
+ if (srl->passflag & (SCE_PASS_ ## name)) { \
+ if (channels == 4) type = SOCK_RGBA; \
+ else if (channels == 3) type = SOCK_VECTOR; \
+ else type = SOCK_FLOAT; \
+ RE_engine_register_pass(engine, scene, srl, RE_PASSNAME_ ## name, channels, chanid, type); \
+ }
+
+ CHECK_PASS(Z, 1, "Z");
+ CHECK_PASS(VECTOR, 4, "XYZW");
+ CHECK_PASS(NORMAL, 3, "XYZ");
+ CHECK_PASS(UV, 3, "UVA");
+ CHECK_PASS(RGBA, 4, "RGBA");
+ CHECK_PASS(EMIT, 3, "RGB");
+ CHECK_PASS(DIFFUSE, 3, "RGB");
+ CHECK_PASS(SPEC, 3, "RGB");
+ CHECK_PASS(AO, 3, "RGB");
+ CHECK_PASS(ENVIRONMENT, 3, "RGB");
+ CHECK_PASS(INDIRECT, 3, "RGB");
+ CHECK_PASS(SHADOW, 3, "RGB");
+ CHECK_PASS(REFLECT, 3, "RGB");
+ CHECK_PASS(REFRACT, 3, "RGB");
+ CHECK_PASS(INDEXOB, 1, "X");
+ CHECK_PASS(INDEXMA, 1, "X");
+ CHECK_PASS(MIST, 1, "Z");
+
+#undef CHECK_PASS
+}
diff --git a/source/blender/render/intern/source/renderdatabase.c b/source/blender/render/intern/source/renderdatabase.c
index 76e6ca8d467..199322795f3 100644
--- a/source/blender/render/intern/source/renderdatabase.c
+++ b/source/blender/render/intern/source/renderdatabase.c
@@ -66,6 +66,7 @@
#include "BLI_math.h"
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_hash.h"
#include "DNA_material_types.h"
#include "DNA_meshdata_types.h"
@@ -1458,6 +1459,14 @@ ObjectInstanceRen *RE_addRenderInstance(
}
}
+ /* Fill object info */
+ if (dob) {
+ obi->random_id = dob->random_id;
+ }
+ else {
+ obi->random_id = BLI_hash_int_2d(BLI_hash_string(obi->ob->id.name + 2), 0);
+ }
+
RE_updateRenderInstance(re, obi, RE_OBJECT_INSTANCES_UPDATE_OBMAT | RE_OBJECT_INSTANCES_UPDATE_VIEW);
if (mat) {
diff --git a/source/blender/render/intern/source/shadeoutput.c b/source/blender/render/intern/source/shadeoutput.c
index a8fb72fb7f8..8dea0930b9e 100644
--- a/source/blender/render/intern/source/shadeoutput.c
+++ b/source/blender/render/intern/source/shadeoutput.c
@@ -2141,6 +2141,16 @@ const float (*RE_object_instance_get_matrix(struct ObjectInstanceRen *obi, int m
return NULL;
}
+float RE_object_instance_get_object_pass_index(struct ObjectInstanceRen *obi)
+{
+ return obi->ob->index;
+}
+
+float RE_object_instance_get_random_id(struct ObjectInstanceRen *obi)
+{
+ return obi->random_id;
+}
+
const float (*RE_render_current_get_matrix(int matrix_id))[4]
{
switch (matrix_id) {
diff --git a/source/blender/render/intern/source/sunsky.c b/source/blender/render/intern/source/sunsky.c
index d4e53eb7305..f0cf29e98ca 100644
--- a/source/blender/render/intern/source/sunsky.c
+++ b/source/blender/render/intern/source/sunsky.c
@@ -398,7 +398,7 @@ void InitAtmosphere(struct SunSky *sunSky, float sun_intens, float mief, float r
vLambda2[0] = fLambda2[0];
vLambda2[1] = fLambda2[1];
vLambda2[2] = fLambda2[2];
-
+
vLambda4[0] = fLambda4[0];
vLambda4[1] = fLambda4[1];
vLambda4[2] = fLambda4[2];
diff --git a/source/blender/render/intern/source/volumetric.c b/source/blender/render/intern/source/volumetric.c
index 610e86caa13..7fe52328781 100644
--- a/source/blender/render/intern/source/volumetric.c
+++ b/source/blender/render/intern/source/volumetric.c
@@ -275,10 +275,12 @@ static float metadensity(Object *ob, const float co[3])
break;
case MB_CUBE:
tp[2] = (tp[2] > ml->expz) ? (tp[2] - ml->expz) : ((tp[2] < -ml->expz) ? (tp[2] + ml->expz) : 0.f);
- /* no break, xy as plane */
+ /* no break, xy as plane */
+ ATTR_FALLTHROUGH;
case MB_PLANE:
tp[1] = (tp[1] > ml->expy) ? (tp[1] - ml->expy) : ((tp[1] < -ml->expy) ? (tp[1] + ml->expy) : 0.f);
- /* no break, x as tube */
+ /* no break, x as tube */
+ ATTR_FALLTHROUGH;
case MB_TUBE:
tp[0] = (tp[0] > ml->expx) ? (tp[0] - ml->expx) : ((tp[0] < -ml->expx) ? (tp[0] + ml->expx) : 0.f);
}
diff --git a/source/blender/render/intern/source/zbuf.c b/source/blender/render/intern/source/zbuf.c
index 9f777631e52..68707f163af 100644
--- a/source/blender/render/intern/source/zbuf.c
+++ b/source/blender/render/intern/source/zbuf.c
@@ -1601,7 +1601,6 @@ void zspan_scanconvert(ZSpan *zspan, void *handle, float *v1, float *v2, float *
* Note: uses globals.
* \param v1 start coordinate s
* \param v2 target coordinate t
- * \param b1
* \param b2
* \param b3
* \param a index for coordinate (x, y, or z)
@@ -3494,7 +3493,7 @@ static void add_transp_speed(RenderLayer *rl, int offset, float speed[4], float
RenderPass *rpass;
for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
- if (rpass->passtype==SCE_PASS_VECTOR) {
+ if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
float *fp= rpass->rect + 4*offset;
if (speed==NULL) {
@@ -3528,7 +3527,7 @@ static void add_transp_obindex(RenderLayer *rl, int offset, Object *ob)
RenderPass *rpass;
for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
- if (rpass->passtype == SCE_PASS_INDEXOB) {
+ if (STREQ(rpass->name, RE_PASSNAME_INDEXOB)) {
float *fp= rpass->rect + offset;
*fp= (float)ob->index;
break;
@@ -3541,7 +3540,7 @@ static void add_transp_material_index(RenderLayer *rl, int offset, Material *mat
RenderPass *rpass;
for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
- if (rpass->passtype == SCE_PASS_INDEXMA) {
+ if (STREQ(rpass->name, RE_PASSNAME_INDEXMA)) {
float *fp= rpass->rect + offset;
*fp= (float)mat->index;
break;
@@ -3558,78 +3557,74 @@ static void merge_transp_passes(RenderLayer *rl, ShadeResult *shr)
int delta= sizeof(ShadeResult)/4;
for (rpass= rl->passes.first; rpass; rpass= rpass->next) {
- float *col= NULL;
- int pixsize= 3;
+ float *col = NULL;
+ int pixsize = 3;
- switch (rpass->passtype) {
- case SCE_PASS_RGBA:
- col= shr->col;
- pixsize= 4;
- break;
- case SCE_PASS_EMIT:
- col= shr->emit;
- break;
- case SCE_PASS_DIFFUSE:
- col= shr->diff;
- break;
- case SCE_PASS_SPEC:
- col= shr->spec;
- break;
- case SCE_PASS_SHADOW:
- col= shr->shad;
- break;
- case SCE_PASS_AO:
- col= shr->ao;
- break;
- case SCE_PASS_ENVIRONMENT:
- col= shr->env;
- break;
- case SCE_PASS_INDIRECT:
- col= shr->indirect;
- break;
- case SCE_PASS_REFLECT:
- col= shr->refl;
- break;
- case SCE_PASS_REFRACT:
- col= shr->refr;
- break;
- case SCE_PASS_NORMAL:
- col= shr->nor;
- break;
- case SCE_PASS_MIST:
- col= &shr->mist;
- pixsize= 1;
- break;
- case SCE_PASS_Z:
- col= &shr->z;
- pixsize= 1;
- break;
- case SCE_PASS_VECTOR:
+ if (STREQ(rpass->name, RE_PASSNAME_RGBA)) {
+ col = shr->col;
+ pixsize = 4;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) {
+ col = shr->emit;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) {
+ col = shr->diff;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) {
+ col = shr->spec;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) {
+ col = shr->shad;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_AO)) {
+ col = shr->ao;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) {
+ col = shr->env;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) {
+ col = shr->indirect;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) {
+ col = shr->refl;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) {
+ col = shr->refr;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) {
+ col = shr->nor;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_MIST)) {
+ col = &shr->mist;
+ pixsize = 1;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_Z)) {
+ col = &shr->z;
+ pixsize = 1;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_VECTOR)) {
+ ShadeResult *shr_t = shr+1;
+ float *fp = shr->winspeed; /* was initialized */
+ int samp;
+
+ /* add minimum speed in pixel */
+ for (samp = 1; samp<R.osa; samp++, shr_t++) {
- {
- ShadeResult *shr_t= shr+1;
- float *fp= shr->winspeed; /* was initialized */
- int samp;
+ if (shr_t->combined[3] > 0.0f) {
+ const float *speed = shr_t->winspeed;
- /* add minimum speed in pixel */
- for (samp= 1; samp<R.osa; samp++, shr_t++) {
-
- if (shr_t->combined[3] > 0.0f) {
- const float *speed= shr_t->winspeed;
-
- if ( (ABS(speed[0]) + ABS(speed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
- fp[0]= speed[0];
- fp[1]= speed[1];
- }
- if ( (ABS(speed[2]) + ABS(speed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
- fp[2]= speed[2];
- fp[3]= speed[3];
- }
- }
+ if ( (ABS(speed[0]) + ABS(speed[1]))< (ABS(fp[0]) + ABS(fp[1])) ) {
+ fp[0] = speed[0];
+ fp[1] = speed[1];
+ }
+ if ( (ABS(speed[2]) + ABS(speed[3]))< (ABS(fp[2]) + ABS(fp[3])) ) {
+ fp[2] = speed[2];
+ fp[3] = speed[3];
}
}
- break;
+ }
}
+
if (col) {
const float *fp= col+delta;
int samp;
@@ -3661,53 +3656,51 @@ static void add_transp_passes(RenderLayer *rl, int offset, ShadeResult *shr, flo
float *fp, *col= NULL;
int pixsize= 3;
- switch (rpass->passtype) {
- case SCE_PASS_Z:
- fp= rpass->rect + offset;
- if (shr->z < *fp)
- *fp= shr->z;
- break;
- case SCE_PASS_RGBA:
- fp= rpass->rect + 4*offset;
- addAlphaOverFloat(fp, shr->col);
- break;
- case SCE_PASS_EMIT:
- col= shr->emit;
- break;
- case SCE_PASS_DIFFUSE:
- col= shr->diff;
- break;
- case SCE_PASS_SPEC:
- col= shr->spec;
- break;
- case SCE_PASS_SHADOW:
- col= shr->shad;
- break;
- case SCE_PASS_AO:
- col= shr->ao;
- break;
- case SCE_PASS_ENVIRONMENT:
- col= shr->env;
- break;
- case SCE_PASS_INDIRECT:
- col= shr->indirect;
- break;
- case SCE_PASS_REFLECT:
- col= shr->refl;
- break;
- case SCE_PASS_REFRACT:
- col= shr->refr;
- break;
- case SCE_PASS_NORMAL:
- col= shr->nor;
- break;
- case SCE_PASS_MIST:
- col= &shr->mist;
- pixsize= 1;
- break;
+ if (STREQ(rpass->name, RE_PASSNAME_Z)) {
+ fp = rpass->rect + offset;
+ if (shr->z < *fp)
+ *fp = shr->z;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_RGBA)) {
+ fp = rpass->rect + 4*offset;
+ addAlphaOverFloat(fp, shr->col);
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_EMIT)) {
+ col = shr->emit;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_DIFFUSE)) {
+ col = shr->diff;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_SPEC)) {
+ col = shr->spec;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_SHADOW)) {
+ col = shr->shad;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_AO)) {
+ col = shr->ao;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_ENVIRONMENT)) {
+ col = shr->env;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_INDIRECT)) {
+ col = shr->indirect;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_REFLECT)) {
+ col = shr->refl;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_REFRACT)) {
+ col = shr->refr;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_NORMAL)) {
+ col = shr->nor;
+ }
+ else if (STREQ(rpass->name, RE_PASSNAME_MIST)) {
+ col = &shr->mist;
+ pixsize = 1;
}
- if (col) {
+ if (col) {
fp= rpass->rect + pixsize*offset;
fp[0]= col[0] + (1.0f-alpha)*fp[0];
if (pixsize==3) {
@@ -3964,7 +3957,7 @@ static void reset_sky_speedvectors(RenderPart *pa, RenderLayer *rl, float *rectf
float *fp, *col;
int a;
- fp = RE_RenderLayerGetPass(rl, SCE_PASS_VECTOR, R.viewname);
+ fp = RE_RenderLayerGetPass(rl, RE_PASSNAME_VECTOR, R.viewname);
if (fp==NULL) return;
col= rectf+3;
@@ -4058,7 +4051,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
/* zero alpha pixels get speed vector max again */
if (addpassflag & SCE_PASS_VECTOR)
if (rl->layflag & SCE_LAY_SOLID) {
- float *rect = RE_RenderLayerGetPass(rl, SCE_PASS_COMBINED, R.viewname);
+ float *rect = RE_RenderLayerGetPass(rl, RE_PASSNAME_COMBINED, R.viewname);
reset_sky_speedvectors(pa, rl, rl->acolrect ? rl->acolrect : rect); /* if acolrect is set we use it */
}
/* filtered render, for now we assume only 1 filter size */
@@ -4246,7 +4239,7 @@ unsigned short *zbuffer_transp_shade(RenderPart *pa, RenderLayer *rl, float *pas
if (alpha != 0.0f) {
RenderLayer *rl_other = ssamp.rlpp[a];
- float *rect = RE_RenderLayerGetPass(rl_other , SCE_PASS_COMBINED, R.viewname);
+ float *rect = RE_RenderLayerGetPass(rl_other , RE_PASSNAME_COMBINED, R.viewname);
addAlphaOverFloat(rect + 4 * od, samp_shr[a].combined);
add_transp_passes(rl_other , od, &samp_shr[a], alpha);
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 1cfd20defe0..a91c30c2807 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -102,7 +102,8 @@ enum {
};
struct wmWindow *WM_window_open(struct bContext *C, const struct rcti *rect);
-struct wmWindow *WM_window_open_temp(struct bContext *C, const struct rcti *rect_init, int type);
+struct wmWindow *WM_window_open_temp(struct bContext *C, int x, int y, int sizex, int sizey, int type);
+void WM_window_set_dpi(wmWindow *win);
/* returns true if draw method is triple buffer */
bool WM_is_draw_triple(struct wmWindow *win);
@@ -186,8 +187,9 @@ struct wmEventHandler *WM_event_add_dropbox_handler(ListBase *handlers, ListBase
/* mouse */
void WM_event_add_mousemove(struct bContext *C);
-bool WM_modal_tweak_exit(const struct wmEvent *event, int tweak_event);
+bool WM_event_is_modal_tweak_exit(const struct wmEvent *event, int tweak_event);
bool WM_event_is_absolute(const struct wmEvent *event);
+bool WM_event_is_last_mousemove(const struct wmEvent *event);
#ifdef WITH_INPUT_NDOF
/* 3D mouse */
diff --git a/source/blender/windowmanager/intern/wm.c b/source/blender/windowmanager/intern/wm.c
index 4351cd22b18..67e961b9cd0 100644
--- a/source/blender/windowmanager/intern/wm.c
+++ b/source/blender/windowmanager/intern/wm.c
@@ -483,13 +483,12 @@ void wm_close_and_free(bContext *C, wmWindowManager *wm)
void wm_close_and_free_all(bContext *C, ListBase *wmlist)
{
- Main *bmain = CTX_data_main(C);
wmWindowManager *wm;
-
+
while ((wm = wmlist->first)) {
wm_close_and_free(C, wm);
BLI_remlink(wmlist, wm);
- BKE_libblock_free_data(bmain, &wm->id);
+ BKE_libblock_free_data(&wm->id, true);
MEM_freeN(wm);
}
}
diff --git a/source/blender/windowmanager/intern/wm_draw.c b/source/blender/windowmanager/intern/wm_draw.c
index 77ffa46b990..25c6980f58e 100644
--- a/source/blender/windowmanager/intern/wm_draw.c
+++ b/source/blender/windowmanager/intern/wm_draw.c
@@ -926,15 +926,14 @@ void wm_draw_update(bContext *C)
for (win = wm->windows.first; win; win = win->next) {
#ifdef WIN32
- if (GPU_type_matches(GPU_DEVICE_INTEL, GPU_OS_ANY, GPU_DRIVER_ANY)) {
- GHOST_TWindowState state = GHOST_GetWindowState(win->ghostwin);
-
- if (state == GHOST_kWindowStateMinimized) {
- /* do not update minimized windows, it gives issues on intel drivers (see [#33223])
- * anyway, it seems logical to skip update for invisible windows
- */
- continue;
- }
+ GHOST_TWindowState state = GHOST_GetWindowState(win->ghostwin);
+
+ if (state == GHOST_kWindowStateMinimized) {
+ /* do not update minimized windows, gives issues on Intel (see T33223)
+ * and AMD (see T50856). it seems logical to skip update for invisible
+ * window anyway.
+ */
+ continue;
}
#endif
if (win->drawmethod != U.wmdrawmethod) {
diff --git a/source/blender/windowmanager/intern/wm_event_system.c b/source/blender/windowmanager/intern/wm_event_system.c
index f26ee0e73ec..32f978ae891 100644
--- a/source/blender/windowmanager/intern/wm_event_system.c
+++ b/source/blender/windowmanager/intern/wm_event_system.c
@@ -615,6 +615,16 @@ bool WM_event_is_absolute(const wmEvent *event)
return (event->tablet_data != NULL);
}
+bool WM_event_is_last_mousemove(const wmEvent *event)
+{
+ while ((event = event->next)) {
+ if (ELEM(event->type, MOUSEMOVE, INBETWEEN_MOUSEMOVE)) {
+ return false;
+ }
+ }
+ return true;
+}
+
#ifdef WITH_INPUT_NDOF
void WM_ndof_deadzone_set(float deadzone)
{
@@ -2852,7 +2862,7 @@ void WM_event_add_mousemove(bContext *C)
/* for modal callbacks, check configuration for how to interpret exit with tweaks */
-bool WM_modal_tweak_exit(const wmEvent *event, int tweak_event)
+bool WM_event_is_modal_tweak_exit(const wmEvent *event, int tweak_event)
{
/* if the release-confirm userpref setting is enabled,
* tweak events can be canceled when mouse is released
diff --git a/source/blender/windowmanager/intern/wm_files.c b/source/blender/windowmanager/intern/wm_files.c
index 028355f9af3..b4a6366fb4e 100644
--- a/source/blender/windowmanager/intern/wm_files.c
+++ b/source/blender/windowmanager/intern/wm_files.c
@@ -316,7 +316,7 @@ static void wm_window_match_do(bContext *C, ListBase *oldwmlist)
}
/* in case UserDef was read, we re-initialize all, and do versioning */
-static void wm_init_userdef(bContext *C, const bool use_factory_settings)
+static void wm_init_userdef(bContext *C, const bool read_userdef_from_memory)
{
Main *bmain = CTX_data_main(C);
@@ -336,14 +336,12 @@ static void wm_init_userdef(bContext *C, const bool use_factory_settings)
}
/* avoid re-saving for every small change to our prefs, allow overrides */
- if (use_factory_settings) {
+ if (read_userdef_from_memory) {
BLO_update_defaults_userpref_blend();
}
/* update tempdir from user preferences */
BKE_tempdir_init(U.tempdir);
-
- BKE_blender_userdef_refresh();
}
@@ -667,7 +665,7 @@ int wm_homefile_read(
*
* And in this case versioning code is to be run.
*/
- bool read_userdef_from_memory = true;
+ bool read_userdef_from_memory = false;
eBLOReadSkip skip_flags = 0;
/* options exclude eachother */
@@ -713,7 +711,6 @@ int wm_homefile_read(
BKE_blender_userdef_set_data(userdef);
MEM_freeN(userdef);
- read_userdef_from_memory = false;
skip_flags |= BLO_READ_SKIP_USERDEF;
printf("Read prefs: %s\n", filepath_userdef);
}
@@ -724,7 +721,7 @@ int wm_homefile_read(
if (filepath_startup_override != NULL) {
/* pass */
}
- else if (app_template_override) {
+ else if (app_template_override && app_template_override[0]) {
app_template = app_template_override;
}
else if (!use_factory_settings && U.app_template[0]) {
@@ -775,6 +772,9 @@ int wm_homefile_read(
success = BKE_blendfile_read_from_memory(
C, datatoc_startup_blend, datatoc_startup_blend_size,
NULL, skip_flags, true);
+ if (success && !(skip_flags & BLO_READ_SKIP_USERDEF)) {
+ read_userdef_from_memory = true;
+ }
if (BLI_listbase_is_empty(&wmbase)) {
wm_clear_default_size(C);
}
@@ -810,6 +810,7 @@ int wm_homefile_read(
/* we need to have preferences load to overwrite preferences from previous template */
userdef_template = BKE_blendfile_userdef_read_from_memory(
datatoc_startup_blend, datatoc_startup_blend_size, NULL);
+ read_userdef_from_memory = true;
}
if (userdef_template) {
BKE_blender_userdef_set_app_template(userdef_template);
@@ -1093,7 +1094,7 @@ static int wm_file_write(bContext *C, const char *filepath, int fileflags, Repor
BKE_reportf(reports, RPT_ERROR, "Cannot save blend file, path '%s' is not writable", filepath);
return ret;
}
-
+
/* note: used to replace the file extension (to ensure '.blend'),
* no need to now because the operator ensures,
* its handy for scripts to save to a predefined name without blender editing it */
diff --git a/source/blender/windowmanager/intern/wm_files_link.c b/source/blender/windowmanager/intern/wm_files_link.c
index 3b733f9558c..f19c999a4f1 100644
--- a/source/blender/windowmanager/intern/wm_files_link.c
+++ b/source/blender/windowmanager/intern/wm_files_link.c
@@ -608,7 +608,8 @@ static void lib_relocate_do(
}
/* Note that in reload case, we also want to replace indirect usages. */
- const short remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE | (do_reload ? 0 : ID_REMAP_SKIP_INDIRECT_USAGE);
+ const short remap_flags = ID_REMAP_SKIP_NEVER_NULL_USAGE | ID_REMAP_NO_INDIRECT_PROXY_DATA_USAGE |
+ (do_reload ? 0 : ID_REMAP_SKIP_INDIRECT_USAGE);
for (item_idx = 0, itemlink = lapp_data->items.list; itemlink; item_idx++, itemlink = itemlink->next) {
WMLinkAppendDataItem *item = itemlink->link;
ID *old_id = item->customdata;
diff --git a/source/blender/windowmanager/intern/wm_init_exit.c b/source/blender/windowmanager/intern/wm_init_exit.c
index 9bafe72d805..00a9976e8be 100644
--- a/source/blender/windowmanager/intern/wm_init_exit.c
+++ b/source/blender/windowmanager/intern/wm_init_exit.c
@@ -181,7 +181,7 @@ void WM_init(bContext *C, int argc, const char **argv)
ED_file_init(); /* for fsmenu */
ED_node_init_butfuncs();
- BLF_init(11, U.dpi); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */
+ BLF_init(); /* Please update source/gamengine/GamePlayer/GPG_ghost.cpp if you change this */
BLT_lang_init();
/* Enforce loading the UI for the initial homefile */
diff --git a/source/blender/windowmanager/intern/wm_operators.c b/source/blender/windowmanager/intern/wm_operators.c
index d827ccafda8..d3ebd3e4d2c 100644
--- a/source/blender/windowmanager/intern/wm_operators.c
+++ b/source/blender/windowmanager/intern/wm_operators.c
@@ -1799,13 +1799,13 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
if (version_suffix != NULL && version_suffix[0]) {
/* placed after the version number in the image,
* placing y is tricky to match baseline */
- int x = 260 - (2 * UI_DPI_WINDOW_FAC);
- int y = 242 + (4 * UI_DPI_WINDOW_FAC);
- int w = 240;
+ int x = 260 * U.pixelsize - (2 * UI_DPI_FAC);
+ int y = 242 * U.pixelsize + (4 * UI_DPI_FAC);
+ int w = 240 * U.pixelsize;
/* hack to have text draw 'text_sel' */
UI_block_emboss_set(block, UI_EMBOSS_NONE);
- but = uiDefBut(block, UI_BTYPE_LABEL, 0, version_suffix, x * U.pixelsize, y * U.pixelsize, w * U.pixelsize, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
+ but = uiDefBut(block, UI_BTYPE_LABEL, 0, version_suffix, x, y, w, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
/* XXX, set internal flag - UI_SELECT */
UI_but_flag_enable(but, 1);
UI_block_emboss_set(block, UI_EMBOSS);
diff --git a/source/blender/windowmanager/intern/wm_playanim.c b/source/blender/windowmanager/intern/wm_playanim.c
index 6bf7bcc2934..77378cf8e0c 100644
--- a/source/blender/windowmanager/intern/wm_playanim.c
+++ b/source/blender/windowmanager/intern/wm_playanim.c
@@ -1256,7 +1256,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
//GHOST_ActivateWindowDrawingContext(g_WS.ghost_window);
/* initialize the font */
- BLF_init(11, 72);
+ BLF_init();
ps.fontid = BLF_load_mem("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);
BLF_size(ps.fontid, 11, 72);
@@ -1428,8 +1428,7 @@ static char *wm_main_playanim_intern(int argc, const char **argv)
ps.next_frame = ps.direction;
-
- while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0)) || ps.wait2) {
+ while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, ps.wait2))) {
if (hasevent) {
GHOST_DispatchEvents(g_WS.ghost_system);
}
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index aaf77946412..e7a1643a1ff 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -375,10 +375,15 @@ void wm_window_title(wmWindowManager *wm, wmWindow *win)
}
}
-static void wm_window_set_dpi(wmWindow *win)
+void WM_window_set_dpi(wmWindow *win)
{
int auto_dpi = GHOST_GetDPIHint(win->ghostwin);
+ /* Clamp auto DPI to 96, since our font/interface drawing does not work well
+ * with lower sizes. The main case we are interested in supporting is higher
+ * DPI. If a smaller UI is desired it is still possible to adjust UI scale. */
+ auto_dpi = MAX2(auto_dpi, 96);
+
/* Lazily init UI scale size, preserving backwards compatibility by
* computing UI scale from ratio of previous DPI and auto DPI */
if (U.ui_scale == 0) {
@@ -406,8 +411,10 @@ static void wm_window_set_dpi(wmWindow *win)
U.pixelsize = GHOST_GetNativePixelSize(win->ghostwin) * pixelsize;
U.dpi = dpi / pixelsize;
U.virtual_pixel = (pixelsize == 1) ? VIRTUAL_PIXEL_NATIVE : VIRTUAL_PIXEL_DOUBLE;
+ U.widget_unit = (U.pixelsize * U.dpi * 20 + 36) / 72;
- BKE_blender_userdef_refresh();
+ /* update font drawing */
+ BLF_default_dpi(U.pixelsize * U.dpi);
}
/* belongs to below */
@@ -483,7 +490,7 @@ static void wm_window_ghostwindow_add(wmWindowManager *wm, const char *title, wm
}
/* needed here, because it's used before it reads userdef */
- wm_window_set_dpi(win);
+ WM_window_set_dpi(win);
wm_window_swap_buffers(win);
@@ -642,14 +649,27 @@ wmWindow *WM_window_open(bContext *C, const rcti *rect)
* \param type: WM_WINDOW_RENDER, WM_WINDOW_USERPREFS...
* \return the window or NULL.
*/
-wmWindow *WM_window_open_temp(bContext *C, const rcti *rect_init, int type)
+wmWindow *WM_window_open_temp(bContext *C, int x, int y, int sizex, int sizey, int type)
{
wmWindow *win_prev = CTX_wm_window(C);
wmWindow *win;
ScrArea *sa;
Scene *scene = CTX_data_scene(C);
const char *title;
- rcti rect = *rect_init;
+
+ /* convert to native OS window coordinates */
+ const float native_pixel_size = GHOST_GetNativePixelSize(win_prev->ghostwin);
+ x /= native_pixel_size;
+ y /= native_pixel_size;
+ sizex /= native_pixel_size;
+ sizey /= native_pixel_size;
+
+ /* calculate postition */
+ rcti rect;
+ rect.xmin = x + win_prev->posx - sizex / 2;
+ rect.ymin = y + win_prev->posy - sizey / 2;
+ rect.xmax = rect.xmin + sizex;
+ rect.ymax = rect.ymin + sizey;
/* changes rect to fit within desktop */
wm_window_check_position(&rect);
@@ -857,7 +877,7 @@ void wm_window_make_drawable(wmWindowManager *wm, wmWindow *win)
GHOST_ActivateWindowDrawingContext(win->ghostwin);
/* this can change per window */
- wm_window_set_dpi(win);
+ WM_window_set_dpi(win);
}
}
@@ -1057,7 +1077,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
WM_jobs_stop(wm, win->screen, NULL);
}
- wm_window_set_dpi(win);
+ WM_window_set_dpi(win);
/* win32: gives undefined window size when minimized */
if (state != GHOST_kWindowStateMinimized) {
@@ -1144,11 +1164,10 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
case GHOST_kEventWindowDPIHintChanged:
{
- wm_window_set_dpi(win);
+ WM_window_set_dpi(win);
/* font's are stored at each DPI level, without this we can easy load 100's of fonts */
BLF_cache_clear();
- BKE_blender_userdef_refresh();
WM_main_add_notifier(NC_WINDOW, NULL); /* full redraw */
WM_main_add_notifier(NC_SCREEN | NA_EDITED, NULL); /* refresh region sizes */
break;
@@ -1234,7 +1253,7 @@ static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr C_void_ptr
{
// only update if the actual pixel size changes
float prev_pixelsize = U.pixelsize;
- wm_window_set_dpi(win);
+ WM_window_set_dpi(win);
if (U.pixelsize != prev_pixelsize) {
// close all popups since they are positioned with the pixel