[Bf-blender-cvs] [4135c7786e4] blender2.8: Multi-Objects: CURVE_OT_separate

Dalai Felinto noreply at git.blender.org
Fri Nov 2 16:17:12 CET 2018


Commit: 4135c7786e479737a26b9ad2ebce90cee31566ff
Author: Dalai Felinto
Date:   Fri Nov 2 12:13:44 2018 -0300
Branches: blender2.8
https://developer.blender.org/rB4135c7786e479737a26b9ad2ebce90cee31566ff

Multi-Objects: CURVE_OT_separate

This is also a first take on trying to handle errors for partial
succeeded operators. Handling it all manually for now.

For the remaining operators I will use changed_multi to get over with
multi-objects. But we can handle their errors in a separate pass.

===================================================================

M	source/blender/editors/curve/editcurve.c

===================================================================

diff --git a/source/blender/editors/curve/editcurve.c b/source/blender/editors/curve/editcurve.c
index 72eb0d41242..13a5039f576 100644
--- a/source/blender/editors/curve/editcurve.c
+++ b/source/blender/editors/curve/editcurve.c
@@ -1294,61 +1294,115 @@ static int separate_exec(bContext *C, wmOperator *op)
 	Scene *scene = CTX_data_scene(C);
 	ViewLayer *view_layer = CTX_data_view_layer(C);
 	View3D *v3d = CTX_wm_view3d(C);
-	Object *oldob, *newob;
-	Base *oldbase, *newbase;
-	Curve *oldcu, *newcu;
-	EditNurb *newedit;
-	ListBase newnurb = {NULL, NULL};
-
-	oldbase = CTX_data_active_base(C);
-	oldob = oldbase->object;
-	oldcu = oldob->data;
-
-	if (oldcu->key) {
-		BKE_report(op->reports, RPT_ERROR, "Cannot separate a curve with vertex keys");
-		return OPERATOR_CANCELLED;
-	}
+
+	struct {
+		int changed;
+		int unselected;
+		int error_vertex_keys;
+		int error_generic;
+	} status = {0};
 
 	WM_cursor_wait(1);
 
