Changeset View
Changeset View
Standalone View
Standalone View
source/blender/blenkernel/intern/dynamicpaint.cc
| Show First 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | ||||
| /* For vertex format, count every vertex that is connected by an edge */ | /* For vertex format, count every vertex that is connected by an edge */ | ||||
| int numOfEdges = mesh->totedge; | int numOfEdges = mesh->totedge; | ||||
| int numOfPolys = mesh->totpoly; | int numOfPolys = mesh->totpoly; | ||||
| const MEdge *edges = BKE_mesh_edges(mesh); | const MEdge *edges = BKE_mesh_edges(mesh); | ||||
| const MPoly *polys = BKE_mesh_polys(mesh); | const MPoly *polys = BKE_mesh_polys(mesh); | ||||
| const MLoop *loops = BKE_mesh_loops(mesh); | const blender::Span<int> corner_verts = mesh->corner_verts(); | ||||
| /* count number of edges per vertex */ | /* count number of edges per vertex */ | ||||
| for (int i = 0; i < numOfEdges; i++) { | for (int i = 0; i < numOfEdges; i++) { | ||||
| ad->n_num[edges[i].v1]++; | ad->n_num[edges[i].v1]++; | ||||
| ad->n_num[edges[i].v2]++; | ad->n_num[edges[i].v2]++; | ||||
| temp_data[edges[i].v1]++; | temp_data[edges[i].v1]++; | ||||
| temp_data[edges[i].v2]++; | temp_data[edges[i].v2]++; | ||||
| } | } | ||||
| /* also add number of vertices to temp_data | /* also add number of vertices to temp_data | ||||
| * to locate points on "mesh edge" */ | * to locate points on "mesh edge" */ | ||||
| for (int i = 0; i < numOfPolys; i++) { | for (int i = 0; i < numOfPolys; i++) { | ||||
| for (int j = 0; j < polys[i].totloop; j++) { | for (int j = 0; j < polys[i].totloop; j++) { | ||||
| temp_data[loops[polys[i].loopstart + j].v]++; | temp_data[corner_verts[polys[i].loopstart + j]]++; | ||||
| } | } | ||||
| } | } | ||||
| /* now check if total number of edges+faces for | /* now check if total number of edges+faces for | ||||
| * each vertex is even, if not -> vertex is on mesh edge */ | * each vertex is even, if not -> vertex is on mesh edge */ | ||||
| for (int i = 0; i < sData->total_points; i++) { | for (int i = 0; i < sData->total_points; i++) { | ||||
| if ((temp_data[i] % 2) || (temp_data[i] < 4)) { | if ((temp_data[i] % 2) || (temp_data[i] < 4)) { | ||||
| ad->flags[i] |= ADJ_ON_MESH_EDGE; | ad->flags[i] |= ADJ_ON_MESH_EDGE; | ||||
| Show All 31 Lines | |||||
| } | } | ||||
| MEM_freeN(temp_data); | MEM_freeN(temp_data); | ||||
| } | } | ||||
| struct DynamicPaintSetInitColorData { | struct DynamicPaintSetInitColorData { | ||||
| const DynamicPaintSurface *surface; | const DynamicPaintSurface *surface; | ||||
| const MLoop *mloop; | const int *corner_verts; | ||||
| const float (*mloopuv)[2]; | const float (*mloopuv)[2]; | ||||
| const MLoopTri *mlooptri; | const MLoopTri *mlooptri; | ||||
| const MLoopCol *mloopcol; | const MLoopCol *mloopcol; | ||||
| ImagePool *pool; | ImagePool *pool; | ||||
| bool scene_color_manage; | bool scene_color_manage; | ||||
| }; | }; | ||||
| static void dynamic_paint_set_init_color_tex_to_vcol_cb(void *__restrict userdata, | static void dynamic_paint_set_init_color_tex_to_vcol_cb(void *__restrict userdata, | ||||
| const int i, | const int i, | ||||
| const TaskParallelTLS *__restrict /*tls*/) | const TaskParallelTLS *__restrict /*tls*/) | ||||
| { | { | ||||
| const DynamicPaintSetInitColorData *data = static_cast<DynamicPaintSetInitColorData *>(userdata); | const DynamicPaintSetInitColorData *data = static_cast<DynamicPaintSetInitColorData *>(userdata); | ||||
| const PaintSurfaceData *sData = data->surface->data; | const PaintSurfaceData *sData = data->surface->data; | ||||
| PaintPoint *pPoint = (PaintPoint *)sData->type_data; | PaintPoint *pPoint = (PaintPoint *)sData->type_data; | ||||
| const MLoop *mloop = data->mloop; | const int *corner_verts = data->corner_verts; | ||||
| const MLoopTri *mlooptri = data->mlooptri; | const MLoopTri *mlooptri = data->mlooptri; | ||||
| const float(*mloopuv)[2] = data->mloopuv; | const float(*mloopuv)[2] = data->mloopuv; | ||||
| ImagePool *pool = data->pool; | ImagePool *pool = data->pool; | ||||
| Tex *tex = data->surface->init_texture; | Tex *tex = data->surface->init_texture; | ||||
| const bool scene_color_manage = data->scene_color_manage; | const bool scene_color_manage = data->scene_color_manage; | ||||
| float uv[3] = {0.0f}; | float uv[3] = {0.0f}; | ||||
| for (int j = 3; j--;) { | for (int j = 3; j--;) { | ||||
| TexResult texres = {0}; | TexResult texres = {0}; | ||||
| const uint vert = mloop[mlooptri[i].tri[j]].v; | const int vert = corner_verts[mlooptri[i].tri[j]]; | ||||
| /* remap to [-1.0, 1.0] */ | /* remap to [-1.0, 1.0] */ | ||||
| uv[0] = mloopuv[mlooptri[i].tri[j]][0] * 2.0f - 1.0f; | uv[0] = mloopuv[mlooptri[i].tri[j]][0] * 2.0f - 1.0f; | ||||
| uv[1] = mloopuv[mlooptri[i].tri[j]][1] * 2.0f - 1.0f; | uv[1] = mloopuv[mlooptri[i].tri[j]][1] * 2.0f - 1.0f; | ||||
| multitex_ext_safe(tex, uv, &texres, pool, scene_color_manage, false); | multitex_ext_safe(tex, uv, &texres, pool, scene_color_manage, false); | ||||
| if (texres.tin > pPoint[vert].color[3]) { | if (texres.tin > pPoint[vert].color[3]) { | ||||
| ▲ Show 20 Lines • Show All 92 Lines • ▼ Show 20 Lines | |||||
| for (int i = 0; i < sData->total_points; i++) { | for (int i = 0; i < sData->total_points; i++) { | ||||
| copy_v4_v4(pPoint[i].color, surface->init_color); | copy_v4_v4(pPoint[i].color, surface->init_color); | ||||
| } | } | ||||
| } | } | ||||
| /* UV mapped texture */ | /* UV mapped texture */ | ||||
| else if (surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) { | else if (surface->init_color_type == MOD_DPAINT_INITIAL_TEXTURE) { | ||||
| Tex *tex = surface->init_texture; | Tex *tex = surface->init_texture; | ||||
| const MLoop *mloop = BKE_mesh_loops(mesh); | const blender::Span<int> corner_verts = mesh->corner_verts(); | ||||
| const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); | const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); | ||||
| const int tottri = BKE_mesh_runtime_looptri_len(mesh); | const int tottri = BKE_mesh_runtime_looptri_len(mesh); | ||||
| char uvname[MAX_CUSTOMDATA_LAYER_NAME]; | char uvname[MAX_CUSTOMDATA_LAYER_NAME]; | ||||
| if (!tex) { | if (!tex) { | ||||
| return; | return; | ||||
| } | } | ||||
| Show All 9 Lines | |||||
| /* for vertex surface loop through tfaces and find uv color | /* for vertex surface loop through tfaces and find uv color | ||||
| * that provides highest alpha */ | * that provides highest alpha */ | ||||
| if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | ||||
| struct ImagePool *pool = BKE_image_pool_new(); | struct ImagePool *pool = BKE_image_pool_new(); | ||||
| DynamicPaintSetInitColorData data{}; | DynamicPaintSetInitColorData data{}; | ||||
| data.surface = surface; | data.surface = surface; | ||||
| data.mloop = mloop; | data.corner_verts = corner_verts.data(); | ||||
| data.mlooptri = mlooptri; | data.mlooptri = mlooptri; | ||||
| data.mloopuv = mloopuv; | data.mloopuv = mloopuv; | ||||
| data.pool = pool; | data.pool = pool; | ||||
| data.scene_color_manage = scene_color_manage; | data.scene_color_manage = scene_color_manage; | ||||
| TaskParallelSettings settings; | TaskParallelSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.use_threading = (tottri > 1000); | settings.use_threading = (tottri > 1000); | ||||
| Show All 15 Lines | |||||
| 0, sData->total_points, &data, dynamic_paint_set_init_color_tex_to_imseq_cb, &settings); | 0, sData->total_points, &data, dynamic_paint_set_init_color_tex_to_imseq_cb, &settings); | ||||
| } | } | ||||
| } | } | ||||
| /* vertex color layer */ | /* vertex color layer */ | ||||
| else if (surface->init_color_type == MOD_DPAINT_INITIAL_VERTEXCOLOR) { | else if (surface->init_color_type == MOD_DPAINT_INITIAL_VERTEXCOLOR) { | ||||
| /* For vertex surface, just copy colors from #MLoopCol. */ | /* For vertex surface, just copy colors from #MLoopCol. */ | ||||
| if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | ||||
| const MLoop *mloop = BKE_mesh_loops(mesh); | const blender::Span<int> corner_verts = mesh->corner_verts(); | ||||
| const int totloop = mesh->totloop; | const int totloop = mesh->totloop; | ||||
| const MLoopCol *col = static_cast<const MLoopCol *>( | const MLoopCol *col = static_cast<const MLoopCol *>( | ||||
| CustomData_get_layer_named(&mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername)); | CustomData_get_layer_named(&mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername)); | ||||
| if (!col) { | if (!col) { | ||||
| return; | return; | ||||
| } | } | ||||
| for (int i = 0; i < totloop; i++) { | for (int i = 0; i < totloop; i++) { | ||||
| rgba_uchar_to_float(pPoint[mloop[i].v].color, (const uchar *)&col[i].r); | rgba_uchar_to_float(pPoint[corner_verts[i]].color, (const uchar *)&col[i].r); | ||||
| } | } | ||||
| } | } | ||||
| else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { | else if (surface->format == MOD_DPAINT_SURFACE_F_IMAGESEQ) { | ||||
| const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); | const MLoopTri *mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); | ||||
| const MLoopCol *col = static_cast<const MLoopCol *>( | const MLoopCol *col = static_cast<const MLoopCol *>( | ||||
| CustomData_get_layer_named(&mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername)); | CustomData_get_layer_named(&mesh->ldata, CD_PROP_BYTE_COLOR, surface->init_layername)); | ||||
| if (!col) { | if (!col) { | ||||
| return; | return; | ||||
| ▲ Show 20 Lines • Show All 90 Lines • ▼ Show 20 Lines | |||||
| /***************************** Modifier processing ******************************/ | /***************************** Modifier processing ******************************/ | ||||
| struct DynamicPaintModifierApplyData { | struct DynamicPaintModifierApplyData { | ||||
| const DynamicPaintSurface *surface; | const DynamicPaintSurface *surface; | ||||
| Object *ob; | Object *ob; | ||||
| float (*vert_positions)[3]; | float (*vert_positions)[3]; | ||||
| const float (*vert_normals)[3]; | const float (*vert_normals)[3]; | ||||
| const MLoop *mloop; | const int *corner_verts; | ||||
| const MPoly *mpoly; | const MPoly *mpoly; | ||||
| float (*fcolor)[4]; | float (*fcolor)[4]; | ||||
| MLoopCol *mloopcol; | MLoopCol *mloopcol; | ||||
| MLoopCol *mloopcol_wet; | MLoopCol *mloopcol_wet; | ||||
| }; | }; | ||||
| static void dynamic_paint_apply_surface_displace_cb(void *__restrict userdata, | static void dynamic_paint_apply_surface_displace_cb(void *__restrict userdata, | ||||
| ▲ Show 20 Lines • Show All 52 Lines • ▼ Show 20 Lines | |||||
| static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata, | static void dynamic_paint_apply_surface_vpaint_cb(void *__restrict userdata, | ||||
| const int p_index, | const int p_index, | ||||
| const TaskParallelTLS *__restrict /*tls*/) | const TaskParallelTLS *__restrict /*tls*/) | ||||
| { | { | ||||
| const DynamicPaintModifierApplyData *data = static_cast<DynamicPaintModifierApplyData *>( | const DynamicPaintModifierApplyData *data = static_cast<DynamicPaintModifierApplyData *>( | ||||
| userdata); | userdata); | ||||
| const MLoop *mloop = data->mloop; | const int *corner_verts = data->corner_verts; | ||||
| const MPoly *mpoly = data->mpoly; | const MPoly *mpoly = data->mpoly; | ||||
| const DynamicPaintSurface *surface = data->surface; | const DynamicPaintSurface *surface = data->surface; | ||||
| PaintPoint *pPoint = (PaintPoint *)surface->data->type_data; | PaintPoint *pPoint = (PaintPoint *)surface->data->type_data; | ||||
| float(*fcolor)[4] = data->fcolor; | float(*fcolor)[4] = data->fcolor; | ||||
| MLoopCol *mloopcol = data->mloopcol; | MLoopCol *mloopcol = data->mloopcol; | ||||
| MLoopCol *mloopcol_wet = data->mloopcol_wet; | MLoopCol *mloopcol_wet = data->mloopcol_wet; | ||||
| for (int j = 0; j < mpoly[p_index].totloop; j++) { | for (int j = 0; j < mpoly[p_index].totloop; j++) { | ||||
| const int l_index = mpoly[p_index].loopstart + j; | const int l_index = mpoly[p_index].loopstart + j; | ||||
| const int v_index = mloop[l_index].v; | const int v_index = corner_verts[l_index]; | ||||
| /* save layer data to output layer */ | /* save layer data to output layer */ | ||||
| /* apply color */ | /* apply color */ | ||||
| if (mloopcol) { | if (mloopcol) { | ||||
| rgba_float_to_uchar((uchar *)&mloopcol[l_index].r, fcolor[v_index]); | rgba_float_to_uchar((uchar *)&mloopcol[l_index].r, fcolor[v_index]); | ||||
| } | } | ||||
| /* apply wetness */ | /* apply wetness */ | ||||
| if (mloopcol_wet) { | if (mloopcol_wet) { | ||||
| Show All 40 Lines | |||||
| continue; | continue; | ||||
| } | } | ||||
| /* process vertex surface previews */ | /* process vertex surface previews */ | ||||
| if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | if (surface->format == MOD_DPAINT_SURFACE_F_VERTEX) { | ||||
| /* vertex color paint */ | /* vertex color paint */ | ||||
| if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) { | if (surface->type == MOD_DPAINT_SURFACE_T_PAINT) { | ||||
| const MLoop *mloop = BKE_mesh_loops(result); | const blender::Span<int> corner_verts = mesh->corner_verts(); | ||||
| const int totloop = result->totloop; | const int totloop = result->totloop; | ||||
| const MPoly *mpoly = BKE_mesh_polys(result); | const MPoly *mpoly = BKE_mesh_polys(result); | ||||
| const int totpoly = result->totpoly; | const int totpoly = result->totpoly; | ||||
| /* paint is stored on dry and wet layers, so mix final color first */ | /* paint is stored on dry and wet layers, so mix final color first */ | ||||
| float(*fcolor)[4] = static_cast<float(*)[4]>( | float(*fcolor)[4] = static_cast<float(*)[4]>( | ||||
| MEM_callocN(sizeof(*fcolor) * sData->total_points, "Temp paint color")); | MEM_callocN(sizeof(*fcolor) * sData->total_points, "Temp paint color")); | ||||
| Show All 35 Lines | |||||
| CD_PROP_BYTE_COLOR, | CD_PROP_BYTE_COLOR, | ||||
| CD_SET_DEFAULT, | CD_SET_DEFAULT, | ||||
| nullptr, | nullptr, | ||||
| totloop, | totloop, | ||||
| surface->output_name2)); | surface->output_name2)); | ||||
| } | } | ||||
| data.ob = ob; | data.ob = ob; | ||||
| data.mloop = mloop; | data.corner_verts = corner_verts.data(); | ||||
| data.mpoly = mpoly; | data.mpoly = mpoly; | ||||
| data.mloopcol = mloopcol; | data.mloopcol = mloopcol; | ||||
| data.mloopcol_wet = mloopcol_wet; | data.mloopcol_wet = mloopcol_wet; | ||||
| { | { | ||||
| TaskParallelSettings settings; | TaskParallelSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.use_threading = (totpoly > 1000); | settings.use_threading = (totpoly > 1000); | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| struct DynamicPaintCreateUVSurfaceData { | struct DynamicPaintCreateUVSurfaceData { | ||||
| const DynamicPaintSurface *surface; | const DynamicPaintSurface *surface; | ||||
| PaintUVPoint *tempPoints; | PaintUVPoint *tempPoints; | ||||
| Vec3f *tempWeights; | Vec3f *tempWeights; | ||||
| const MLoopTri *mlooptri; | const MLoopTri *mlooptri; | ||||
| const float (*mloopuv)[2]; | const float (*mloopuv)[2]; | ||||
| const MLoop *mloop; | const int *corner_verts; | ||||
| int tottri; | int tottri; | ||||
| const Bounds2D *faceBB; | const Bounds2D *faceBB; | ||||
| uint32_t *active_points; | uint32_t *active_points; | ||||
| }; | }; | ||||
| static void dynamic_paint_create_uv_surface_direct_cb(void *__restrict userdata, | static void dynamic_paint_create_uv_surface_direct_cb(void *__restrict userdata, | ||||
| const int ty, | const int ty, | ||||
| const TaskParallelTLS *__restrict /*tls*/) | const TaskParallelTLS *__restrict /*tls*/) | ||||
| { | { | ||||
| const DynamicPaintCreateUVSurfaceData *data = | const DynamicPaintCreateUVSurfaceData *data = | ||||
| static_cast<const DynamicPaintCreateUVSurfaceData *>(userdata); | static_cast<const DynamicPaintCreateUVSurfaceData *>(userdata); | ||||
| const DynamicPaintSurface *surface = data->surface; | const DynamicPaintSurface *surface = data->surface; | ||||
| PaintUVPoint *tempPoints = data->tempPoints; | PaintUVPoint *tempPoints = data->tempPoints; | ||||
| Vec3f *tempWeights = data->tempWeights; | Vec3f *tempWeights = data->tempWeights; | ||||
| const MLoopTri *mlooptri = data->mlooptri; | const MLoopTri *mlooptri = data->mlooptri; | ||||
| const float(*mloopuv)[2] = data->mloopuv; | const float(*mloopuv)[2] = data->mloopuv; | ||||
| const MLoop *mloop = data->mloop; | const int *corner_verts = data->corner_verts; | ||||
| const int tottri = data->tottri; | const int tottri = data->tottri; | ||||
| const Bounds2D *faceBB = data->faceBB; | const Bounds2D *faceBB = data->faceBB; | ||||
| const float jitter5sample[10] = JITTER_SAMPLES; | const float jitter5sample[10] = JITTER_SAMPLES; | ||||
| const int aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1; | const int aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1; | ||||
| const int w = surface->image_resolution; | const int w = surface->image_resolution; | ||||
| const int h = w; | const int h = w; | ||||
| ▲ Show 20 Lines • Show All 55 Lines • ▼ Show 20 Lines | |||||
| barycentric_weights_v2(uv1, uv2, uv3, uv, tempWeights[index * aa_samples + j].v); | barycentric_weights_v2(uv1, uv2, uv3, uv, tempWeights[index * aa_samples + j].v); | ||||
| } | } | ||||
| /* Set surface point face values */ | /* Set surface point face values */ | ||||
| tPoint->tri_index = i; | tPoint->tri_index = i; | ||||
| /* save vertex indexes */ | /* save vertex indexes */ | ||||
| tPoint->v1 = mloop[mlooptri[i].tri[0]].v; | tPoint->v1 = corner_verts[mlooptri[i].tri[0]]; | ||||
| tPoint->v2 = mloop[mlooptri[i].tri[1]].v; | tPoint->v2 = corner_verts[mlooptri[i].tri[1]]; | ||||
| tPoint->v3 = mloop[mlooptri[i].tri[2]].v; | tPoint->v3 = corner_verts[mlooptri[i].tri[2]]; | ||||
| sample = 5; /* make sure we exit sample loop as well */ | sample = 5; /* make sure we exit sample loop as well */ | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| static void dynamic_paint_create_uv_surface_neighbor_cb(void *__restrict userdata, | static void dynamic_paint_create_uv_surface_neighbor_cb(void *__restrict userdata, | ||||
| const int ty, | const int ty, | ||||
| const TaskParallelTLS *__restrict /*tls*/) | const TaskParallelTLS *__restrict /*tls*/) | ||||
| { | { | ||||
| const DynamicPaintCreateUVSurfaceData *data = | const DynamicPaintCreateUVSurfaceData *data = | ||||
| static_cast<const DynamicPaintCreateUVSurfaceData *>(userdata); | static_cast<const DynamicPaintCreateUVSurfaceData *>(userdata); | ||||
| const DynamicPaintSurface *surface = data->surface; | const DynamicPaintSurface *surface = data->surface; | ||||
| PaintUVPoint *tempPoints = data->tempPoints; | PaintUVPoint *tempPoints = data->tempPoints; | ||||
| Vec3f *tempWeights = data->tempWeights; | Vec3f *tempWeights = data->tempWeights; | ||||
| const MLoopTri *mlooptri = data->mlooptri; | const MLoopTri *mlooptri = data->mlooptri; | ||||
| const float(*mloopuv)[2] = data->mloopuv; | const float(*mloopuv)[2] = data->mloopuv; | ||||
| const MLoop *mloop = data->mloop; | const int *corner_verts = data->corner_verts; | ||||
| uint32_t *active_points = data->active_points; | uint32_t *active_points = data->active_points; | ||||
| const float jitter5sample[10] = JITTER_SAMPLES; | const float jitter5sample[10] = JITTER_SAMPLES; | ||||
| const int aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1; | const int aa_samples = (surface->flags & MOD_DPAINT_ANTIALIAS) ? 5 : 1; | ||||
| const int w = surface->image_resolution; | const int w = surface->image_resolution; | ||||
| const int h = w; | const int h = w; | ||||
| ▲ Show 20 Lines • Show All 48 Lines • ▼ Show 20 Lines | |||||
| /* Add b-weights per anti-aliasing sample */ | /* Add b-weights per anti-aliasing sample */ | ||||
| for (int j = 0; j < aa_samples; j++) { | for (int j = 0; j < aa_samples; j++) { | ||||
| uv[0] = point[0] + jitter5sample[j * 2] / w; | uv[0] = point[0] + jitter5sample[j * 2] / w; | ||||
| uv[1] = point[1] + jitter5sample[j * 2 + 1] / h; | uv[1] = point[1] + jitter5sample[j * 2 + 1] / h; | ||||
| barycentric_weights_v2(uv1, uv2, uv3, uv, tempWeights[index * aa_samples + j].v); | barycentric_weights_v2(uv1, uv2, uv3, uv, tempWeights[index * aa_samples + j].v); | ||||
| } | } | ||||
| /* save vertex indexes */ | /* save vertex indexes */ | ||||
| tPoint->v1 = mloop[mlooptri[i].tri[0]].v; | tPoint->v1 = corner_verts[mlooptri[i].tri[0]]; | ||||
| tPoint->v2 = mloop[mlooptri[i].tri[1]].v; | tPoint->v2 = corner_verts[mlooptri[i].tri[1]]; | ||||
| tPoint->v3 = mloop[mlooptri[i].tri[2]].v; | tPoint->v3 = corner_verts[mlooptri[i].tri[2]]; | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| ▲ Show 20 Lines • Show All 124 Lines • ▼ Show 20 Lines | |||||
| static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceData *data, | static void dynamic_paint_find_island_border(const DynamicPaintCreateUVSurfaceData *data, | ||||
| DynamicPaintFindIslandBorderData *bdata, | DynamicPaintFindIslandBorderData *bdata, | ||||
| int tri_index, | int tri_index, | ||||
| const float pixel[2], | const float pixel[2], | ||||
| int in_edge, | int in_edge, | ||||
| int depth) | int depth) | ||||
| { | { | ||||
| const MLoop *mloop = data->mloop; | const int *corner_verts = data->corner_verts; | ||||
| const MLoopTri *mlooptri = data->mlooptri; | const MLoopTri *mlooptri = data->mlooptri; | ||||
| const float(*mloopuv)[2] = data->mloopuv; | const float(*mloopuv)[2] = data->mloopuv; | ||||
| const uint *loop_idx = mlooptri[tri_index].tri; | const uint *loop_idx = mlooptri[tri_index].tri; | ||||
| /* Enumerate all edges of the triangle, rotating the vertex list accordingly. */ | /* Enumerate all edges of the triangle, rotating the vertex list accordingly. */ | ||||
| for (int edge_idx = 0; edge_idx < 3; edge_idx++) { | for (int edge_idx = 0; edge_idx < 3; edge_idx++) { | ||||
| /* but not the edge we have just recursed through */ | /* but not the edge we have just recursed through */ | ||||
| Show All 21 Lines | |||||
| (sidep > 0 && side2 < 0); | (sidep > 0 && side2 < 0); | ||||
| /* Allow exactly on edge for the non-recursive case */ | /* Allow exactly on edge for the non-recursive case */ | ||||
| if (!correct_side && sidep != 0.0f) { | if (!correct_side && sidep != 0.0f) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| /* Now find another face that is linked to that edge. */ | /* Now find another face that is linked to that edge. */ | ||||
| const int vert0 = mloop[loop_idx[(edge_idx + 0)]].v; | const int vert0 = corner_verts[loop_idx[(edge_idx + 0)]]; | ||||
| const int vert1 = mloop[loop_idx[(edge_idx + 1) % 3]].v; | const int vert1 = corner_verts[loop_idx[(edge_idx + 1) % 3]]; | ||||
| /* Use a pre-computed vert-to-looptri mapping, | /* Use a pre-computed vert-to-looptri mapping, | ||||
| * speeds up things a lot compared to looping over all looptri. */ | * speeds up things a lot compared to looping over all looptri. */ | ||||
| const MeshElemMap *map = &bdata->vert_to_looptri_map[vert0]; | const MeshElemMap *map = &bdata->vert_to_looptri_map[vert0]; | ||||
| bool found_other = false; | bool found_other = false; | ||||
| int target_tri = -1; | int target_tri = -1; | ||||
| int target_edge = -1; | int target_edge = -1; | ||||
| float ouv0[2], ouv1[2]; | float ouv0[2], ouv1[2]; | ||||
| for (int i = 0; i < map->count && !found_other; i++) { | for (int i = 0; i < map->count && !found_other; i++) { | ||||
| const int lt_index = map->indices[i]; | const int lt_index = map->indices[i]; | ||||
| if (lt_index == tri_index) { | if (lt_index == tri_index) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| const uint *other_loop_idx = mlooptri[lt_index].tri; | const uint *other_loop_idx = mlooptri[lt_index].tri; | ||||
| /* Check edges for match, looping in the same order as the outer loop. */ | /* Check edges for match, looping in the same order as the outer loop. */ | ||||
| for (int j = 0; j < 3; j++) { | for (int j = 0; j < 3; j++) { | ||||
| const int overt0 = mloop[other_loop_idx[(j + 0)]].v; | const int overt0 = corner_verts[other_loop_idx[(j + 0)]]; | ||||
| const int overt1 = mloop[other_loop_idx[(j + 1) % 3]].v; | const int overt1 = corner_verts[other_loop_idx[(j + 1) % 3]]; | ||||
| /* Allow for swapped vertex order */ | /* Allow for swapped vertex order */ | ||||
| if (overt0 == vert0 && overt1 == vert1) { | if (overt0 == vert0 && overt1 == vert1) { | ||||
| found_other = true; | found_other = true; | ||||
| copy_v2_v2(ouv0, mloopuv[other_loop_idx[(j + 0)]]); | copy_v2_v2(ouv0, mloopuv[other_loop_idx[(j + 0)]]); | ||||
| copy_v2_v2(ouv1, mloopuv[other_loop_idx[(j + 1) % 3]]); | copy_v2_v2(ouv1, mloopuv[other_loop_idx[(j + 1) % 3]]); | ||||
| } | } | ||||
| else if (overt0 == vert1 && overt1 == vert0) { | else if (overt0 == vert1 && overt1 == vert0) { | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| PaintSurfaceData *sData; | PaintSurfaceData *sData; | ||||
| DynamicPaintCanvasSettings *canvas = surface->canvas; | DynamicPaintCanvasSettings *canvas = surface->canvas; | ||||
| Mesh *mesh = dynamicPaint_canvas_mesh_get(canvas); | Mesh *mesh = dynamicPaint_canvas_mesh_get(canvas); | ||||
| PaintUVPoint *tempPoints = nullptr; | PaintUVPoint *tempPoints = nullptr; | ||||
| Vec3f *tempWeights = nullptr; | Vec3f *tempWeights = nullptr; | ||||
| const MLoopTri *mlooptri = nullptr; | const MLoopTri *mlooptri = nullptr; | ||||
| const float(*mloopuv)[2] = nullptr; | const float(*mloopuv)[2] = nullptr; | ||||
| const MLoop *mloop = nullptr; | |||||
| Bounds2D *faceBB = nullptr; | Bounds2D *faceBB = nullptr; | ||||
| int *final_index; | int *final_index; | ||||
| *progress = 0.0f; | *progress = 0.0f; | ||||
| *do_update = true; | *do_update = true; | ||||
| if (!mesh) { | if (!mesh) { | ||||
| return setError(canvas, N_("Canvas mesh not updated")); | return setError(canvas, N_("Canvas mesh not updated")); | ||||
| } | } | ||||
| if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ) { | if (surface->format != MOD_DPAINT_SURFACE_F_IMAGESEQ) { | ||||
| return setError(canvas, N_("Cannot bake non-'image sequence' formats")); | return setError(canvas, N_("Cannot bake non-'image sequence' formats")); | ||||
| } | } | ||||
| mloop = BKE_mesh_loops(mesh); | const blender::Span<int> corner_verts = mesh->corner_verts(); | ||||
| mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); | mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); | ||||
| const int tottri = BKE_mesh_runtime_looptri_len(mesh); | const int tottri = BKE_mesh_runtime_looptri_len(mesh); | ||||
| /* get uv map */ | /* get uv map */ | ||||
| if (CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) { | if (CustomData_has_layer(&mesh->ldata, CD_PROP_FLOAT2)) { | ||||
| CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, surface->uvlayer_name, uvname); | CustomData_validate_layer_name(&mesh->ldata, CD_PROP_FLOAT2, surface->uvlayer_name, uvname); | ||||
| mloopuv = static_cast<const float(*)[2]>( | mloopuv = static_cast<const float(*)[2]>( | ||||
| CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname)); | CustomData_get_layer_named(&mesh->ldata, CD_PROP_FLOAT2, uvname)); | ||||
| ▲ Show 20 Lines • Show All 71 Lines • ▼ Show 20 Lines | |||||
| /* Loop through every pixel and check if pixel is uv-mapped on a canvas face. */ | /* Loop through every pixel and check if pixel is uv-mapped on a canvas face. */ | ||||
| DynamicPaintCreateUVSurfaceData data{}; | DynamicPaintCreateUVSurfaceData data{}; | ||||
| data.surface = surface; | data.surface = surface; | ||||
| data.tempPoints = tempPoints; | data.tempPoints = tempPoints; | ||||
| data.tempWeights = tempWeights; | data.tempWeights = tempWeights; | ||||
| data.mlooptri = mlooptri; | data.mlooptri = mlooptri; | ||||
| data.mloopuv = mloopuv; | data.mloopuv = mloopuv; | ||||
| data.mloop = mloop; | data.corner_verts = corner_verts.data(); | ||||
| data.tottri = tottri; | data.tottri = tottri; | ||||
| data.faceBB = faceBB; | data.faceBB = faceBB; | ||||
| { | { | ||||
| TaskParallelSettings settings; | TaskParallelSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| settings.use_threading = (h > 64 || tottri > 1000); | settings.use_threading = (h > 64 || tottri > 1000); | ||||
| BLI_task_parallel_range(0, h, &data, dynamic_paint_create_uv_surface_direct_cb, &settings); | BLI_task_parallel_range(0, h, &data, dynamic_paint_create_uv_surface_direct_cb, &settings); | ||||
| ▲ Show 20 Lines • Show All 42 Lines • ▼ Show 20 Lines | |||||
| MeshElemMap *vert_to_looptri_map; | MeshElemMap *vert_to_looptri_map; | ||||
| int *vert_to_looptri_map_mem; | int *vert_to_looptri_map_mem; | ||||
| BKE_mesh_vert_looptri_map_create(&vert_to_looptri_map, | BKE_mesh_vert_looptri_map_create(&vert_to_looptri_map, | ||||
| &vert_to_looptri_map_mem, | &vert_to_looptri_map_mem, | ||||
| mesh->totvert, | mesh->totvert, | ||||
| mlooptri, | mlooptri, | ||||
| tottri, | tottri, | ||||
| mloop, | corner_verts.data(), | ||||
| mesh->totloop); | mesh->totloop); | ||||
| int total_border = 0; | int total_border = 0; | ||||
| for (int ty = 0; ty < h; ty++) { | for (int ty = 0; ty < h; ty++) { | ||||
| for (int tx = 0; tx < w; tx++) { | for (int tx = 0; tx < w; tx++) { | ||||
| const int index = tx + w * ty; | const int index = tx + w * ty; | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| static void mesh_tris_spherecast_dp(void *userdata, | static void mesh_tris_spherecast_dp(void *userdata, | ||||
| int index, | int index, | ||||
| const BVHTreeRay *ray, | const BVHTreeRay *ray, | ||||
| BVHTreeRayHit *hit) | BVHTreeRayHit *hit) | ||||
| { | { | ||||
| const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; | const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; | ||||
| const float(*positions)[3] = data->vert_positions; | const float(*positions)[3] = data->vert_positions; | ||||
| const MLoopTri *mlooptri = data->looptri; | const MLoopTri *mlooptri = data->looptri; | ||||
| const MLoop *mloop = data->loop; | const int *corner_verts = data->corner_verts; | ||||
| const float *t0, *t1, *t2; | const float *t0, *t1, *t2; | ||||
| float dist; | float dist; | ||||
| t0 = positions[mloop[mlooptri[index].tri[0]].v]; | t0 = positions[corner_verts[mlooptri[index].tri[0]]]; | ||||
| t1 = positions[mloop[mlooptri[index].tri[1]].v]; | t1 = positions[corner_verts[mlooptri[index].tri[1]]]; | ||||
| t2 = positions[mloop[mlooptri[index].tri[2]].v]; | t2 = positions[corner_verts[mlooptri[index].tri[2]]]; | ||||
| dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2); | dist = bvhtree_ray_tri_intersection(ray, hit->dist, t0, t1, t2); | ||||
| if (dist >= 0 && dist < hit->dist) { | if (dist >= 0 && dist < hit->dist) { | ||||
| hit->index = index; | hit->index = index; | ||||
| hit->dist = dist; | hit->dist = dist; | ||||
| hit->no[0] = 0.0f; | hit->no[0] = 0.0f; | ||||
| } | } | ||||
| } | } | ||||
| /* A modified callback to bvh tree nearest point. | /* A modified callback to bvh tree nearest point. | ||||
| * The tree must have been built using bvhtree_from_mesh_looptri. | * The tree must have been built using bvhtree_from_mesh_looptri. | ||||
| * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. | * userdata must be a BVHMeshCallbackUserdata built from the same mesh as the tree. | ||||
| * | * | ||||
| * To optimize brush detection speed this doesn't calculate hit normal. | * To optimize brush detection speed this doesn't calculate hit normal. | ||||
| */ | */ | ||||
| static void mesh_tris_nearest_point_dp(void *userdata, | static void mesh_tris_nearest_point_dp(void *userdata, | ||||
| int index, | int index, | ||||
| const float co[3], | const float co[3], | ||||
| BVHTreeNearest *nearest) | BVHTreeNearest *nearest) | ||||
| { | { | ||||
| const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; | const BVHTreeFromMesh *data = (BVHTreeFromMesh *)userdata; | ||||
| const float(*positions)[3] = data->vert_positions; | const float(*positions)[3] = data->vert_positions; | ||||
| const MLoopTri *mlooptri = data->looptri; | const MLoopTri *mlooptri = data->looptri; | ||||
| const MLoop *mloop = data->loop; | const int *corner_verts = data->corner_verts; | ||||
| float nearest_tmp[3], dist_sq; | float nearest_tmp[3], dist_sq; | ||||
| const float *t0, *t1, *t2; | const float *t0, *t1, *t2; | ||||
| t0 = positions[mloop[mlooptri[index].tri[0]].v]; | t0 = positions[corner_verts[mlooptri[index].tri[0]]]; | ||||
| t1 = positions[mloop[mlooptri[index].tri[1]].v]; | t1 = positions[corner_verts[mlooptri[index].tri[1]]]; | ||||
| t2 = positions[mloop[mlooptri[index].tri[2]].v]; | t2 = positions[corner_verts[mlooptri[index].tri[2]]]; | ||||
| closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2); | closest_on_tri_to_point_v3(nearest_tmp, co, t0, t1, t2); | ||||
| dist_sq = len_squared_v3v3(co, nearest_tmp); | dist_sq = len_squared_v3v3(co, nearest_tmp); | ||||
| if (dist_sq < nearest->dist_sq) { | if (dist_sq < nearest->dist_sq) { | ||||
| nearest->index = index; | nearest->index = index; | ||||
| nearest->dist_sq = dist_sq; | nearest->dist_sq = dist_sq; | ||||
| copy_v3_v3(nearest->co, nearest_tmp); | copy_v3_v3(nearest->co, nearest_tmp); | ||||
| ▲ Show 20 Lines • Show All 184 Lines • ▼ Show 20 Lines | |||||
| const DynamicPaintBrushSettings *brush; | const DynamicPaintBrushSettings *brush; | ||||
| Object *brushOb; | Object *brushOb; | ||||
| const Scene *scene; | const Scene *scene; | ||||
| float timescale; | float timescale; | ||||
| int c_index; | int c_index; | ||||
| Mesh *mesh; | Mesh *mesh; | ||||
| const float (*positions)[3]; | const float (*positions)[3]; | ||||
| const MLoop *mloop; | const int *corner_verts; | ||||
| const MLoopTri *mlooptri; | const MLoopTri *mlooptri; | ||||
| float brush_radius; | float brush_radius; | ||||
| const float *avg_brushNor; | const float *avg_brushNor; | ||||
| const Vec3f *brushVelocity; | const Vec3f *brushVelocity; | ||||
| const ParticleSystem *psys; | const ParticleSystem *psys; | ||||
| float solidradius; | float solidradius; | ||||
| Show All 17 Lines | |||||
| VolumeGrid *grid = bData->grid; | VolumeGrid *grid = bData->grid; | ||||
| const DynamicPaintBrushSettings *brush = data->brush; | const DynamicPaintBrushSettings *brush = data->brush; | ||||
| const float timescale = data->timescale; | const float timescale = data->timescale; | ||||
| const int c_index = data->c_index; | const int c_index = data->c_index; | ||||
| const float(*positions)[3] = data->positions; | const float(*positions)[3] = data->positions; | ||||
| const MLoop *mloop = data->mloop; | const int *corner_verts = data->corner_verts; | ||||
| const MLoopTri *mlooptri = data->mlooptri; | const MLoopTri *mlooptri = data->mlooptri; | ||||
| const float brush_radius = data->brush_radius; | const float brush_radius = data->brush_radius; | ||||
| const float *avg_brushNor = data->avg_brushNor; | const float *avg_brushNor = data->avg_brushNor; | ||||
| const Vec3f *brushVelocity = data->brushVelocity; | const Vec3f *brushVelocity = data->brushVelocity; | ||||
| BVHTreeFromMesh *treeData = static_cast<BVHTreeFromMesh *>(data->treeData); | BVHTreeFromMesh *treeData = static_cast<BVHTreeFromMesh *>(data->treeData); | ||||
| const int index = grid->t_index[grid->s_pos[c_index] + id]; | const int index = grid->t_index[grid->s_pos[c_index] + id]; | ||||
| ▲ Show 20 Lines • Show All 57 Lines • ▼ Show 20 Lines | |||||
| if (ELEM(brush->collision, MOD_DPAINT_COL_VOLUME, MOD_DPAINT_COL_VOLDIST)) { | if (ELEM(brush->collision, MOD_DPAINT_COL_VOLUME, MOD_DPAINT_COL_VOLDIST)) { | ||||
| BLI_bvhtree_ray_cast( | BLI_bvhtree_ray_cast( | ||||
| treeData->tree, ray_start, ray_dir, 0.0f, &hit, mesh_tris_spherecast_dp, treeData); | treeData->tree, ray_start, ray_dir, 0.0f, &hit, mesh_tris_spherecast_dp, treeData); | ||||
| if (hit.index != -1) { | if (hit.index != -1) { | ||||
| /* We hit a triangle, now check if collision point normal is facing the point */ | /* We hit a triangle, now check if collision point normal is facing the point */ | ||||
| /* For optimization sake, hit point normal isn't calculated in ray cast loop */ | /* For optimization sake, hit point normal isn't calculated in ray cast loop */ | ||||
| const int vtri[3] = { | const int vtri[3] = { | ||||
| int(mloop[mlooptri[hit.index].tri[0]].v), | corner_verts[mlooptri[hit.index].tri[0]], | ||||
| int(mloop[mlooptri[hit.index].tri[1]].v), | corner_verts[mlooptri[hit.index].tri[1]], | ||||
| int(mloop[mlooptri[hit.index].tri[2]].v), | corner_verts[mlooptri[hit.index].tri[2]], | ||||
| }; | }; | ||||
| float dot; | float dot; | ||||
| normal_tri_v3(hit.no, positions[vtri[0]], positions[vtri[1]], positions[vtri[2]]); | normal_tri_v3(hit.no, positions[vtri[0]], positions[vtri[1]], positions[vtri[2]]); | ||||
| dot = dot_v3v3(ray_dir, hit.no); | dot = dot_v3v3(ray_dir, hit.no); | ||||
| /* If ray and hit face normal are facing same direction | /* If ray and hit face normal are facing same direction | ||||
| * hit point is inside a closed mesh. */ | * hit point is inside a closed mesh. */ | ||||
| ▲ Show 20 Lines • Show All 131 Lines • ▼ Show 20 Lines | |||||
| } | } | ||||
| /* velocity brush, only do on main sample */ | /* velocity brush, only do on main sample */ | ||||
| if (brush->flags & MOD_DPAINT_USES_VELOCITY && ss == 0 && brushVelocity) { | if (brush->flags & MOD_DPAINT_USES_VELOCITY && ss == 0 && brushVelocity) { | ||||
| float weights[3]; | float weights[3]; | ||||
| float brushPointVelocity[3]; | float brushPointVelocity[3]; | ||||
| float velocity[3]; | float velocity[3]; | ||||
| const int v1 = mloop[mlooptri[hitTri].tri[0]].v; | const int v1 = corner_verts[mlooptri[hitTri].tri[0]]; | ||||
| const int v2 = mloop[mlooptri[hitTri].tri[1]].v; | const int v2 = corner_verts[mlooptri[hitTri].tri[1]]; | ||||
| const int v3 = mloop[mlooptri[hitTri].tri[2]].v; | const int v3 = corner_verts[mlooptri[hitTri].tri[2]]; | ||||
| /* calculate barycentric weights for hit point */ | /* calculate barycentric weights for hit point */ | ||||
| interp_weights_tri_v3(weights, positions[v1], positions[v2], positions[v3], hitCoord); | interp_weights_tri_v3(weights, positions[v1], positions[v2], positions[v3], hitCoord); | ||||
| /* Simple check based on brush surface velocity, | /* Simple check based on brush surface velocity, | ||||
| * TODO: perhaps implement something that handles volume movement as well. */ | * TODO: perhaps implement something that handles volume movement as well. */ | ||||
| /* interpolate vertex speed vectors to get hit point velocity */ | /* interpolate vertex speed vectors to get hit point velocity */ | ||||
| ▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | |||||
| Scene *scene, | Scene *scene, | ||||
| float timescale) | float timescale) | ||||
| { | { | ||||
| PaintSurfaceData *sData = surface->data; | PaintSurfaceData *sData = surface->data; | ||||
| PaintBakeData *bData = sData->bData; | PaintBakeData *bData = sData->bData; | ||||
| Mesh *mesh = nullptr; | Mesh *mesh = nullptr; | ||||
| Vec3f *brushVelocity = nullptr; | Vec3f *brushVelocity = nullptr; | ||||
| const MLoopTri *mlooptri = nullptr; | const MLoopTri *mlooptri = nullptr; | ||||
| const MLoop *mloop = nullptr; | |||||
| if (brush->flags & MOD_DPAINT_USES_VELOCITY) { | if (brush->flags & MOD_DPAINT_USES_VELOCITY) { | ||||
| dynamicPaint_brushMeshCalculateVelocity( | dynamicPaint_brushMeshCalculateVelocity( | ||||
| depsgraph, scene, brushOb, brush, &brushVelocity, timescale); | depsgraph, scene, brushOb, brush, &brushVelocity, timescale); | ||||
| } | } | ||||
| Mesh *brush_mesh = dynamicPaint_brush_mesh_get(brush); | Mesh *brush_mesh = dynamicPaint_brush_mesh_get(brush); | ||||
| if (brush_mesh == nullptr) { | if (brush_mesh == nullptr) { | ||||
| return false; | return false; | ||||
| } | } | ||||
| { | { | ||||
| BVHTreeFromMesh treeData = {nullptr}; | BVHTreeFromMesh treeData = {nullptr}; | ||||
| float avg_brushNor[3] = {0.0f}; | float avg_brushNor[3] = {0.0f}; | ||||
| const float brush_radius = brush->paint_distance * surface->radius_scale; | const float brush_radius = brush->paint_distance * surface->radius_scale; | ||||
| int numOfVerts; | int numOfVerts; | ||||
| int ii; | int ii; | ||||
| Bounds3D mesh_bb = {{0}}; | Bounds3D mesh_bb = {{0}}; | ||||
| VolumeGrid *grid = bData->grid; | VolumeGrid *grid = bData->grid; | ||||
| mesh = BKE_mesh_copy_for_eval(brush_mesh, false); | mesh = BKE_mesh_copy_for_eval(brush_mesh, false); | ||||
| float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh); | float(*positions)[3] = BKE_mesh_vert_positions_for_write(mesh); | ||||
| const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); | const float(*vert_normals)[3] = BKE_mesh_vertex_normals_ensure(mesh); | ||||
| mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); | mlooptri = BKE_mesh_runtime_looptri_ensure(mesh); | ||||
| mloop = BKE_mesh_loops(mesh); | const blender::Span<int> corner_verts = mesh->corner_verts(); | ||||
| numOfVerts = mesh->totvert; | numOfVerts = mesh->totvert; | ||||
| /* Transform collider vertices to global space | /* Transform collider vertices to global space | ||||
| * (Faster than transforming per surface point | * (Faster than transforming per surface point | ||||
| * coordinates and normals to object space) */ | * coordinates and normals to object space) */ | ||||
| for (ii = 0; ii < numOfVerts; ii++) { | for (ii = 0; ii < numOfVerts; ii++) { | ||||
| mul_m4_v3(brushOb->object_to_world, positions[ii]); | mul_m4_v3(brushOb->object_to_world, positions[ii]); | ||||
| boundInsert(&mesh_bb, positions[ii]); | boundInsert(&mesh_bb, positions[ii]); | ||||
| Show All 37 Lines | |||||
| data.surface = surface; | data.surface = surface; | ||||
| data.brush = brush; | data.brush = brush; | ||||
| data.brushOb = brushOb; | data.brushOb = brushOb; | ||||
| data.scene = scene; | data.scene = scene; | ||||
| data.timescale = timescale; | data.timescale = timescale; | ||||
| data.c_index = c_index; | data.c_index = c_index; | ||||
| data.mesh = mesh; | data.mesh = mesh; | ||||
| data.positions = positions; | data.positions = positions; | ||||
| data.mloop = mloop; | data.corner_verts = corner_verts.data(); | ||||
| data.mlooptri = mlooptri; | data.mlooptri = mlooptri; | ||||
| data.brush_radius = brush_radius; | data.brush_radius = brush_radius; | ||||
| data.avg_brushNor = avg_brushNor; | data.avg_brushNor = avg_brushNor; | ||||
| data.brushVelocity = brushVelocity; | data.brushVelocity = brushVelocity; | ||||
| data.treeData = &treeData; | data.treeData = &treeData; | ||||
| TaskParallelSettings settings; | TaskParallelSettings settings; | ||||
| BLI_parallel_range_settings_defaults(&settings); | BLI_parallel_range_settings_defaults(&settings); | ||||
| ▲ Show 20 Lines • Show All 92 Lines • Show Last 20 Lines | |||||