Merge branch 'master' into blender2.8
authorBastien Montagne <montagne29@wanadoo.fr>
Tue, 24 May 2016 14:48:10 +0000 (16:48 +0200)
committerBastien Montagne <montagne29@wanadoo.fr>
Tue, 24 May 2016 14:48:10 +0000 (16:48 +0200)
Conflicts:
intern/cycles/blender/blender_curves.cpp
source/blender/blenkernel/intern/dynamicpaint.c
source/blender/blenkernel/intern/particle.c
source/blender/blenloader/intern/versioning_270.c
source/blender/editors/physics/particle_edit.c
source/blender/editors/transform/transform_snap_object.c
source/blender/editors/util/undo.c
source/blender/makesrna/intern/rna_object_force.c

69 files changed:
1  2 
intern/cycles/blender/CMakeLists.txt
intern/cycles/blender/addon/properties.py
intern/cycles/blender/addon/ui.py
intern/cycles/blender/blender_object.cpp
intern/cycles/blender/blender_sync.cpp
intern/cycles/blender/blender_sync.h
intern/cycles/blender/blender_util.h
release/scripts/startup/bl_ui/space_dopesheet.py
release/scripts/startup/bl_ui/space_view3d.py
release/scripts/startup/bl_ui/space_view3d_toolbar.py
source/blender/blenkernel/BKE_cloth.h
source/blender/blenkernel/BKE_dynamicpaint.h
source/blender/blenkernel/BKE_library.h
source/blender/blenkernel/BKE_modifier.h
source/blender/blenkernel/intern/DerivedMesh.c
source/blender/blenkernel/intern/cdderivedmesh.c
source/blender/blenkernel/intern/cloth.c
source/blender/blenkernel/intern/dynamicpaint.c
source/blender/blenkernel/intern/effect.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/scene.c
source/blender/blenkernel/intern/subsurf_ccg.c
source/blender/blenloader/intern/readfile.c
source/blender/blenloader/intern/versioning_270.c
source/blender/blentranslation/BLT_translation.h
source/blender/depsgraph/intern/depsgraph_build_nodes.cc
source/blender/depsgraph/intern/depsgraph_build_relations.cc
source/blender/depsgraph/intern/depsgraph_tag.cc
source/blender/editors/animation/anim_channels_defines.c
source/blender/editors/gpencil/drawgpencil.c
source/blender/editors/interface/interface_icons.c
source/blender/editors/interface/interface_templates.c
source/blender/editors/interface/interface_widgets.c
source/blender/editors/space_file/filesel.c
source/blender/editors/space_outliner/outliner_select.c
source/blender/editors/space_view3d/drawarmature.c
source/blender/editors/space_view3d/drawmesh.c
source/blender/editors/space_view3d/drawobject.c
source/blender/editors/space_view3d/view3d_draw.c
source/blender/editors/space_view3d/view3d_edit.c
source/blender/editors/space_view3d/view3d_intern.h
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform.h
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c
source/blender/editors/transform/transform_snap.c
source/blender/editors/transform/transform_snap_object.c
source/blender/editors/util/CMakeLists.txt
source/blender/editors/util/undo.c
source/blender/gpu/GPU_material.h
source/blender/gpu/intern/gpu_basic_shader.c
source/blender/gpu/intern/gpu_buffers.c
source/blender/gpu/intern/gpu_draw.c
source/blender/gpu/intern/gpu_material.c
source/blender/gpu/shaders/gpu_shader_basic_frag.glsl
source/blender/gpu/shaders/gpu_shader_basic_vert.glsl
source/blender/makesdna/DNA_scene_types.h
source/blender/makesdna/intern/makesdna.c
source/blender/makesrna/intern/rna_internal.h
source/blender/makesrna/intern/rna_nodetree.c
source/blender/makesrna/intern/rna_scene.c
source/blender/makesrna/intern/rna_space.c
source/blender/modifiers/intern/MOD_collision.c
source/blender/modifiers/intern/MOD_laplaciandeform.c
source/blender/modifiers/intern/MOD_softbody.c
source/blender/render/intern/source/pipeline.c
source/blenderplayer/bad_level_call_stubs/stubs.c
source/creator/creator.c

Simple merge
Simple merge
Simple merge
Simple merge
Simple merge
  #include "BKE_image.h"
  #include "BKE_main.h"
  #include "BKE_material.h"