-	/* 1. duplicate geometry and check for valid selection for separate */
-	adduplicateflagNurb(oldob, v3d, &newnurb, SELECT, true);
+	uint bases_len = 0;
+	Base **bases = BKE_view_layer_array_from_bases_in_edit_mode_unique_data(view_layer, &bases_len);
+	for (uint b_index = 0; b_index < bases_len; b_index++) {
+		Base *oldbase = bases[b_index];
+		Base *newbase;
+		Object *oldob, *newob;
+		Curve *oldcu, *newcu;
+		EditNurb *newedit;
+		ListBase newnurb = {NULL, NULL};
+
+		oldob = oldbase->object;
+		oldcu = oldob->data;
 
-	if (BLI_listbase_is_empty(&newnurb)) {
-		WM_cursor_wait(0);
-		BKE_report(op->reports, RPT_ERROR, "Cannot separate current selection");
-		return OPERATOR_CANCELLED;
-	}
+		if (oldcu->key) {
+			status.error_vertex_keys++;
+			continue;
+		}
+
+		if (!ED_curve_select_check(v3d, oldcu->editnurb)) {
+			status.unselected++;
+			continue;
+		}
 
-	/* 2. duplicate the object and data */
-	newbase = ED_object_add_duplicate(bmain, scene, view_layer, oldbase, 0); /* 0 = fully linked */
-	DEG_relations_tag_update(bmain);
+		/* 1. Duplicate geometry and check for valid selection for separate. */
+		adduplicateflagNurb(oldob, v3d, &newnurb, SELECT, true);
+
+		if (BLI_listbase_is_empty(&newnurb)) {
+			status.error_generic++;
+			continue;
+		}
 
-	newob = newbase->object;
-	newcu = newob->data = BKE_curve_copy(bmain, oldcu);
-	newcu->editnurb = NULL;
-	id_us_min(&oldcu->id); /* because new curve is a copy: reduce user count */
+		/* 2. Duplicate the object and data. */
+		newbase = ED_object_add_duplicate(bmain, scene, view_layer, oldbase, 0); /* 0 = fully linked. */
+		DEG_relations_tag_update(bmain);
 
-	/* 3. put new object in editmode, clear it and set separated nurbs */
-	ED_curve_editnurb_make(newob);
-	newedit = newcu->editnurb;
-	BKE_nurbList_free(&newedit->nurbs);
-	BKE_curve_editNurb_keyIndex_free(&newedit->keyindex);
-	BLI_movelisttolist(&newedit->nurbs, &newnurb);
+		newob = newbase->object;
+		newcu = newob->data = BKE_curve_copy(bmain, oldcu);
+		newcu->editnurb = NULL;
+		id_us_min(&oldcu->id); /* Because new curve is a copy: reduce user count. */
 
-	/* 4. put old object out of editmode and delete separated geometry */
-	ED_curve_editnurb_load(bmain, newob);
-	ED_curve_editnurb_free(newob);
-	curve_delete_segments(oldob, v3d, true);
+		/* 3. Put new object in editmode, clear it and set separated nurbs. */
+		ED_curve_editnurb_make(newob);
+		newedit = newcu->editnurb;
+		BKE_nurbList_free(&newedit->nurbs);
+		BKE_curve_editNurb_keyIndex_free(&newedit->keyindex);
+		BLI_movelisttolist(&newedit->nurbs, &newnurb);
 
-	DEG_id_tag_update(&oldob->id, OB_RECALC_DATA);  /* this is the original one */
-	DEG_id_tag_update(&newob->id, OB_RECALC_DATA);  /* this is the separated one */
+		/* 4. Put old object out of editmode and delete separated geometry. */
+		ED_curve_editnurb_load(bmain, newob);
+		ED_curve_editnurb_free(newob);
+		curve_delete_segments(oldob, v3d, true);
 
-	WM_event_add_notifier(C, NC_GEOM | ND_DATA, oldob->data);
-	WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, newob);
+		DEG_id_tag_update(&oldob->id, OB_RECALC_DATA);  /* This is the original one. */
+		DEG_id_tag_update(&newob->id, OB_RECALC_DATA);  /* This is the separated one. */
 
+		WM_event_add_notifier(C, NC_GEOM | ND_DATA, oldob->data);
+		WM_event_add_notifier(C, NC_OBJECT | ND_DRAW, newob);
+		status.changed++;
+	}
+	MEM_freeN(bases);
 	WM_cursor_wait(0);
 
+	if (status.unselected == bases_len) {
+		BKE_report(op->reports, RPT_ERROR, "No point was selected");
+		return OPERATOR_CANCELLED;
+	}
+
+	if (status.error_vertex_keys || status.error_generic) {
+		const int tot_errors = status.error_vertex_keys + status.error_generic;
+
+		/* Some curves changed, but some curves failed: don't explain why it failed. */
+		if (status.changed) {
+			BKE_reportf(op->reports,
+			            RPT_INFO,
+			            tot_errors == 1 ? "%d curve could not be separated" :
+			                              "%d curves could not be separated",
+			                              tot_errors);
+			return OPERATOR_FINISHED;
+		}
+
+		/* All curves failed: If there is more than one error give a generic error report. */
+		if (((status.error_vertex_keys ? 1 : 0) + (status.error_generic ? 1 : 0)) > 1) {
+			BKE_report(op->reports,
+			           RPT_ERROR,
+			           tot_errors == 1 ? "Could not separate selected curves" :
+			                             "Could not separate selected curve");
+		}
+
+		/* All curves failed due to the same error. */
+		if (status.error_vertex_keys) {
+			BKE_report(op->reports, RPT_ERROR, "Cannot separate curves with vertex keys");
+		}
+		else {
+			BLI_assert(status.error_generic);
+			BKE_report(op->reports, RPT_ERROR, "Cannot separate current selection");
+		}
+		return OPERATOR_CANCELLED;
+	}
+
 	return OPERATOR_FINISHED;
 }



More information about the Bf-blender-cvs mailing list