Changeset View
Changeset View
Standalone View
Standalone View
source/blender/geometry/intern/add_curves_on_mesh.cc
| Show First 20 Lines • Show All 297 Lines • ▼ Show 20 Lines | AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, | ||||
| for (const int i : new_curves_range) { | for (const int i : new_curves_range) { | ||||
| curve_offsets[i + 1] += curve_offsets[i]; | curve_offsets[i + 1] += curve_offsets[i]; | ||||
| } | } | ||||
| const int new_points_num = curves.offsets().last(); | const int new_points_num = curves.offsets().last(); | ||||
| curves.resize(new_points_num, new_curves_num); | curves.resize(new_points_num, new_curves_num); | ||||
| MutableSpan<float3> positions_cu = curves.positions_for_write(); | MutableSpan<float3> positions_cu = curves.positions_for_write(); | ||||
| /* The new elements are added at the end of the arrays. */ | |||||
| outputs.new_points_range = curves.points_range().drop_front(old_points_num); | |||||
| outputs.new_curves_range = curves.curves_range().drop_front(old_curves_num); | |||||
| /* Initialize attachment information. */ | /* Initialize attachment information. */ | ||||
| MutableSpan<float2> surface_uv_coords = curves.surface_uv_coords_for_write(); | MutableSpan<float2> surface_uv_coords = curves.surface_uv_coords_for_write(); | ||||
| surface_uv_coords.take_back(added_curves_num).copy_from(used_uvs); | surface_uv_coords.take_back(added_curves_num).copy_from(used_uvs); | ||||
| /* Determine length of new curves. */ | /* Determine length of new curves. */ | ||||
| Array<float> new_lengths_cu(added_curves_num); | Array<float> new_lengths_cu(added_curves_num); | ||||
| if (inputs.interpolate_length) { | if (inputs.interpolate_length) { | ||||
| interpolate_from_neighbors<float>( | interpolate_from_neighbors<float>( | ||||
| Show All 19 Lines | AddCurvesOnMeshOutputs add_curves_on_mesh(CurvesGeometry &curves, | ||||
| Array<float3> new_normals_su(added_curves_num); | Array<float3> new_normals_su(added_curves_num); | ||||
| threading::parallel_for(IndexRange(added_curves_num), 256, [&](const IndexRange range) { | threading::parallel_for(IndexRange(added_curves_num), 256, [&](const IndexRange range) { | ||||
| for (const int i : range) { | for (const int i : range) { | ||||
| new_normals_su[i] = compute_surface_point_normal( | new_normals_su[i] = compute_surface_point_normal( | ||||
| *looptris[i], bary_coords[i], inputs.corner_normals_su); | *looptris[i], bary_coords[i], inputs.corner_normals_su); | ||||
| } | } | ||||
| }); | }); | ||||
| /* Update selection arrays when available. */ | |||||
| const VArray<float> points_selection = curves.selection_point_float(); | |||||
| if (points_selection.is_span()) { | |||||
| MutableSpan<float> points_selection_span = curves.selection_point_float_for_write(); | |||||
| points_selection_span.drop_front(old_points_num).fill(1.0f); | |||||
| } | |||||
| const VArray<float> curves_selection = curves.selection_curve_float(); | |||||
| if (curves_selection.is_span()) { | |||||
| MutableSpan<float> curves_selection_span = curves.selection_curve_float_for_write(); | |||||
| curves_selection_span.slice(new_curves_range).fill(1.0f); | |||||
| } | |||||
| /* Initialize position attribute. */ | /* Initialize position attribute. */ | ||||
| if (inputs.interpolate_shape) { | if (inputs.interpolate_shape) { | ||||
| interpolate_position_with_interpolation(curves, | interpolate_position_with_interpolation(curves, | ||||
| root_positions_cu, | root_positions_cu, | ||||
| neighbors_per_curve, | neighbors_per_curve, | ||||
| old_curves_num, | old_curves_num, | ||||
| new_lengths_cu, | new_lengths_cu, | ||||
| new_normals_su, | new_normals_su, | ||||
| *inputs.transforms, | *inputs.transforms, | ||||
| inputs.surface_looptris, | inputs.surface_looptris, | ||||
| *inputs.reverse_uv_sampler, | *inputs.reverse_uv_sampler, | ||||
| inputs.corner_normals_su); | inputs.corner_normals_su); | ||||
| } | } | ||||
| else { | else { | ||||
| interpolate_position_without_interpolation(curves, | interpolate_position_without_interpolation(curves, | ||||
| old_curves_num, | old_curves_num, | ||||
| root_positions_cu, | root_positions_cu, | ||||
| new_lengths_cu, | new_lengths_cu, | ||||
| new_normals_su, | new_normals_su, | ||||
| inputs.transforms->surface_to_curves_normal); | inputs.transforms->surface_to_curves_normal); | ||||
| } | } | ||||
| curves.fill_curve_types(new_curves_range, CURVE_TYPE_CATMULL_ROM); | curves.fill_curve_types(new_curves_range, CURVE_TYPE_CATMULL_ROM); | ||||
| /* Explicitly set all other attributes besides those processed above to default values. */ | |||||
| bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); | bke::MutableAttributeAccessor attributes = curves.attributes_for_write(); | ||||
| Set<std::string> attributes_to_skip{{"position", | |||||
| "curve_type", | /* Explicitly set all other attributes besides those processed above to default values. */ | ||||
| "surface_uv_coordinate", | Set<std::string> attributes_to_skip{{"position", "curve_type", "surface_uv_coordinate"}}; | ||||
| ".selection_point_float", | |||||
| ".selection_curve_float"}}; | |||||
| attributes.for_all( | attributes.for_all( | ||||
| [&](const bke::AttributeIDRef &id, const bke::AttributeMetaData /*meta_data*/) { | [&](const bke::AttributeIDRef &id, const bke::AttributeMetaData /*meta_data*/) { | ||||
| if (id.is_named() && attributes_to_skip.contains(id.name())) { | if (id.is_named() && attributes_to_skip.contains(id.name())) { | ||||
| return true; | return true; | ||||
| } | } | ||||
| bke::GSpanAttributeWriter attribute = attributes.lookup_for_write_span(id); | bke::GSpanAttributeWriter attribute = attributes.lookup_for_write_span(id); | ||||
| /* The new elements are added at the end of the array. */ | |||||
| const int old_elements_num = attribute.domain == ATTR_DOMAIN_POINT ? old_points_num : | |||||
| old_curves_num; | |||||
| const CPPType &type = attribute.span.type(); | const CPPType &type = attribute.span.type(); | ||||
| GMutableSpan new_data = attribute.span.drop_front(old_elements_num); | GMutableSpan new_data = attribute.span.slice(attribute.domain == ATTR_DOMAIN_POINT ? | ||||
| outputs.new_points_range : | |||||
| outputs.new_curves_range); | |||||
| type.fill_assign_n(type.default_value(), new_data.data(), new_data.size()); | type.fill_assign_n(type.default_value(), new_data.data(), new_data.size()); | ||||
| attribute.finish(); | attribute.finish(); | ||||
| return true; | return true; | ||||
| }); | }); | ||||
| return outputs; | return outputs; | ||||
| } | } | ||||
| } // namespace blender::geometry | } // namespace blender::geometry | ||||