+ #include "BKE_mesh_mapping.h"
  #include "BKE_modifier.h"
  #include "BKE_object.h"
 -#include "BKE_particle.h"
 -#include "BKE_pointcache.h"
  #include "BKE_scene.h"
  #include "BKE_texture.h"
  
@@@ -565,13 -559,15 +558,15 @@@ static bool boundsIntersectDist(Bounds3
  }
  
  /* check whether bounds intersects a point with given radius */
- static int UNUSED_FUNCTION(boundIntersectPoint)(Bounds3D *b, float point[3], float radius)
 -static bool boundIntersectPoint(Bounds3D *b, float point[3], const float radius)
++static bool UNUSED_FUNCTION(boundIntersectPoint)(Bounds3D *b, float point[3], const float radius)
  {
-       int i = 2;
-       if (!b->valid) return 0;
-       for (; i >= 0; i -= 1)
-               if (!(b->min[i] <= (point[i] + radius) && b->max[i] >= (point[i] - radius))) return 0;
-       return 1;
+       if (!b->valid)
+               return false;
+       for (int i = 2; i--;) {
+               if (!(b->min[i] <= (point[i] + radius) && b->max[i] >= (point[i] - radius)))
+                       return false;
+       }
+       return true;
  }
  
  /* expand bounds by a new point */
