Changeset View
Changeset View
Standalone View
Standalone View
source/blender/geometry/intern/trim_curves.cc
| Show First 20 Lines • Show All 226 Lines • ▼ Show 20 Lines | if (src_range.cycles()) { | ||||
| dst_index += increment; | dst_index += increment; | ||||
| increment = src_range.size_after_loop(); | increment = src_range.size_after_loop(); | ||||
| dst_data.slice(dst_index, increment) | dst_data.slice(dst_index, increment) | ||||
| .copy_from(src_data.slice(src_range.curve_range().first(), increment)); | .copy_from(src_data.slice(src_range.curve_range().first(), increment)); | ||||
| dst_index += increment; | dst_index += increment; | ||||
| } | } | ||||
| else { | else { | ||||
| increment = src_range.one_after_last() - src_range.first(); | increment = src_range.one_after_last() - int64_t(src_range.first()); | ||||
| dst_data.slice(dst_index, increment).copy_from(src_data.slice(src_range.first(), increment)); | dst_data.slice(dst_index, increment).copy_from(src_data.slice(src_range.first(), increment)); | ||||
| dst_index += increment; | dst_index += increment; | ||||
| } | } | ||||
| return dst_index; | return dst_index; | ||||
| } | } | ||||
| /** \} */ | /** \} */ | ||||
| ▲ Show 20 Lines • Show All 215 Lines • ▼ Show 20 Lines | if (src_range.cycles() && increment > 0) { | ||||
| dst_handles_r.slice(dst_range_looped).copy_from(src_handles_r.slice(src_range_looped)); | dst_handles_r.slice(dst_range_looped).copy_from(src_handles_r.slice(src_range_looped)); | ||||
| dst_types_l.slice(dst_range_looped).copy_from(src_types_l.slice(src_range_looped)); | dst_types_l.slice(dst_range_looped).copy_from(src_types_l.slice(src_range_looped)); | ||||
| dst_types_r.slice(dst_range_looped).copy_from(src_types_r.slice(src_range_looped)); | dst_types_r.slice(dst_range_looped).copy_from(src_types_r.slice(src_range_looped)); | ||||
| dst_index += increment; | dst_index += increment; | ||||
| } | } | ||||
| if (start_point_trimmed) { | if (start_point_trimmed) { | ||||
| dst_handles_l[dst_range.first() + 1] = start_point_insert.handle_next; | dst_handles_l[dst_range.first() + 1] = start_point_insert.handle_next; | ||||
| /* No need to set handle type (remains the same)! */ | /* No need to change handle type (remains the same). */ | ||||
| } | } | ||||
| /* Handle 'end_point' */ | /* Handle 'end_point' */ | ||||
| bke::curves::bezier::Insertion end_point_insert; | bke::curves::bezier::Insertion end_point_insert; | ||||
| if (end_point.is_controlpoint()) { | if (end_point.parameter == 0.0f) { | ||||
| /* Do nothing, the 'end_point' control point is included in the copy iteration. */ | if (end_point.index == start_point.index) { | ||||
| /* Start point is same point or in the same segment. */ | |||||
| if (start_point.parameter == 0.0f) { | |||||
| /* Same point. */ | |||||
| BLI_assert(dst_range.size() == 1LL + src_range.size_range()); | |||||
| dst_handles_l[dst_range.first()] = dst_positions[dst_range.first()]; | |||||
| dst_handles_r[dst_range.last()] = dst_positions[dst_range.first()]; | |||||
| } | |||||
| else if (start_point.parameter == 1.0f) { | |||||
| /* Start is next controlpoint, do nothing. */ | |||||
| } | |||||
| else { | |||||
| /* Within the segment. */ | |||||
| BLI_assert(dst_range.size() == 1LL + src_range.size_range() || dst_range.size() == 2); | |||||
| dst_handles_r[dst_range.last()] = start_point_insert.handle_prev; | |||||
| } | |||||
| } | |||||
| /* Start point is considered 'before' the endpoint and ignored. */ | |||||
| } | |||||
| else if (end_point.parameter == 1.0f) { | |||||
| if (end_point.next_index == start_point.index) { | |||||
| /* Start point is same or in 'next' segment. */ | |||||
| if (start_point.parameter == 0.0f) { | |||||
| /* Same point */ | |||||
| BLI_assert(dst_range.size() == 1LL + src_range.size_range()); | |||||
| dst_handles_l[dst_range.first()] = dst_positions[dst_range.first()]; | |||||
| dst_handles_r[dst_range.last()] = dst_positions[dst_range.first()]; | |||||
| } | |||||
| else if (start_point.parameter == 1.0f) { | |||||
| /* Start is next controlpoint, do nothing. */ | |||||
| } | |||||
| else { | |||||
| /* In next segment. */ | |||||
| BLI_assert(dst_range.size() == 1LL + src_range.size_range() || dst_range.size() == 2); | |||||
| dst_handles_r[dst_range.last()] = start_point_insert.handle_prev; | |||||
| } | |||||
| } | |||||
| } | } | ||||
| else { | else { | ||||
| /* Trimmed in both ends within the same (and only) segment! Ensure both end points is not a | /* Trimmed in both ends within the same (and only) segment! Ensure both end points is not a | ||||
| * loop. */ | * loop. */ | ||||
| if (start_point_trimmed && start_point.index == end_point.index && | if (start_point.index == end_point.index && start_point.parameter < 1.0f) { | ||||
| start_point.parameter <= end_point.parameter) { | BLI_assert(dst_range.size() == 2 || dst_range.size() == 2ll + src_range.size_range() || | ||||
| dst_range.size() == 1LL + src_range.size_range()); | |||||
| if (start_point.parameter > end_point.parameter && start_point.parameter < 1.0f) { | |||||
| /* Start point comes after the endpoint within the segment. */ | |||||
| BLI_assert(end_point.parameter >= 0.0f); | |||||
| const float parameter = end_point.parameter / start_point.parameter; | |||||
| end_point_insert = bke::curves::bezier::insert(dst_positions[dst_index - 1], | |||||
| start_point_insert.handle_prev, | |||||
| start_point_insert.left_handle, | |||||
| start_point_insert.position, | |||||
| parameter); | |||||
| /* Copy following segment control point. */ | /* Update startpoint handle. */ | ||||
| dst_positions[dst_index] = src_positions[end_point.next_index]; | dst_handles_l[dst_range.first()] = end_point_insert.handle_next; | ||||
| dst_handles_r[dst_index] = src_handles_r[end_point.next_index]; | } | ||||
| else { | |||||
| /* Start point lies before the endpoint within the segment. */ | |||||
| /* Compute interpolation in the result curve. */ | |||||
| const float parameter = (end_point.parameter - start_point.parameter) / | const float parameter = (end_point.parameter - start_point.parameter) / | ||||
| (1.0f - start_point.parameter); | (1.0f - start_point.parameter); | ||||
| end_point_insert = knot_insert_bezier( | /* Unused only when parameter == 0.0f! */ | ||||
| dst_positions, | const float3 handle_next = start_point.parameter == 0.0f ? | ||||
| dst_handles_l, | src_handles_l[end_point.next_index] : | ||||
| dst_handles_r, | start_point_insert.handle_next; | ||||
| {{int(dst_range.first()), int(dst_range.first() + 1)}, parameter}); | end_point_insert = bke::curves::bezier::insert(dst_positions[dst_index - 1], | ||||
| dst_handles_r[dst_index - 1], | |||||
| handle_next, | |||||
| src_positions[end_point.next_index], | |||||
| parameter); | |||||
| } | |||||
| } | } | ||||
| else { | else { | ||||
| /* General case, compute the insertion point. */ | /* General case, compute the insertion point. */ | ||||
| end_point_insert = knot_insert_bezier( | end_point_insert = knot_insert_bezier( | ||||
| src_positions, src_handles_l, src_handles_r, end_point); | src_positions, src_handles_l, src_handles_r, end_point); | ||||
| if ((start_point.parameter >= end_point.parameter && end_point.index == start_point.index) || | |||||
| (start_point.parameter == 0.0f && end_point.next_index == start_point.index)) { | |||||
| /* Start point is next controlpoint. */ | |||||
| dst_handles_l[dst_range.first()] = end_point_insert.handle_next; | |||||
| /* No need to change handle type (remains the same). */ | |||||
| } | |||||
| } | } | ||||
| dst_handles_r[dst_index - 1] = end_point_insert.handle_prev; | dst_handles_r[dst_index - 1] = end_point_insert.handle_prev; | ||||
| dst_types_r[dst_index - 1] = src_types_l[end_point.index]; | dst_types_r[dst_index - 1] = src_types_l[end_point.index]; | ||||
| dst_handles_l[dst_index] = end_point_insert.left_handle; | dst_handles_l[dst_index] = end_point_insert.left_handle; | ||||
| dst_handles_r[dst_index] = end_point_insert.right_handle; | dst_handles_r[dst_index] = end_point_insert.right_handle; | ||||
| dst_positions[dst_index] = end_point_insert.position; | dst_positions[dst_index] = end_point_insert.position; | ||||
| ▲ Show 20 Lines • Show All 207 Lines • ▼ Show 20 Lines | static void trim_evaluated_curves(const bke::CurvesGeometry &src_curves, | ||||
| for (bke::AttributeTransferData &attribute : transfer_attributes) { | for (bke::AttributeTransferData &attribute : transfer_attributes) { | ||||
| attribute_math::convert_to_static_type(attribute.meta_data.data_type, [&](auto dummy) { | attribute_math::convert_to_static_type(attribute.meta_data.data_type, [&](auto dummy) { | ||||
| using T = decltype(dummy); | using T = decltype(dummy); | ||||
| threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) { | threading::parallel_for(selection.index_range(), 512, [&](const IndexRange range) { | ||||
| for (const int64_t curve_i : selection.slice(range)) { | for (const int64_t curve_i : selection.slice(range)) { | ||||
| /* Interpolate onto the evaluated point domain and sample the evaluated domain. */ | /* Interpolate onto the evaluated point domain and sample the evaluated domain. */ | ||||
| const IndexRange src_evaluated_points = src_curves.evaluated_points_for_curve(curve_i); | const IndexRange src_evaluated_points = src_curves.evaluated_points_for_curve(curve_i); | ||||
| GArray evaluated_data(CPPType::get<T>(), src_evaluated_points.size()); | GArray<> evaluated_data(CPPType::get<T>(), src_evaluated_points.size()); | ||||
| GMutableSpan evaluated_span = evaluated_data.as_mutable_span(); | GMutableSpan evaluated_span = evaluated_data.as_mutable_span(); | ||||
| src_curves.interpolate_to_evaluated( | src_curves.interpolate_to_evaluated( | ||||
| curve_i, attribute.src.slice(src_curves.points_for_curve(curve_i)), evaluated_span); | curve_i, attribute.src.slice(src_curves.points_for_curve(curve_i)), evaluated_span); | ||||
| sample_interval_linear<T>(evaluated_span.typed<T>(), | sample_interval_linear<T>(evaluated_span.typed<T>(), | ||||
| attribute.dst.span.typed<T>(), | attribute.dst.span.typed<T>(), | ||||
| src_ranges[curve_i], | src_ranges[curve_i], | ||||
| dst_curves.points_for_curve(curve_i), | dst_curves.points_for_curve(curve_i), | ||||
| start_points[curve_i], | start_points[curve_i], | ||||
| ▲ Show 20 Lines • Show All 302 Lines • Show Last 20 Lines | |||||