@@@ -834,11 -854,11 +853,11 @@@ static void free_bakeData(PaintSurfaceD
  /* free surface data if it's not used anymore */
  static void surface_freeUnusedData(DynamicPaintSurface *surface)
  {
-       if (!surface->data) return;
+       if (!surface->data)
+               return;
  
        /* free bakedata if not active or surface is baked */
-       if (!(surface->flags & MOD_DPAINT_ACTIVE))
-       {
 -      if (!(surface->flags & MOD_DPAINT_ACTIVE) || (surface->pointcache && surface->pointcache->flag & PTCACHE_BAKED)) {
++      if (!(surface->flags & MOD_DPAINT_ACTIVE)) {
                free_bakeData(surface->data);
        }
  }
@@@ -1020,9 -1052,11 +1042,9 @@@ bool dynamicPaint_createType(struct Dyn
                                return false;
                        brush->pmd = pmd;
  
 -                      brush->psys = NULL;
 -
                        brush->flags = MOD_DPAINT_ABS_ALPHA | MOD_DPAINT_RAMP_ALPHA;
                        brush->collision = MOD_DPAINT_COL_VOLUME;
-                       
                        brush->mat = NULL;
                        brush->r = 0.15f;
                        brush->g = 0.4f;
@@@ -1837,11 -1994,32 +1972,13 @@@ static void dynamicPaint_frameUpdate(Dy
                        /* limit frame range */
                        CLAMP(current_frame, surface->start_frame, surface->end_frame);
  
-                       if (no_surface_data || current_frame != surface->current_frame || (int)scene->r.cfra == surface->start_frame) {
+                       if (no_surface_data || current_frame != surface->current_frame ||
+                           (int)scene->r.cfra == surface->start_frame)
+                       {
 -                              PointCache *cache = surface->pointcache;
 -                              PTCacheID pid;
                                surface->current_frame = current_frame;
  
 -                              /* read point cache */
 -                              BKE_ptcache_id_from_dynamicpaint(&pid, ob, surface);
 -                              pid.cache->startframe = surface->start_frame;
 -                              pid.cache->endframe = surface->end_frame;
 -                              BKE_ptcache_id_time(&pid, scene, (float)scene->r.cfra, NULL, NULL, NULL);
 -
 -                              /* reset non-baked cache at first frame */
 -                              if ((int)scene->r.cfra == surface->start_frame && !(cache->flag & PTCACHE_BAKED)) {
 -                                      cache->flag |= PTCACHE_REDO_NEEDED;
 -                                      BKE_ptcache_id_reset(scene, &pid, PTCACHE_RESET_OUTDATED);
 -                                      cache->flag &= ~PTCACHE_REDO_NEEDED;
 -                              }
 -
 -                              /* try to read from cache */
 -                              if (BKE_ptcache_read(&pid, (float)scene->r.cfra)) {
 -                                      BKE_ptcache_validate(cache, (int)scene->r.cfra);
 -                              }
 -                              /* if read failed and we're on surface range do recalculate */
 -                              else if ((int)scene->r.cfra == current_frame && !(cache->flag & PTCACHE_BAKED)) {
 +                              /* if we're on surface range do recalculate */
 +                              if ((int)scene->r.cfra == current_frame) {
                                        /* calculate surface frame */
                                        canvas->flags |= MOD_DPAINT_BAKING;
                                        dynamicPaint_calculateFrame(surface, scene, ob, current_frame);
@@@ -3100,6 -3443,31 +3399,30 @@@ static void dynamicPaint_brushObjectCal
        mul_v3_fl(brushVel->v, 1.0f / timescale);
  }
  
 -      const ParticleSystem *psys;
+ typedef struct DynamicPaintPaintData {
+       const DynamicPaintSurface *surface;
+       const DynamicPaintBrushSettings *brush;
+       Object *brushOb;
+       const BrushMaterials *bMats;
+       const Scene *scene;
+       const float timescale;
+       const int c_index;
+       DerivedMesh *dm;
+       const MVert *mvert;
+       const MLoop *mloop;
+       const MLoopTri *mlooptri;
+       const float brush_radius;
+       const float *avg_brushNor;
+       const Vec3f *brushVelocity;
+       const float solidradius;
+       void *treeData;
+       float *pointCoord;
+ } DynamicPaintPaintData;
  /*
   *    Paint a brush object mesh to the surface
   */
@@@ -3487,111 -3909,420 +3864,143 @@@ static int dynamicPaint_paintMesh(Dynam
        return 1;
  }
  
 -/*
 - *    Paint a particle system to the surface
 - */
 -static void dynamic_paint_paint_particle_cell_point_cb_ex(
 -        void *userdata, void *UNUSED(userdata_chunk), const int id, const int UNUSED(threadid))
 -{
 -      const DynamicPaintPaintData *data = userdata;
 -
 -      const DynamicPaintSurface *surface = data->surface;
 -      const PaintSurfaceData *sData = surface->data;
 -      const PaintBakeData *bData = sData->bData;
 -      VolumeGrid *grid = bData->grid;
 -
 -      const DynamicPaintBrushSettings *brush = data->brush;
 -
 -      const ParticleSystem *psys = data->psys;
 -
 -      const float timescale = data->timescale;
 -      const int c_index = data->c_index;
 -
 -      KDTree *tree = data->treeData;
 -
 -      const float solidradius = data->solidradius;
 -      const float smooth = brush->particle_smooth * surface->radius_scale;
 -      const float range = solidradius + smooth;
 -      const float particle_timestep = 0.04f * psys->part->timetweak;
 -
 -      const int index = grid->t_index[grid->s_pos[c_index] + id];
 -      float disp_intersect = 0.0f;
 -      float radius = 0.0f;
 -      float strength = 0.0f;
 -      int part_index = -1;
 -
 -      /*
 -       *      With predefined radius, there is no variation between particles.
 -       *      It's enough to just find the nearest one.
 -       */
 -      {
 -              KDTreeNearest nearest;
 -              float smooth_range, part_solidradius;
 -
 -              /* Find nearest particle and get distance to it */
 -              BLI_kdtree_find_nearest(tree, bData->realCoord[bData->s_pos[index]].v, &nearest);
 -              /* if outside maximum range, no other particle can influence either */
 -              if (nearest.dist > range)
 -                      return;
 -
 -              if (brush->flags & MOD_DPAINT_PART_RAD) {
 -                      /* use particles individual size */
 -                      ParticleData *pa = psys->particles + nearest.index;
 -                      part_solidradius = pa->size;
 -              }
 -              else {
 -                      part_solidradius = solidradius;
 -              }
 -              radius = part_solidradius + smooth;
 -              if (nearest.dist < radius) {
 -                      /* distances inside solid radius has maximum influence -> dist = 0      */
 -                      smooth_range = max_ff(0.0f, (nearest.dist - part_solidradius));
 -                      /* do smoothness if enabled     */
 -                      if (smooth)
 -                              smooth_range /= smooth;
 -
 -                      strength = 1.0f - smooth_range;
 -                      disp_intersect = radius - nearest.dist;
 -                      part_index = nearest.index;
 -              }
 -      }
 -      /* If using random per particle radius and closest particle didn't give max influence   */
 -      if (brush->flags & MOD_DPAINT_PART_RAD && strength < 1.0f && psys->part->randsize > 0.0f) {
 -              /*
 -               *      If we use per particle radius, we have to sample all particles
 -               *      within max radius range
 -               */
 -              KDTreeNearest *nearest;
 -
 -              float smooth_range = smooth * (1.0f - strength), dist;
 -              /* calculate max range that can have particles with higher influence than the nearest one */
 -              const float max_range = smooth - strength * smooth + solidradius;
 -              /* Make gcc happy! */
 -              dist = max_range;
 -
 -              const int particles = BLI_kdtree_range_search(
 -                                        tree, bData->realCoord[bData->s_pos[index]].v, &nearest, max_range);
 -
 -              /* Find particle that produces highest influence */
 -              for (int n = 0; n < particles; n++) {
 -                      ParticleData *pa = &psys->particles[nearest[n].index];
 -
 -                      /* skip if out of range */
 -                      if (nearest[n].dist > (pa->size + smooth))
 -                              continue;
 -
 -                      /* update hit data */
 -                      const float s_range = nearest[n].dist - pa->size;
 -                      /* skip if higher influence is already found */
 -                      if (smooth_range < s_range)
 -                              continue;
 -
 -                      /* update hit data */
 -                      smooth_range = s_range;
 -                      dist = nearest[n].dist;
 -                      part_index = nearest[n].index;
 -
 -                      /* If inside solid range and no disp depth required, no need to seek further */
 -                      if ((s_range < 0.0f) && !ELEM(surface->type, MOD_DPAINT_SURFACE_T_DISPLACE, MOD_DPAINT_SURFACE_T_WAVE)) {
 -                              break;
 -                      }
 -              }
 -
 -              if (nearest)
 -                      MEM_freeN(nearest);
 -
 -              /* now calculate influence for this particle */
 -              const float rad = radius + smooth;
 -              if ((rad - dist) > disp_intersect) {
 -                      disp_intersect = radius - dist;
 -                      radius = rad;
 -              }
 -
 -              /* do smoothness if enabled     */
 -              CLAMP_MIN(smooth_range, 0.0f);
 -              if (smooth)
 -                      smooth_range /= smooth;
 -
 -              const float str = 1.0f - smooth_range;
 -              /* if influence is greater, use this one        */
 -              if (str > strength)
 -                      strength = str;
 -      }
 -
 -      if (strength > 0.001f) {
 -              float paintColor[4] = {0.0f};
 -              float depth = 0.0f;
 -              float velocity_val = 0.0f;
 -
 -              /* apply velocity */
 -              if ((brush->flags & MOD_DPAINT_USES_VELOCITY) && (part_index != -1)) {
 -                      float velocity[3];
 -                      ParticleData *pa = psys->particles + part_index;
 -                      mul_v3_v3fl(velocity, pa->state.vel, particle_timestep);
 -
 -                      /* substract canvas point velocity */
 -                      if (bData->velocity) {
 -                              sub_v3_v3(velocity, bData->velocity[index].v);
 -                      }
 -                      velocity_val = normalize_v3(velocity);
 -
 -                      /* store brush velocity for smudge */
 -                      if ((surface->type == MOD_DPAINT_SURFACE_T_PAINT) &&
 -                          (brush->flags & MOD_DPAINT_DO_SMUDGE && bData->brush_velocity))
 -                      {
 -                              copy_v3_v3(&bData->brush_velocity[index * 4], velocity);
 -                              bData->brush_velocity[index * 4 + 3] = velocity_val;
 -                      }
 -              }
 -
 -              if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
 -                      copy_v3_v3(paintColor, &brush->r);
 -              }
 -              else if (ELEM(surface->type, MOD_DPAINT_SURFACE_T_DISPLACE, MOD_DPAINT_SURFACE_T_WAVE)) {
 -                      /* get displace depth   */
 -                      disp_intersect = (1.0f - sqrtf(disp_intersect / radius)) * radius;
 -                      depth = max_ff(0.0f, (radius - disp_intersect) / bData->bNormal[index].normal_scale);
 -              }
 -
 -              dynamicPaint_updatePointData(surface, index, brush, paintColor, strength, depth, velocity_val, timescale);
 -      }
 -}
 -
 -static int dynamicPaint_paintParticles(DynamicPaintSurface *surface,
 -                                       ParticleSystem *psys,
 -                                       DynamicPaintBrushSettings *brush,
 -                                       float timescale)
 -{
 -      ParticleSettings *part = psys->part;
 -      PaintSurfaceData *sData = surface->data;
 -      PaintBakeData *bData = sData->bData;
 -      VolumeGrid *grid = bData->grid;
 -
 -      KDTree *tree;
 -      int particlesAdded = 0;
 -      int invalidParticles = 0;
 -      int p = 0;
 -
 -      const float solidradius = surface->radius_scale *
 -                                ((brush->flags & MOD_DPAINT_PART_RAD) ? part->size : brush->particle_radius);
 -      const float smooth = brush->particle_smooth * surface->radius_scale;
 -
 -      const float range = solidradius + smooth;
 -
 -      Bounds3D part_bb = {0};
 -
 -      if (psys->totpart < 1)
 -              return 1;
 -
 -      /*
 -       *      Build a kd-tree to optimize distance search
 -       */
 -      tree = BLI_kdtree_new(psys->totpart);
 -
 -      /* loop through particles and insert valid ones to the tree     */
 -      p = 0;
 -      for (ParticleData *pa = psys->particles; p < psys->totpart; p++, pa++) {
 -              /* Proceed only if particle is active   */
 -              if ((pa->alive == PARS_UNBORN && (part->flag & PART_UNBORN) == 0) ||
 -                  (pa->alive == PARS_DEAD && (part->flag & PART_DIED) == 0) ||
 -                  (pa->flag & PARS_UNEXIST))
 -              {
 -                      continue;
 -              }
 -
 -              /*      for debug purposes check if any NAN particle proceeds
 -               *      For some reason they get past activity check, this should rule most of them out */
 -              if (isnan(pa->state.co[0]) || isnan(pa->state.co[1]) || isnan(pa->state.co[2])) {
 -                      invalidParticles++;
 -                      continue;
 -              }
 -
 -              /* make sure particle is close enough to canvas */
 -              if (!boundIntersectPoint(&grid->grid_bounds, pa->state.co, range))
 -                      continue;
 -
 -              BLI_kdtree_insert(tree, p, pa->state.co);
 -
 -              /* calc particle system bounds */
 -              boundInsert(&part_bb, pa->state.co);
 -
 -              particlesAdded++;
 -      }
 -      if (invalidParticles)
 -              printf("Warning: Invalid particle(s) found!\n");
 -
 -      /* If no suitable particles were found, exit    */
 -      if (particlesAdded < 1) {
 -              BLI_kdtree_free(tree);
 -              return 1;
 -      }
 -
 -      /* begin thread safe malloc */
 -      BLI_begin_threaded_malloc();
 -
 -      /* only continue if particle bb is close enough to canvas bb */
 -      if (boundsIntersectDist(&grid->grid_bounds, &part_bb, range)) {
 -              int c_index;
 -              int total_cells = grid->dim[0] * grid->dim[1] * grid->dim[2];
 -
 -              /* balance tree */
 -              BLI_kdtree_balance(tree);
 -
 -              /* loop through space partitioning grid */
 -              for (c_index = 0; c_index < total_cells; c_index++) {
 -                      /* check cell bounding box */
 -                      if (!grid->s_num[c_index] ||
 -                          !boundsIntersectDist(&grid->bounds[c_index], &part_bb, range))
 -                      {
 -                              continue;
 -                      }
 -
 -                      /* loop through cell points */
 -                      DynamicPaintPaintData data = {
 -                              .surface = surface,
 -                          .brush = brush, .psys = psys,
 -                          .solidradius = solidradius, .timescale = timescale, .c_index = c_index,
 -                              .treeData = tree,
 -                      };
 -                      BLI_task_parallel_range_ex(0, grid->s_num[c_index], &data, NULL, 0,
 -                                                 dynamic_paint_paint_particle_cell_point_cb_ex,
 -                                                 grid->s_num[c_index] > 250, true);
 -              }
 -      }
 -      BLI_end_threaded_malloc();
 -      BLI_kdtree_free(tree);
 -
 -      return 1;
 -}
 -
  /* paint a single point of defined proximity radius to the surface */
- static int dynamicPaint_paintSinglePoint(DynamicPaintSurface *surface, float *pointCoord, DynamicPaintBrushSettings *brush,
-                                          Object *brushOb, BrushMaterials *bMats, Scene *scene, float timescale)
+ static void dynamic_paint_paint_single_point_cb_ex(
+         void *userdata, void *UNUSED(userdata_chunk), const int index, const int UNUSED(threadid))
  {
-       int index;
-       float brush_radius = brush->paint_distance * surface->radius_scale;
-       PaintSurfaceData *sData = surface->data;
-       PaintBakeData *bData = sData->bData;
-       Vec3f brushVel;
+       const DynamicPaintPaintData *data = userdata;
  
-       if (brush->flags & MOD_DPAINT_USES_VELOCITY)
-               dynamicPaint_brushObjectCalculateVelocity(scene, brushOb, &brushVel, timescale);
+       const DynamicPaintSurface *surface = data->surface;
+       const PaintSurfaceData *sData = surface->data;
+       const PaintBakeData *bData = sData->bData;
  
-       /*
-        *      Loop through every surface point
-        */
- #pragma omp parallel for schedule(static)
-       for (index = 0; index < sData->total_points; index++) {
-               float distance = len_v3v3(pointCoord, bData->realCoord[bData->s_pos[index]].v);
-               float colorband[4] = {0.0f};
-               float strength;
+       const DynamicPaintBrushSettings *brush = data->brush;
+       Object *brushOb = data->brushOb;
+       const BrushMaterials *bMats = data->bMats;
  
-               if (distance > brush_radius) continue;
+       const Scene *scene = data->scene;
+       const float timescale = data->timescale;
  
-               /* Smooth range or color ramp   */
-               if (brush->proximity_falloff == MOD_DPAINT_PRFALL_SMOOTH ||
-                   brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP)
-               {
-                       strength = 1.0f - distance / brush_radius;
-                       CLAMP(strength, 0.0f, 1.0f);
-               }
-               else {
-                       strength = 1.0f;
-               }
+       const MVert *mvert = data->mvert;
+       const float brush_radius = data->brush_radius;
+       const Vec3f *brushVelocity = data->brushVelocity;
  
-               if (strength >= 0.001f) {
-                       float paintColor[3] = {0.0f};
-                       float depth = 0.0f;
-                       float velocity_val = 0.0f;
+       float *pointCoord = data->pointCoord;
  
-                       /* material */
-                       if (brush_usesMaterial(brush, scene)) {
-                               float alpha_factor = 1.0f;
-                               float hit_coord[3];
-                               MVert *mvert = brush->dm->getVertArray(brush->dm);
-                               /* use dummy coord of first vertex */
-                               copy_v3_v3(hit_coord, mvert[0].co);
-                               mul_m4_v3(brushOb->obmat, hit_coord);
-                               dynamicPaint_doMaterialTex(bMats, paintColor, &alpha_factor, brushOb, bData->realCoord[bData->s_pos[index]].v, hit_coord, 0, brush->dm);
-                       }
+       const float distance = len_v3v3(pointCoord, bData->realCoord[bData->s_pos[index]].v);
+       float colorband[4] = {0.0f};
+       float strength;
  
-                       /* color ramp */
-                       if (brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP && do_colorband(brush->paint_ramp, (1.0f - strength), colorband))
-                               strength = colorband[3];
+       if (distance > brush_radius)
+               return;
  
-                       if (brush->flags & MOD_DPAINT_USES_VELOCITY) {
-                               float velocity[3];
+       /* Smooth range or color ramp   */
+       if (brush->proximity_falloff == MOD_DPAINT_PRFALL_SMOOTH ||
+           brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP)
+       {
+               strength = 1.0f - distance / brush_radius;
+               CLAMP(strength, 0.0f, 1.0f);
+       }
+       else {
+               strength = 1.0f;
+       }
  
-                               /* substract canvas point velocity */
-                               if (bData->velocity) {
-                                       sub_v3_v3v3(velocity, brushVel.v, bData->velocity[index].v);
-                               }
-                               else {
-                                       copy_v3_v3(velocity, brushVel.v);
-                               }
-                               velocity_val = len_v3(velocity);
+       if (strength >= 0.001f) {
+               float paintColor[3] = {0.0f};
+               float depth = 0.0f;
+               float velocity_val = 0.0f;
  
-                               /* store brush velocity for smudge */
-                               if (surface->type == MOD_DPAINT_SURFACE_T_PAINT && 
-                                   brush->flags & MOD_DPAINT_DO_SMUDGE && bData->brush_velocity)
-                               {
-                                       copy_v3_v3(&bData->brush_velocity[index * 4], velocity);
-                                       mul_v3_fl(&bData->brush_velocity[index * 4], 1.0f / velocity_val);
-                                       bData->brush_velocity[index * 4 + 3] = velocity_val;
-                               }
+               /* material */
+               if (brush_usesMaterial(brush, scene)) {
+                       float alpha_factor = 1.0f;
+                       float hit_coord[3];
+                       /* use dummy coord of first vertex */
+                       mul_v3_m4v3(hit_coord, brushOb->obmat, mvert[0].co);
+                       dynamicPaint_doMaterialTex(bMats, paintColor, &alpha_factor, brushOb,
+                                                  bData->realCoord[bData->s_pos[index]].v, hit_coord, 0, brush->dm);
+               }
+               /* color ramp */
+               if (brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP &&
+                   do_colorband(brush->paint_ramp, (1.0f - strength), colorband))
+               {
+                       strength = colorband[3];
+               }
+               if (brush->flags & MOD_DPAINT_USES_VELOCITY) {
+                       float velocity[3];
+                       /* substract canvas point velocity */
+                       if (bData->velocity) {
+                               sub_v3_v3v3(velocity, brushVelocity->v, bData->velocity[index].v);
+                       }
+                       else {
+                               copy_v3_v3(velocity, brushVelocity->v);
                        }
+                       velocity_val = len_v3(velocity);
  
-                       if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
-                               if (brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP &&
-                                   !(brush->flags & MOD_DPAINT_RAMP_ALPHA))
-                               {
-                                       paintColor[0] = colorband[0];
-                                       paintColor[1] = colorband[1];
-                                       paintColor[2] = colorband[2];
-                               }
-                               else {
-                                       if (!brush_usesMaterial(brush, scene)) {
-                                               paintColor[0] = brush->r;
-                                               paintColor[1] = brush->g;
-                                               paintColor[2] = brush->b;
-                                       }
-                               }
+                       /* store brush velocity for smudge */
+                       if (surface->type == MOD_DPAINT_SURFACE_T_PAINT &&
+                           brush->flags & MOD_DPAINT_DO_SMUDGE && bData->brush_velocity)
+                       {
+                               mul_v3_v3fl(&bData->brush_velocity[index * 4], velocity, 1.0f / velocity_val);
+                               bData->brush_velocity[index * 4 + 3] = velocity_val;
                        }
-                       else if (surface->type == MOD_DPAINT_SURFACE_T_DISPLACE ||
-                                surface->type == MOD_DPAINT_SURFACE_T_WAVE)
+               }
+               if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) {
+                       if (brush->proximity_falloff == MOD_DPAINT_PRFALL_RAMP &&
+                           !(brush->flags & MOD_DPAINT_RAMP_ALPHA))
                        {
-                               /* get displace depth   */
-                               float disp_intersect = (1.0f - sqrtf((brush_radius - distance) / brush_radius)) * brush_radius;
-                               depth = (brush_radius - disp_intersect) / bData->bNormal[index].normal_scale;
-                               if (depth < 0.0f) depth = 0.0f;
+                               paintColor[0] = colorband[0];
+                               paintColor[1] = colorband[1];
+                               paintColor[2] = colorband[2];
+                       }
+                       else {
+                               if (!brush_usesMaterial(brush, scene)) {
+                                       paintColor[0] = brush->r;
+                                       paintColor[1] = brush->g;
+                                       paintColor[2] = brush->b;
+                               }
                        }
-                       dynamicPaint_updatePointData(surface, index, brush, paintColor, strength, depth, velocity_val, timescale);
                }
+               else if (ELEM(surface->type, MOD_DPAINT_SURFACE_T_DISPLACE, MOD_DPAINT_SURFACE_T_WAVE)) {
+                       /* get displace depth   */
+                       const float disp_intersect = (1.0f - sqrtf((brush_radius - distance) / brush_radius)) * brush_radius;
+                       depth = max_ff(0.0f, (brush_radius - disp_intersect) / bData->bNormal[index].normal_scale);
+               }
+               dynamicPaint_updatePointData(surface, index, brush, paintColor, strength, depth, velocity_val, timescale);
        }
+ }
+ static int dynamicPaint_paintSinglePoint(
+         DynamicPaintSurface *surface, float *pointCoord, DynamicPaintBrushSettings *brush,
+         Object *brushOb, BrushMaterials *bMats, Scene *scene, float timescale)
+ {
+       PaintSurfaceData *sData = surface->data;
+       float brush_radius = brush->paint_distance * surface->radius_scale;
+       Vec3f brushVel;
+       if (brush->flags & MOD_DPAINT_USES_VELOCITY)
+               dynamicPaint_brushObjectCalculateVelocity(scene, brushOb, &brushVel, timescale);
+       const MVert *mvert = brush->dm->getVertArray(brush->dm);
+       /*
+        *      Loop through every surface point
+        */
+       DynamicPaintPaintData data = {
+               .surface = surface,
+               .brush = brush, .brushOb = brushOb, .bMats = bMats,
+               .scene = scene, .timescale = timescale,
+               .mvert = mvert,
+               .brush_radius = brush_radius, .brushVelocity = &brushVel,
+           .pointCoord = pointCoord,
+       };
+       BLI_task_parallel_range_ex(0, sData->total_points, &data, NULL, 0,
+                                                          dynamic_paint_paint_single_point_cb_ex,
+                                                          sData->total_points > 1000, true);
  
        return 1;
  }
@@@ -3796,10 -4619,7 +4297,7 @@@ static int dynamicPaint_prepareEffectSt
  
        /* Init force data if required */
        if (surface->effect & MOD_DPAINT_EFFECT_DO_DRIP) {
-               float vel[3] = {0};
 -              ListBase *effectors = pdInitEffectors(scene, ob, NULL, surface->effector_weights, true);
 +              ListBase *effectors = pdInitEffectors(scene, ob, surface->effector_weights, true);
  
                /* allocate memory for force data (dir vector + strength) */
                *force = MEM_mallocN(sData->total_points * 4 * sizeof(float), "PaintEffectForces");
@@@ -958,6 -1066,24 +993,15 @@@ void blo_do_versions_270(FileData *fd, 
        }
  
        if (!MAIN_VERSION_ATLEAST(main, 277, 1)) {
 -              for (Scene *scene = main->scene.first; scene; scene = scene->id.next) {
 -                      ParticleEditSettings *pset = &scene->toolsettings->particle;
 -                      for (int a = 0; a < PE_TOT_BRUSH; a++) {
 -                              if (pset->brush[a].strength > 1.0f) {
 -                                      pset->brush[a].strength *= 0.01f;
 -                              }
 -                      }
 -              }
 -
+               /* init grease pencil smooth level iterations */
+               for (bGPdata *gpd = main->gpencil.first; gpd; gpd = gpd->id.next) {
+                       for (bGPDlayer *gpl = gpd->layers.first; gpl; gpl = gpl->next) {
+                               if (gpl->draw_smoothlvl == 0) {
+                                       gpl->draw_smoothlvl = 1;
+                               }
+                       }
+               }
                for (bScreen *screen = main->screen.first; screen; screen = screen->id.next) {
                        for (ScrArea *sa = screen->areabase.first; sa; sa = sa->next) {
                                for (SpaceLink *sl = sa->spacedata.first; sl; sl = sl->next) {
@@@ -908,9 -1336,24 +1336,9 @@@ static bool snapObjectsRay
  
                retval |= snapObject(
                        sctx, ob, ob->obmat, true, snap_to,
-                       mval, dist_px,
+                       mval, dist_px, ob_index++,
                        ray_start, ray_normal, ray_origin, ray_depth,
-                       r_loc, r_no, r_index, r_ob, r_obmat);
 -                      r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list);
 -      }
 -
 -      /* 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;
 -      if (base && base->object && base->object->mode & OB_MODE_PARTICLE_EDIT) {
 -              Object *ob = base->object;
 -              retval |= snapObject(
 -                      sctx, ob, ob->obmat, false, snap_to,
 -                      mval, dist_px, ob_index++,
 -                      ray_start, ray_normal, ray_origin, ray_depth,
+                       r_loc, r_no, r_index, r_ob, r_obmat, r_hit_list);
        }
  
        for (base = sctx->scene->base.first; base != NULL; base = base->next) {
@@@ -420,7 -435,9 +420,8 @@@ void ED_undo_operator_repeat_cb_evt(bCo
  enum {
        UNDOSYSTEM_GLOBAL   = 1,
        UNDOSYSTEM_EDITMODE = 2,
-       UNDOSYSTEM_IMAPAINT = 3
 -      UNDOSYSTEM_PARTICLE = 3,
 -      UNDOSYSTEM_IMAPAINT = 4,
 -      UNDOSYSTEM_SCULPT   = 5,
++      UNDOSYSTEM_IMAPAINT = 3,
++      UNDOSYSTEM_SCULPT   = 4,
  };
  
  static int get_undo_system(bContext *C)
Simple merge
Simple merge
Simple merge